2017-10-01 105 views
0

我想挂钩到mmap和munmap,通常在内存分配器函数中调用libc内部。一种方法是LD_PRELOAD - 无论如何要做到这一点编程?请注意,我想钩住libc中的mmap/munmap,而不是来自我的应用程序。Hook mmap/munmap without LD_PRELOAD

+0

在Linux上,使用'ptrace' ... –

回答

1

LD_PRELOAD只能在glibc中重定向函数调用,以获取与分配器(mallocfree等)相关的一小部分函数。系统调用通常是内联的,所以根本不涉及函数调用。正如Antti Haapala所说,使用ptrace,或者您也可以使用systemtap或手动编写的内核模块。

0

是否有编程方式做到这一点?

有,但它不漂亮。

可以扫描的libc.so.6.text,寻找CALL __mmap指令,那就是:0xE8(或其它操作码CALL),随后4个字节等于下一指令和__mmap之间增量。

一旦你找到了这样的指令,就可以mprotect页面可写,它更新为CALL不同的套路,并mprotect回来。

有几个缺点:

  1. 这是一个黑客。
  2. 您最好确保在修补时没有线程同时运行。
  3. 您最好确保在修补时不要拨打malloc(或其他可以调用您正在修补的代码)。
  4. 错误肯定是可能的(看起来像CALL的字节序列实际上可能不是CALL)。在我看来,这从未发生过。
  5. 在64位的过程中,你的目标程序可能离CALL更远,然后+/-2GiB偏移量你可以填入CALL指令本身。解决这个问题需要另外一个粗陋的窍门(CALL给蹦床,你可以在libc.so.6本身内建立足够长的NOPs序列;蹦床可以执行任意地址的JMP)。

我提到这不美吗?

另一种选择是建立自己的libc.so.6,其中__mmap__munmap例程通过PLT公开。这个补丁很小,但是只有在你运行的每个地方都可以使用你自己的GLIBC版本的情况下,这个补丁才有效。

0

这取决于你需要什么。您可以随时使用env或putenv()设置备用环境,然后执行目标程序。同样,你可以使用gdb将一个断点添加到进程中。

为什么你不描述你的真实任务?