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

问题描述 投票:-2回答:1

我正在尝试为我的安全性类进行缓冲区溢出,不允许调用任何函数,我们需要跳转到秘密函数,并且还应返回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;
}
c pointers segmentation-fault buffer-overflow
1个回答
1
投票

在某些半汇编程序中,假设使用某种x86。 (BP是用于EBP或RBP的伪代码,假设您实际上并未针对16位模式进行编译。可能是32位模式,因此int与返回地址的宽度相同。)

; entrance:
; - stack has return address to main
push  bp                         ; decrement SP by a pointer width
mov   bp,sp
sub   sp, 10*sizeof(int)         ; reserve space for an array
;....
; doNotTouch[0] is probably at [bp - 10*sizeof(int)]

[循环到14时,首先覆盖i == 10处的已保存bp,然后返回到main的返回地址(这是正确的),然后覆盖更多的地址,最终导致seg错误。因此,您只需要执行*(doNotTouch + 11) = (int) &secret;-假设int是函数指针的大小。 (或者,如果编译器为堆栈对齐或自己使用留下空白,则可能要多一点。在调试版本中,其他本地变量将具有堆栈插槽。覆盖它们可能会导致无限循环,超出范围。)

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

secret返回时,实际上现在是main的返回,但它无法执行return 0;

所以秘密应该是:

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

免责声明:“ ....我认为。”

© www.soinside.com 2019 - 2024. All rights reserved.