如何从堆栈缓冲区溢出中恢复

问题描述 投票:0回答:2

这个问题超出了我的专业知识。在“C”中,如何从堆栈溢出中恢复? 您使用声明为

char string[12]
的字符变量,并将
12
字符移动到只有
11
字符空间的位置。如何检测中途堆栈溢出溢出?如果您确实检测到超限,如何解决问题并正常进行?

我这样做的方式是这样的:

  character dform[12];
  strcpy(dform,"june-11-2024"); when it should have been strcpy(dform,"jun-11-2024")
  checkdate(dform); /// you have just invoked a stack buffer overrun, as you've passed on into a subroutine. 
///  dform is only suppose to hold 11 characters and not 12 characters. 
////    the 12th character causes the stack buffer overrun. 

我如何在中途检测到它,如果是这样,请解决中游问题,然后在子例程中照常继续处理业务,然后传回更正后的值。

尝试过很多变通方法,但没有成功。但希望将其消灭在萌芽状态,然后修复并继续。 (这让我想起了C#的异常处理能力。)

c stack-overflow
2个回答
3
投票

你不知道。这是致命的。

dform
包含 12 个字符,包括尾随的 null,因此您已经编写了 13 个字符。代码的其他部分很可能已经在接下来的字节中存储了一些重要的内容,一旦您覆盖了它,就没有了知道它是什么的方法。您可以很容易想象在单个字节上写入零的后果是任意糟糕的场景(例如它包含
bool avert_global_armageddon = true;
。)

如果接下来的字节恰好位于未映射的页面上,理论上在某些系统上可以捕获 SIGSEGV 信号并恢复,因为在这种情况下实际上没有数据被覆盖。但对于像你描述的那样的错误来说,这实际上不太可能。

如果您知道如何检测溢出,请在有问题的访问之前执行此操作,如果您确定会发生溢出,请不要这样做!

如果您通过某种方式确实确定发生了缓冲区溢出等情况,则需要立即中止程序(例如

abort()
)。继续执行可能会造成更多损害(例如损坏更多内存或数据)或允许攻击者进行漏洞利用。


1
投票

您正在使用声明为 charstring[12] 的字符变量,并且您移动了 12 个字符;其中只有 11 个字符的空间。现在,如何检测中途堆栈溢出溢出。

在溢出发生后检测溢出是没有意义的,因为那时你的程序由于调用未定义的行为而已经处于不可预测的状态。

考虑:

if (strlen("june-11-2024") < sizeof dform) {
    strcpy(dform,"june-11-2024");
} else {
    // handle error here
}

或者使用更大的缓冲区大小,或者使用

malloc()
和 family 动态分配内存。

我如何在中途检测到它,如果是这样,请解决中游问题,然后在子例程中照常继续处理业务,然后传回更正后的值。

无法修复。假设您之后确实检测到它,请致电

abort()

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