把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放到r3和r0,即返回0x8ce4。
而函数key3里:
0x00008d28 <+8>: mov r3, lr 0x00008d2c <+12>: mov r0, r3
由于调用key3时返回地址lr是0x8d80,于是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的