如何从应用程序内执行调试器命令 [英] How to execute a debugger command from within the app

查看:83
本文介绍了如何从应用程序内执行调试器命令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在运行时,我试图恢复未导出但可以通过共享库的符号表使用并且因此对调试器可见的函数的地址.

In runtime I'm trying to recover an address of a function that is not exported but is available through shared library's symbols table and therefore is visible to the debugger.

我正在开发高级调试程序,该程序需要捕获某些事件并操纵运行时.其中一项操作要求了解专用功能的地址(仅该地址),该地址在其他地方用作键.

I'm working on advanced debugging procedure that needs to capture certain events and manipulate runtime. One of the actions requires knowledge of an address of a private function (just the address) which is used as a key elsewhere.

我当前的解决方案使用nm在构建时计算该私有函数相对于已知导出函数的偏移量.该解决方案依赖于共享库的特定内部版本,因​​此限制了调试功能.

My current solution calculates offset of that private function relative to a known exported function at build time using nm. This solution restricts debugging capabilities since it depends on a particular build of the shared library.

首选解决方案应该能够在运行时恢复地址.

The preferable solution should be capable of recovering the address in runtime.

我希望从应用程序内部与附加的调试器进行通信,但是很难找到用于此目的的任何API.

I was hoping to communicate with the attached debugger from within the app, but struggle to find any API for that.

我有什么选择?

推荐答案

在lldb中,如果调试器可以通过任何方式知道它,则可以通过设置符号断点来快速找到地址:

In lldb you can quickly find the address by setting a symbolic breakpoint if it's known to the debugger by whatever means:

b symbolname

如果要从未连接调试器的库中调用非导出函数,则有几个选项,但从长远来看,每个选项都不可靠:

If you want call a non exported function from a library without a debugger attached there are couple of options but each will not be reliable in the long run:

  • 对导出的库中的偏移量进行硬编码,并调用exportSymbol + offset(这将适用于特定的库二进制版本,但可能会破坏其他功能)
  • 尝试在已加载的库中搜索未导出函数的二进制签名. (不太容易被破坏,但是二进制签名可能总是会改变)

也许,如果您提供更详细的上下文信息,可以考虑您正在尝试实现更好的选择.

Perhaps if you provide more detailed context what are you trying achieve better options can be considered.

更新:
由于lldb以某种方式知道该符号,因此我怀疑它是在您的库的Mach-O LC_SYMTAB load命令中定义的.要验证您是否可以使用 MachOView

Update:
Since lldb is somehow aware of the symbol I suspect it's defined in Mach-O LC_SYMTAB load command of your library. To verify that you could inspect your lib binary with tools like MachOView or MachOExplorer . Or Apple's otool or Jonathan Levin's jtool/jtool2 in console.

这是从MachOView中的LC_SYMTAB产生的第一个符号输入的示例.这是/usr/lib/dyld二进制文件 在示例中,此处0x1000是虚拟地址.您的库很可能是64位的,因此请期待0x10000000及更高版本.实际基数由ASLR随机分配,但是您可以使用

Here's an example from very 1st symbol entry yielded from LC_SYMTAB in MachOView. This is /usr/lib/dyld binary In the example here 0x1000 is virtual address. Your library most likely will be 64bit so expect 0x10000000 and above. The actual base gets randomized by ASLR, but you can verify the current value with

sample yourProcess

yourProcess是使用您所需要的库的可执行文件. 输出应包含:

yourProcess being an executable using the library you're after. The output should contain:

Binary Images:
       0x10566a000 -        0x105dc0fff  com.apple.finder (10.14.5 - 1143.5.1) <3B0424E1-647C-3279-8F90-4D374AA4AC0D> /System/Library/CoreServices/Finder.app/Contents/MacOS/Finder
       0x1080cb000 -        0x1081356ef  dyld (655.1.1) <D3E77331-ACE5-349D-A7CC-433D626D4A5B> /usr/lib/dyld
...

这些是由ASLR移位的加载地址0x100000000.对于dylib,如何精确选择这些地址可能会有更多的细微差别,但您会明白的.

These are the loaded addresses 0x100000000 shifted by ASLR. There might be more nuances how exactly those addresses are chosen for dylibs but you get the idea.

我从来不需要以编程方式找到这样的地址,但这绝对是可行的(因为/usr/bin/sample可以做到).

Tbh I've never needed to find such address programmatically but it's definitely doable (as /usr/bin/sample is able to do it).

从这里实际实现一些目标:

From here to achieve something practically:

  1. 解析您的lib二进制文件的Mach-o标头(请检查& (对于初学者)
  2. 查找LC_SYMTAB加载命令
  3. 找到基于符号文本的条目并找到虚拟地址(红色框内的东西)
  4. 计算ASLR并应用班次
  1. Parse Mach-o header of your lib binary (check this & this for starters)
  2. Find LC_SYMTAB load command
  3. Find your symbol text based entry and find the virtual address (the red box stuff)
  4. Calculate ASLR and apply the shift

有一些用于解析Mach-O的C Apple API.野外也存在一些Python代码(在逆向工程人员中很流行).

There is some C Apple API for parsing Mach-O. Also some Python code exists in the wild (being popular among reverse engineering folks).

希望有帮助.

这篇关于如何从应用程序内执行调试器命令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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