掌握了基本技巧后,基本上已不难理解所有的反汇编结果。授之以鱼不如授之以渔:
通过观察自己写的代码的反汇编来掌握各种代码的反汇编结果,从而逆向推测系统代码的源码。
调试自己写的代码时,可以不断切换查看源码和反汇编来定位代码执行到何处
这里用分别用两个很简单的C++和Objective-C类来做示例:
class TestC { int m_var; public: int getVar(); void setVar(int var); }; @interface TestOC : NSObject { int m_var; } - (void)setVar:(int)var; @end int g_var = 0; int *g_pVar = &g_var; void TestC::setVar(int var) { int l_var = 0; l_var = var; m_var = var; g_var = var; *g_pVar = var; } @implementation TestOC - (void)setVar:(int)var { int l_var = 0; l_var = var; m_var = var; g_var = var; *g_pVar = var; } @end
在外部,这样调用:
- (void)viewDidLoad { TestC test; test.setVar(100); TestOC *t = [[TestOC new] autorelease]; [t setVar:100]; .......
分别在两个类的setVar加断点,看反汇编结果。
WebViewResearch`TestC::setVar(int) at TestClass.mm:15: 0x8bda: pushl %ebp 0x8bdb: movl %esp, %ebp 0x8bdd: calll 0x8be2 ; TestC::setVar(int) + 8 at TestClass.mm:15 0x8be2: popl %eax 0x8be3: movl 12(%ebp), %ecx 0x8be6: movl 8(%ebp), %edx 0x8be9: movl %ecx, (%edx) 0x8beb: movl %ecx, 30406(%eax) 0x8bf1: movl 29170(%eax), %eax 0x8bf7: movl %ecx, (%eax) 0x8bf9: popl %ebp 0x8bfa: ret
WebViewResearch`-[TestOC setVar:] at TestClass.mm:25: 0x8bfb: pushl %ebp 0x8bfc: movl %esp, %ebp 0x8bfe: pushl %esi 0x8bff: calll 0x8c04 ; -[TestOC setVar:] + 9 at TestClass.mm:29 0x8c04: popl %eax 0x8c05: movl 29372(%eax), %edx 0x8c0b: movl 16(%ebp), %ecx 0x8c0e: movl 8(%ebp), %esi 0x8c11: movl %ecx, (%esi,%edx) 0x8c14: movl %ecx, 30372(%eax) 0x8c1a: movl 29136(%eax), %eax 0x8c20: movl %ecx, (%eax) 0x8c22: popl %esi 0x8c23: popl %ebp 0x8c24: ret
以上是release版的结果。可以看到,编译器做了优化,没有实际用处的局部变量l_var直接被省略到了,既不为它分配空间,连对它的赋值语句都没要。
对于操作成员变量、全局变量,没法直观地看出来,需要自己计算好各个偏移,才会明白那些带括号的间接寻址的操作。这些麻烦的事情可以借助IPA Pro来看(后面会有一系列来讲)。
下面是调用两个类的setVar函数的反汇编语句。
0x441e: leal -16(%ebp), %eax 0x4421: movl %eax, (%esp) 0x4424: movl $100, 4(%esp) 0x442c: calll 0x8bda ; TestC::setVar(int) at TestClass.mm:15
0x445b: movl 45819(%esi), %ecx 0x4461: movl %ecx, 4(%esp) 0x4465: movl %eax, (%esp) 0x4468: movl $100, 8(%esp) 0x4470: calll 0x97c0 ; symbol stub for: objc_msgSend
可以看到C++能更直接地看出下一步的去向,OC则需要知道是哪个类的对象以及Selector(可用register read来查看)。
对比类的函数以及被调用处的行数,也可以间接地表明,Objective-C的效率会比C++慢一点,但也差不了多少。
Apple也有一些帮助反汇编调试的文档:
http://developer.apple.com/library/ios/#technotes/tn2239/_index.html
转载请注明出处:http://blog.csdn.net/hursing
(一)查看反汇编 |
(二)看懂反汇编 |
(三)查看Objective-C函数与参数 |
(四)自动断点应用之NSNotificationCenter |
(五)调试objc_msgSend函数 |
(六)函数出入口处的处理与局部变量 |
(七)Debug与Release的区别 |
|