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
LD_DEBUG=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 :
- 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.
- 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 patchelf --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 !
libncurses5
instead of trying to patch the binary? Currentncurses
ships bothlibncurses5
andlibncurses6
packages, and not just for the fun of it. – Stephen Kitt Jan 17 '22 at 09:47Also, if you could please provide more deep insight as to why (aside the "they're incompatible in some way*") there are several versions of the given ncurses lib (besides the 'not just for fun' reason) , it would be much more valueable than just stating the obvious I guess the, no offense - Thanks ! – cg79 Jan 19 '22 at 15:03
ncurses
specifics ;-). Forncurses
specifically, it’s not an older version of the library, it’s the same version built with an older API and ABI (notably, with different underlying types for some important data types). See https://salsa.debian.org/debian/ncurses/-/blob/master/debian/rules for details. – Stephen Kitt Jan 19 '22 at 15:03libncurses6
instead oflibncurses5
is unlikely to produce a fully working result. – Stephen Kitt Jan 19 '22 at 15:06