demo解说ASLR
下面是我的demo例子代码
ViewController.m
int a = 10;
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)testASLR:(NSString *)text{
a = 20;
NSLog(@"测试ASLR的%@",text);
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
[self testASLR:@"demo"];
}
编译过后,获取该demo二进制文件,然后放到Hooper中分析,如下效果图

这里我们以这个 -[ViewController testASLR:] 方法做测试案例,这里假设我想在这里打一个断点,从hooper可以看到0000000100006538是这个方法的内存地址,在Xcode的终端上面,我们通过命令行设置一个断点,如下图

(lldb) b 0x100006538
Breakpoint 2: no locations (pending).
WARNING: Unable to resolve breakpoint to any actual locations.
(lldb) b list
Breakpoint 3: where = CoreGraphics`std::__1::list<CG::Chunk, CG::Allocator<CG::Chunk> >::list(std::__1::list<CG::Chunk, CG::Allocator<CG::Chunk> > const&), address = 0x0000000184ede2c8
点击屏幕测试
2020-05-02 22:19:36.408 ASLR说明Demo[5376:1565220] 测试ASLR的demo
发现断点并没有生效,这个是为什么呢?是因为iOS中有ASLR的概念,而我们在hooper中得到的是没有加上ASLR的,所以也并不是我们真正的函数内存地址,所以断点并没有生效,所以我们需要对真正的函数地址设置断点,这样才会生效的,因此我们需要获取ASLR的地址
获取ASLR
(lldb) image list
[ 0] 15280D12-8A2C-3A40-BFAD-CCC7413FA577 0x000000010000c000 /Users/forest/Library/Developer/Xcode/DerivedData/ASLR说明Demo-aetozzfnbbhtyhasrrwqqvoajtgp/Build/Products/Debug-iphoneos/ASLR说明Demo.app/ASLR说明Demo
-
0x000000010000c000 这个地址是mach-o,加进去内存地址时候的真正地址,而mach-o加载进去虚拟内存地址的时候,是会首先有一个vmaddress的一个概念的,我们可以通过machView 这个工具查看
Snip20200502_39.png
所以ASLR地址 = 0x000000010000c000 - 0000000100000000 = 0xC000;
这个时候我们就可以直接计算函数的真正内存地址
函数的真正内存地址 = ASLR + mach-o 基址 + 函数的偏移地址
但是将二进制拖拽进去hooper的时候,显示的方法地址已经是mach-o基址 + 函数的偏移地址,所以这个时候改函数的真正内存地址 = 0xC000 + 0000000100006538 = 0x100012538
对真正地址设置断点
(lldb) b 0x100012538
Breakpoint 10: where = ASLR说明Demo`-[ViewController testASLR:] at ViewController.m:24, address = 0x0000000100012538
点击屏幕测试[图片上传失败...(image-f71d86-1588430338068)]
可以看到这个时候断点调试成功,到这里应该会对ASLR有一定的基础概念了吧,现在我们再来看看全局属性的获取,在代码中我们可以看到我们有一个a的变量,那么这个变量存放在哪个地址断呢?
从xcode中的终端打印出a的内存地址
(lldb) p a
(int) $6 = 20
(lldb) p &a
(int *) $7 = 0x0000000100014e30
这里如果我们需要去MachOView中寻找a变量的存放处,同样需要减去ASLR地址和vmaddress的地址值,这个值可以从前面得到的ASLR地址和vmaddress去计算或者直接从image list 获取到的第一个地址值直接减去这个值也可以
MachOView-a的内存 = 0x0000000100014e30 - (image list)函数的第一个地址0x000000010000c000
或者
MachOView-a的内存 = 0x0000000100014e30 - 0x100000000 - 0xC000
最后计算得出MachOView-a的内存 = 0x8E30

网友评论