日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Mach-O的动态链接相关知识

發布時間:2025/3/15 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Mach-O的动态链接相关知识 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

0x00 摘要

通過分析Mach-O的動態鏈接過程,加深對Mach-O文件結構的理解。對Mach-O文件格式的簡單的分析看這里這里。

0x01 Mach-O Lazy Bind

Mach-O文件的通過dyld加載的時候并沒有確定每一個函數的具體地址在哪里,而是在真正調用該函數的時候通過過程連接表(procedure linkage table),后面簡稱PLT,來進行一次lazybind

結合Mach-O文件的分析與代碼的調試簡單的分析一下,只能算是管中窺豹了。

源碼很簡單。

1 2 3 4 5 6 7 8 #include <stdio.h> int main(int argc, const char * argv[]) { // insert code here... printf("Hello, World!\n"); printf("2Hello, World!\n"); return 0; }

分別在兩個printf函數處下斷點,啟動程序。

1.1 第一次調用prinf

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 lazy_bind`main: 0x100000f10 <+0>: pushq %rbp 0x100000f11 <+1>: movq %rsp, %rbp 0x100000f14 <+4>: subq $0x20, %rsp 0x100000f18 <+8>: leaq 0x57(%rip), %rax ; "Hello, World!\n" 0x100000f1f <+15>: movl $0x0, -0x4(%rbp) 0x100000f26 <+22>: movl %edi, -0x8(%rbp) 0x100000f29 <+25>: movq %rsi, -0x10(%rbp) 0x100000f2d <+29>: movq %rax, %rdi 0x100000f30 <+32>: movb $0x0, %al -> 0x100000f32 <+34>: callq 0x100000f56 ; symbol stub for: printf 0x100000f37 <+39>: leaq 0x47(%rip), %rdi ; "2Hello, World!\n" 0x100000f3e <+46>: movl %eax, -0x14(%rbp) 0x100000f41 <+49>: movb $0x0, %al 0x100000f43 <+51>: callq 0x100000f56 ; symbol stub for: printf 0x100000f48 <+56>: xorl %ecx, %ecx 0x100000f4a <+58>: movl %eax, -0x18(%rbp) 0x100000f4d <+61>: movl %ecx, %eax 0x100000f4f <+63>: addq $0x20, %rsp 0x100000f53 <+67>: popq %rbp 0x100000f54 <+68>: retq

在0x100000f52 <+34>行處通過callq 0x100000f64來調用printf。

執行callq指令之后代碼跳轉到這里:

1 2 lazy_bind`printf: -> 0x100000f56 <+0>: jmpq *0xb4(%rip) ; (void *)0x0000000100000f6c

1.2 __Data,__la_symbol_ptr 獲取函數地址

這里的jmpq要跳轉到0x0000000100000f6c這個地址是從__Data,__la_symbol_ptr中的Lazy Symbol Pointers中獲取到的。(怎么來的不是很清楚?)希望通過stub來調用printf函數。

通過命令行查看0x100001010處的地址獲得了同樣的值。

1 2 3 (lldb) x 0x100001010 0x100001010: 6c 0f 00 00 01 00 00 00 00 00 00 00 00 00 00 00 l............... 0x100001020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

1.3 通過__stub__helper進行lazybind

在Mach-O中每一個Symbol Stub可能有以下兩種行為其中之一:

  • 跳轉到函數的指令,執行函數體
  • 通過動態鏈接器查找函數的Symbol(符號),然后執行函數。

通過工具查看__stubs的Section數據,發現只有一個函數就是_printf。

這里的Data其實就是上面看到的jmpq代碼。執行之后代碼跳轉到了這樣的代碼片段。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 -> 0x100000f6c: pushq $0x0 0x100000f71: jmp 0x100000f5c 0x100000f76: gs ;這里往下都沒有!!!! 0x100000f78: insb %dx, %es:(%rdi) 0x100000f79: insb %dx, %es:(%rdi) 0x100000f7a: outsl (%rsi), %dx 0x100000f7b: subb $0x20, %al 0x100000f7d: pushq %rdi 0x100000f7e: outsl (%rsi), %dx 0x100000f7f: jb 0x100000fed 0x100000f81: andl %ecx, %fs:(%rdx) 0x100000f84: addb %dh, (%rdx) 0x100000f86: gs 0x100000f88: insb %dx, %es:(%rdi) 0x100000f89: insb %dx, %es:(%rdi) 0x100000f8a: outsl (%rsi), %dx

