Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C缓冲区溢出导致分段错误_C_Pointers_Segmentation Fault_Buffer Overflow - Fatal编程技术网

C缓冲区溢出导致分段错误

C缓冲区溢出导致分段错误,c,pointers,segmentation-fault,buffer-overflow,C,Pointers,Segmentation Fault,Buffer Overflow,我正在尝试为我的安全类执行缓冲区溢出,我们不允许调用任何函数,我们需要跳转到secret函数,并返回0而不出现分段错误。我写了下面的代码,并成功地跳转到秘密,但我得到了一个分段错误。我如何才能成功终止该程序?或者,当我尝试写一个地址而不是for循环时,是否可以只写一个地址,而不改变任何内容 #include <stdio.h> void secret() { printf("now inside secret()!\n"); } void entrance() {

我正在尝试为我的安全类执行缓冲区溢出,我们不允许调用任何函数,我们需要跳转到secret函数,并返回0而不出现分段错误。我写了下面的代码,并成功地跳转到秘密,但我得到了一个分段错误。我如何才能成功终止该程序?或者,当我尝试写一个地址而不是for循环时,是否可以只写一个地址,而不改变任何内容

#include <stdio.h>

void secret()
{
    printf("now inside secret()!\n");
}

void entrance()
{
    int doNotTouch[10];
    // can only modify this section BEGIN
    // cant call secret(), maybe use secret (pointer to function)
    for (int i = 0; i < 14; i++) {
        *(doNotTouch + i) = (int) &secret;
    }
    // can only modify this section END
    printf("now inside entrance()!\n");
}

int main (int argc, char *argv[])
{
    entrance();
    return 0;
}
#包括
无效机密()
{
printf(“现在是内部机密()!\n”);
}
无效入口()
{
int doNotTouch[10];
//只能从开始修改此部分
//无法调用secret(),可能使用secret(指向函数的指针)
对于(int i=0;i<14;i++){
*(doNotTouch+i)=(int)和secret;
}
//只能修改此节结束
printf(“现在在入口内()!\n”);
}
int main(int argc,char*argv[])
{
入口();
返回0;
}

在某些半汇编程序中,假设使用某种x86。(BP是EBP或RBP的伪代码,假设您实际上不是为16位模式编译。32位模式很可能是这样的
int
与返回地址的宽度相同。)

当循环到14时,首先覆盖i==10处保存的bp,然后覆盖main的返回地址(这是正确的),然后再覆盖一些,最终导致seg故障。所以你只需要做
*(doNotTouch+11)=(int)&secret-假设int是函数指针的大小。(如果编译器为堆栈对齐或自己的使用留下间隙,则可能会更多。在调试构建中,其他局部变量将有堆栈槽。覆盖它们可能会导致无限循环,超出范围。)

然后跟随printf,然后函数返回,但它不会返回到main,而是“跳转”到
secret

secret
返回时,它实际上是从main返回的,但它不能执行
返回0

所以秘密应该是:

int secret()
{
    printf("now inside secret()!\n");
    return 0;
}

免责声明:“……我想。”

我试过*(doNotTouch+11)=(int)和secret;但什么也没发生,程序正常执行,我不允许将返回0添加到secret中。为什么你认为正确的数字是11?doNotTouch由int组成,所以我认为它应该是4个字节*10=40个字节,帧ptr(我猜是4个字节)所以(doNotTouch+44)是我的猜测,它是整数还是字符不重要吗?
int doNotTouch[10]为0..9;指标10为血压;索引11是返回地址。但是您可以检查汇编程序,并在调试器中运行它,以查看发生了什么。在您的原始代码中还有一个int i。有些编译器分配的内存超过10个。
int secret()
{
    printf("now inside secret()!\n");
    return 0;
}