`

Mach-O 的动态链接(Lazy Bind 机制)

阅读更多

原文出自【听云技术博客】:http://blog.tingyun.com/web/article/detail/1347

动态链接

要解决空间浪费和更新困难这两个问题最简单的方法就是把程序的模块相互分割开来,形成独立的文件,而不再将它们静态的链接在一起。简单地讲,就是不对那些组成程序的目标文件进行链接,等到程序要运行时才进行链接。也就是说,把链接过程推迟到了运行时再进行,这就是 _动态链接(Dynamic Linking)_的思想。

延迟绑定(PLT)

动态链接比静态链接性能低,主要原因是动态链接下对于全局和静态的数据访问都要进行复杂的GOT定位,间接寻址;对于模块间的调用也要先定位GOT,间接跳转,  程序的运行速度一定会减慢。 另外因为动态链接是在运行时完成链接的工作:在程序开始执行时,动态链接器都要进行一次链接工作,动态链接器会 search 并 load 所需要的 共享对象,然后进行符号查询 地址重定位,这一系列动作会减慢程序的启动速度。 

PLT 就是为了优化动态链接性能而存在,基本思想就是 当函数第一次被调用到时才进行绑定(符号查找,重定位),如果没有用到则不进行 bind。 这样在程序执行时,模块间的函数调用都没有进行 bind , 而是需要调用时才由 动态链接器来负责 bind 。这样可以加速程序的启动速度。

Mach-O Lazy Bind

Mach-O 文件通过dyld 加载的时候并没有确定每一个函数的具体地址在哪里,而是在真正调用该函数的时候通过 过程链接表(procedure linkage table),简称 PLT,来进行一次lazybind。

结合Mach-O 文件的分析与代码的调试简单的分析一下。

 源代码如下:

1.png

分别在两个printf函数处下 断点。

第一个调用printf函数

2.png

在0x100000f52 \<+34\>行处通过callq 0x100000f76 来调用printf。

执行callq指令 之后代码跳转到这里:

2-2.png

这里的jmpq 要跳转到 0x0000000100000F8C ,这个地址是从 —Data , —la-symbol-ptr  中的Lazy Symbol Pointers 中获取到的。

3.png

通过lldb 的命令 查看 0x100001010处的地址 获取了同样的值。

通过—stub—helper进行lazybind

在Mach-O 中每一个Symbol Stub 可能有以下两种行为其中之一:跳转到函数的指令,执行函数体,通过动态动态库链接器查找函数的Symbol,然后执行函数体

查看 —stubs的Section 数据,发现只有一个函数就是 printf

4.png

这里的Data 其实就是上面看到的 jmpq 的代码。执行之后代码跳转到了这样的代码片段。

5.png

这里就是通过 —stub-helper来调用 dyld-stubbinder函数来计算printf 函数的真是地址。 通过下面的 信息可以看出来,jmpq 0x100000f7c ,就是在压如入参数0x0 (函数的link 的时候给的编号) 之后跳转到Section的起始处,调用 binder(一段汇编代码, 作用就是计算具体的函数地址,并调用printf 函数)

6.png

第二次调用printf 函数

7.png

执行指令之后发现和第一次调用printf 已经不一样了。

8.png

再一次查看 0x100001010 处内存值。已经很第一次不同了,也就是说, —Data, —la-symbol-ptr 中指向printf地址的值已经发生了变化,指向了 printf的指令。

这就证明了,延迟绑定只会在第一次调用的时候发生。整个流程与 linux中的PLT 和GOT 在实现逻辑上基本相同,只是实现代码不同而已。

参考《Mac OS X  and iOS Internals》、《链接,装载与库》

0
0
分享到:
评论

相关推荐

    Mach-O_File_Format

    随着OSX操作系统目标动态链接功能的发展,Mach-O格式被扩展以支持动态链接,因此它成为了一个既支持静态链接又支持动态链接代码的单一种类文件格式。 Mach-O文件的基本结构分为三个主要区域: 1. 文件开头是文件头...

    Mac OS X ABI Mach-O File Format Reference.pdf

    iOS 可执行文件是 Mach-O 格式,主要由 Header、Load Commands、Data 三部分 Header 头部,包含可以执行的CPU架构,比如x86,arm64 Load commands 加载命令,包含文件的组织架构和在虚拟内存中的布局方式 Data数据,...

    Mach-O格式全称为Mach Object文件格式的缩写,是mac上可执行文件的格式,类似于windows上的PE格式 (Po

    Mach-O格式全称为Mach Object文件格式的缩写,是mac上可执行文件的格式,类似于windows上的PE格式 (Portable Executable ), linux上的elf格式 (Executable and Linking Format)。

    Generate Objective-C headers from Mach-O files..zip

    Mach-O(Mach Object)是Apple操作系统中用于执行代码的二进制文件格式,包含了编译后的Objective-C类、函数和其他机器可执行的数据。当我们需要从Mach-O文件中提取Objective-C头文件(.h文件)时,通常是为了理解或...

    MachOview查看Mach-O文件结构.zip

    通过使用MachOview,开发者可以更好地理解和调试Mach-O文件,特别是当遇到链接错误、代码混淆或性能问题时,这款工具能提供宝贵的洞察力。对于macOS和iOS开发人员来说,掌握Mach-O文件结构和使用MachOview这样的工具...

    swift-通过Mach-O文件NonlazyClassList构建动态库进行iOSload方法耗时检测

    本文将深入探讨如何通过Mach-O文件中的`NonlazyClassList`来构建动态库,进而实现对iOS应用`load`方法耗时的检测。 首先,我们需要了解Mach-O文件。Mach-O是Mac OS X和iOS操作系统使用的二进制文件格式,它包含了可...

    MachOTool:用于分析和分析Mach-O二进制文件的便携式工具

    Mach-O工具旨在成为分析Mach-O二进制文件的便携式工具。 它完全用Python编写,并且可以与任何标准Python 2.7安装一起使用,而无需其他软件包。 (GUI部分要求使用Tkinter,它应该是大多数平台中的标准软件包。) 它...

    MACH-Aero-tutorial-master_aero_tool_

    《MACH-Aero工具大师教程详解》 在航空航天领域,流体力学的计算与分析是一项至关重要的任务。MACH-Aero工具就是专为此目的设计的一款高效、精准的空气动力学计算软件。本教程将深入探讨MACH-Aero工具的使用方法,...

    strongarm:Mach-O分析库:flexed_biceps:

    strongarm是功能齐全的跨平台ARM64 Mach-O分析库。 strongarm可以投入生产,并且可以在DataTheorem的iOS静态分析器堆栈中使用。 此存储库包含多种工具,可用于研究Strongarm和API。 在scripts文件夹中,一些强大...

    MachO-Kit:用于解析Mach-O文件的CObjective-C库

    什么是Mach-O套件? Mach-O Kit是用于解析Darwin平台(macOS,iOS,tvOS和watchOS)使用的Mach-O二进制文件的Objective-C框架。 该项目还包括一个轻量级的C库-libMachO-用于解析当前进程中加载​​的Mach-O图像。 ...

    Python库 | mach-composer-1.0.0rc25.tar.gz

    《Python库mach-composer-1.0.0rc25:构建高效后端开发的得力工具》 在IT行业中,Python作为一种强大的开发语言,因其简洁的语法和丰富的库支持,广泛应用于各种领域,尤其是后端开发。今天我们将探讨一个名为...

    仙灵:神奇的ELF和Mach-o对象文件编写器后端

    Mach-o文件结构与ELF类似,但有一些特定于Apple环境的特性,如支持多个CPU架构和动态加载。这种格式允许开发者为不同架构创建单一的二进制,适应了Apple多平台策略的需求。 “仙灵”项目的目标是为Rust编程语言提供...

    mach-smdk2410.rar_V2 _mach

    本文基于标题"Mach-smdk2410.rar_V2_mach"及描述"Linux arch arm mach-s3c2410 mach-smdk2410 for Linux v2.13.6.",结合压缩包内的文件“mach-smdk2410.c”,来揭示这一平台的细节。 首先,我们要理解"MACH"在...

    取消签名:从OSX Mach-O二进制文件中删除代码签名(注意:当前无法重新设计未签名的二进制文件。欢迎使用补丁!)

    Mach-O是MacOS和iOS操作系统中用于可执行文件、动态库和内核扩展的二进制格式。它包含了程序的机器指令、符号表和其他元数据。代码签名通常嵌入在Mach-O文件的LC_CODE_SIGNATURE加载命令中。 取消签名的工具通常...

    machobot:用于Mach-O文件分析的Python工具箱

    用于Mach-O文件分析的Python工具箱。 严重依赖macholib 。 安装 用途 $ [sudo] pip install machobot 为了发展 $ pip install nose macholib $ git clone https://github.com/rodionovd/machobot.git machobot $ cd...

    class-dump:从Mach-O文件生成Objective-C标头

    class-dump是一个命令行实用程序,用于检查Mach-O文件的Objective-C段。 它为类,类别和协议生成声明。 这是使用'otool -ov'提供的相同信息,但以普通的Objective-C声明形式提供。 最新版本和信息可在以下位置获得...

Global site tag (gtag.js) - Google Analytics