pwnable 笔记 Toddler's Bottle - leg

考察基本的 ARM 汇编指令
leg

题目源码

main函数

main

key1函数

key1

key2函数

key2

key3函数

key3

题目分析

main()中:

   0x00008d84 <+72>:    add r2, r4, r3
   0x00008d88 <+76>:    ldr r3, [r11, #-16]
-> 0x00008d8c <+80>:    cmp r2, r3
 x 0x00008d90 <+84>:    bne 0x8da8 <main+108>
   0x00008d94 <+88>:    ldr r0, [pc, #44]   ; 0x8dc8 <main+140>
   0x00008d98 <+92>:    bl  0x1050c <puts>
   0x00008d9c <+96>:    ldr r0, [pc, #40]   ; 0x8dcc <main+144>
-> 0x00008da0 <+100>:   bl  0xf89c <system>

0x00008d84这里计算了r2r3r4,三个寄存器中数值的和,把结果赋给r2。然后把r11-16h赋给r3,最后比较r2r3是否相等。如果相等的话0x00008d90处的bne(非0则跳)将不会发生,程序会继续进行下去,一直到0x00008da0 <+100>调用system()打印flag

通过分析可以发现r11-16h的值是0x00008d64处程序调用scanf得到的我们所输入的值。

继续分析三个寄存器中的数值是从哪里来的:

   0x00008d68 <+44>:    bl  0x8cd4 <key1>
-> 0x00008d6c <+48>:    mov r4, r0
   0x00008d70 <+52>:    bl  0x8cf0 <key2>
-> 0x00008d74 <+56>:    mov r3, r0
   0x00008d78 <+60>:    add r4, r4, r3
   0x00008d7c <+64>:    bl  0x8d20 <key3>
-> 0x00008d80 <+68>:    mov r3, r0
   0x00008d84 <+72>:    add r2, r4, r3

main()中可以看到这三个寄存器中的数值来自key1()key2()key3()被调用后,寄存器r0中的值。

所以当我们输入的数值等于key1key2key3三个函数执行后寄存器r0的值的总和,即可以得到flag

解题过程

   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

key1()r3 = pc , r0 = r3
arm中程序计数器pc指向下两条指令的地址)

最终 r0 = pc = 0x8cdc + 0x8

   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

key2()r3 = pc , r0 = r3

这里有一条ADDS指令,看样子像是对r3进行了操作

   0x00008d06 <+22>:    adds    r3, #4

但是查一下用法,发现ADDS 指令只是把 r3 + 4h 的值存入当前状态寄存器CPSR中,并不对r3的值进行修改,相当于 CPSR = r3 + 4

(注: ADD r3, #4r3 进行修改,相当于 r3 = r3 + 4

所以最终 r0 = pc = 0x8d04 + 0x8

   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

最后的key3()r3 = lr , r0 = r3

lr 是连接寄存器 (Link Register) 当程序通过BLBLX指令调用子程序时,R14被设置成该子程序的返回地址

   0x00008d7c <+64>:    bl  0x8d20 <key3>
   0x00008d80 <+68>:    mov r3, r0

main()调用key3()时,key3()的返回地址是它的下一条指令的地址 即 lr = 0x8d80
最终 r0 = lr = 0x8d80

现在已经找到了三个r0的值,相加即可
py

ans

More

关于ARM寄存器指令的更多信息可以看一下我这里的总结:
http://blog.csdn.net/smalosnail/article/details/53065048
http://blog.csdn.net/smalosnail/article/details/53048784

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

TaQini852

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值