gpt4 book ai didi

C函数栈布局

转载 作者:行者123 更新时间:2023-12-04 11:04:25 25 4
gpt4 key购买 nike

我有一个看起来像这样的函数:

int bof(char *str)
{
char buffer[12];

strcpy(buffer, str);

return 1;
}

我正在尝试覆盖它的返回地址。我发现我可以通过使用例如 memcpy(buffer+24, "\x15\xf1\xff\xbf", 4) 来做到这一点。我不明白的是为什么我需要访问 buffer + 24。我对C内存模型的理解告诉我,这个函数执行时的栈应该是这样的

bottom of                                                            top of
memory memory
buffer(12) sfp(4) ret(4) str(4)
<------ [ ][ ][ ][ ] --->

top of bottom of
stack stack

这表明我应该将 ret 地址从 buffer+16 开始。额外的 8 个字节从哪里来?

顺便说一下,我在 32 位系统上运行它。

最佳答案

检查 ISO C 99 和更早的标准,您会发现没有 C 内存模型这样的东西。每个编译器都可以自由使用它喜欢的任何模型来满足功能规范。一个简单的例子是编译器可以使用或省略帧指针。它还可以为返回值分配空间或使用寄存器。

当我在我的机器上编译这段代码时,我得到

_bof:
pushl %ebp
movl %esp, %ebp
subl $40, %esp
movl 8(%ebp), %eax
movl %eax, 4(%esp)
leal -20(%ebp), %eax
movl %eax, (%esp)
call _strcpy
movl $1, %eax
leave
ret

leal 指令正在计算 bp-20 处的缓冲区起始位置。在序言之后,堆栈框架如下所示:

[ bp+8: str ] [bp+4: rtn address ] [bp: saved bp] [ bp-20: buf ] ...

因此看起来您必须写入 28 个字节才能更改此处的返回地址。我的猜测是编译器试图在段落边界上对齐堆栈帧。此处包括 strcpy arg 设置的完整帧为 48 字节,即 3 个段落。段落对齐有助于提高总线和缓存性能。

关于C函数栈布局,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13244531/

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