最近在研究PongoOS的时候看到一个函数 xnu_pf_maskmatch, 于是就拿ASLR练练手。
ASLR 的全称是 Address Space Layout Randomization(地址空间布局随机化),通俗一点讲就是类似WINDOWS下的随机基址,默认情况下每次模块被加载到内存中的基址都是不一样的
要想修改ASLR首先要知道这个值是怎么计算的,刚好XNU是开源的,下载对应版本的源码,搜索load_machofile 可以找到赋值的地方
dyld_aslr_page_offset计算的方式是通过随机数与ASLR slide page计算得来的,如果能在内核中定位到这段代码就可以修改这这个值,有了代码还需要对应的 kernelcache 文件
IOS的kernelcacheke可以从ipsw中提取,比如 IOS15.8.4的是 kernelcache.release.n66
使用ida加载这个文件,打开后选择kernel only, 我们不需要分析 kexts

kernelcache本身是没有符号的,通过查看XNU源码可以发现搜索字符串"Mach-o Binary"能定位到函数load_machofile,


通过对比源码可以确定 v27 就是 dyld_aslr_page_offset, 剩下的只需要找到内核中的位置修改汇编将 LSL X8, X8, X10 改为 mov x8, #0即可

由于checkra1n不支持IOS15.8.4,所以选择palera1n刷入PongoOS, 在官网下载palera1n-macos-arm64 执行 -p, -p 代表 Boots to PongoOS shell
palera1n-macos-arm64 -p
然后神奇的又发现一个错误,
PongoOS image is too large: must be at most 0x7fe00, have 0xa5060
因为我的是IOS15系统,解决这个错误需要自己编译PongoOS的IOS15分支

编译PongoOS 比较简单,直接 make all 就行,编译后再执行
./palera1n-macos-arm64 -k /Users/cmg/Desktop/PongoOs/checkra1n/PongoOS/build/Pongo.bin -p
然后根据提示进入DFU,成功的话会出现 PongoOS 界面,要登陆PongoOS 使用
./PongoOS/scripts/pongoterm
如果一切顺利可以看到
最后就可以愉快的编写代码了,
回调函数如下,0xd2800008 对应的就是 mov x8, #0
编写完代码直接make,然后将编译后的 kext bundle 文件上传到PongoOS,文件这么大是因为我把capstone也编译进去了
在修改之前可以先打印看看内存
修改完后再看看效果,可以看到0x4042fd660已经修改成功了
最后一步就是完成之前的越狱操作,由于命令太多直接放到txt中,图中的几个bin文件通过解密palera1n获取,也就是抓USB包,网上也有人分享

最后执行
./PongoOS/scripts/pongoterm < ./jail.txt
手机重启后,编写一个简单的函数试试效果
使用scp上传到手机直接运行,正常情况下这个地址每次运行都不是固定的

由于我的IOS系统版本是15.8.4,使用的是palera1n + IOS15 PongoOS,checkra1n需要你自己测试,PongoOS里面应该可以做很多事情,刚好最近失业了可以好好研究一下 :(
github
if (!(imgp->ip_flags & IMGPF_DISABLE_ASLR)) {
vm_map_get_max_aslr_slide_section(map, &aslr_section_offset, &aslr_section_size);
aslr_section_offset = (random() % aslr_section_offset) * aslr_section_size;
aslr_page_offset = random();
aslr_page_offset = (aslr_page_offset % (vm_map_get_max_aslr_slide_pages(map) - 1)) + 1;
aslr_page_offset <<= vm_map_page_shift(map);
dyld_aslr_page_offset = random();
dyld_aslr_page_offset = (dyld_aslr_page_offset %
(vm_map_get_max_loader_aslr_slide_pages(map) - 1)) + 1;
dyld_aslr_page_offset <<= vm_map_page_shift(map);
aslr_page_offset += aslr_section_offset;
}
if (!(imgp->ip_flags & IMGPF_DISABLE_ASLR)) {
vm_map_get_max_aslr_slide_section(map, &aslr_section_offset, &aslr_section_size);
aslr_section_offset = (random() % aslr_section_offset) * aslr_section_size;
aslr_page_offset = random();
aslr_page_offset = (aslr_page_offset % (vm_map_get_max_aslr_slide_pages(map) - 1)) + 1;
aslr_page_offset <<= vm_map_page_shift(map);
dyld_aslr_page_offset = random();
dyld_aslr_page_offset = (dyld_aslr_page_offset %
(vm_map_get_max_loader_aslr_slide_pages(map) - 1)) + 1;
dyld_aslr_page_offset <<= vm_map_page_shift(map);
aslr_page_offset += aslr_section_offset;
}
lret = load_machfile(imgp, mach_header, thread, &map, &load_result);
lret = load_machfile(imgp, mach_header, thread, &map, &load_result);
➜ PongoOs ./PongoOS/scripts/pongoterm
[Connected]
Booted by: iBoot-7459.140.15
Built with: Clang 14.0.3 (clang-1403.0.22.14.1)
Running on: Apple A9 (S8003, TSMC)
pongoOS>
➜ PongoOs ./PongoOS/scripts/pongoterm
[Connected]
Booted by: iBoot-7459.140.15
Built with: Clang 14.0.3 (clang-1403.0.22.14.1)
Running on: Apple A9 (S8003, TSMC)
pongoOS>
void module_entry(){
command_register("dis", "disassemble", disassemble);
command_register("kfind", "kfind", kfind);
command_register("hd", "hexdump", hexdump0);
command_register("mpp", "mem patch", mem_patch);
return;
}
void module_entry(){
command_register("dis", "disassemble", disassemble);
command_register("kfind", "kfind", kfind);
command_register("hd", "hexdump", hexdump0);
command_register("mpp", "mem patch", mem_patch);
return;
}
uint64_t matches[] = {
0x1b0ba188,
0x11000508,
0x9aca2108,
};
uint64_t masks[] = {
0x1b0ba188,
0x11000508,
0x9aca2108,
};
xnu_pf_patchset_t *text_exec_patchset = xnu_pf_patchset_create(XNU_PF_ACCESS_32BIT);
struct mach_header_64* hdr = xnu_header();
xnu_pf_range_t* text_exec_range = xnu_pf_section(hdr, "__TEXT_EXEC", "__text");
// printf("aslr %llx\n", text_exec_range->device_base + 0x4C56E4);
xnu_pf_maskmatch(text_exec_patchset, "disable_aslr", matches, masks,
sizeof(matches) / sizeof(uint64_t), false,
(void *)aslr_callback);
xnu_pf_emit(text_exec_patchset);
xnu_pf_apply(text_exec_range, text_exec_patchset);
xnu_pf_patchset_destroy(text_exec_patchset);
uint64_t matches[] = {
0x1b0ba188,
0x11000508,
0x9aca2108,
};
uint64_t masks[] = {
0x1b0ba188,
0x11000508,
0x9aca2108,
};
xnu_pf_patchset_t *text_exec_patchset = xnu_pf_patchset_create(XNU_PF_ACCESS_32BIT);
struct mach_header_64* hdr = xnu_header();
[培训]Windows内核深度攻防:从Hook技术到Rootkit实战!
最后于 2025-7-31 17:57
被just赋予编辑
,原因: 添加 github