Import class-dump info into GDB(将类转储信息导入 GDB)
问题描述
有没有办法将 class-dump
的输出导入 GDB?
Is there a way to import the output from class-dump
into 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
", [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
我知道我现在可以在 gdb
中使用 b *0x0000000100000e50
,但是有没有办法修改 GDB 的符号表以使其接受 b +[TestClass随机数]
?
I know I can now use b *0x0000000100000e50
in gdb
, but is there a way of modifying GDB's symbol table to make it accept b +[TestClass randomNum]
?
如果它可以与 GDB v6 而不仅仅是 GDB v7 一起使用会更好,因为 GDB v6 是带有 Apple 补丁的最新版本.
It would be preferably if it would work with GDB v6 and not only GDB v7, as GDB v6 is the latest version with Apple's patches.
推荐答案
可以使用 add-symbol-file
命令在 gdb 中加载符号文件.最难的部分是生成这个符号文件.
It’s possible to load a symbol file in gdb with the add-symbol-file
command. The hardest part is to produce this symbol file.
借助 libMachObjC(它是 class-dump 的一部分),这非常容易转储所有地址及其对应的 Objective-C 方法.我写了一个小工具,objc-symbols 正是这样做的.
With the help of libMachObjC (which is part of class-dump), it’s very easy to dump all addresses and their corresponding Objective-C methods. I have written a small tool, objc-symbols which does exactly this.
我们以 Calendar.app 为例.如果您尝试使用 nm
工具列出符号,您会注意到日历应用程序已被剥离:
Let’s use Calendar.app as an example. If you try to list the symbols with the nm
tool, you will notice that the Calendar app has been stripped:
$ nm -U /Applications/Calendar.app/Contents/MacOS/Calendar
0000000100000000 T __mh_execute_header
0000000005614542 - 00 0000 OPT radr://5614542
但是使用 objc-symbols
您可以轻松检索所有缺少的 Objective-C 方法的地址:
But with objc-symbols
you can easily retrieve the addresses of all the missing Objective-C methods:
$ objc-symbols /Applications/Calendar.app
00000001000c774c +[CALCanvasAttributedText textWithPosition:size:text:]
00000001000c8936 -[CALCanvasAttributedText createTextureIfNeeded]
00000001000c8886 -[CALCanvasAttributedText bounds]
00000001000c883b -[CALCanvasAttributedText updateBezierRepresentation]
...
00000001000309eb -[CALApplication applicationDidFinishLaunching:]
...
然后,使用 SymTabCreator 你可以创建一个符号文件,它实际上只是一个空的 dylib所有的符号.
Then, with SymTabCreator you can create a symbol file, which is just actually an empty dylib with all the symbols.
同时使用 objc-symbols
和 SymTabCreator
很简单:
Using objc-symbols
and SymTabCreator
together is straightforward:
$ objc-symbols /Applications/Calendar.app | SymTabCreator -o Calendar.stabs
您可以检查 Calendar.stabs
是否包含所有符号:
You can check that Calendar.stabs
contains all the symbols:
$ 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 中发生了什么:
Now let’s see what happens in 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 vs 0x1000309eb,相差7个字节),这是因为gdb会自动识别函数序言并在其后设置断点.
You will notice that the breakpoint address does not exactly match the symbol address (0x1000309f2 vs 0x1000309eb, 7 bytes of difference), this is because gdb automatically recognizes the function prologue and sets the breakpoint just after.
<小时>
假设剥离的可执行文件是当前目标,您可以使用此 GDB 脚本自动执行此操作.
You can use this GDB script to automate this, given that the stripped executable is the current target.
将下面的脚本添加到您的 .gdbinit
,定位到剥离的可执行文件并在 gdb 中运行命令 objc_symbols
:
Add the script from below to your .gdbinit
, target the stripped executable and run the command objc_symbols
in gdb:
$ 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
这篇关于将类转储信息导入 GDB的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:将类转储信息导入 GDB
基础教程推荐
- android 应用程序已发布,但在 google play 中找不到 2022-01-01
- 当从同一个组件调用时,两个 IBAction 触发的顺序是什么? 2022-01-01
- 如何让对象对 Cocos2D 中的触摸做出反应? 2022-01-01
- UIWebView 委托方法 shouldStartLoadWithRequest:在 WKWebView 中等效? 2022-01-01
- 在 gmail 中为 ios 应用程序检索朋友的朋友 2022-01-01
- 如何在 UIImageView 中异步加载图像? 2022-01-01
- Kivy Buildozer 无法构建 apk,命令失败:./distribute.sh -m “kivy"d 2022-01-01
- Android:对话框关闭而不调用关闭 2022-01-01
- 如何在 iPhone 上显示来自 API 的 HTML 文本? 2022-01-01
- 如何在没有IB的情况下将2个按钮添加到右侧的UINavigationbar? 2022-01-01