粉碎堆栈示例3.c混乱
文章可以找到 我正在阅读有关粉碎堆栈的内容,发现自己被示例3.c卡住了粉碎堆栈示例3.c混乱,c,stack-overflow,buffer-overflow,disassembly,C,Stack Overflow,Buffer Overflow,Disassembly,文章可以找到 我正在阅读有关粉碎堆栈的内容,发现自己被示例3.c卡住了 0x80004a3 <main+19>: call 0x8000470 <function> 0x80004a8 <main+24>: addl $0xc,%esp 0x80004ab <main+27>: movl $0x1,0xfffffffc(%ebp) 0x80004b2 <main+34>: movl 0xfffff
0x80004a3 <main+19>: call 0x8000470 <function>
0x80004a8 <main+24>: addl $0xc,%esp
0x80004ab <main+27>: movl $0x1,0xfffffffc(%ebp)
0x80004b2 <main+34>: movl 0xfffffffc(%ebp),%eax
作者还说:“我们怎么知道在回信地址上加8呢?我们使用了
首先测试值(例如1)“他在哪里使用了这个测试值?这不是我对这篇文章的解释。按照我的理解,他想修改回信地址,使
x=1代码>赋值被跳过,即他希望函数
返回执行printf
的位置
正如您在反汇编中所看到的,分配是8个字节(c7 44 24 1c 01 00 00
),因此将返回地址向前移动8个字节将使其越过此指令。至于“我们首先使用了测试值”的评论。。也许他只是指他在反汇编程序中查看代码以计算长度,或者他尝试了不同的偏移量(?)文章中的位移是错误的,应该是10
字节。调用函数(或执行跳转)时,返回地址设置为等于指令指针+当前指令大小:
ret = IP + Curr_Inst_size
因此,当函数调用返回时,指令指针应等于0x80004a8
(0x80004a3
+调用指令大小):
实际指令大小取决于操作数、机器类型等。。但在本例中,addl
的长度为3字节,movl
的长度为7字节。您可以检查指令的确切大小,也可以编译和反汇编此代码,您将看到这两条指令的长度为10字节:
int main()
{
asm("addl $0xc,%esp\n\
movl $0x1,0xfffffffc(%ebp)");
}
gdb:
0x08048397:83 c4 0c添加$0xc,%esp
0x0804839a:c7 45 fc 01 00 movl$0x1,-0x4(%ebp)
在示例3中,也有关于这个完全相同的问题的讨论和讨论。根据用户请求转到StackOverflow。(+1,好问题。)如果你像那篇文章那样减去地址,你会得到10个字节:)检查我答案末尾的链接,偏移量是错误的。有一个答案说它现在已经被修改了。这是最新消息
0x80004a3 <main+19>: call 0x8000470 <function>
--> 0x80004a8 <main+24>: addl $0xc,%esp
0x80004ab <main+27>: movl $0x1,0xfffffffc(%ebp)
0x80004b2 <main+34>: movl 0xfffffffc(%ebp),%eax
0x80004a3 <main+19>: call 0x8000470 <function>
0x80004a8 <main+24>: addl $0xc,%esp
0x80004ab <main+27>: movl $0x1,0xfffffffc(%ebp)
--> 0x80004b2 <main+34>: movl 0xfffffffc(%ebp),%eax
int main()
{
asm("addl $0xc,%esp\n\
movl $0x1,0xfffffffc(%ebp)");
}
0x08048397 <+3>: 83 c4 0c add $0xc,%esp
0x0804839a <+6>: c7 45 fc 01 00 00 00 movl $0x1,-0x4(%ebp)