反编译是IDA最让人振奋的功能,它的本质是IDA的一个插件,不过会被当做hex-rays的另一个产品。既然是产品,那当然就另外收费,demo版是没有的。反编译的快捷键是F5,菜单位置在 顶部菜单View->Open Subviews->Pseudocode。(有网友问到为什么按照第一篇的地址下载IDA后也没有F5,最终是发现他自己装了python,设了环境变量,这会令IDA工作不正常)
在显示反汇编的窗口中按F5,经过分析后,会多了一个标签栏Pseudocode-A:
继续上一节(可用两个浏览器窗口对比)的示例,以-[TestButton printLog]为例,可得到反编译代码:
__CFString *__cdecl _TestButton_Test__printLog_(void *a1) { int v1; // ebx@1 __CFString *result; // eax@3 void *v3; // ecx@3 v1 = OBJC_IVAR___TestButton_m_model; if ( DataModel__count(*(_DWORD *)((char *)a1 + OBJC_IVAR___TestButton_m_model)) ) { if ( DataModel__count(*(_DWORD *)((char *)a1 + v1)) == 1 ) { v3 = objc_msgSend(a1, (const __seg *)model[0]);// 改名前显示为v3 = objc_msgSend(a1, (const __seg *)off_57FC[0]); result = &cfstr_Fine; if ( !v3 ) result = &cfstr_Error; } else { result = *(__CFString **)((char *)a1 + OBJC_IVAR___TestButton_m_printLog); } } else { result = &cfstr_Ok; if ( *(_DWORD *)((char *)a1 + OBJC_IVAR___TestButton_m_printLog) ) result = *(__CFString **)((char *)a1 + OBJC_IVAR___TestButton_m_printLog); } return result; }
改名的操作同样可在反编译代码中进行,只是界面稍有不同。在off_57FC处右键单击,选择Rename global item。无论在反汇编还是反编译改名,都会在另一方同步修改。
Objective-C和C++一样,每个类的函数实际都可用static的C函数表示,第一参数是self或this指针。所以反编译代码中,参数a1的类型显示为void*,实际也就是id,类的实例对象,即self指针。相比源码,反编译中有许多冗余代码,而且好多的类型转换和解引用,这是难免的,代码写法太多,总不能要求IDA这么智能。其实看多了也就习惯了,O(∩_∩)O
再看另一个函数:
源码中 @symthesize model 会得到 -[TestButton setModel:]函数,其反编译代码为:
int __cdecl _TestButton_setModel__(int a1, int a2, int a3) { int result; // eax@1 result = OBJC_IVAR___TestButton_m_model; *(_DWORD *)(a1 + OBJC_IVAR___TestButton_m_model) = a3; return result; }实际上这个函数返回值应该是void,但编译器是没有void返回值概念的,总会把一些东西返回,只是没用。a2是selector,实质为字符串的起始地址,IDA只能识别为int。a3是Objective-C语法的第一个参数,即被setModel的model,我们知道它是DataModel*,即传来的是一个地址,也被IDA当做int了,即32bit的数值。 这个结果很容易看出来实际操作是 m_model = a3;
第3个例子:
- (bool)inWindow { return self.window != nil; }
bool __cdecl _TestButton_inWindow_(void *a1) { return objc_msgSend(a1, (const __seg *)off_57C4[0]) != 0; }
其中off_57C4改名后就是window。如此简单的源码才可能和反编译代码形同。另外也可看出,0可能会代表实际代码中的 NO,false,NULL,nil等。1则可能会代表YES,true。
当没有debugging symbol时,bool会被显示为char,因为bool是语法类型,不是编译器类型,占1个字节,和char相同。
上一篇:IDA反汇编/反编译静态分析iOS模拟器程序(四)反汇编的符号信息与改名
下一篇:IDA反汇编/反编译静态分析iOS模拟器程序(六)交叉引用
本文请勿转载。