frida / frida-gum

Cross-platform instrumentation and introspection library written in C
https://frida.re
Other
753 stars 245 forks source link

Injected code resolves symbols from target binary, not from libc #742

Open randomdude opened 1 year ago

randomdude commented 1 year ago

Hi all. I've come across some 'unexpected behaviour' that ate up a day or two of my time, and wanted to fix/share/document it. I don't know if this is the result of bug in Frida, the dynamic linker, or simply an unexpected consequence of how the dynamic linker works.

I was fuzzing a Linux-based router platform using Frida, but the target immediately segfaulted when I tried to attach with frida-server (or immediately on load if I tried to LD_PRELOAD the libgadget.so library). After a considerable amount of debugging, I realised that the injected Frida code was calling poll as exported from the target binary, not from libc itself, which was causing problems. I ran with LD_DEBUG=all and saw the following in the log, showing that various symbols were bound incorrectly to the target binary:

smokinggun

At first I thought this was caused by Frida incorrectly specifying RTLD_NEXT to dlsym, but I was unable to confirm this by navigating the Frida source. Debugging with gdb seems to indicate this is not the case, but I can't be sure, I'm at the limit of my debugging skills here :)

In my case, I worked around the problem by modifying the target such that it no longer exports these symbols. However, I thought the Frida team would like to know about the behaviour. However, I'm a little out of my depth! Can someone with more experience in this area of dynamic linking comment? My question/suggestions would be the following:

1) Is this a bug in Frida? If so, suggestion is (obviously) to fix it.

2) Otherwise, is this simply a consequence of how the OS works? If so, my suggestion would be to detect this condition at runtime (symbols resolved outside of libc.so) and abort with an error message, and/or to document this behaviour somewhere.

Apologies for the open-ended nature of this filing - I hope it is useful and productive.

For reference, this is all from Frida 16.0.19 running on an x86_64 Linux host (embedded, so the layout of libraries on the filesystem may be unusual). The kernel is 4.14.127 compiled by myself (so no weird vendor modifications) from kernel.org sources. ldd --version reports ldd (Gentoo 2.23-r8 p8 2.23). The Frida binaries I'm using were downloaded via the GitHub releases page. In case it is useful, the full list of incorrectly resolved symbols is close, read, write, and poll.

Please let me know if there's any more information I can supply to help!