IDA反汇编/反编译静态分析iOS模拟器程序(四)反汇编的符号信息与改名

原创 2013年05月16日 11:34:45

首先看看windows IDA和xcode的反汇编有什么不同。因为不确定直接分析UIKit的代码会不会有法律问题,还是自己写个例子吧。分析UIKit的时候因为没有完整的debugging symbols,所以得到的反汇编信息会比自己写的代码较少。

一个在命名空间ANameSpace的类DataInternal,一个DataModel的C++类,一个继承自UIButton的TestButton。演示的是TestButton的printLog函数。

这是源码:

namespace ANameSpace
{
    class DataInternal
    {
        int m_sample;
    public:
        void add();
    };
}

class DataModel {
    int m_count;
    int m_index;
    float m_number;
    std::vector<long> m_longData;
    double m_value;
    char m_name[10];
    ANameSpace::DataInternal m_internal;
    static DataModel* s_sharedInstance;
    DataModel();
public:
    int count();
    int index() { return m_index; }
    float number();
    static DataModel *sharedInstance();
    double getValueAfterAddedNumber(double number);
    void addLongData(long data);
};

class DataModel;

@interface TestButton : UIButton
{
    DataModel *m_model;
    NSString *m_printLog;
}

- (bool)inWindow;
@property (nonatomic, assign) DataModel *model;

@end

@interface TestButton (Construct)

+ (TestButton*)createAButton;
- (id)initWithNothing:(id)nilPointer;

@end

@interface TestButton (Test)

- (void)setParam1:(CGRect)p1 para2:(CGFloat)p2;
- (NSString*)printLog;

@end

- (NSString*)printLog
{
    if (m_model->count() == 0)
    {
        if (m_printLog)
            return m_printLog;
        else
            return @"ok";
    }
    else if (m_model->count() == 1)
    {
        if ([self model])
            return @"fine";
        else
            return @"error";
    }
    else
        return m_printLog;
}

这是IDA得到的反汇编:

__text:000026B5 ; =============== S U B R O U T I N E =======================================
__text:000026B5
__text:000026B5 ; Attributes: bp-based frame
__text:000026B5
__text:000026B5 __TestButton_Test__printLog_ proc near
__text:000026B5
__text:000026B5 arg_0           = dword ptr  8
__text:000026B5
__text:000026B5                 push    ebp
__text:000026B6                 mov     ebp, esp
__text:000026B8                 push    ebx
__text:000026B9                 push    edi
__text:000026BA                 push    esi
__text:000026BB                 sub     esp, 0Ch
__text:000026BE                 call    $+5
__text:000026C3                 pop     esi
__text:000026C4                 mov     ebx, ds:(_OBJC_IVAR_$_TestButton_m_model - 26C3h)[esi]
__text:000026CA                 mov     edi, [ebp+arg_0]
__text:000026CD                 mov     eax, [edi+ebx]
__text:000026D0                 mov     [esp], eax
__text:000026D3                 call    __ZN9DataModel5countEv ; DataModel::count(void)
__text:000026D8                 test    eax, eax
__text:000026DA                 jz      short loc_2713
__text:000026DC                 mov     eax, [edi+ebx]
__text:000026DF                 mov     [esp], eax
__text:000026E2                 call    __ZN9DataModel5countEv ; DataModel::count(void)
__text:000026E7                 cmp     eax, 1
__text:000026EA                 jnz     short loc_2729
__text:000026EC                 mov     eax, ds:(off_57FC - 26C3h)[esi]
__text:000026F2                 mov     [esp+4], eax
__text:000026F6                 mov     [esp], edi
__text:000026F9                 call    _objc_msgSend
__text:000026FE                 mov     ecx, eax
__text:00002700                 lea     edx, (cfstr_Error.isa - 26C3h)[esi] ; "error"
__text:00002706                 lea     eax, (cfstr_Fine.isa - 26C3h)[esi] ; "fine"
__text:0000270C                 test    ecx, ecx
__text:0000270E                 cmovz   eax, edx
__text:00002711                 jmp     short loc_2732
__text:00002713 ; ---------------------------------------------------------------------------
__text:00002713
__text:00002713 loc_2713:                               ; CODE XREF: __TestButton_Test__printLog_+25j
__text:00002713                 mov     eax, ds:(_OBJC_IVAR_$_TestButton_m_printLog - 26C3h)[esi]
__text:00002719                 mov     ecx, [edi+eax]
__text:0000271C                 lea     eax, (cfstr_Ok.isa - 26C3h)[esi] ; "ok"
__text:00002722                 test    ecx, ecx
__text:00002724                 cmovnz  eax, ecx
__text:00002727                 jmp     short loc_2732
__text:00002729 ; ---------------------------------------------------------------------------
__text:00002729
__text:00002729 loc_2729:                               ; CODE XREF: __TestButton_Test__printLog_+35j
__text:00002729                 mov     eax, ds:(_OBJC_IVAR_$_TestButton_m_printLog - 26C3h)[esi]
__text:0000272F                 mov     eax, [edi+eax]
__text:00002732
__text:00002732 loc_2732:                               ; CODE XREF: __TestButton_Test__printLog_+5Cj
__text:00002732                                         ; __TestButton_Test__printLog_+72j
__text:00002732                 add     esp, 0Ch
__text:00002735                 pop     esi
__text:00002736                 pop     edi
__text:00002737                 pop     ebx
__text:00002738                 pop     ebp
__text:00002739                 retn
__text:00002739 __TestButton_Test__printLog_ endp

