Ber*_*rgP 4 iphone reverse-engineering objective-c ida cydia-substrate
从objc来源我们可以看到SEL定义为typedef struct objc_selector *SEL;
我用idaq反汇编我的dylib ,并且我确实调用了_MSHookMessageEx函数,它是从libsubstrate.dylib链接的
_MSHookMessageEx 有以下签名
void MSHookMessageEx(Class class, SEL selector, IMP replacement, IMP *result);
Run Code Online (Sandbox Code Playgroud)
所以我们可以假设在源代码中有类似@selector(someMethod:)第二个参数的东西
在目标文件的数据部分,我可以看到源代码中使用的所有CFStrings

但是这里没有任何选择器字符串,所以我们可以看到它@selector()没有转换成静态CFString
我很感兴趣找到传递给_MSHookMessageEx函数的选择器和类的String表示.
如何从目标文件(Mach-o)获取SEL(@selector())?SEL如何存储在Mach-o中?
谢谢!
更新:
我确实在调用方法之前在ida方法表示中有一些字符串

我猜有些选择器传入函数.我对吗?
rob*_*off 10
选择器名称存储在__objc_methname段的__TEXT部分中:
:; otool -v -s __TEXT __objc_methname /System/Library/Frameworks/AppKit.framework/AppKit | head
/System/Library/Frameworks/AppKit.framework/AppKit:
Contents of (__TEXT,__objc_methname) section
0x000000000097cbd8 count
0x000000000097cbde countByEnumeratingWithState:objects:count:
0x000000000097cc09 alloc
0x000000000097cc0f initWithObjects:count:
0x000000000097cc26 release
0x000000000097cc2e autorelease
0x000000000097cc3a copy
0x000000000097cc3f timeIntervalSinceNow
Run Code Online (Sandbox Code Playgroud)
选择器的指针存储在__objc_selrefs段的__DATA部分中:
:; otool -v -s __DATA __objc_selrefs /System/Library/Frameworks/AppKit.framework/AppKit | head
/System/Library/Frameworks/AppKit.framework/AppKit:
Contents of (__DATA,__objc_selrefs) section
0x0000000000d77d80 __TEXT:__objc_methname:initWithObjects:count:
0x0000000000d77d88 __TEXT:__objc_methname:copy
0x0000000000d77d90 __TEXT:__objc_methname:timeIntervalSinceNow
0x0000000000d77d98 __TEXT:__objc_methname:sharedAppleEventManager
0x0000000000d77da0 __TEXT:__objc_methname:_prepareForDispatch
0x0000000000d77da8 __TEXT:__objc_methname:_setLaunchTaskMaskBits:
0x0000000000d77db0 __TEXT:__objc_methname:_disableSuddenTermination
0x0000000000d77db8 __TEXT:__objc_methname:_appleEventActivationInProgress
Run Code Online (Sandbox Code Playgroud)
甲SEL在源代码实际上是(目前)的指针选择的C字符串名称.所以,如果你这样写:
SEL s = @selector(initWithObjects:count:);
Run Code Online (Sandbox Code Playgroud)
然后s是有效的char const *,它指向字符串initWithObjects:count:.直到最近,您可以通过执行以下操作来打印选择器名称:
NSLog(@"selector is %s", (char *)s);
Run Code Online (Sandbox Code Playgroud)
但是,Apple更改了编译器(我认为Xcode 4.6),禁止将a转换SEL为a char *,因此他们可能会在将来更改选择器的实现.
无论如何,棘手的部分是机器代码__objc_selrefs使用PC相对寻址加载来自该部分的指针.PC是"程序计数器",它是当前正在执行的指令的地址.在x86架构上,它通常称为IP(指令指针)或EIP(扩展IP).
这就是你的反汇编的相关说明中发生的事情:
1444 LDR R1, =(off_2038 - 0x145C)
...
1454 LDR R1, (PC,R1)
Run Code Online (Sandbox Code Playgroud)
指向选择器的指针从地址0x2038处的字加载.但是常量0x2038实际上并没有出现在机器代码中.您的反汇编程序通过分析程序的数据流为您帮助计算了它.存储在第一LDR条指令中的常量实际上是0xBDC,因为0xBDC + 0x145C = 0x2038.
您可能想知道为什么当第二LDR条指令位于地址0x1454 时它使用0x145C.当ARM处理器使用PC相对寻址计算地址时,PC的值实际上是当前正在执行的指令的地址加4或加8(取决于处理器模式). 这是在这里记录的(可能还有其他地方).