我有一个缓冲区溢出实验室用于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.然后让我自己的代码通向已经编写的其他函数的指定地址 .

提前谢谢,如果有任何问题让我感到困惑,请告诉我,我会尽力详细说明 .