行业知识
04-工具篇-ascan内存工具
2026-10-20 00:33:57
来源:互联网转载
利���C或C++编写系统时,容易出现内存方面的问题,当代码量过大时,我们需要用工具检查代码。其中ascan工具在开销小,本章对此工具的使用作一个简单介绍。
()1.栈溢出
#include #include #include int func0(void){ char str[4] = {0}; strcpy(str,"1234"); return 0;}int main(int argc,char *argv[]){ func0(); return 0;} 编译
()$ g++ -g 1.cpp -o 1 -fsanitize=leak -fsanitize=address -fno-omit-frame-pointer
运行
$ ./1===================================================================21786==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffc1f3df6e4 at pc 0x7faf3475077a bp 0x7ffc1f3df6b0 sp 0x7ffc1f3dee58WRITE of size 5 at 0x7ffc1f3df6e4 thread T0 #0 0x7faf34750779 (/usr/lib/x86_64-linux-gnu/libasan.so.4+0x79779) #1 0x5643f7fedb48 in func0() /home/zg/zg_code/zg_test/test/ascan_demo/1.cpp:8 #2 0x5643f7fedbac in main /home/zg/zg_code/zg_test/test/ascan_demo/1.cpp:13 #3 0x7faf34307c86 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21c86) #4 0x5643f7fed999 in _start (/home/zg/zg_code/zg_test/test/ascan_demo/1+0x999)
定位出第8行有栈溢出
2 堆溢出
#include #include #include void func1(void) { char * p = (char*) malloc(sizeof(char)*4); char chs[] ={"12345"}; memset(p,0x0,4); if (p != NULL) { memcpy(p,chs,5); }} int main(int argc,char *argv[]){ func1(); return 0;} 编译
$ g++ -g 2.cpp -o 2 -fsanitize=leak -fsanitize=address -fno-omit-frame-pointer
运行
$ ./2===================================================================21804==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000014 at pc 0x7fa9abe2477a bp 0x7ffefe188770 sp 0x7ffefe187f18WRITE of size 5 at 0x602000000014 thread T0 #0 0x7fa9abe24779 (/usr/lib/x86_64-linux-gnu/libasan.so.4+0x79779) #1 0x558db4c94b3e in func1() /home/zg/zg_code/zg_test/test/ascan_demo/2.cpp:11 #2 0x558db4c94ba0 in main /home/zg/zg_code/zg_test/test/ascan_demo/2.cpp:17 #3 0x7fa9ab9dbc86 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21c86) #4 0x558db4c94919 in _start (/home/zg/zg_code/zg_test/test/ascan_demo/2+0x919)0x602000000014 is located 0 bytes to the right of 4-byte region [0x602000000010,0x602000000014)allocated by thread T0 here: #0 0x7fa9abe89b40 in __interceptor_malloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xdeb40) #1 0x558db4c94a86 in func1() /home/zg/zg_code/zg_test/test/ascan_demo/2.cpp:7 #2 0x558db4c94ba0 in main /home/zg/zg_code/zg_test/test/ascan_demo/2.cpp:17 #3 0x7fa9ab9dbc86 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21c86)SUMMARY: AddressSanitizer: heap-buffer-overflow (/usr/lib/x86_64-linux-gnu/libasan.so.4+0x79779) Shadow bytes around the buggy address: 0x0c047fff7fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c047fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c047fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c047fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c047fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00=>0x0c047fff8000: fa fa[04]fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c047fff8010: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c047fff8020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c047fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c047fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c047fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa faShadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Container overflow: fc Array cookie: ac Intra object redzone: bb ASan internal: fe Left alloca redzone: ca Right alloca redzone: cb==21804==ABORTING
检测出第11行有堆溢出
3 释放后使用
就是申请了一块内存区域,释放后没有设置为NULL,后续继续使用了。
#include #include #include void func2(void){ int * a = (int*)malloc(sizeof(int)*1); if ( a != NULL ) {*a = 1;printf("a is:%d.",*a);free(a);*a = 2;printf("error a is:%d.",*a);}}int main(int argc,char *argv[]){ func2(); return 0;} g++ -g 3.cpp -o 3 -fsanitize=leak -fsanitize=address -fno-omit-frame-pointer
$ ./3===================================================================21822==ERROR: AddressSanitizer: heap-use-after-free on address 0x602000000010 at pc 0x561a596b4ae8 bp 0x7ffed1292570 sp 0x7ffed1292560WRITE of size 4 at 0x602000000010 thread T0 #0 0x561a596b4ae7 in func2() /home/zg/zg_code/zg_test/test/ascan_demo/3.cpp:12 #1 0x561a596b4b21 in main /home/zg/zg_code/zg_test/test/ascan_demo/3.cpp:19 #2 0x7f6527861c86 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21c86) #3 0x561a596b4949 in _start (/home/zg/zg_code/zg_test/test/ascan_demo/3+0x949)0x602000000010 is located 0 bytes inside of 4-byte region [0x602000000010,0x602000000014)freed by thread T0 here: #0 0x7f6527d0f7a8 in __interceptor_free (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xde7a8) #1 0x561a596b4ab0 in func2() /home/zg/zg_code/zg_test/test/ascan_demo/3.cpp:11 #2 0x561a596b4b21 in main /home/zg/zg_code/zg_test/test/ascan_demo/3.cpp:19 #3 0x7f6527861c86 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21c86)previously allocated by thread T0 here: #0 0x7f6527d0fb40 in __interceptor_malloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xdeb40) #1 0x561a596b4a3b in func2() /home/zg/zg_code/zg_test/test/ascan_demo/3.cpp:7 #2 0x561a596b4b21 in main /home/zg/zg_code/zg_test/test/ascan_demo/3.cpp:19 #3 0x7f6527861c86 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21c86)SUMMARY: AddressSanitizer: heap-use-after-free /home/zg/zg_code/zg_test/test/ascan_demo/3.cpp:12 in func2()Shadow bytes around the buggy address:
检测出第12行,内存使用有问题
4 全局缓存溢出
#include #include #include int g_abc[11];int func3(void){ int i = 0; for (i = 0; i printf("value:%d\t",g_abc[i]); if (i%10 == 0 && i != 0) { printf("\n"); } } return g_abc[12];}int main(int argc,char *argv[]){ func3(); return 0;} char * p = (char*) malloc(5); memset(p,0x0,5); memcpy(p,"1234",4), printf("%s\n",p);}int main(int argc,char *argv[]){ func4(); return 0;}
上一篇:手机为什么没声音了?