首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Mach-O符号存根(IOS)

Mach-O符号存根(IOS)
EN

Stack Overflow用户
提问于 2012-01-12 03:37:12
回答 1查看 6.8K关注 0票数 7

我正在尝试理解Mach-o文件是如何工作的,并且已经在可用的在线资源(特别是这里的苹果页面:http://developer.apple.com/library/mac/#documentation/developertools/conceptual/MachORuntime/Reference/reference.html)方面取得了很大的进展,但在理解符号存根是如何工作的方面遇到了障碍。

使用"otool -l“我可以看到以下部分:

代码语言:javascript
复制
Section
  sectname __symbolstub1
   segname __TEXT
      addr 0x00005fc0
      size 0x00000040
    offset 20416
     align 2^2 (4)
    reloff 0
    nreloc 0
     flags 0x80000408

但是,当我在十六进制编辑器中查看二进制文件中的数据时,我看到以下4个字节一次又一次地重复:

代码语言:javascript
复制
00005FC0  38 F0 9F E5 38 F0 9F E5  38 F0 9F E5 38 F0 9F E5  88
00005FD0  38 F0 9F E5 38 F0 9F E5  38 F0 9F E5 38 F0 9F E5  88
00005FE0  38 F0 9F E5 38 F0 9F E5  38 F0 9F E5 38 F0 9F E5  88  
00005FF0  38 F0 9F E5 38 F0 9F E5  38 F0 9F E5 38 F0 9F E5  88

这看起来有点像LDR,它将PC增加固定的数量,但我不明白为什么符号表中的每个条目的数量都是相同的。

如果有人能解释为什么会这样,或者提供任何资源,让我知道。

谢谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-01-12 22:20:51

我将使用当前的iOS来描述这种情况,它在旧版本中有所不同。

符号存根确实将函数指针加载到PC中。对于标准的“惰性”(按需)导入,指针驻留在__lazy_symbol部分,并且最初指向__stub_helper部分中的帮助器例程,例如:

代码语言:javascript
复制
__symbolstub1 _AudioServicesAddSystemSoundCompletion
__symbolstub1 LDR  PC, _AudioServicesAddSystemSoundCompletion$lazy_ptr
__symbolstub1 ; End of function _AudioServicesAddSystemSoundCompletion

__lazy_symbol _AudioServicesAddSystemSoundCompletion$lazy_ptr DCD _AudioServicesAddSystemSoundCompletion$stubHelper

__stub_helper _AudioServicesAddSystemSoundCompletion$stubHelper
__stub_helper LDR R12, =nnn ; symbol info offset in the lazy bind table
__stub_helper B   dyld_stub_binding_helper

函数dyld_stub_binding_helper__stub_helper部分的第一个函数,本质上只是dyld中dyld_stub_binder函数的一个跳床,传递给它我称之为"symbol info offset“的值。该值是惰性绑定信息流(由LC_DYLD_INFO或LC_DYLD_INFO_ONLY load命令指向)中的偏移量,它是一种带有用于dyld的命令的字节码流。惰性导入的典型序列如下所示:

代码语言:javascript
复制
72: BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB(M, 0xYYYYY)
19: BIND_OPCODE_SET_DYLIB_ORDINAL_IMM(NNNN)
40: BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM(0x00, '_AudioServicesAddSystemSoundCompletion')
90: BIND_OPCODE_DO_BIND()

在这里,dyld将执行以下操作:

  1. 从加载命令中列出的dylib列表中的dylib号NNNN查找名为'_AudioServicesAddSystemSoundCompletion‘的函数。
  2. 查找可执行文件的段号M(很可能是__DATA)
  3. 将函数指针写入偏移量yyyyy.
  4. 跳转到查找的地址,以便实际函数完成其工作

写入的地址恰好是_AudioServicesAddSystemSoundCompletion$lazy_ptr插槽。因此,下一次调用_AudioServicesAddSystemSoundCompletion时,它将直接跳转到导入的函数,而不是通过dyld。

注意:您不应该立即查看文件中的偏移量05fc0。addr字段是虚拟地址,您应该查找包含段的命令,看看它从哪个VA开始,以及它的文件偏移量是多少,然后进行计算。通常,__TEXT段从1000开始。

然而,实际的符号存根看起来确实像你粘贴的,可能你有一个fat mach-o,fat报头取了前1000个字节,所以偏移量排成一行。

票数 15
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8825537

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档