這里就是通過_stub_helper來調用dyld_stubbinder函數來計算printf函數的真實地址。通過下面的\_TEXT,__stub_helper具體信息可以看出,jmpq 0x100000f5c,就是在壓入參數0x0(函數的link的時候給的編號)之后跳轉到Section的起始處,調用了binder。

binder是一塊匯編代碼。這里就不做解釋了。作用就是計算具體的函數地址,并調用printf。

1.4 第二次調用printf函數

這個釋放斷點,程序將在調用第二個printf函數的地方停下來。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 lazy_bind`main: 0x100000f10 <+0>: pushq %rbp 0x100000f11 <+1>: movq %rsp, %rbp 0x100000f14 <+4>: subq $0x20, %rsp 0x100000f18 <+8>: leaq 0x57(%rip), %rax ; "Hello, World!\n" 0x100000f1f <+15>: movl $0x0, -0x4(%rbp) 0x100000f26 <+22>: movl %edi, -0x8(%rbp) 0x100000f29 <+25>: movq %rsi, -0x10(%rbp) 0x100000f2d <+29>: movq %rax, %rdi 0x100000f30 <+32>: movb $0x0, %al 0x100000f32 <+34>: callq 0x100000f56 ; symbol stub for: printf 0x100000f37 <+39>: leaq 0x47(%rip), %rdi ; "2Hello, World!\n" 0x100000f3e <+46>: movl %eax, -0x14(%rbp) 0x100000f41 <+49>: movb $0x0, %al -> 0x100000f43 <+51>: callq 0x100000f56 ; symbol stub for: printf 0x100000f48 <+56>: xorl %ecx, %ecx 0x100000f4a <+58>: movl %eax, -0x18(%rbp) 0x100000f4d <+61>: movl %ecx, %eax 0x100000f4f <+63>: addq $0x20, %rsp 0x100000f53 <+67>: popq %rbp 0x100000f54 <+68>: retq

執行指令之后發現和第一次調用printf已經不一樣了。

1 2 lazy_bind`printf: -> 0x100000f56 <+0>: jmpq *0xb4(%rip) ; (void *)0x00007fff96b1815c: printf

通過指令再一次查看0x100001010處的內存值。

1 2 3 (lldb) x 0x100001010 0x100001010: 5c 81 b1 96 ff 7f 00 00 00 00 00 00 00 00 00 00 \............... 0x100001020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

也就是說 __Data,__la_symbol_ptr中指向printf地址的值已經發生了變化,指向了printf的指令。

1.5 小結

證明了,延遲綁定只會在第一次調用的時候發生。整個流程與linux中的PLT與GOT在實現邏輯上基本是相同的,只是具體的代碼實現不一樣。

0x02 相關LoadCommand

上面只是通過調試簡單的了解了動態鏈接的表現,要理解動態鏈接還需對幾個數據結構有所了解。

2.1 LC_SYMTAB

LC_SYMTAB這個LoadCommand主要提供了兩個信息

  • Symbol Table的偏移量與Symbol Table中元素的個數
  • String Table的偏移量與String Table的長度

2.1.1 Symbol Table

在計算機科學中,符號表是一種用于語言翻譯器(例如編譯器和解釋器)中的數據結構。在符號表中,程序源代碼中的每個標識符都和它的聲明或使用信息綁定在一起,比如其數據類型、作用域以及內存地址。

–wiki

簡單的理解就是Symbol Table里面包含了所有會被調用的函數的信息,無論是已經bind的還是沒有bind的函數。

2.2.2 String Table

這個很好理解,在符號處理時所有會用到的字符串放在了這里。和__TEXT,__cstring不同。

2.2 LC_DYSYMTAB

LC_DYSYMTAB的數據結構,如圖所示。這一個LoadCommand與動態鏈接相關的就是紅框標出的兩個字段,標示了需要動態符號表的偏移量與符號個數。

