关键词:插桩,软件测试
二进制插桩作用
1. 程序运行时拦截,在运行时向程序注入我们自己的代码。
2. 调试程序
3. Tracing and logging, 分析函数调用关系图,api覆盖数据。
4. 提取数据,从程序中提取一些感兴趣的关键data。
5. 改变程序行为,如程序打补丁,模拟数据(emulation)。
一般二进制插桩方法
LD_PRELOAD设置一个动态库路径,该动态库会在其他库(包括the C runtime, libc.so)之前加载。下面可以使程序ls使用我们自己编写的malloc ()
$ LD_PRELOAD=/path/to/my/ libmalloc.so /bin/ls
编写拦截函数,加载原来系统的动态库。
注入指令(inject)
函数地址查找,插入和移除插桩,调用原始函数地址(写回原指令,并刷新cache)。
注入动态库
补丁(patch)
Proc文件,/proc/
ELF文件,符号段里面查找符号。
计算绝对地址,相对地址+基址(Symbol address + base address)
内存泄漏check动态库
使用我们自己的malloc hook程序的malloc调用。
/* lcheck() is for memory leak check; its code is not shown
here */
void lcheck(void);
void* malloc(size_t size)
{
static void* (*my_malloc)(size_t) = NULL;
if (!my_malloc)
my_malloc = dlsym(RTLD_NEXT, "malloc"); /* returns the object reference for malloc */
void *p = my_malloc(size); /* call malloc() using function pointer my_malloc */
printf("malloc(%d) = %p\n", size, p);
lcheck(); /* calling do_your_stuff function */
printf("returning from shared object...\n");
return p;
}
void lcheck(void)
{
printf("displaying memory leaks...\n");
/* do required stuff here */
}
编译和执行
gcc -shared -Wl,--no-as-needed -ldl -fPIC prog2.c -o libprog2.so
LD_PRELOAD=/home/wuchao/sbox/kernel/hook/libprog2.so /bin/ls
Intel pin工具
从intel网站下载pin-2.13-65163-gcc.4.4.7-linux.tar.gz
解压后就可以使用。
编译pintool工具
$ cd source/tools/ManualExamples
$ make strace.test
检查ls程序
pin-2.13-65163-gcc.4.4.7-linux$ ./pin -t source/tools/ManualExamples/obj-ia32/strace.so -- /bin/ls
$ cat ./strace.out
0xb77b5f92: 45(0x0, 0xb77c0ff4, 0x0, 0xb779f000, 0x9, 0xb779f414)returns: 0x9f59000
0xb77b7caf: 33(0xb77ba0e5, 0x0, 0xb77c0ff4, 0xb779f1f4, 0x4, 0xbf831138)returns: 0xffffffff
0xb77b7d61: 192(0x0, 0x2000, 0x3, 0x22, 0xffffffff, 0x0)returns: 0xb6063000
0xb77b7caf: 33(0xb77b9d96, 0x4, 0xb77c0ff4, 0xb77b9d96, 0xb77c1c14, 0xbf8312a8)returns: 0xffffffff
0xb77b7b72: 5(0xb77ba081, 0x80000, 0x0, 0xb77c189c, 0xb77c1b00, 0x1)returns: 0x4
0xb77b7afb: 197(0x4, 0xbf830c40, 0xb77c0ff4, 0xb77c189c, 0x4, 0x1)returns: 0x0