Is there a tool for modifying the shared library entries in the dynamic section of an ELF binary? I would like to explicitly modify the shared library dependencies in my binary (i.e. replace path to existing library with a custom path)
是否有用于修改ELF二进制文件的动态部分中的共享库条目的工具?我想显式修改二进制文件中的共享库依赖项(即用自定义路径替换现有库的路径)
3 个解决方案
#1
3
replace path to existing library with a custom path
使用自定义路径替换现有库的路径
If this is your own library, then you probably linking it like that:
如果这是您自己的库,那么您可能会像这样链接它:
$ cc -o prog1 -l/full/path/to/libABC.so prog1.o
instead of the proper:
而不是正确的:
$ cc -o prog1 -L/full/path/to/ -lABC prog1.o
The first approach tells Linux linker that application needs precisely that library, only that library and no override should be possible. Second approach tells that application needs the library which would be installed somewhere on the system, either in the default library path or one pointed by the $LD_LIBRARY_PATH (would be looked up during run-time). -L is used only during link-time.
第一种方法告诉Linux链接器应用程序正好需要该库,只有该库并且不应该覆盖。第二种方法告诉应用程序需要安装在系统某处的库,可以是默认库路径,也可以是$ LD_LIBRARY_PATH指向的库(将在运行时查找)。 -L仅在链接时使用。
Otherwise, instead of patching the ELF, first check if you can substitute the library using a symlink. This is the usual trick: it is hard to modify executable afterward, but it is very easy to change where to the symlink points.
否则,不要修补ELF,首先检查是否可以使用符号链接替换库。这是通常的技巧:之后很难修改可执行文件,但很容易更改符号链接指向的位置。
#2
1
You may want to check the LD_LIBRARY_PATH
environment variable.
您可能想要检查LD_LIBRARY_PATH环境变量。
#3
1
If you look at the .dynsym section in Linux via readelf
, you'll just see something like:
如果你通过readelf查看Linux中的.dynsym部分,你会看到类似的东西:
1: 0000000000000000 163 FUNC GLOBAL DEFAULT UND fseek@GLIBC_2.2.5 (2)
which just contains a symbolic name of the library. However, if you include the dynamic loader info, you get:
它只包含库的符号名称。但是,如果包含动态加载程序信息,则会得到:
libc.so.6 => /lib/libc.so.6 (0x00002ba11da4a000)
/lib64/ld-linux-x86-64.so.2 (0x00002ba11d82a000)
So as mentioned, the absolute easiest thing to do (assuming you're doing this for debugging, and not forever) would just be to create a new session, export your custom path in front of the existing LD_LIBRARY_PATH
, and go from there.
如上所述,绝对最容易做的事情(假设您正在进行调试,而不是永远)只是创建一个新会话,在现有LD_LIBRARY_PATH之前导出自定义路径,然后从那里开始。
#1
3
replace path to existing library with a custom path
使用自定义路径替换现有库的路径
If this is your own library, then you probably linking it like that:
如果这是您自己的库,那么您可能会像这样链接它:
$ cc -o prog1 -l/full/path/to/libABC.so prog1.o
instead of the proper:
而不是正确的:
$ cc -o prog1 -L/full/path/to/ -lABC prog1.o
The first approach tells Linux linker that application needs precisely that library, only that library and no override should be possible. Second approach tells that application needs the library which would be installed somewhere on the system, either in the default library path or one pointed by the $LD_LIBRARY_PATH (would be looked up during run-time). -L is used only during link-time.
第一种方法告诉Linux链接器应用程序正好需要该库,只有该库并且不应该覆盖。第二种方法告诉应用程序需要安装在系统某处的库,可以是默认库路径,也可以是$ LD_LIBRARY_PATH指向的库(将在运行时查找)。 -L仅在链接时使用。
Otherwise, instead of patching the ELF, first check if you can substitute the library using a symlink. This is the usual trick: it is hard to modify executable afterward, but it is very easy to change where to the symlink points.
否则,不要修补ELF,首先检查是否可以使用符号链接替换库。这是通常的技巧:之后很难修改可执行文件,但很容易更改符号链接指向的位置。
#2
1
You may want to check the LD_LIBRARY_PATH
environment variable.
您可能想要检查LD_LIBRARY_PATH环境变量。
#3
1
If you look at the .dynsym section in Linux via readelf
, you'll just see something like:
如果你通过readelf查看Linux中的.dynsym部分,你会看到类似的东西:
1: 0000000000000000 163 FUNC GLOBAL DEFAULT UND fseek@GLIBC_2.2.5 (2)
which just contains a symbolic name of the library. However, if you include the dynamic loader info, you get:
它只包含库的符号名称。但是,如果包含动态加载程序信息,则会得到:
libc.so.6 => /lib/libc.so.6 (0x00002ba11da4a000)
/lib64/ld-linux-x86-64.so.2 (0x00002ba11d82a000)
So as mentioned, the absolute easiest thing to do (assuming you're doing this for debugging, and not forever) would just be to create a new session, export your custom path in front of the existing LD_LIBRARY_PATH
, and go from there.
如上所述,绝对最容易做的事情(假设您正在进行调试,而不是永远)只是创建一个新会话,在现有LD_LIBRARY_PATH之前导出自定义路径,然后从那里开始。