我也要学iOS逆向工程--全局变量

Posted on 2015-01-30 12:13  dodolook  阅读(3708)  评论(13编辑  收藏

  大家好!很久不见了.我之前去音乐学院进修爵士吉他去了.现在回来了.之前我一直在学windows开发和逆向.后来到了音乐学院,老师推荐了1个录音软件叫logic prox.可惜啊!当时我只有个索尼的笔记本电脑,后来我在淘宝上找了个卖家,专门安装黑苹果的,结果我的电脑声卡驱动不了.这下完蛋了.后来.只有花血本买了个15寸视网膜macbook.再后来我安装了个xcode.哈哈!再后来没想到,MACOS,IOS 开发比 Windows 开发好玩多了.然后学了半年的 IOS 开发.觉得非常有意思.以至于logic prox现在我都没有学得好.不过也还在坚持学习当中了.现在我找到了一些资料和以前学习 Windows 开发时候的小经验,好好学学 IOS 逆向方面的知识.大家一起来吧.

全局变量:

  全局变量这下子懵了.在 IOS 下好像,我还没有用到过.不过 OC 百分之90几都是 C,既然 C 有时候会用到全局变量.那么就从它开始吧.没准哪天分析的程序用到了呢.学习IOS逆向工程肯定要懂得arm汇编了.但是直接学习arm汇编好像很枯燥呢.干脆就不直接学了.通过分析程序再随时查阅吧.之前学习了x86汇编不知道对arm有帮助没?!

先看一段代码了:

 1 #import <UIKit/UIKit.h>
 2 #import "AppDelegate.h"
 3 
 4 int gi = 12;
 5 
 6 int addFunction() {
 7    
 8     return gi;
 9 }
10 
11 int main(int argc, char * argv[]) {
12 
断点13     int d = addFunction();
14     printf("%d\r\n", d);
15     @autoreleasepool {
16         return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
17     }
18 }

首先这里我们声明并初始化了1个全局变量gi;然后在13行处打一个断点,这样调试的时候就会停止在addFunction()函数这里了.我们先运行并打开反汇编窗口哦!

恩!不错,进到了不少眼熟的,比如push,mov sub add 不过还有好多不眼熟啊!什么str ldr什么的.不过先不去管这些.目前来说,我们所知道的线索是:

首先我们在addFunction下的断点.程序调试运行后,应用会停在这个函数上.如图,确实是这样的.那么说明bl这个指令应该就是调用指令,比如 X86里的call一样. bl 后面的0x15ddc应该就是函数地址了.我们先进去看看再说.

 

果然我们来到了0x15ddc.呵呵!但是又看到好多不认识的.什么movw,晕啊!多了个w什么意思的呢,先不管了.不过第2行的意思应该是把0x1a0c地址放进r0寄存器中.诶!我们不是要学习全局变量的吗.我差点给忘记了.那我们先看看gi这个全局变量的地址.我们用po &gi 打印下看看.

0x000177f4.我们先记下来.在学习x86的时候,我记得全局变量是写入了可执行文件的,也就是说,程序里要找到它要么是直接给出其地址,要么是给出1个基地址+偏移找到它的.我们在这里没有发现程序直接去找到它.不过我们发现了1点可疑的地方.[r0]. 这个寄存器加了个中括号.这说明,这里以r0的值作为地址去取了内存的值.然后依据这个线索,我们看看r0的值什么时候曾经被改变过的.第2行movw r0 #0x1a0c ;还有第4行 add r0, pc 这两条指令改变过它的.那么可以这么去假设了.0x1a0c是一个偏移.pc寄存器里的值是一个基地址. 这两者一加或者就是全局变量gi的地址.那么我们首先打印下pc寄存器的值

我们再打开计算器计算下.0x1a0c + 0x00015ddc = 0x177E8 .感觉不对.仔细想想肯定不对.但是又差不多太远.因为0x177E8 和0x177f4不很远.可惜不正确啊!

仔细想想.或者这个 PC 寄存器不是这么用的.或者这个PC寄存器是表示当前指令的地址.那我们改变下算法.

我们这样来 0x1a0c + 0x15de4 = 0x177F0. 哇!离0x177f4越来越近了.只差4字节了.

只差4了也!这4会是什么.查阅了下资料.arm里1条指令长度是32位也就是4字节.那么也就是说我们这里还要加上当前指令的长度4.这样正好就是全局变量gi的地址了.不知道这个算不算是迷信了.应该我想的是对的吧.

但是我们发现我们目前用的全局变量是申明的时候就初始化过了.如果申明的时候没有初始化过,会是什么情况呢,我们先看看代码

#import <UIKit/UIKit.h>
#import "AppDelegate.h"

int gi ;

int addFunction() {
   
    gi = 12;
    return gi;
}

int main(int argc, char * argv[]) {

断点    int d = addFunction();
    printf("%d\r\n", d);
    @autoreleasepool {
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}

然后看汇编代码:

同样我们安装刚才的算法计算下gi的地址:

然后再:0x1264 + 0xefddc +4 = 0xF1044. 晕死!完全不对.怎么回事呢?!

我们继续看看代码.我们发现后面好几条指令都有[r0], 也就是说,后面的一些指令做过这样的操作:以r0为地址取内存的值.这里有点思路了.或许没有初始化的全局变量是需要以基地址+偏移+4 然后再以这个值作为地址取内容的.好.我们去内存里以这个0xf1044以地址取内容

真好!确实是这样子的.

至此全局变量分析完了.之后我会继续学习其余的内容,比如函数啊.OC 里的方法啊.和其他什么的.反正我们的目标是看懂IOS反汇编.然后就可以分析自己和别人的app了.加油哦!我很喜欢有个女孩子的博客.叫  程序媛念茜. http://blog.csdn.net/yiyaaixuexi/   因为我觉得她写的东西都好酷.都还看不懂!努力学习吧!希望哪天能够读懂.像她一样的酷!