| 导语 本文主要介绍如何打内存断点进入第三方的MachO文件,必备工具协助工具MachOView、Hopper
1 MachOView和Hopper解析后的效果图
- MachOView 解析的结果,请留意Offset和pFile字段
![](https://img.haomeiwen.com/i19476148/0aaf4329dd901294.png)
- Hopper解析的结果图
![](https://img.haomeiwen.com/i19476148/e9fad4bf2c568d7f.png)
2 如何查看MachO文件的虚拟内存大小
通过MachOView的VM size字段可以查看虚拟内存的大小,如下图所示,虚拟内存大小为42949674296(十进制) = 4G(2^32),对应的16进制为:0x100000000
![](https://img.haomeiwen.com/i19476148/7e173892cd6c4c82.png)
3 MachOView和Hopper的地址的差别
在MachOView文件中Offset和pFile字段表示的该地址相对MachO文件的偏移,它们需要加上VM Size才是真正的虚拟地址,Hopper解析后地址直接是虚拟地址。它们2个的关系为:
Hopper = offset/pFile + VM size
4 如何找到某个方法在运行的时候对应的内存地址
以下面这段代码为例
-(void)eatWithObject:(NSString *)objc{
NSLog(@"吃到了%@",objc);
}
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
[self eatWithObject:@"汉堡!"];
}
通过Hopper查看上面代码对应的MachO文件,如下图:eatWithObject在MachO文件的虚拟内存为:0x0000000100005ea4,相对MachO文件的偏移为:0x0000000100005ea4 - 0x100000000 = 5ea4
![](https://img.haomeiwen.com/i19476148/f0194eb4b10a9ed1.png)
4.1 如何查看MachO文件在内存中的物理地址
通过命令:image list 可以查看加载MachO文件在内存中的物理地址,如下图,MachO文件在内存的地址是:0x00000001024d8000
![](https://img.haomeiwen.com/i19476148/3790565fa2755b84.png)
4.2 eatWithObject:方法的物理内存地址
-
公式:eatWithObject的物理内存地址 = MachO文件的内存地址 + eatWithObject在MachO文件中的偏移地址
-
例子:用MachO文件在内存的地址0x00000001024d8000加上eatWithObject在MachO文件的偏移地址5ea4,就可以得到本次运行eatWithObject方法在内存中的物理地址 = 0x00000001024d8000 + 0x5ea4 = 0x1024DDEA4
-
设置断点: 通过 b -a 0x1024DDEA4设置一个内存地址,可见断点设置成功,并且再点击屏幕,能够正确命中 ,如下图
![](https://img.haomeiwen.com/i19476148/b1df71a32427bba9.png)
5 ASLR:地址空间配置随机
- 计算公式:ASLR = 物理地址 - 虚拟地址
- 这个ASLR在每次程序运行的时候都会不同,但是可以通过image list 命令得到MachO文件的物理地址,通过查MachO文件的虚拟内存为0x100000000;所以ASLR = 通过image list可以得到MachO文件的内存地址 - MachO文件的虚拟地址 = 0x1024d8000 - 0x100000000 = 24d8000
- 测试:
- 通过上面可以知道ASLR为24d8000,而从Hopper中可以找到eatWithObject虚拟地址为0x100005ea4,那么执行lldb设置断点:b -a 0x24d8000+0x100005ea4,效果如图所示,成功新增了一个断点。
![](https://img.haomeiwen.com/i19476148/f1af4b4d06fe58b1.png)
6 通过某个物理地址,查找MachO文件的虚拟地址
通过公式ASLR = 物理地址 - 虚拟地址 ,所以假设我们知道某个对象的物理地址,就可以反推出这个对象在MachO文件中的虚拟地址。
测试:
定义int a = 10;
的全局变量
-
通过:image list 得到MachO文件的在此次运行的内存地址:0x0000000104360000,则可以计算出ASLR地址为:0x4360000
-
通过查看变量A的地址:p &a ==> 0x0000000104369318
-
那么全局变量a在MachO中的地址为: 0x0000000104369318 - 0x4360000 = 0x100009318
-
MachO文件的虚拟内存为:0x100000000,则全局变量a在MachO文件的偏移地址为0x9318,通过MachOView查看MachO文件9318这个位置的值是0A恰好是10。而在Hopper中直接查0x100009318地址所对应的值也是10。如下图所示。
![](https://img.haomeiwen.com/i19476148/bb7bb4b7a18b8896.png)
7 实操一下第三方的MachO文件
最近在学习逆向开发,下面实操一下微信的MachO文件的内存断点设置。
步骤1:通过解析微信页面的元素,找到action对应的方法名:showFileManagerWindow:
步骤2:通过Hopper查找showFileManagerWindow:如下图所示,选取第一行的地址:0x0000000101271fec,Hopper里的地址是虚拟地址
![](https://img.haomeiwen.com/i19476148/e58fdb404822b859.png)
步骤3:计算ASLR,通过image list命令可以得到此次运行的MachO文件的物理地址,如下图所示,则ASLR = 0x0000000106d98000 - 0x100000000 = 0x6d98000
![](https://img.haomeiwen.com/i19476148/da439596159a2dda.png)
步骤4:计算步骤二在运行的时候对应的物理地址 = ASLR + 虚拟地址 = 0x0000000101271fec + 0x6d98000 = 0x108009FEC
步骤5:通过命令对地址0x108009FEC设置断点b -a 0x108009FEC
,结果如下图所示
![](https://img.haomeiwen.com/i19476148/ecbad3a850d890fc.png)
步骤6:测试点击文件图标,能够正确触发步骤5设置的断点,结果如下图
- xcode命中的断点调试
![](https://img.haomeiwen.com/i19476148/c7bc7a29f8b93f45.png)
- Hopper工具解析的指令,对比2者发现,步骤5的断点确实生效了,并且进入了第三方MachO文件里
![](https://img.haomeiwen.com/i19476148/e8e11599e8884871.png)
总结
本文介绍了如何计算MachO文件在内存中的物理地址和如何下内存断点,这是在逆向开发中必须掌握的方法,此文的目的主要是当做自己的笔记,仅供参考。
遗留问题:此文还有一个遗留问题是如何调试汇编,这个在学习中,后续在写一篇笔记记录如何调试汇编。
网友评论