因为反汇编看到了调用 srand 和 rand 的 call,可能是我理解或解读错了?
4a63c4: c7 04 24 44 10 4b 00 movl $0x4b1044,(%esp)
4a63cb: e8 40 b0 f5 ff call 401410 <_printf>
4a63d0: 8d 44 24 18 lea 0x18(%esp),%eax
4a63d4: c7 04 24 51 10 4b 00 movl $0x4b1051,(%esp)
4a63db: 89 44 24 04 mov %eax,0x4(%esp)
4a63df: e8 64 62 f7 ff call 41c648 <_scanf>
4a63e4: a1 7c 80 4f 00 mov 0x4f807c,%eax
4a63e9: 39 44 24 18 cmp %eax,0x18(%esp)
4a63ed: 0f 84 af 00 00 00 je 4a64a2 <_main+0x102>
4a63f3: c7 04 24 69 10 4b 00 movl $0x4b1069,(%esp)
4a63fa: e8 11 b0 f5 ff call 401410 <_printf>
这是反汇编得到的部分代码,其中能看到 0x4a63cb 处一个 printf 和 0x4a63df 处一个 scanf ,分别是输出提示和读入输入(从提供的参数字符串也能确定)
0x4a63e9 处的 cmp 就是比对密码是否正确的指令,一方来自于 %eax ,另一方是 [%esp+0x18] ,这个地址作为参数传给了 scanf ,因此这里存储的输入,那么目标就是导出 %eax 的值。
下方 0x4a63ed 处的 je 就是当密码正确的时候跳转到对应的输出处,而没有跳转走意味着密码错误, 0x4a63f3 和 0x4a63fa 处的指令恰好就是装载密码错误提示并 printf 输出。利用这个 printf 调用,只要把第一个参数修改成 "%d" 而第二个参数处设为 %eax 就可以输出密码了
找到虚拟地址 0x4b1069 对应处的字符串(密码错误),修改前三个字节为 0x25 0x64 0x00 ,这个字符串就变成了 "%d";把 4a63ed 处的 je 指令修改为 89 44 24 04 即 mov %eax,0x4(%esp), 就将 %eax 的值放到了第二个参数处,多余的两个字节用 90 即空指令填充,避免破坏结构。此时再运行程序,随便输入一些内容,程序就告诉我们密码是多少了 |