基本上,我正在试图弄清楚PIN如何使用IMG_AddInstrumentFunction跟踪“图像”加载。文档说“使用它来注册回调以捕获图像的加载”。 (source / tools / ManualExamples中有一个imageload
pintool使用它。)
From what I understand执行(execve'd)的ELF二进制文件由内核mmaped到内存中。如果可执行文件具有PT_INTERP段(指向ld-linux.so.2之类的段),则将该文件的段mmaps到内存中并将控制传递给它。
我想弄清楚的是:什么行为导致PIN识别“图像加载”?
最初我认为这将是一组open-fstat-mmap2-close系统调用,表明图像负载。 PIN还显示加载中的初始可执行映像,但由于它无法拦截从execve到内核空间的mmap调用,所以我想象PIN也会监视execve的。
然而,当我尝试在Linux上使用带有UPX压缩二进制文件的PIN(最终被剥离并静态链接)时,我根本找不到任何图像加载(甚至连主要的可执行图像都没有)。
为什么会这样?
答案 0 :(得分:2)
什么行为导致PIN识别"图像加载"
有一个"标准" ld-linux.so
和调试器(例如GDB)之间的接口:每次加载或卸载ELF图像时,ld-linux
设置全局变量_r_debug.r_state == RT_CONSISTENT
并调用函数_dl_debug_state()
(在其内部)。该功能通常只有一个RET
。
[这个描述简化了它的实际工作方式,但实际发生的细节在这里无关紧要。]
调试器应在_dl_debug_state
上设置断点,然后检查_r_debug.r_state
和_r_debug.r_map
以查看发生的情况。
我认为PIN使用相同的技术来观察"正常"图像加载和卸载。
当我尝试使用带有UPX压缩二进制文件的PIN时......我找不到任何图像加载
这就是我所期望的:PIN查看了UPX的二进制文件,发现它是完全静态的,并且没有设置任何断点(毕竟,ld-linux.so
不是当控制到达UPX二进制时加载到内存中,因此即使它想要,它也不能在_dl_debug_state
上设置断点。
在UPX' d二进制文件上运行GDB,并且设置stop-on-solib-events 1
也不会停止。 IOW,UPX"傻瓜" GDB和PIN认为共享库在这个二进制文件中是不可能的。