使用scanf的简单缓冲区溢出(Mac OS X 10.6.5 64位)

使用scanf的简单缓冲区溢出(Mac OS X 10.6.5 64位),c,macos,64-bit,buffer,overflow,C,Macos,64 Bit,Buffer,Overflow,出于教育目的,我试图实现一个缓冲区溢出,将程序引导到不同的地址 这是c程序: #include <stdio.h> #include <stdlib.h> #include <string.h> void secret1(void) { puts("You found the secret function No. 1!\n"); } int main () { char string[2]; puts("Input: "); scanf("%s

出于教育目的,我试图实现一个缓冲区溢出,将程序引导到不同的地址

这是c程序:

#include <stdio.h> 
#include <stdlib.h>
#include <string.h>

void secret1(void) {
 puts("You found the secret function No. 1!\n");
}

int main () {
 char string[2];
 puts("Input: ");
 scanf("%s", string);
 printf("You entered %s.\n", string);
 return 0;
}
…即使新的伪RIP正确(即0x0000000100000d6c用于secret1,0x0000000100000d7e用于secret2),它也可以在不跳到任何函数的情况下对故障进行分段。偏移量和gdb告诉我的一样(或者说是不是?)

我注意到,当程序“足够大”以0x100000d结尾的内存区域中放置秘密函数时,我的任何尝试都不起作用当它们位于0x100000e的某个位置时,它就像一个符咒

当我在32位模式下编译它时(地址相应地改变),它也可以处理多个秘密函数,但不能在64位模式下编译

-fno-stack-protector // doesn't make any difference.

谁能给我解释一下这种奇怪的行为吗?非常感谢你

也许创建多个隐藏函数会在没有执行权限的情况下将它们全部放入内存页中。。。尝试使用mprotect显式地向该页面授予RWX权限。可能还有很多其他问题,但这是我要解决的第一个问题

至于-fno-stack-protector-gcc选项,我确信在gcc4.2.1中有一段时间这是模糊的。但在进一步使用它之后,我了解到为了启用金丝雀堆栈保护,sizeof(buffer)>=8必须为真。此外,它必须是一个字符缓冲区,除非指定-fstack protector all或-fnostack protector all选项,该选项甚至可以为不包含字符缓冲区的函数启用canaris。我使用前面提到的gcc版本运行OS X 10.6.5 64位操作系统,在我编写的缓冲区溢出漏洞攻击代码段上,使用-fstack protector all编译与不使用相关选项编译时,我的堆栈会发生变化(可能是因为被攻击的函数没有字符缓冲区)。因此,如果要确定此功能已禁用或启用,请确保使用选项的-all变体

...
void secret1(void) {
 puts("You found the secret function No. 1!\n");
}

void secret2(void) {
 puts("You found the secret function No. 2!\n");
}

void secret3(void) {
 puts("You found the secret function No. 3!\n");
}
...
-fno-stack-protector // doesn't make any difference.