函数地址查找
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
复制代码
4.查看.o文件的代码段:终端使用如下命令:
//将test.m生成目标文件test
clang -c test.m -o test.o
复制代码
objdump --macho -d test.o
复制代码
- 编译是按照文件声明的顺序编译的,即:_text、_text1、_main
e8
固定机器码,代表callq
指令C
框函数_text
地址等于A
框偏移量加B
框偏移量
_text1
函数的偏移量都是0,但是往上面看能够看到,_test1
偏移量是10,所以,当前函数调用的地址并不是真实的地址。链接的时候还会分配虚拟内存地址,链接的时候要告诉编译器将真实的地址拿过来覆盖这些占位的00 00 00 00
,_test1
放到重定位符号表里
5.查看需要重定位的符号:
objdump --macho --reloc test.o
复制代码
_test1
的地址是49,对比就能找到占位地址位置
在编译成目标文件的时候,没有分配真实的虚拟内存地址,用了临时变量占位,把需要重新定位的函数放到重定位符号表里
6.生成可执行文件并查看:
clang test.m -o test
复制代码
objdump --macho -d test
复制代码
iOS是小端模式,这里最高位就是ff,所以为负,ff是补码,需要变成原码,所有的1取反后为0,所以这里直接看b8。
b8目前是补码,求原码
b8(补码)二进制表示:10111000
反码(补码-1): 10110111
原码(反码取反): 01001000
当前算出的原码16进制就是0x48
因为高位是ff,为负
_test
地址就等于0x100003FA8
加上负的0x48
等于0x100003F60
globle变量地址查找
c7 05 是movl指令
21的十进制就是15
21地址就是0x100003f99
+0x4067
就是 0x100008000
查看macho所有内容
objdump --macho -s test
复制代码
红框后面Oa就是代码中的int global = 10;
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END