我无法弄清楚如何在 OS X 10.10.5 (Yosemite) 上禁用堆栈保护。我一直在拼凑来自各种在线线程的有希望的 gcc 标志,但到目前为止还没有设法禁用保护。我目前正在编译我的程序:
gcc -g3 -std=c99 -pedantic -Wall -m32 -fno-stack-protector -fno-sanitize=address -D_FORTIFY_SOURCE=0 -Wl,-no_pie -o program program.c
但是当我尝试粉碎堆栈时,我会出现段错误。
我在 Red Hat Enterprise Linux Server 7.2 (Maipo) 上尝试过相同的程序,在适当调整内存地址差异后,在编译后粉碎堆栈没有问题:
gcc -g3 -std=c99 -pedantic -Wall -m32 -fno-stack-protector -o program program.c
还可能值得注意的是,与大多数 Mac 一样,我机器上的 gcc 是 clang 的符号链接(Apple LLVM 版本 7.0.0 (clang-700.0.72))。
如何禁用 Yosemite 的堆栈保护?
额外细节
我正在使用的虚拟程序是:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int authenticate() {
char password[10];
printf("Enter password: ");
scanf("%s", password);
return strcmp(password, "1234567890") == 0;
}
void success() {
printf("Access granted\n");
exit(0);
}
void failure() {
printf("Access denied\n");
exit(1);
}
int main(int argc, char** argv) {
if (authenticate()) {
success();
} else {
failure();
}
}
当我运行时otool -tv program
,我注意到以下内容:
success
我要跳转到的例程在 address 0x00001e70
。
我们通常会返回的指令authenticate
位于 address 0x00001efe
。
当我gdb
在输入虚拟密码“xxxxxxxxxx”并使用 检查缓冲区后运行时x/30xb &password
,我观察到:
0xbffffc32: 0x78 0x78 0x78 0x78 0x78 0x78 0x78 0x78
0xbffffc3a: 0x78 0x78 0x00 0x00 0x00 0x00 0x00 0x00
0xbffffc42: 0x00 0x00 0xfc 0xfc 0xff 0xbf 0x68 0xfc
0xbffffc4a: 0xff 0xbf 0xfe 0x1e 0x00 0x00
我们想将第 270xfe
个字节覆盖为0x70
.
当我尝试按如下方式粉碎堆栈时:
printf "xxxxxxxxxxxxxxxxxxxxxxxxxx\x70" | ./program # 26 bytes of junk, followed by 0x70
我得到一个段错误。