内存检测工具 AddressSanitizer

2020-11-11  本文已影响0人  wayyyy

AddressSanitizer 是一个内存检测工具。支持GCC 4.8 及以上。在编译时添加-fsanitize=address选项,如果为了得到更全面的信息可以用-fno-omit-frame-pointer

它可以检测出以下错误:

use after free
Heap buffer overflow
int main(int argc, char **argv) {
  int *array = new int[100];
  array[0] = 0;
  int res = array[argc + 100];  // BOOM
  delete [] array;
  return res;
}
g++ -fsanitize=address
Stack buffer overflow
int main(int argc, char **argv) {
    int stack_array[100];
    stack_array[1] = 0;
    return stack_array[argc + 100];  // BOOM
}
Global buffer overflow
int global_array[100] = {-1};
int main(int argc, char **argv) {
  return global_array[argc + 100];  // BOOM
}
Use after return
int *ptr;
__attribute__((noinline))
void FunctionThatEscapesLocalObject() {
  int local[100];
  ptr = &local[0];
}

int main(int argc, char **argv) {
  FunctionThatEscapesLocalObject();
  return ptr[argc];
}
Use after scope
volatile int *p = 0;

int main() {
  {
    int x = 0;
    p = &x;
  }
  *p = 5;
  return 0;
}
Initialization order bugs
Memory leaks
#include <stdlib.h>

void *p;

int main() {
  p = malloc(7);
  p = 0; // The memory is leaked here.
  return 0;
}

原理

原理上还是分为2部分:

插桩主要是对访问内存的操作(store,load,alloca等),将它们进行处理。
hook动态运行库主要提供将malloc,free等系统调用函数hook住。

该算法的思路是:如果想防住Buffer Overflow漏洞,只需要在每块内存区域右端(或两端,能防overflow和underflow)加一块区域(RedZone),使RedZone的区域的影子内存(Shadow Memory)设置为不可写即可。具体的示意图如下图所示。

image.png

这样可以有效的防止buffer overflow。

hook malloc/free函数。在malloc函数中额外的分配了Redzone区域的内存,将与Redzone区域对应的影子内存加锁,主要的内存区域对应的影子内存不加锁。
free函数将所有分配的内存区域加锁,并放到了隔离区域的队列中(保证在一定的时间内不会再被malloc函数分配),可检测Use after free类的问题。


参考资料
1、https://github.com/google/sanitizers/wiki/AddressSanitizer
2、https://www.bynav.com/cn/resource/bywork/healthy-work/70.html?id=35

上一篇下一篇

猜你喜欢

热点阅读