这是lldb的:

HursingTest`-[TestButton(Test) printLog] at TestButton.mm:51:
0x26b3:  pushl  %ebp
0x26b4:  movl   %esp, %ebp
0x26b6:  pushl  %ebx
0x26b7:  pushl  %edi
0x26b8:  pushl  %esi
0x26b9:  subl   $12, %esp
0x26bc:  calll  0x26c1                    ; -[TestButton(Test) printLog] + 14 at TestButton.mm:53
0x26c1:  popl   %esi
0x26c2:  movl   13207(%esi), %ebx
0x26c8:  movl   8(%ebp), %edi
0x26cb:  movl   (%edi,%ebx), %eax
0x26ce:  movl   %eax, (%esp)
0x26d1:  calll  0x2742                    ; DataModel::count() at DataModel.cpp:22
0x26d6:  testl  %eax, %eax
0x26d8:  je     0x2711                    ; -[TestButton(Test) printLog] + 94 at TestButton.mm:55
0x26da:  movl   (%edi,%ebx), %eax
0x26dd:  movl   %eax, (%esp)
0x26e0:  calll  0x2742                    ; DataModel::count() at DataModel.cpp:22
0x26e5:  cmpl   $1, %eax
0x26e8:  jne    0x2727                    ; -[TestButton(Test) printLog] + 116 at TestButton.mm:68
0x26ea:  movl   12607(%esi), %eax
0x26f0:  movl   %eax, 4(%esp)
0x26f4:  movl   %edi, (%esp)
0x26f7:  calll  0x352c                    ; symbol stub for: objc_msgSend
0x26fc:  movl   %eax, %ecx
0x26fe:  leal   13279(%esi), %edx
0x2704:  leal   13263(%esi), %eax
0x270a:  testl  %ecx, %ecx
0x270c:  cmovel %edx, %eax
0x270f:  jmp    0x2730                    ; -[TestButton(Test) printLog] + 125 at TestButton.mm:69
0x2711:  movl   13211(%esi), %eax
0x2717:  movl   (%edi,%eax), %ecx
0x271a:  leal   13247(%esi), %eax
0x2720:  testl  %ecx, %ecx
0x2722:  cmovnel%ecx, %eax
0x2725:  jmp    0x2730                    ; -[TestButton(Test) printLog] + 125 at TestButton.mm:69
0x2727:  movl   13211(%esi), %eax
0x272d:  movl   (%edi,%eax), %eax
0x2730:  addl   $12, %esp
0x2733:  popl   %esi
0x2734:  popl   %edi
0x2735:  popl   %ebx
0x2736:  popl   %ebp
0x2737:  ret    

两者会有以下区别:

1.IDA计算出了成员变量的偏移地址并把symbol直接显示出来

IDA:__text:000026C4                 mov     ebx, ds:(_OBJC_IVAR_$_TestButton_m_model - 26C3h)[esi]
xcode:0x26c2:  movl   13207(%esi), %ebx

TestButton的成员变量DataModel* m_model以_OBJC_IVAR_$_TestButton_m_model 为名显示。(其中IVAR是Objective-C运行时的类型,其概念请参考xcode文档)
2.函数参数在IDA中被赋予名称,ebp+8为arg_0,ebp+12为arg_1。 arg即为argument的缩写,第n个参数在+号后面的偏移量不是绝对的,请参考《xcode反汇编调试iOS模拟器程序(三)查看Objective-C函数与参数》。在函数开头和代码中,名称都会直接替换掉实际偏移量。对于Objective-C函数,arg_0都是self。

IDA:__text:000026CA                 mov     edi, [ebp+arg_0]

xcode:0x26c8:  movl   8(%ebp), %edi

3.常数值型偏移地址被赋予名称,以loc_为前缀。

IDA:jmp     short loc_2732

xcode:0x270f:  jmp    0x2730                    ; -[TestButton(Test) printLog] + 125 at TestButton.mm:69

4.IDA是intel汇编,xcode是AT&T汇编。

另外,IDA在00002713处有一个全减号的注释,这是表示上面的代码不会顺序执行到下面,只可能是有跳转指令才会执行到这里。

在分析UIKit时,代码偏移地址在IDA和xcode间是相差很远的,因为IDA中的地址是相对于库文件的,xcode中的地址是相对于运行中的程序的。不过偏移地址的后三位会相同,因为linker会令部分地址对齐。


这个例子没用到局部变量,如果用到:

__text:0004F0AF __UIView_Geometry__convertSize_toView__ proc near
__text:0004F0AF                                         ; DATA XREF: __objc_const:0075E28Co
__text:0004F0AF
__text:0004F0AF var_18          = dword ptr -18h
__text:0004F0AF var_14          = dword ptr -14h
__text:0004F0AF var_10          = dword ptr -10h
局部变量,即 ebp-xxx 会被命名为 var_xxx。关于局部变量请参考《xcode反汇编调试iOS模拟器程序(六)函数出入口处的处理与局部变量

下面这个IDA特性也许比较激动人心:把鼠标悬停在000026EC行的off_57FC上,会有悬浮框显示这个名字的意义。


000026F9处是objc_msgSend函数,所以000026EC这里是在传递selector,悬浮框显示的是selector的字符串。其中aModel的a表示off_57FC处的是字符串。后边的分号注释中,第一行是交叉引用的信息(后面的章节再讲),第二行是symbol信息,所以000026EC行是表示把"model"这个selector字符串的起始地址传到edx。悬停鼠标就能看到,相比于xcode方便多了。

再方便一点,在off_57FC上右键单击,在菜单中选择Rename(或者按快捷键N)

即可为off_7E4960这个自动生成的名字改名,方便以后查看。因为它代表的是selector,所以直接改成selector的名字就最直观了。


修改完毕后就会显示为:

__text:000026EC                 mov     eax, ds:(model - 26C3h)[esi]

各种IDA自动生成的名字都可以改名,怎么易理解就怎么改。为了免除输入麻烦,可以双击off_7E4960跳转到那个地址,然后复制model这个字符串,再回到刚才的界面,rename,粘贴~~~

如果是带参数的selector,粘贴后,冒号会自动变成下划线的。
退出IDA的时候保存到idb文件,下次启动的时候,改名仍然有效。


上一篇:IDA反汇编/反编译静态分析iOS模拟器程序(三)函数表示与搜索函数

下一篇:IDA反汇编/反编译静态分析iOS模拟器程序(五)F5反编译

本文请勿转载。

版权声明:转载请注明出处:http://blog.csdn.net/hursing

自学 IDA PRO 反汇编so 的血泪史

一直就有写博客的想法,原因是看到好多 比较牛的人 一直在写,写他的收货,总结,纯技术教程。而我什么都没有,就不知道写什么。今天突然恨有感慨就 写下我的处女贴。 接触Android逆向已有1年多了,但只...

IDA PRO 静态反汇编与OllyDbg动态调试实战技巧汇总

 ********************************** 案例一: 使用IDA PRO+OllyDbg+PEview 追踪windows API 动态链接库函...

C++数值类型与string的相互转换

使用函数模板将基本数据类型(整型、字符型、实型、布尔型)转换成string。//ostringstream对象用来进行格式化的输出,常用于将各种类型转换为string类型 //ostringstrea...
  • K346K346
  • K346K346
  • 2016年03月18日 22:11
  • 27836

java 中的Scanner(非常详细不看后悔)

java.util.Scanner是Java5的新特征,主要功能是简化文本扫描。这个类最实用的地方表现在获取控制台输入,其他的功能都很鸡肋,尽管Java API文档中列举了大量的API方法,但是都不怎...

IDA反汇编/反编译静态分析iOS模拟器程序(七)识别类的信息

C++类的实质是个结构体。先举个例: class TestClass { int m_val1; int m_val2; public: int getVal1(); ...
  • hursing
  • hursing
  • 2013年05月31日 11:35
  • 9609

IDA反汇编/反编译静态分析iOS模拟器程序(二)加载文件与保存数据库

启动windows版的IDA,在Quickstart界面点击New,弹出一个对话框选择文件。也可以按取消后再把文件拖进IDA。由于Mac版的IDA没注册,没有save功能,所以只好先把Mac上的东西拷...
  • hursing
  • hursing
  • 2013年05月14日 09:56
  • 11644

IDA反汇编/反编译静态分析iOS模拟器程序

转载自:http://blog.csdn.net/hursing (一)利用IDA和LLDB探索WebCore的C++类的继承关系 开刀的类名叫 PluginWidgetIOS,利用lld...
  • zkdemon
  • zkdemon
  • 2016年06月24日 15:22
  • 4509

IDA反汇编/反编译静态分析iOS模拟器程序(六)交叉引用

交叉引用cross reference是指 这个地址的 数据或代码 引用了哪个地址 以及 被哪些地址的代码所引用。引用了哪个地址,在反汇编就能看出来,一行汇编代码自然只会引用一个地址。但被引用是一对多...
  • hursing
  • hursing
  • 2013年05月30日 14:43
  • 15947

IDA反汇编/反编译静态分析iOS模拟器程序(五)F5反编译

反编译是IDA最让人振奋的功能,它的本质是IDA的一个插件,不过会被当做hex-rays的另一个产品。既然是产品,那当然就另外收费,demo版是没有的。反编译的快捷键是F5,菜单位置在 顶部菜单Vie...
  • hursing
  • hursing
  • 2013年05月16日 17:20
  • 16319

IDA反汇编/反编译静态分析iOS模拟器程序(八)IDA for Mac

iOS多用OC(Objective-C)编程,Mac也类似,所以IDA for Mac对OC的支持似乎强些。Windows的IDA在反汇编某些SDK库文件时会识别不出OC的函数名,而且对OC运行时的结...
  • hursing
  • hursing
  • 2013年06月04日 10:23
  • 26020
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:IDA反汇编/反编译静态分析iOS模拟器程序(四)反汇编的符号信息与改名
举报原因:
原因补充:

(最多只允许输入30个字)