Usage of objcopy / elfedit to patchelf symbol (versions) in elf file
0
votes
0
answers
1765
views
The context is as follows: on my o.s. there is (already) *liba.so.v2* of "liba" which contains the string 'symbol_version-2' as the symbol version for its functions , e.g. *functionX@version-2* (in my case, for ex. *wrefresh@NCURSES6_5.0.19991023* in *objdump -T / readelf* output).
There is this new *binary_a* which I downloaded and want to run. This, however, has a dependency for a previous versions of the lib, *liba.so.v1*, which contains a different symbol version string, e.g. 'symbol_version-1' (in my case *wrefresh@NCURSES_5.0.19991023* (notice the missing '6').
Notes:
- The functions (all of them) exist in both so libs and the new lib is **found** by ld.so (checked that using
=libs ldd ./binary_a
)
- The binary unfortunately doesn't have any reference to the 'new' symbol, otherwise, it would be easy to hexedit the binary , and adjust the *vna_flags* (see NewAppsOnOldGlibc link below)
My questions are :
1. **how to patch the binary such as to refer to the new symbol in the new lib** - using either dedicated Tools (objcopy / elfedit, others ...?), or even hexedit. For the latter case I'd need please step-by-step advice on how to recalculate the hashes (if needed; according to link it seems it's needed). There seems to be enough details in dynTable-hash , however the information presented there is too complicated for me to make any practical use of for my use-case.
2. Why is *ld.so* (still) complaining that "it cannot find version", after I've hexedit out all references to the old lib.so and the old symbol ? *Is ld.so's cache somehow interferring ?*
All my attempts led to ldd (actually ld.so) complaining after patching the file, that it cannot find the new symbol version...
The ideal solution would avoid (re)compiling stuff (i.e. the *binary_a*) , except maybe compiling a 'dummy' function like in previous link, would avoid using LD_PRELOADs variables.
**What I've tried:**
- In my tests with *patchelf*, it produced a corrupt binary with flags *--remove-needed liba.so.v2* ; using *patchelf --replace-needed liba.so.v2 liba.so.v1* did rearrange the 'physical' layout of the file (as viewed with hexedit), but the symbols still referenced the v2 so lib, so I have doubts that this option worked as intended .To add more info: am hitting this with patchelf. The 'rearrangement' of the binary, seems it is referred to be *patchelf --debug* when among other lines it says:
shifting new PT_LOAD segment by %d bytes to work around a Linux kernel bug
- Testing with *elfsh* yielded another error, upon loading the binary, don't have it in front of me know, but somthing like: *'elf header AMD64-x64 not recognized'*
- When 'hexediting' **another ** binary, where the symbol versions had the **same** string length (not like in this case, where there is a one char difference in the version string length) - so, an easier case - doing *ldd* on the resulted binary still complained that "symbol_version-2" not found. I would imagine adding a new entry ("symbol_version-2" ) in the *.dynstr* Table is not feasible (i.e. without decompiling the binary), is it ? If that would be doable, then I'd simply hexedit (overwrite) in the *vna_flags* field of *Elfxx_Vernaux* entry corresponding to the 'old' symbol, to be the offset (in the .dynstr Table) of this new string, i.e. "symbol_version-2", again along the lines of NewAppsOnOldGlibc
Would following help - (a) changing the *soname* inside the lib.so.v2 file (using --set-soname
or similar), (b) renaming the *lib.so.v2* file to *lib.so.v1* and (c) fiddling with the version name (string) **only** ?
This would lead me again to asking: how would i trick *ld.so* into accepting my manual modification to the binary ?
Thanks in advance for your help !
Asked by cg79
(21 rep)
Jan 17, 2022, 09:42 AM
Last activity: Jan 17, 2022, 12:19 PM
Last activity: Jan 17, 2022, 12:19 PM