-
-
[原创]一行函数分析 ios
-
发表于: 2013-4-14 20:37 4526
-
-(void)show:(NSString *)str
{
NSLog(,str);
}
最近,下班玩玩这个挺有意思的。
简要分析下debug,release版本。
0x000d4e5c <+0000> push {r7, lr} //此处压栈处理,此时 ro指向当前对象,r1指向show:的指针,(可以通过这个查看,print "%s",(char *)$r1 ),r2为str
0x000d4e5e <+0002> mov r7, sp //将当前栈顶,保存在r7中
0x000d4e60 <+0004> sub sp, #12 //再往下分配12字节的栈空间
0x000d4e62 <+0006> movw r3, #24926 ; 0x615e // 往r3低2个字节处,传递参数,下面的movt 往r3上面2个字节处赋值,其实这个赋值就是,相对下面PC寄存器的相对地址。
0x000d4e66 <+0010> movt r3, #0 ; 0x0
0x000d4e6a <+0014> add r3, pc //此处,根据上面r3相对位置,找"111%@"
0x000d4e6c <+0016> str r0, [sp, #8] //下面3行,将ro,r1,r2 压栈保存
0x000d4e6e <+0018> str r1, [sp, #4]
0x000d4e70 <+0020> str r2, [sp, #0]
0x000d4e72 <+0022> ldr r1, [sp, #0] //这里其实就是加载上面的r2寄存器值到r1,r2就是show:方法的str参数。
0x000d4e74 <+0024> mov r0, r3 // 将上面的"111%@" 赋值给r0,为NSLog的调用准备。
0x000d4e76 <+0026> blx 0xd9f5c <dyld_stub_NSLog> //NSLog的调用
0x000d4e7a <+0030> add sp, #12 //栈空间上移
0x000d4e7c <+0032> pop {r7, pc} //出栈 恢复r7,pc,出栈 PC相当于跳转。
release代码,更加简练
0x000bf8a0 <-[ViewController show:]+0>: push {r7, lr}
0x000bf8a2 <-[ViewController show:]+2>: movw r0, #18186 ; 0x470a
0x000bf8a6 <-[ViewController show:]+6>: mov r1, r2
0x000bf8a8 <-[ViewController show:]+8>: movt r0, #0 ; 0x0
0x000bf8ac <-[ViewController show:]+12>: mov r7, sp
0x000bf8ae <-[ViewController show:]+14>: add r0, pc
0x000bf8b0 <-[ViewController show:]+16>: blx 0xc2f68 <dyld_stub_NSLog>
0x000bf8b4 <-[ViewController show:]+20>: pop {r7, pc}
上面的看明白了,下面的你应该也懂了了。。。
经验总结:
看到blx,差不多就相当于x86中的Call,对应源代码中的消息发送。,看到” add r*, pc “时,应该是程序开始找参数了。。。
bx lr, pop {r4, r5, r6, r7, pc} 用于程序返回。
难的不会,写点简单的吧。。。
{
NSLog(,str);
}
最近,下班玩玩这个挺有意思的。
简要分析下debug,release版本。
0x000d4e5c <+0000> push {r7, lr} //此处压栈处理,此时 ro指向当前对象,r1指向show:的指针,(可以通过这个查看,print "%s",(char *)$r1 ),r2为str
0x000d4e5e <+0002> mov r7, sp //将当前栈顶,保存在r7中
0x000d4e60 <+0004> sub sp, #12 //再往下分配12字节的栈空间
0x000d4e62 <+0006> movw r3, #24926 ; 0x615e // 往r3低2个字节处,传递参数,下面的movt 往r3上面2个字节处赋值,其实这个赋值就是,相对下面PC寄存器的相对地址。
0x000d4e66 <+0010> movt r3, #0 ; 0x0
0x000d4e6a <+0014> add r3, pc //此处,根据上面r3相对位置,找"111%@"
0x000d4e6c <+0016> str r0, [sp, #8] //下面3行,将ro,r1,r2 压栈保存
0x000d4e6e <+0018> str r1, [sp, #4]
0x000d4e70 <+0020> str r2, [sp, #0]
0x000d4e72 <+0022> ldr r1, [sp, #0] //这里其实就是加载上面的r2寄存器值到r1,r2就是show:方法的str参数。
0x000d4e74 <+0024> mov r0, r3 // 将上面的"111%@" 赋值给r0,为NSLog的调用准备。
0x000d4e76 <+0026> blx 0xd9f5c <dyld_stub_NSLog> //NSLog的调用
0x000d4e7a <+0030> add sp, #12 //栈空间上移
0x000d4e7c <+0032> pop {r7, pc} //出栈 恢复r7,pc,出栈 PC相当于跳转。
release代码,更加简练
0x000bf8a0 <-[ViewController show:]+0>: push {r7, lr}
0x000bf8a2 <-[ViewController show:]+2>: movw r0, #18186 ; 0x470a
0x000bf8a6 <-[ViewController show:]+6>: mov r1, r2
0x000bf8a8 <-[ViewController show:]+8>: movt r0, #0 ; 0x0
0x000bf8ac <-[ViewController show:]+12>: mov r7, sp
0x000bf8ae <-[ViewController show:]+14>: add r0, pc
0x000bf8b0 <-[ViewController show:]+16>: blx 0xc2f68 <dyld_stub_NSLog>
0x000bf8b4 <-[ViewController show:]+20>: pop {r7, pc}
上面的看明白了,下面的你应该也懂了了。。。
经验总结:
看到blx,差不多就相当于x86中的Call,对应源代码中的消息发送。,看到” add r*, pc “时,应该是程序开始找参数了。。。
bx lr, pop {r4, r5, r6, r7, pc} 用于程序返回。
难的不会,写点简单的吧。。。
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
赞赏
他的文章
- [求助]静态分析 2017
- [原创] 一个动画功能的逆向 8388
- [求助] 亮哥的那篇文章,是不是现在不行了? 5263
- [原创]一行函数分析 ios 4527
- [求助]ios anti-debug 4402
看原图
赞赏
雪币:
留言: