上下文如下:在我的操作系统上(已经)liba.so.v2“liba”,其中包含字符串“symbol_version-2”作为其函数的符号版本,例如functionX@version-2(就我而言,例如刷新@NCURSES6_5.0.19991023 在objdump -T / readelf输出)。有这个新的二进制_a我下载并想运行它。然而,这依赖于以前版本的库,liba.so.v1,其中包含不同的符号版本字符串,例如“symbol_version-1”(在我的例子中wrefresh@NCURSES_5.0.19991023(注意缺少“6”)。
笔记:
- 这些函数(所有这些)都存在于 so 库中,而新库是成立通过 ld.so (检查使用
LD_DEBUG=libs ldd ./binary_a
) - 不幸的是,二进制文件没有任何对“新”符号的引用,否则,很容易对二进制文件进行十六进制编辑,并调整vna_flags(请参阅下面的 NewAppsOnOldGlibc 链接)
我的问题是:
- 如何修补二进制文件,例如引用新库中的新符号- 使用专用工具(objcopy / elfedit,其他......?),甚至十六进制编辑。对于后一种情况,我需要有关如何重新计算哈希值的分步建议(如果需要;根据关联看来是需要的)。似乎有足够的细节动态表哈希,但是那里提供的信息对我来说太复杂了,无法在我的用例中进行任何实际用途。
- 为什么是ld.so (仍然)抱怨“它找不到版本”,在我十六进制编辑掉对旧 lib.so 和旧符号的所有引用之后?ld.so 的缓存是否有某种干扰?
我所有的尝试都导致 ldd (实际上是 ld.so)在修补文件后抱怨,它找不到新的符号版本......
理想的解决方案是避免(重新)编译东西(即二进制_a) ,除非像之前的链接那样编译“虚拟”函数,否则会避免使用 LD_PRELOADs 变量。
我尝试过的:
- 在我的测试中帕切尔夫,它产生了一个带有标志的损坏的二进制文件--删除需要的 liba.so.v2;使用patchelf --替换需要的 liba.so.v2 liba.so.v1确实重新排列了文件的“物理”布局(如使用 hexedit 查看),但符号仍然引用 v2 so lib,因此我怀疑此选项是否按预期工作。要添加更多信息:正在点击这与补丁。二进制文件的“重新排列”,似乎被称为patchelf——调试 除其他几行外,它还写着:
shifting new PT_LOAD segment by %d bytes to work around a Linux kernel bug
- 测试用小精灵加载二进制文件时产生了另一个错误,我知道它没有在我面前,但类似于:'elf 标头 AMD64-x64 无法识别'
- 当“十六进制编辑”**另一个**二进制文件时,符号版本具有相同的字符串长度(不像在本例中,版本字符串长度有一个字符的差异) - 所以,一种更简单的情况 - 做LDD结果二进制文件仍然抱怨找不到“symbol_version-2”。我想在中添加一个新条目(“symbol_version-2”).dynstr表不可行(即不反编译二进制文件),是吗?如果这是可行的,那么我只需在vna_flags现场 Elfxx_维诺与“旧”符号相对应的条目,是这个新字符串的偏移量(在 .dynstr 表中),即“symbol_version-2”,同样沿着旧 Glibc 上的新应用
以下帮助 - (a) 改变索纳姆在 lib.so.v2 文件内(使用patchelf --set-soname
或类似),(b) 重命名库.so.v2文件到库.so.v1 (c) 修改版本名称(字符串)仅有的?这会让我再次问:我该如何欺骗ld.so接受我对二进制文件的手动修改?
在此先感谢您的帮助 !