防止在 OS X 上调试可执行文件的一种古老且众所周知的技术是使用以下对 ptrace 的调用来拒绝调试器将自身附加到可执行文件。
ptrace(PT_DENY_ATTACH, 0, 0, 0);
尝试在 GDB 中运行包含此代码的可执行文件将导致 GDB 退出,响应为[Inferior 1 (process #) exited with code 055]
。解决这个问题的方法很简单,只需将可执行文件加载到 gdb 中,然后使用 b ptrace
在 ptrace 上设置断点,并在询问时输入 y
Make Breakpointending on future共享库加载? (y 或 [n])
。不幸的是,当可执行文件运行时,永远不会设置此断点,并且它会退出而不继续。
以下是重现问题的方法。
- 使用命令行工具安装 Xcode 5。
- 通过 Homebrew 安装 GDB (
brew install https://raw.github.com/Homebrew/homebrew-dupes/master/gdb.rb
),对可执行文件进行代码签名 ( http://sourceware.org/gdb/wiki/BuildingOnDarwin ),然后重新启动(重新启动任务似乎不起作用)。 编译以下C程序
ptrace.c
,使用gcc -o ptrace ptrace.c
编译#include <stdio.h> #include <sys/types.h> #include <sys/ptrace.h> int main() { ptrace(PT_DENY_ATTACH, 0, 0, 0); printf("Hello, World!\n"); }
从包含已编译可执行文件的目录中,执行以下操作。
$ gdb ptrace ... (gdb) b ptrace Function "ptrace" not defined. Make breakpoint pending on future shared library load? (y or [n]) y Breakpoint 1 (ptrace) pending. (gdb) r Starting program: .../ptrace [Inferior 1 (process #) exited with code 055]
经过进一步测试,对于不属于可执行文件的其他函数(例如 printf
)也是如此。我已经在互联网上搜索过,但没有找到任何表明上述内容可能不起作用的内容。我对使用 gdb 或 lldb 的几乎任何解决方案持开放态度,并且也希望获得有关问题可能是什么的任何文档。
最佳答案
更新: GDB 7.8 现在可以通过 Homebrew 获得,它现在至少可以解析一些符号。有一些警告,但现在似乎有效。但是,不支持胖可执行文件。
事实证明,通过 Homebrew 提供的 GDB 是官方 GDB,与以前版本的 Xcode 中提供的 Apple GDB 不同。官方GDB无法将符号解析到系统库,从而导致问题的出现。从以前的安装中复制 Apple GDB 是可能的,因为它包含 Apple 的修改,但是它是一个比官方 GDB 旧得多的版本,并且在 OS X 10.9 Mavericks 上首次加载可执行文件时会产生许多警告(似乎否则可以工作)不过现在还好)。
Apple 不太可能继续开发 GDB,因此在 GDB 修复此问题之前,使用 LLDB 似乎是更好的解决方案。这是一个例子。
$ lldb ptrace
(lldb) b ptrace
(lldb) r
断点将在ptrace
处停止执行。
关于c - GDB 中断 ptrace 和其他 API 调用在 OS X Mavericks 上不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21807698/