Mach-O中的地址查找

函数地址查找

1.准备test.m文件

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.查看代码段。终端使用如下命令:

objdump --macho -d test
复制代码

图片.png
4.查看.o文件的代码段:终端使用如下命令:

//将test.m生成目标文件test
clang -c test.m -o test.o
复制代码
objdump --macho -d test.o
复制代码

图片.png

  • 编译是按照文件声明的顺序编译的,即:_text、_text1、_main
  • e8固定机器码,代表callq指令
  • C框函数_text地址等于A框偏移量加B框偏移量

图片.png

  • _text1函数的偏移量都是0,但是往上面看能够看到,_test1偏移量是10,所以,当前函数调用的地址并不是真实的地址。链接的时候还会分配虚拟内存地址,链接的时候要告诉编译器将真实的地址拿过来覆盖这些占位的00 00 00 00 _test1放到重定位符号表里

5.查看需要重定位的符号:

objdump --macho --reloc test.o
复制代码

图片.png

图片.png
_test1的地址是49,对比就能找到占位地址位置

在编译成目标文件的时候,没有分配真实的虚拟内存地址,用了临时变量占位,把需要重新定位的函数放到重定位符号表里

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;

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享