有没有办法将class-dump
的输出导入GDB?
示例代码:
$ cat > test.m
#include <stdio.h>
#import <Foundation/Foundation.h>
@interface TestClass : NSObject
+ (int)randomNum;
@end
@implementation TestClass
+ (int)randomNum {
return 4; // chosen by fair dice roll.
// guaranteed to be random.
}
@end
int main(void) {
printf("num: %d\n", [TestClass randomNum]);
return 0;
}
^D
$ gcc test.m -lobjc -o test
$ ./test
num: 4
$ gdb test
...
(gdb) b +[TestClass randomNum]
Breakpoint 1 at 0x100000e5c
(gdb) ^D
$ strip test
$ gdb test
...
(gdb) b +[TestClass randomNum]
Function "+[TestClass randomNum]" not defined.
(gdb) ^D
$ class-dump -A test
...
@interface TestClass : NSObject
{
}
+ (int)randomNum; // IMP=0x0000000100000e50
@end
我知道我现在可以在b *0x0000000100000e50
中使用gdb
,但有没有办法修改GDB的符号表以使其接受b +[TestClass randomNum]
?
编辑:如果它可以与GDB v6一起使用,而不仅仅是GDB v7,因为GDB v6是Apple补丁的最新版本。
答案 0 :(得分:35)
可以使用add-symbol-file
命令在gdb中加载符号文件。最难的部分是生成这个符号文件。
在libMachObjC(它是class-dump的一部分)的帮助下,转储所有地址及其相应的Objective-C方法非常容易。我写了一个小工具,objc-symbols就是这样做的。
我们以Calendar.app为例。如果您尝试使用nm
工具列出符号,您会发现日历应用已被剥离:
$ nm -U /Applications/Calendar.app/Contents/MacOS/Calendar
0000000100000000 T __mh_execute_header
0000000005614542 - 00 0000 OPT radr://5614542
但是使用objc-symbols
,您可以轻松检索所有缺少的Objective-C方法的地址:
$ objc-symbols /Applications/Calendar.app
00000001000c774c +[CALCanvasAttributedText textWithPosition:size:text:]
00000001000c8936 -[CALCanvasAttributedText createTextureIfNeeded]
00000001000c8886 -[CALCanvasAttributedText bounds]
00000001000c883b -[CALCanvasAttributedText updateBezierRepresentation]
...
00000001000309eb -[CALApplication applicationDidFinishLaunching:]
...
然后,使用SymTabCreator,你可以创建一个符号文件,它实际上是一个带有所有符号的空dylib。
同时使用objc-symbols
和SymTabCreator
非常简单:
$ objc-symbols /Applications/Calendar.app | SymTabCreator -o Calendar.stabs
您可以检查Calendar.stabs
是否包含所有符号:
$ nm Calendar.stabs
000000010014a58b T +[APLCALSource printingCachedTextSize]
000000010013e7c5 T +[APLColorSource alternateGenerator]
000000010013e780 T +[APLColorSource defaultColorSource]
000000010013e7bd T +[APLColorSource defaultGenerator]
000000010011eb12 T +[APLConstraint constraintOfClass:withProperties:]
...
00000001000309eb T -[CALApplication applicationDidFinishLaunching:]
...
现在让我们看看gdb中会发生什么:
$ gdb --silent /Applications/Calendar.app
Reading symbols for shared libraries ................................. done
没有符号文件:
(gdb) b -[CALApplication applicationDidFinishLaunching:]
Function "-[CALApplication applicationDidFinishLaunching:]" not defined.
Make breakpoint pending on future shared library load? (y or [n]) n
加载符号文件后:
(gdb) add-symbol-file Calendar.stabs
add symbol table from file "Calendar.stabs"? (y or n) y
Reading symbols from /Users/0xced/Calendar.stabs...done.
(gdb) b -[CALApplication applicationDidFinishLaunching:]
Breakpoint 1 at 0x1000309f2
您会注意到断点地址与符号地址不完全匹配(0x1000309f2与0x1000309eb,差异为7个字节),这是因为gdb会自动识别函数序言并在之后设置断点。
<小时/>
您可以使用此GDB脚本自动执行此操作,因为已剥离的可执行文件是当前目标。
将下面的脚本添加到.gdbinit
,定位已剥离的可执行文件并在gdb中运行命令objc_symbols
:
$ gdb test
...
(gdb) b +[TestClass randomNum]
Function "+[TestClass randomNum]" not defined.
(gdb) objc_symbols
(gdb) b +[TestClass randomNum]
Breakpoint 1 at 0x100000ee1
(gdb) ^D
define objc_symbols
shell rm -f /tmp/gdb-objc_symbols
set logging redirect on
set logging file /tmp/gdb-objc_symbols
set logging on
info target
set logging off
shell target="$(head -1 /tmp/gdb-objc_symbols | head -1 | awk -F '"' '{ print $2 }')"; objc-symbols "$target" | SymTabCreator -o /tmp/gdb-symtab
set logging on
add-symbol-file /tmp/gdb-symtab
set logging off
end
答案 1 :(得分:4)
没有直接的方法(我知道),但这似乎是一个好主意。
现在有办法做到这一点......很好的回答,0xced!
DWARF文件格式为well documented,IIRC,并且,当lldb source可用时,您有一个解析器的工作示例。
由于source to class-dump也可用,因此修改它以引入可以加载到调试器中的DWARF输出应该不会太难。
显然,你无法以完全保真的方式转储符号,但这可能非常有用。
答案 2 :(得分:0)
您可以使用DSYMCreator。
使用DSYMCreator,您可以从iOS可执行二进制文件创建符号文件。
这是一个工具链,所以你可以像这样使用它。
$ ./main.py --only-objc /path/to/binary/xxx
然后将创建一个文件/path/to/binary/xxx.symbol
,这是一个DWARF格式符号。您可以自己将其导入lldb
。
除此之外,DSYMCreator
还支持从IDA Pro导出符号,您可以像这样使用它。
$ ./main.py /path/to/binary/xxx
是,只需忽略--only-objc
标志。然后IDA Pro将自动运行,然后将创建一个文件/path/to/binary/xxx.symbol
,即符号文件。
感谢0xced创建了objc-symbols
,这是DSYMCreator工具链的一部分。