美文网首页
MachO的动态链接——1

MachO的动态链接——1

作者: 政在coding | 来源:发表于2019-01-14 21:09 被阅读0次

对于存在于别的动态库的函数,程序在运行的时候需要通过动态链接来获取函数的调用地址。在iOS上是通过dyld来实现的。下面对这个原理做一下梳理。

以最令人熟悉的NSLog来做例子
先写一个简单的程序

- (void)viewDidLoad {
    [super viewDidLoad];
    NSLog(@"first");
    NSLog(@"second");
}

然后在两个NSLog都打上断点,运行。
程序断住之后,调节成汇编模式Debug --> Debug Workflow --> Always Show Disassembly,然后会切换到下面的视图

image.png
留意到symbol stub for: NSLog 这句,这句就是跳转到NSLog的stub实现imp___stubs__NSLog
我们先用image list命令来获取模块的基地址
image.png
0x0000000100d80000就是这次运行时模块的基地址。为什么说是这次运行呢?因为iOS有ASLR(Address space layout randomization),将可执行程序随机装载到内存中,这里的随机只是偏移,而不是打乱。所以程序运行时候的基地址为:静态的基地址+ASLR偏移
静态的基地址可以使用machOView来看
静态基地址
或者去看TEXT段
image.png

总结一下:运行时程序的基址 = __LINKEDIT.VM_Address –__LINKEDIT.File_Offset + ASLR偏移

所以,这次运行的时候ASLR偏移=0x0000000100d80000 - 0x100000000 = 0xd80000
好了,回到刚刚的bl 0x100dc2dac ; symbol stub for: NSLog,我们可以去看看这个地址里面究竟是什么代码,先求出它对应的 静态地址=运行时地址-ASLR偏移 = 0x100dc2dac - 0xd80000 = 0x100042DAC。然后用hopper打开,跳转到该地址,如下

image.png
这三句代码是取值之后跳转,先看看#0x100050228的值,单击点进去。这里有个坑,如果你用hopper导入的时候选择了Resolve Lazy Binding,那么这个地址会解析成了符号。所以导入的时候不要选,那么可以看到这个地址的值如下:
0000000100050228 dq 0x0000000100043598
所以上面的三句汇编的意思是跳转0x0000000100043598这个地址,然后我们再切到这个地址看看。 image.png
在这里压入一个参数之后,继续跳转到0x1000433b8执行,继续跟入到这里,终于找到了stub_helper的调用。
stub_helper

继续执行,到第二次进入NSLog,然后你会发现0x100dc2dac处的执行代码变成了下面的,这里其实仍然是取的静态地址0x100050228处的值,只不过这个值已经变成了0x18350e680

image.png
我们可以打印一下静态地址0x100050228对应的动态地址0x100050228+ 0xd80000 = 0x100DD0228,确实已经变成了0x18350e680
image.png

然后进入0x18350e680这个地址,你会发现这里就是NSLog的函数入口

NSLog
附上刚刚image list的另外一个模块,你会发现0x18350e680这个地址已经是另外模块的了。
[ 6] 18908B96-750C-3898-8EB0-D7028C656A6D 0x00000001834b5000 /Users/zheng/Library/Developer/Xcode/iOS DeviceSupport/11.3.1 (15E302)/Symbols/System/Library/Frameworks/Foundation.framework/Foundation

这个就是MachO的懒加载符号表的加载过程。第一次调用的时候是指向stub_helper,调用完一次之后,就会修改懒加载符号指针,让其指向真正的函数地址,以后就可以直接跳转。

最后再附上MachOView上的几张图片,指明了刚刚所说的几处函数位置,这里是Symbol Stubs,留意到这个0x00042DAC是不是很熟悉?这个是文件偏移,它和静态基地址的关系是静态基地址 = 模块起始地址 + 文件偏移。起始下面就是我们调用NSLog最开始会跳转的地方。它的值就是刚刚那三句跳转代码。

image.png
到静态地址0x100050228的地方(留意这里是DATA区),可以看到它的值是最开始的0x0000000100043598,当调用过一次之后,stub_helper就会把这里的值改为函数的真实地址。
image.png

至于stub_helper的绑定过程,看汇编比较麻烦,建议去看源码吧
libdyld.dylib dyld_stub_binder --> libdyld.dylib _dyld_fast_stub_entry --> dyld::fastBindLazySymbol -->ImageLoaderMachO::bindLocation

相关文章

  • MachO的动态链接——1

    对于存在于别的动态库的函数,程序在运行的时候需要通过动态链接来获取函数的调用地址。在iOS上是通过dyld来实现的...

  • MachO的动态链接

    对于存在别的动态库的函数,程序在运行的时候需要通过动态链接来获取函数的调用地址,在iOS上是通过dyld来实现的,...

  • MachO与动态链接

    前置知识 符号 静态链接 汇编基础 虚拟内存 跳转指令的编码:PC相对地址与绝对地址 汇编跳转指令:直接跳转与间接...

  • MachO的动态链接——2

    这次说一下懒加载符号表的查找。先回忆起上次讲的这张图,这里去#0x100050228这个地址取值,然后跳转,第一次...

  • MachO的动态链接——3

    之前说了通过stub_helper绑定真实函数地址,在调用stub_helper的时候传入了一个参数,如下图。调用...

  • fishHook原理

    fishHook fishHook是Facebook提供的一个动态修改链接mach-O文件的工具。利用MachO文...

  • iOS逆向之fishHook原理探究

    HOOK原理 1、MachO是被谁加载的? DYLD动态加载 2、ASLR技术(地址空间布局随机化):MachO文...

  • iOS逆向工程 - fishhook原理

    fishhook是Facebook提供的一个动态修改链接mach-O文件的工具。利用MachO文件加载原理,通过修...

  • fishHook原理分析

    fishHook是Facebook提供的一个动态修改链接mach-O文件的工具。利用MachO文件加载原理,通过修...

  • 《iOS 逆向》010.10Hook原理探究

    HOOK原理: 1.MachO是被谁加载的?DYLD动态加载的。2.ASLR(地址空间布局随机化)技术MachO文...

网友评论

      本文标题:MachO的动态链接——1

      本文链接:https://www.haomeiwen.com/subject/zzcddqtx.html