Linux 重写libc open()库函数
在我的库中,我有相同的被覆盖的open(),它是由glibc提供的&我首先用我的库设置了Linux 重写libc open()库函数,linux,gcc,overriding,ld,glibc,Linux,Gcc,Overriding,Ld,Glibc,在我的库中,我有相同的被覆盖的open(),它是由glibc提供的&我首先用我的库设置了LD\u PRELOAD,因此当进程调用open()时,将调用库中定义的open 问题:-在glibc中还有其他几个函数调用open(),一旦这样的例子是getpt(),当getpt()调用open()时,open()在glibc中定义的open()被调用,我将如何使getpt()调用open()在我的库()中定义 约束条件:-我没有编译glibc的选项。我认为使用LD\u PRELOAD无法做到这一点 如果
LD\u PRELOAD
,因此当进程调用open()
时,将调用库中定义的open
问题:-在glibc中还有其他几个函数调用open(),一旦这样的例子是getpt()
,当getpt()
调用open()
时,open()
在glibc中定义的open()
被调用,我将如何使getpt()
调用open()
在我的库()中定义
约束条件:-我没有编译glibc的选项。我认为使用LD\u PRELOAD无法做到这一点 如果您查看libc的反汇编(例如使用
objdump--disassemble/lib64/libc.so.6 | grep-A20):“
,您可以看到getpt()
调用\u open()
,这是open()
的别名
0000000000 11e9d0:
11e9d0:53推送%rbx
[...]
11e9ee:e8 dd d9 fb ff呼叫dc3d0
但是,对uu open的调用是一个不通过PLT的PC相关调用-这意味着您可以不使用LD_PRELOAD插入符号,因为libc中的所有调用都不会使用PLT。这可能是因为libc与-BSymbolic
链接
剩下的唯一选项是执行strace所做的操作,并使用ptrace附加到流程。请参阅其工作原理。正如tmcguire正确指出的那样,从
posix\u openpt
到\u open
的调用是对内部符号的调用,不能插入
有效地,<代码> GLUBC/<代码>开发人员认为这个调用是实现细节,您没有更改的业务。
我正在寻找编译时解决方案 你不能拥有它 超过运行时解决方案导致运行时解决方案将对性能产生影响 运行时解决方案不需要有任何性能影响(除了调用open
而不是glibc
s的开销)
我只知道库插入glibc
内部调用的一种方法:运行时补丁
- 查找
libc.so.6
(这是open
的别名)的地址\uu open
- 在运行时定位
glibc
部分的边界.text
- 扫描它以查看
说明CALL\u open
- 对于任何此类指示
m保护它所在的页面,使其可写
- 计算一条新指令,该指令是
,并将其修补到原始指令的“顶部”CALL my_open
返回页面以读取和执行m保护
调用
可以“到达”4GB地址空间内的任何其他指令。它不适用于x86_64,在x86_64中,调用
仍被限制在+/-2GB,但从库到glibc
的距离可能会超过这个范围
在这种情况下,您需要在
libc.so.6
中找到一个合适的蹦床,您可以将原始调用重定向到该蹦床,并且可以将寄存器间接JMP
放置到最终目的地。幸运的是,libc.so.6
通常有多个大小合适的未使用NOP
区域,因为函数对齐。我可以在编译时通过在库中定义getpt()函数来解决这个问题
此解决方案不完整,因为glibc[getpt()]中可能有其他函数可以调用open,然后将调用glibc中的open调用
我现在可以接受这个解决方案,但我需要在将来完全修复它。虽然ptrace是一个不错的选择,但要使用ptrace,您需要一个不可接受的父子关系,因为我提供了一个库,如果我必须使用ptrace,那么我必须分叉,然后对孩子进行跟踪。我不认为我可以有这个解决方案如果你不能使用ptrace,那么我看不到拦截open()调用的方法,缺少像Intel的PIN库那样的动态运行时插装。嗯,好吧,让我们看看是否有其他人有想法,我正在寻找编译时解决方案,而不是运行时解决方案,因为运行时解决方案会对性能产生影响。好吧,在基于生产的环境中进行这种黑客攻击是不好的&正如您所说的,确实很难看。@user3465381 FWIW,使用LD_PRELOAD
插入open
只是稍微不那么难看,可以说你也不应该在生产中这样做。好的,我提供了一个库,可供内部应用程序和第三方应用程序使用。我没有编辑第三方代码的选项。dlopen也不是sa的选项我解释第三方代码无法编辑的原因。鉴于这些限制,您如何让第三方应用程序调用库中定义的open函数。?这不是LD_PRELOAD的确切用例吗。?我喜欢“实现细节”部分,尽管正如您所说,修补内容很难看。
000000000011e9d0 <posix_openpt>:
11e9d0: 53 push %rbx
[...]
11e9ee: e8 dd d9 fb ff callq dc3d0 <__open>