gdb 可以使函数指针指向另一个位置吗? [英] Can gdb make a function pointer point to another location?

查看:20
本文介绍了gdb 可以使函数指针指向另一个位置吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我会解释:

假设我有兴趣替换某个应用程序使用的 rand() 函数.

所以我将 gdb 附加到这个进程并让它加载我的自定义共享库(它有一个自定义的 rand() 函数):

call (int) dlopen("path_to_library/asdf.so")

这会将自定义的 rand() 函数放置在进程的内存中.但是,此时符号 rand 仍将指向默认的 rand() 函数.有没有办法让 gdb 将符号指向新的 rand() 函数,强制进程使用我的版本?

我必须说我也不允许为此使用 LD_PRELOAD (linux) 或 DYLD_INSERT_LIBRARIES (mac os x) 方法,因为它们只允许代码注入在程序执行的开始.

我想替换 rand() 的应用程序启动了几个线程,其中一些启动了新进程,我有兴趣在其中一个新进程上注入代码.正如我上面提到的,GDB 非常适合此用途,因为它允许将代码注入特定进程.

解决方案

我关注了 这篇文章这个演示文稿 并为带有 x86-64 可执行文件的 OSX 提供了以下 gdb 命令集,可以在附加到进程时使用 -x 选项加载:

设置 $s = dyld_stub_rand设置 $p = ($s+6+*(int*)($s+2))调用 (void*)dlsym((void*)dlopen("myrand.dylib"), "my_rand")设置 *(void**)$p = my_randC

神奇之处在于 set $p = ... 命令.dyld_stub_rand 是一个 6 字节的跳转指令.跳转偏移在 dyld_stub_rand+2(4 个字节).这是一个 $rip 相对跳转,因此将偏移量添加到此时 $rip 的位置(就在指令之后,dyld_stub_rand+6).

这指向一个符号表条目,它应该是真正的 rand 或动态链接器例程来加载它(如果它从未被调用过).然后将其替换为 my_rand.

有时 gdb 会从 libSystem 或其他共享库中获取 dyld_stub_rand,如果发生这种情况,请先使用 remove-symbol-file 卸载它们,然后再运行其他命令.p>

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 -x option when attaching to the process:

set $s = dyld_stub_rand
set $p = ($s+6+*(int*)($s+2))
call (void*)dlsym((void*)dlopen("myrand.dylib"), "my_rand")
set *(void**)$p = my_rand
c

The magic is in set $p = ... command. dyld_stub_rand is a 6-byte jump instruction. Jump offset is at dyld_stub_rand+2 (4 bytes). This is a $rip-relative jump, so add offset to what $rip would be at this point (right after the instruction, dyld_stub_rand+6).

This points to a symbol table entry, which should be either real rand or dynamic linker routine to load it (if it was never called). It is then replaced by my_rand.

Sometimes gdb will pick up dyld_stub_rand from libSystem or another shared library, if that happens, unload them first with remove-symbol-file before running other commands.

这篇关于gdb 可以使函数指针指向另一个位置吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