作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
考虑以下最小的 C 程序:
案例编号 1 :
#include <stdio.h>
#include <string.h>
void foo(char* s)
{
char buffer[10];
strcpy(buffer,s);
}
int main(void)
{
foo("01234567890134567");
}
void main()
{
foo("012345678901345678");
^
}
foo(char*):
pushq %rbp
movq %rsp, %rbp
subq $48, %rsp
movq %rdi, -40(%rbp)
movq %fs:40, %rax
movq %rax, -8(%rbp)
xorl %eax, %eax
movq -40(%rbp), %rdx
leaq -32(%rbp), %rax
movq %rdx, %rsi
movq %rax, %rdi
call strcpy
movq -8(%rbp), %rax
xorq %fs:40, %rax
je .L2
call __stack_chk_fail
.L2:
leave
ret
.LC0:
.string "01234567890134567"
main:
pushq %rbp
movq %rsp, %rbp
movl $.LC0, %edi
call foo(char*)
movl $0, %eax
popq %rbp
ret
最佳答案
我相信你明白你已经实现了一些导致未定义行为的东西。因此,很难回答为什么它会因额外的字符串而失败而不会与原始字符串有关。它可能与内部编译器实现+受编译标志(如对齐、优化等)的影响有关。
您可以尝试反汇编二进制文件或创建汇编代码并查看缓冲区放在堆栈中的确切位置。您可以使用不同的优化级别执行相同的操作,以检查汇编代码和行为中的更改。
how does the OS (Windows in this case) detects the bad memory access? Normally as per the Windows documentation the default stack size is 1MB Stack Size. So I don't see how the OS detects that the address being accessed is outside the process memory specially when the minimum page size is normally 4k. Does the OS use the SP in this case to check the address?
strcpy
上失败(如果您编写足够的数据来访问某些禁止地址,它可以,但很可能不是这种情况) - 当它从
foo
函数返回时失败。
strcpy
只是覆盖了指向
foo
函数之后的下一条指令的下一条指令指针。因此,指令指针填充了来自“012345678901345678”字符串的数据,并尝试从“垃圾”地址获取下一条指令,但由于上述原因而失败。
关于c - 预期的缓冲区溢出并不总是导致程序崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33013195/
我是一名优秀的程序员,十分优秀!