void vuln( char * arg ) {
char buf[256];
strcpy(buf, arg);
}
反汇编为:
0x0804842b 55 push ebp
0x0804842c 89e5 mov ebp, esp
0x0804842e 81ec08010000 sub esp, 0x108
0x08048434 83ec08 sub esp, 8
0x08048437 ff7508 push dword [arg_8h]
0x0804843a 8d85f8feffff lea eax, ebp - 0x108
0x08048440 50 push eax
0x08048441 e8bafeffff call sym.imp.strcpy
0x08048446 83c410 add esp, 0x10
0x08048449 c9 leave
0x0804844a c3 ret
当参数为264 = 0x108时溢出字符,我期待256字节。为什么编译器用
sub esp,8
增加8个字节? #1 楼
根据SYS V i386 ABI,在执行
CALL
指令之前,堆栈必须以最小操作系统字对齐。 彼得·科德斯(Peter Cordes)对x86组装中的堆栈对齐的责任的回答的摘录:在函数输入时为16B对齐。 (即,ESP必须在CALL指令之前对齐16B,因此堆栈上的args从16B边界开始。这与x86-64 System V相同。)
另外,GCC通过defualt将堆栈对齐到16字节边界。为此,GCC将在函数的堆栈框架内的某个区域中分配额外的空间,而该区域不会被ABI限制:
其他区域取决于编译器和所编译的代码。标准调用序列没有定义最大堆栈框架大小,也没有限制语言系统如何使用标准堆栈框架的“未指定”区域。
在ABI中函数返回地址被认为是当前堆栈帧的一部分:
这些信息足以让我们确定编译器为何生成可创建未使用空间的代码在堆栈上。让我们检查一下代码,重点关注导致堆栈帧内存分配的指令:
0x0804842b 55 push ebp ( 1 )
0x0804842c 89e5 mov ebp, esp
0x0804842e 81ec08010000 sub esp, 0x108 ( 2 )
0x08048434 83ec08 sub esp, 8 ( 3 )
0x08048437 ff7508 push dword [arg_8h] ( 4 )
0x0804843a 8d85f8feffff lea eax, ebp - 0x108
0x08048440 50 push eax ( 5 )
0x08048441 e8bafeffff call sym.imp.strcpy ( 6 )
0x08048446 83c410 add esp, 0x10
0x08048449 c9 leave
0x0804844a c3 ret
返回地址被认为是当前堆栈帧的一部分。 i386机器具有32位体系结构,因此返回地址占用4个字节的空间,执行指令
push ebp
将使堆栈指针减少4个字节。 4 + 4 = 8,所以此时堆栈帧的大小为8个字节。
,这将创建264个字节的空间。
8 + 264 = 272
sub esp, 8
-有问题的特定说明。在堆栈框架上额外创建8个字节的空间。和以前一样,
push
具有添加4个字节空间的效果。280 + 4 = 284
另一个
push
。 /> 284 + 4 = 288
现在是时候执行
call
指令了。此时,堆栈帧的大小为288字节。让我们检查是否与16字节边界对齐:结论:
编译器使用
sub esp, 8
来保持堆栈框架对齐到16字节的边界。另请参见:
https://stackoverflow.com/questions/4175281/what-does-it-mean-对齐堆栈
https://software.intel.com/zh-cn/forums/intel-isa-extensions/topic/291241
评论
@ usr2564301是的,很好。我会改变它。谢谢。
– julian♦
17年12月29日在23:49
极好的答案@SYS_V。谢谢。您能解释一下为什么它为char buf [256]保留0x108(264)字节而不是0x100吗?
– Kartone
17年12月30日在1:07
@Kartone我能做的最好的猜测是:如果为缓冲区分配了264个字节,则我们有8 + 264 + 8 + 4 + 4 = 288,其中288%16 =0。但是,如果为缓冲区分配了256个字节,对于给定的代码,我们取而代之的是8 + 256 + 8 + 4 + 4 = 280,其中280%16 = 8,这意味着堆栈未正确对齐16字节边界。要对此进行更正,编译器将必须生成其他指令以对齐堆栈。
– julian♦
17/12/30在1:24
@Kartone没问题,欢迎您
– julian♦
17年12月30日在21:44
评论
可能是因为strcpy为什么呢什么 ?怎么样 ? :-)