[Pwn]
Pwnable.kr leg
· 2 分钟阅读 · @admin

先看题目提供的源码;

分析后知道只要我们输入的key等于key()、key2()和key3()的值的和就能得到flag。
key1()+key2()+key3()) == key
这三个函数都是内嵌的汇编。我们在来看题目提供的 gdb反汇编的代码。
key1()
(gdb) disass key1
Dump of assembler code for function key1:
0x00008cd4 <+0>: push {r11} ; (str r11, [sp, #-4]!)
0x00008cd8 <+4>: add r11, sp, #0
0x00008cdc <+8>: mov r3, pc
0x00008ce0 <+12>: mov r0, r3
0x00008ce4 <+16>: sub sp, r11, #0
0x00008ce8 <+20>: pop {r11} ; (ldr r11, [sp], #4)
0x00008cec <+24>: bx lr
End of assembler dump.
关键部分:
0x00008cdc <+8>: mov r3, pc
0x00008ce0 <+12>: mov r0, r3
arm汇编是以r0作为函数的返回值的,pc的值为当前地址+8 即0x00008cdc+ 8
key2()
(gdb) disass key2
Dump of assembler code for function key2:
0x00008cf0 <+0>: push {r11} ; (str r11, [sp, #-4]!)
0x00008cf4 <+4>: add r11, sp, #0
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
0x00008d14 <+36>: sub sp, r11, #0
0x00008d18 <+40>: pop {r11} ; (ldr r11, [sp], #4)
0x00008d1c <+44>: bx lr
End of assembler dump.
关键部分:
0x00008d00 <+16>: bx r6
0x00008d04 <+20>: mov r3, pc
0x00008d06 <+22>: adds r3, #4
......
0x00008d10 <+32>: mov r0, r3
r6 = 0x00008cfc + 8 +1 = 0x00008d04。 bx r6在r6地址处切换成thumb模式。在thumb模式下pc = 当前地址+4。r0 =r3 = 0x00008d04 +4+4
key3()
(gdb) disass key3
Dump of assembler code for function key3:
0x00008d20 <+0>: push {r11} ; (str r11, [sp, #-4]!)
0x00008d24 <+4>: add r11, sp, #0
0x00008d28 <+8>: mov r3, lr
0x00008d2c <+12>: mov r0, r3
0x00008d30 <+16>: sub sp, r11, #0
0x00008d34 <+20>: pop {r11} ; (ldr r11, [sp], #4)
0x00008d38 <+24>: bx lr
End of assembler dump.
关键部分
0x00008d28 <+8>: mov r3, lr
0x00008d2c <+12>: mov r0, r3
r0等于lr即key3()函数的返回地址0x00008d80。
最后得到的值全部相加就得108400。


