gpt4 book ai didi

c++ - 如何知道返回地址在栈上的位置c/c++

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:42:05 27 4
gpt4 key购买 nike

我一直在阅读有关可以覆盖其返回地址的函数。

void foo(const char* input)
{
char buf[10];

//What? No extra arguments supplied to printf?
//It's a cheap trick to view the stack 8-)
//We'll see this trick again when we look at format strings.
printf("My stack looks like:\n%p\n%p\n%p\n%p\n%p\n% p\n\n"); //%p ie expect pointers

//Pass the user input straight to secure code public enemy #1.
strcpy(buf, input);
printf("%s\n", buf);

printf("Now the stack looks like:\n%p\n%p\n%p\n%p\n%p\n%p\n\n");
}

有人建议这就是堆栈的样子

foo 的地址 = 00401000

我的堆栈看起来像:
00000000
00000000
7FFDF000
0012FF80
0040108A <-- 我们想覆盖 foo 的返回地址。
00410EDE

问题:
-.为什么作者要随意选择倒数第二个值作为foo()的返回地址?

-.值是从底部还是从顶部添加到堆栈?

  • 除了函数返回地址,我在堆栈上看到的其他值是什么?即为什么它不填充零

谢谢。

最佳答案

它上面的那个是之前的 EBP (0012FF80)。 prev-EBP 之上的值始终是返回地址。

(这显然假设非 FPO 二进制文件和 32 位 Windows)1

如果你还记得,序言是这样的:

push ebp      ; back up the previous ebp on the stack
mov ebp, esp ; set up the new frame pointer

以及调用函数时,例如

call 0x00401000

当前的 EIP 被压入栈中(用作返回地址),因此序言之后的栈如下所示:

[ebp+0xc]  ; contains parameter 1, etc
[ebp+0x8] ; contains parameter 0
[ebp+0x4] ; contains return address
[ebp] ; contains prev-EBP

因此对于每个 %p,printf 使用从 [ebp+0xc] 开始的接下来的 4 个字节(第一个 %p 参数) .最终,您命中了存储在堆栈中的前一个 EBP 值,即 (0012FF80),然后下一个是返回地址。

请注意,这些地址必须“有意义”,他们在这里清楚地做到了这一点(尽管可能并非所有人都“清楚”)。

关于问题 2)堆栈向下增长。所以当你push eax时,esp减去4,然后eax的值被移动到[esp],等价于代码:

push eax
; <=>
sub esp, 4
mov [esp], eax

  1. 这本书是编写安全代码,是吗?

关于c++ - 如何知道返回地址在栈上的位置c/c++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2666301/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com