I’ll explain:
Let’s say I’m interested in replacing the rand() function used by a certain application.
So I attach gdb to this process and make it load my custom shared library (which has a customized rand() function):
call (int) dlopen("path_to_library/asdf.so")
This would place the customized rand() function inside the process’ memory. However, at this point the symbol rand will still point to the default rand() function. Is there a way to make gdb point the symbol to the new rand() function, forcing the process to use my version?
I must say I’m also not allowed to use the LD_PRELOAD (linux) nor DYLD_INSERT_LIBRARIES (mac os x) methods for this, because they allow code injection only in the beginning of the program execution.
The application that I would like to replace rand(), starts several threads and some of them start new processes, and I’m interested in injecting code on one of these new processes. As I mentioned above, GDB is great for this purpose because it allows code injection into a specific process.
I followed this post and this presentation and came up with the following set of gdb commands for OSX with x86-64 executable, which can be loaded with
-xoption when attaching to the process:The magic is in
set $p = ...command.dyld_stub_randis a 6-byte jump instruction. Jump offset is atdyld_stub_rand+2(4 bytes). This is a$rip-relative jump, so add offset to what$ripwould be at this point (right after the instruction,dyld_stub_rand+6).This points to a symbol table entry, which should be either real
randor dynamic linker routine to load it (if it was never called). It is then replaced bymy_rand.Sometimes gdb will pick up
dyld_stub_randfrom libSystem or another shared library, if that happens, unload them first withremove-symbol-filebefore running other commands.