没有LD_PRELOAD的钩子mmap / munmap

时间:2017-10-01 03:04:14

标签: c hook mmap libc

我想挂钩到mmap和munmap,通常在内存分配器函数中调用libc。一种方法是LD_PRELOAD - 无论如何要以编程方式执行此操作吗?请注意,我想挂钩libc中的mmap / munmap,而不是我的应用程序中的mmap / munmap。

3 个答案:

答案 0 :(得分:1)

malloc只能将glibc中的函数调用重定向到与分配器相关的一小组函数(freeptrace等等)。特别是系统调用通常是内联的,因此根本不涉及函数调用。正如Antti Haapala所说,使用array_diff,或者您也可以使用systemtap或手动编写的内核模块。

答案 1 :(得分:0)

  

无论如何都要以编程方式执行此操作?

有,但它不漂亮。

您可以扫描.text libc.so.6,查找CALL __mmap指令,即:0xE8(或其他CALL操作码)后跟4个字节等于下一条指令和__mmap之间的差值。

找到此类说明后,您可以mprotect将该页面设为可写,将其修补为CALL不同的例程,并mprotect将其恢复。

有一些缺点:

  1. 这是严重的黑客攻击。
  2. 您最好确保在修补时没有并发运行的线程。
  3. 您最好确保在修补时不要拨打malloc(或其他任何可以调用您当前正在修补的代码的内容)。
  4. 可能出现误报(看起来像CALL的字节序列实际上可能不是CALL)。在我的经验中,这从未发生过。
  5. 在64位进程中,您的目标例程可能距离CALL更远,然后+/-2GiB偏移量可以填入CALL指令本身。解决这个问题需要另一个严重的黑客攻击(CALL到蹦床,你可以在NOPlibc.so.6内的足够长的序列中建立;蹦床可以执行{{1} }到任意地址)。
  6. 我提到过这不是很漂亮吗?

    另一种方法是构建您自己的JMP,并通过PLT公开libc.so.6__mmap例程。执行此操作的补丁非常小,但只有在您运行的任何地方都可以依赖自己的GLIBC构建时才能使用。

答案 2 :(得分:0)

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

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