動態符號表的數據結構非常的簡單,是一個32bit的索引的數組。通過索引可以在Symbol Table中尋找到對應的函數信息。

0x03 小結

通過分析兩次printf的調用流程,加深對Mach-O結構以及動態鏈接的流程理解,為進一步理解dyld的工作原理,源碼閱讀提供了知識的儲備。

通過和Linux的PTL與GOT比較可以更容易理解邏輯。

整個流程是如何通過代碼實現的還需要進一步的分析與研究。

0x04 參考

1.Dynamic Linking: ELF vs. Mach-O

http://timetobleed.com/dynamic-linking-elf-vs-mach-o/

2.Dynamic symbol table duel: ELF vs Mach-O, round 2

http://timetobleed.com/dynamic-symbol-table-duel-elf-vs-mach-o-round-2/


原文地址:http://turingh.github.io/2016/03/10/Mach-O%E7%9A%84%E5%8A%A8%E6%80%81%E9%93%BE%E6%8E%A5/

總結

以上是生活随笔為你收集整理的Mach-O的动态链接相关知识的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 性做久久久久 | 激情福利在线 | 69xx网站 | 老司机精品视频网站 | 秋霞成人午夜鲁丝一区二区三区 | 哺乳期喷奶水丰满少妇 | 麻豆精品 | 久久久欧美精品sm网站 | 精品久久久久久久久久久aⅴ | 欧美孕妇性xx | 国产香蕉在线 | 亚洲国产精品毛片av不卡在线 | 国产精品视频麻豆 | 国内自拍网站 | 日日色综合 | 麻豆一区二区 | 97伦伦午夜电影理伦片 | 丝袜美腿av | 波多野结衣av片 | 11孩岁女毛片 | 向着小小的花蕾绽放 | 日韩欧美亚洲国产精品字幕久久久 | 国产色在线视频 | 一区二区三区精品免费视频 | 亚洲成人国产精品 | 亚洲麻豆一区二区三区 | 久久视频中文字幕 | 精品久久久久成人码免费动漫 | 久久极品 | av网站网址| 在线天堂1 | 久久人成 | 女人扒开双腿让男人捅 | 美女黄色小视频 | 国产在线高潮 | 欧美日视频 | 一区二区三区伦理片 | www.av在线免费观看 | 欧美综合图区 | 91免费高清在线观看 | 91亚洲一线产区二线产区 | 在线a网 | 国产精品久久影视 | 亚洲精品中文字幕乱码三区 | 国产四区视频 | 天天摸天天碰 | 日韩av色图 | 亚洲av无码一区二区乱孑伦as | 色黄视频| 国产精品久久久久久久久晋中 | 超碰青草 | 国产无遮挡免费观看视频网站 | 国产suv精品一区二区68 | 亚洲视频一区二区三区在线观看 | 亚洲一区二区三区四区电影 | 欧美永久免费 | 蜜桃成熟时李丽珍国语 | 国产精品福利在线 | 爱上av| 亚洲欧美成人综合 | 麻豆传媒网页 | 免费看国产黄色 | 警察高h荡肉呻吟男男 | 91精品网| 免费黄色网址在线观看 | 成人在线免费观看视频 | 天天操天天操天天操天天操天天操 | 强行侵犯视频在线观看 | 亚洲国产精品国自产拍av | 综合久久综合 | 好吊妞视频一区二区三区 | 午夜视频入口 | 日本精品视频 | 国产资源免费 | 亚洲欧美精品一区二区 | 亚洲美女偷拍 | 久久久黄色 | 国内外成人免费视频 | 欧美性jizz18性欧美 | 免费在线播放黄色片 | 好吊色青青草 | av基地网| 看黄网站在线观看 | 亚洲高清在线观看 | 亚洲精品久久久久久国 | 日韩在线视频免费播放 | 女同性69囗交 | 一本色道久久hezyo加勒比 | 嫩草影院永久入口 | 少妇诱惑av | 黄色一级片免费观看 | 久久久男女 | 亚洲精品久久一区二区三区777 | 在线步兵区 | 视频在线观看你懂的 | 欧美亚洲国产精品 | 国产成人亚洲精品无码h在线 | 亚洲AV无码AV吞精久久中文版 | 娇妻av|