在没有符号的设备上调试iOS应用程序

时间:2012-05-27 21:00:12

标签: ios xcode delphi lldb

我需要在实际设备上调试ios应用程序的启动...并且通过启动我的意思是当操作系统控制到应用程序时执行的第一条指令 。不是“主要”。此外,此应用程序没有任何符号(即调试信息不​​可用..)。我不在乎是否必须在CPU指令级调试。我知道该怎么做(已经做了30多年)。当控件即将传输到应用程序时,我希望调试器停止。当我使用Attach | by Name命令并运行时,它只是说“已完成运行”。

哦,这个应用程序不是在XCode中构建的,但是我构建,签名和配置并移动到设备的应用程序。应用程序运行,因为我可以看到控制台输出。万一你以为我是一个黑客试图调试别人的应用程序。

高阶订单怎么样?我敢打赌,没有人可以回答这个问题......我无法找到任何有关如何使用XCode构建的项目执行此操作的信息。我想知道苹果霸主是不可能或“允许”它?

你怎么说,Stack Overflow神?

更新:我应该澄清一些事情。此应用程序使用任何商用或开源工具构建。我与工具供应商合作创建编译器,框架和IDE。 IOW,你不能得到这个工具......在引导新工具链的过程中,必须经常采用一些非常低级的原始调试。特别是如果工具生成的代码中存在错误。

3 个答案:

答案 0 :(得分:23)

我将回答我自己的问题,因为我认为我偶然发现了一个解决方案。如果有人比这更优雅和简单,请回答。关于步骤:

从原始的单片iOS可执行文件开始(不是捆绑的.app,而是实际的二进制机器文件,即机器代码)。

  1. 创建一个新的同名空Xcode项目。在设备上构建并运行它。
  2. 找到输出包的.app文件夹。
  3. 将上述原始iOS可执行文件复制到.app软件包文件夹中的现有iOS可执行文件。
  4. 应用程序现在将具有无效签名,无法部署和运行。
  5. 对应用程序包运行codesign(您可以通过在上面的Xcode项目上运行xcodebuild找到命令行)。
  6. 在bundle的.app文件夹中,在二进制映像上运行otool -h -l。找到LC_UNIXTHREAD加载命令,找到与'pc'寄存器关联的值。这是os加载程序将跳转到您的应用程序的地址。如果这个地址是奇数,那么这些是Thumb指令,否则它将是ARM(我认为这是它的工作方式)。
  7. 添加符号断点(我使用GDB而不是LLDB)并输入地址为'* 0x00001234'作为符号。
  8. 选择产品|执行操作|不使用构建运行。
  9. 假设GDB能够评估断点表达式并设置断点,并且您已选择“产品|调试工作流程|调试时显示反汇编”,则该过程应该在应用程序中要执行的第一条指令处中断。

    您现在可以单步执行指令并使用GDB控制台获取/设置寄存器值。

答案 1 :(得分:2)

您的问题没有意义 - 主要是进入应用程序的入口点。它是第一个应该遇到的代码,除非你可能为某些类重写了initialize()(但即便如此,我认为main会在运行时之前被命中)。

我认为你在发布时遇到了一些奇怪的错误,你认为你想在入口处设置一个断点来捕获它,但更有可能的是帮助你在发布时描述问题并让其中一个已经看到并修复了同样崩溃的4000人帮助你...

但是,如果你真的想使用GDB打破没有符号的应用程序(但是你从XCode启动),你可以按照以下方式在程序集地址上打破GDB:

How to break on assembly instruction at a given address in gdb?

要查找主要(或其他方法)的地址,您可以使用工具或atos,此问题中的一些示例:

Matching up offsets in iOS crash dump to disassembled binary

此外:

如果出于某种原因,XCode无法启动您的应用程序进行调试,您还可以在设备本身进行越狱并安装GDB,从而完全控制调试。如果XCode可以启动你的应用程序,我认为没有理由为什么能够在任意内存地址中断,并没有给你你寻求的能力......

答案 2 :(得分:1)

我找到的唯一解决方案是使用webview的应用程序,但通过Safari远程调试器在模拟器中。这是偏离主题的,但也许这一个或其他可能会受益。

http://hiediutley.com/2011/11/22/debugging-ios-apps-using-safari-web-inspector/

或者使用netcat for IOs ...不是最完美的解决方案,但至少你会看到发生了什么。