Mach-O的符号存根(IOS) [英] Mach-O symbol stubs (IOS)

查看:424
本文介绍了Mach-O的符号存根(IOS)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想了解的Mach-O文件如何工作,并取得了与现有的在线资源发展的良好交易(尤其是苹果页面在这里:<一href=\"http://developer.apple.com/library/mac/#documentation/developertools/conceptual/MachORuntime/Reference/reference.html\">http://developer.apple.com/library/mac/#documentation/developertools/conceptual/MachORuntime/Reference/reference.html),但我已经打在了解如何符号存根工作的绊脚石。

I am trying to understand how Mach-o files work, and have made a good deal of progress with the online resources available (In particular, the Apple page here: http://developer.apple.com/library/mac/#documentation/developertools/conceptual/MachORuntime/Reference/reference.html), but I have hit a roadblock on understanding how symbol stubs work.

使用otool -l我看到了以下部分:

Using "otool -l" I see the following section:

Section
  sectname __symbolstub1
   segname __TEXT
      addr 0x00005fc0
      size 0x00000040
    offset 20416
     align 2^2 (4)
    reloff 0
    nreloc 0
     flags 0x80000408

然而,当我看数据从二进制文件中的十六进制编辑器我看到下面的4个字节一再重复:

However when I look at the data from the binary file in a hex editor I see the following 4 bytes repeated again and again:

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

这看起来就像它通过一个固定的数额增加了PC一个LDR,但我不明白为什么量在符号表中的每个条目是相同的。

This looks something like a LDR which increases the PC by a fixed amount, but I don't see why the amount is the same for each entry in the symbol table.

如果有人能对为什么是这样阐明,或提供得到这个低水平的资源,请让我知道。

If someone can shed light on why this is so, or provide any resources that get this low level, please let me know.

谢谢!

推荐答案

我所描述的情况与目前的iOS,它在旧版本有所不同。

I will describe the situation with the current iOS, it's somewhat different in the old versions.

符号确实存根加载到PC的函数指针。对于标准的懒(按需)进口,指针所在的 __ lazy_symbol 部分,最初在 __ stub_helper <指向辅助函数/ code>部分,例如:

The symbol stubs indeed load into the PC a function pointer. For the standard "lazy" (on-demand) imports, the pointer resides in the __lazy_symbol section and initially points to a helper routine in the __stub_helper section, e.g.:

__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_stub_binder 在dyld的功能,将其传递给我称之为符号信息偏移的价值。该值是在延迟绑定信息流(由LC_DYLD_INFO或LC_DYLD_INFO_ONLY负荷命令所指向的),这是一种与dyld的命令字节code流的内部的偏移量。对于一个懒惰的进口典型的顺序是这样的:

The function dyld_stub_binding_helper is the fist one in the __stub_helper section and essentially is just a trampoline to the dyld_stub_binder function in dyld, passing to it what I call "symbol info offset" value. That value is an offset inside the lazy binding info stream (pointed to by the LC_DYLD_INFO or LC_DYLD_INFO_ONLY load command), which is a sort of bytecode stream with commands for dyld. Typical sequence for a lazy import looks like this:

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的将做到以下几点:

here dyld would do the following:


  1. 从名为_AudioServicesAddSystemSoundCompletion查询功能
    在负载中列出的dylibs列表的dylib数字nnnn
    命令。

  2. 查找可执行文件的段数M(最有可能的__DATA)

  3. 写在偏移YYYYY函数指针。

  4. 跳转到查找地址,这样实际的功能,它的工作

写入地址恰好是 _AudioServicesAddSystemSoundCompletion $ lazy_ptr 插槽。所以,下一次 _AudioServicesAddSystemSoundCompletion 被调用时,它会直接跳转到进口功能,无需通过dyld的打算。

The address written to happens to be the _AudioServicesAddSystemSoundCompletion$lazy_ptr slot. So, the next time the _AudioServicesAddSystemSoundCompletion is called, it will jump directly to the imported function, without going via dyld.

N.B 的:你不应该看偏移05fc0文件中的时候了。在地址字段是虚拟地址,你应该看看了包含段命令,并看到它VA开始什么,什么是它的文件偏移,然后做数学题。通常情况下,__TEXT段开始于1000

N.B.: you should not look at the offset 05fc0 in the file right away. The addr field is the virtual address, you should look up the containing segment command and see at what VA it starts and what is its file offset, then do the math. Usually the __TEXT segment starts at 1000.

但是,实际的符号存根看起来象您粘贴,也许你有一个胖的Mach-O的脂肪头取前1000个字节,因此偏移排队。

However, the actual symbol stubs do look like you pasted, probably you have a fat mach-o with the fat header taking the first 1000 bytes, so the offsets line up.

这篇关于Mach-O的符号存根(IOS)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