第一次做ARM逆向的题目

Posted by rk700 on December 25, 2014

把ARM环境搭好后,就可以动态调试了。之前一道arm逆向的题目,由于没有环境一直只能静态分析,但对arm完全不熟,进行不下去。果然能动态调试就好了。

题目给了一个.c文件和一个.asm文件。我首先编译.c文件,但发现得到的结果用了好多thumb的16 bits的代码,而这和给的.asm文件是不同的。搜索后发现需要指定-marm。于是

$ gcc leg.c -g -marm -o leg

然后就可以用gdb一步步看了,非常清楚。

特别地,我之前还一直以为执行时寄存器pc里的值是下一条指令的地址,但发现实际是

The address of the currently executing instruction is typically PC-8 for ARM, or PC-4 for Thumb.

pc里应该是当前执行的地址加8。所以函数key1里:

0x00008cdc <+8>: mov r3, pc
0x00008ce0 <+12>:    mov r0, r3

会把0x8cdc+8=0x8ce4放到r3r0,即返回0x8ce4

而函数key3里:

0x00008d28 <+8>: mov r3, lr
0x00008d2c <+12>:    mov r0, r3

由于调用key3时返回地址lr0x8d80,于是key3返回0x8d80

最后来看函数key2:

0x00008cf8 <+8>: push    {r6}        ; (str r6, [sp, #-4]!)
0x00008cfc <+12>:    add r6, pc, #1
0x00008d00 <+16>:    bx  r6
0x00008d04 <+20>:    mov r3, pc
0x00008d06 <+22>:    adds    r3, #4
0x00008d08 <+24>:    push    {r3}
0x00008d0a <+26>:    pop {pc}
0x00008d0c <+28>:    pop {r6}        ; (ldr r6, [sp], #4)
0x00008d10 <+32>:    mov r0, r3

0x8cfc那里,会把r6的值设为0x8cfc+8+1=0x8d05,然后bx r6会转成thumb模式。而这里0x8d05不是2的倍数,用gdb调试发现执行时因为对齐,似乎会从2的倍数那里执行,即0x8d04。因为是thumb模式,于是接下来又把r3设为0x8d04+4+4=0x8d0c,作为返回值。

综上,需要输入的数是0x8ce4+0x8d80+0x8d0c=108400

补充:大概查了下,关于bx的地址有加1那里,加1是为了指定跳转到thumb模式,如果还是跳到arm模式就不需要了;此外即使加了1,bx最后取的地址还是没加1的