Mach-O中的地址查找

函數地址查找

1.準備test.m文件markdown

void test(){
    
}
void test1(){
    
}
int global = 10;
int main(){
    global = 21;
    global = 20;
    test();
    test1();
   return 0;
}

複製代碼

2.生成可執行文件。終端使用以下命令:函數

//將test.m生成可執行文件test
clang test.m -o test
複製代碼

3.查看代碼段。終端使用以下命令:ui

objdump --macho -d test
複製代碼

圖片.png 4.查看.o文件的代碼段:終端使用以下命令:spa

//將test.m生成目標文件test
clang -c test.m -o test.o
複製代碼
objdump --macho -d test.o
複製代碼

圖片.png

  • 編譯是按照文件聲明的順序編譯的,即:_text、_text一、_main
  • e8固定機器碼,表明callq指令
  • C框函數_text地址等於A框偏移量加B框偏移量

圖片.png

  • _text1函數的偏移量都是0,可是往上面看可以看到,_test1偏移量是10,因此,當前函數調用的地址並非真實的地址。連接的時候還會分配虛擬內存地址,連接的時候要告訴編譯器將真實的地址拿過來覆蓋這些佔位的00 00 00 00 _test1放到重定位符號表裏

5.查看須要重定位的符號:3d

objdump --macho --reloc test.o
複製代碼

圖片.png

圖片.png _test1的地址是49,對比就能找到佔位地址位置code

在編譯成目標文件的時候,沒有分配真實的虛擬內存地址,用了臨時變量佔位,把須要從新定位的函數放到重定位符號表裏orm

6.生成可執行文件並查看:圖片

clang test.m -o test
複製代碼
objdump --macho -d test
複製代碼

圖片.png iOS是小端模式,這裏最高位就是ff,因此爲負,ff是補碼,須要變成原碼,全部的1取反後爲0,因此這裏直接看b8。內存

b8目前是補碼,求原碼編譯器

b8(補碼)二進制表示:10111000

反碼(補碼-1): 10110111

原碼(反碼取反): 01001000

當前算出的原碼16進制就是0x48 由於高位是ff,爲負 _test地址就等於0x100003FA8加上負的0x48等於0x100003F60

圖片.png

globle變量地址查找

圖片.png c7 05 是movl指令

21的十進制就是15

21地址就是0x100003f99+0x4067 就是 0x100008000

查看macho全部內容

objdump --macho -s test
複製代碼

圖片.png 紅框後面Oa就是代碼中的int global = 10;

相關文章
相關標籤/搜索