I have a linux binary that imports functions from an external library (shared object). The functions are lazy loaded and not available when rip is at @main
or @entry
. When i step into such a function (like call sym.imp.<function>
) it goes into plt->got->linker->function. Doing this manually (step-into) is very time consuming and uncomfortable. None of the analysis functions (aaa
) seem to register any functions (afl ~ <function>
) of the lazy loaded library so there is no way to gather the function start address (until the linker fills the plt/got).
The only way i figured out so far is to break at the call
, look up the mapped memory (dm
) of the (now loaded) library and adding the offset of the function (gathered by directly/statically loading the library beforehand). This finally leads to the target function start address.
Even though this works i think its still too complicated for such a basic task and there might be a much easier way. I can remember that IDA/Windows allowed to prepare a static environment (load binary, libs, add comments, annotations and such) and once going into the debugger the initialization phase (linker) detected the prepared libs and asked to use/overload them in the dynamic session. There, you could easily set breakpoints on the functions and the debugger stopped successfully.
The question is: How to get into lazy loaded imported functions without going over plt/got/linker in radare2?
Edit: Here is a specific example:
r2 -d /usr/bin/rar
aaa
db sym.imp.__swprintf_chk
dc
Then you end up in the .plt
(twice) and then in map.usr_lib_ld_2.27.so.r_x + 50055
.