Patching an ELF file
Practical CLI Tutorial: Patching an ELF Binary#
This tutorial demonstrates a common use case for arwen: patching an ELF executable so it can find its required shared library (.so file) using a relative path. This makes the application "relocatable," meaning you can install it in different locations without breaking its ability to find its dependencies.
Goal:
To modify an application (my_app) that depends on a library (libcustom.so) so that my_app can find libcustom.so when they are placed in a specific directory structure (e.g., bin/ and lib/ subdirectories within a main installation folder).
Scenario:
- We have a simple ELF executable named
my_app. my_appdepends on a custom ELF shared library namedlibcustom.so.- Initially,
my_appexpectslibcustom.soto be in a standard system library path (like/usr/lib) or a path listed inLD_LIBRARY_PATH. - We want to install the application into
/opt/my_app/, placing the executable at/opt/my_app/bin/my_appand the library at/opt/my_app/lib/libcustom.so. - We will use
arwento patch/opt/my_app/bin/my_appso it automatically looks forlibcustom.soin the adjacent../libdirectory.
Prerequisites:
- The
arwencommand-line tool installed and in your PATH. - A simple ELF executable (
my_app) and an ELF shared library (libcustom.so) it depends on.- Note: For experimentation, you can often use simple existing tools or create minimal examples if you have a C compiler like GCC:
libcustom.c:int custom_function() { return 42; }my_app.c:int custom_function(); int main() { return custom_function(); }- Compile:
gcc -shared -fPIC -o libcustom.so libcustom.cgcc my_app.c -o my_app -L. -lcustom(Link against the library in the current dir)
- Note: For experimentation, you can often use simple existing tools or create minimal examples if you have a C compiler like GCC:
Step 1: Inspecting the Initial State
First, let's see how my_app currently finds (or fails to find) its dependency and what its embedded paths look like. Assume my_app and libcustom.so are in your current directory for now.
# Check dynamic dependencies using the standard ldd tool
# note that this command is not available on macos
ldd ./my_app
You'll likely see output similar to this, indicating libcustom.so is needed but perhaps not found yet in standard locations:
linux-vdso.so.1 (0x...)
libcustom.so => not found # <--- The problem! Or it might point to /usr/lib if installed there
libc.so.6 (0x...) => /lib/x86_64-linux-gnu/libc.so.6 (...)
/lib64/ld-linux-x86-64.so.2 (0x...)
Or you can use arwen to verify the rpaths the ELF file directly:
You can see that we have no RPATH set, which means it will not look in any custom directories for libcustom.so.
Step 2: Patching the ELF Binary
Now, we will patch my_app to add a relative RPATH that points to the lib/ directory where libcustom.so will be located.
Step 2: Patching the ELF Binary
Now, we will patch my_app to add a relative RPATH that points to the lib/ directory where libcustom.so will be located.
If we run arwen elf print-rpath my_app again, we should see the new RPATH set to ../lib.
Step 3: Removing the DT_NEEDED
Sometimes you might want to remove the DT_NEEDED entry for a library, for example when stripping dependencies.
Now, if we check the dependencies again with ldd or arwen, we should see that libcustom.so is no longer listed as a required dependency.
Conclusion:
In this small tutorial, we took a look in a practical example how to use arwen for patching binaries and setup a different RPATH for an ELF binary. This allows the application to find its dependencies in a custom directory structure, making it more portable and easier to deploy.