一尘不染

无效的读/写有时会导致分段错误,有时不会

linux

示例代码:

int main ()
{
  char b[] = {"abcd"};
  char *c = NULL;
  printf("\nsize: %d\n",sizeof(b));
  c = (char *)malloc(sizeof(char) * 3);
  memcpy(c,b,10);   // here invalid read and invalid write
  printf("\nb: %s\n",b);
  printf("\nc: %s\n",c);

  return 0;
}

在代码中,我已经执行了一些无效的读取和无效的写入,但是这个小程序可以正常工作,并且不会创建core dump

但是一旦进入我的大库,每当我进行1个字节的无效读取或无效写入时,它总是在创建核心转储。

题:

为什么有时我会通过无效的读/写操作获得核心转储,而有时却没有获得核心转储?


阅读 236

收藏
2020-06-03

共1个答案

一尘不染

您想要做的基本上是缓冲区溢出&在您的代码示例中,更具体地说是堆溢出。您有时只看到崩溃的原因取决于您正在访问的内存区域以及您是否有权访问/写入它(Dan
Fego对此做了很好的解释)。我认为Dan
Fego提供的示例更多地是关于堆栈溢出(欢迎更正!)。gcc具有与堆栈上的缓冲区溢出(堆栈粉碎)相关的保护。您可以在以下示例中看到此消息(基于堆栈的溢出):

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

int main (void)
{
    char b[] = { "abcdefghijk"};
    char c [8];
    memcpy (c, b, sizeof c + 1);      // here invalid read and invalid write
    printf ("\nsize: %d\n", sizeof b); 
    printf ("\nc: %s\n", c); 
    return 0;
}

样本输出:

$ ./a.out

size: 12

c: abcdefghi���
*** stack smashing detected ***: ./a.out terminated

可以使用-fno-stack-protectorgcc中的选项禁用此保护。
缓冲区溢出是导致安全漏洞的主要原因之一。不幸的是,像memcpy这样的功能不能检查这类问题,但是有一些方法可以防止此类问题。
希望这可以帮助!

2020-06-03