最近由于工作原因需要调研一些内存监测方面的开源库,偶然间了解到了一个项目,叫iqiyi/xHook。 以前只用过malloc的hook,看完这个库作者写的文档后,我才发现,原来所有的动态链接库符号都可以hook(其实以前做过类似的,但是没有作者玩的这么骚)。 不想听我废话的朋友可以直接滑到最后,点击阅读原文看这个开源库的ReadMe。 下面是我的啰嗦环节。。。 这里主要介绍下我为什么推荐这个库?(不是广告,没收费,也不认识作者) 如果看完这个库的ReadMe,我相信大家会对Linux内存分布有更深层次的了解,会对动态链接库的整个链接寻址过程有清晰的认识。 据我了解,介绍Linux编译链接知识点的资料很少,貌似最出名的也就是《程序员的自我修养》,这本书真的很好,但只是介绍了理论知识,看完后很多人根本不知道这些知识点的用处在哪里,我为什么要学习这些东西?对我实际工作会有什么帮助?还是就是为了应付面试?请继续往下看。 作者首先介绍了ELF封装格式,又介绍了ELF的分段细节。然后介绍了动态链接的整个过程,通过一个实际示例,结合之前介绍的动态链接原理,将动态链接库的某个符号成功hook。 类似这样,将malloc函数hook到了my_malloc上,其中0x3f90是malloc函数的相对地址。malloc的相对地址可使用readelf拿到: 整个hook的示例程序如下: #include <inttypes.h> #include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <sys/mman.h> #include <test.h>
#define PAGE_START(addr) ((addr) & PAGE_MASK) #define PAGE_END(addr) (PAGE_START(addr) + PAGE_SIZE)
void *my_malloc(size_t size) { printf('%zu bytes memory are allocated by libtest.so\n', size); return malloc(size); }
void hook() { char line[512]; FILE *fp; uintptr_t base_addr = 0; uintptr_t addr;
//find base address of libtest.so if(NULL == (fp = fopen('/proc/self/maps', 'r'))) return; while(fgets(line, sizeof(line), fp)) { if(NULL != strstr(line, 'libtest.so') && sscanf(line, '%'PRIxPTR'-%*lx %*4s 00000000', &base_addr) == 1) break; } fclose(fp); if(0 == base_addr) return;
//the absolute address addr = base_addr + 0x3f90; //add write permission mprotect((void *)PAGE_START(addr), PAGE_SIZE, PROT_READ | PROT_WRITE);
//replace the function address *(void **)addr = my_malloc;
//clear instruction cache __builtin___clear_cache((void *)PAGE_START(addr), (void *)PAGE_END(addr)); }
int main() { hook(); say_hello(); return 0; } 结果不用多说,肯定hook成功了。 想要详细了解的话大家还是直接去看这个开源库吧!推荐大家都了解一下。相信学完后大家会有所收获。我就介绍到这里。 打完收工。 |
|
来自: 新用户0118F7lQ > 《文件夹1》