代码自映射Self-Remapping Code
程序节区重新映射时设置Section属性为SEC_NO_CHANGE,避免代码被inline hook和设置断点调试。
本方法主要参考 https://github.com/changeofpace/Self-Remapping-Code 这个GitHub项目,作者在19年重构了一版但是没有放到release上。
0x01 编译注意事项
- 因为在使用NtMapViewOfSection函数时基址或文件的偏移量参数需要和系统分配颗粒度对齐,这个颗粒度一般为0x10000,所以在项目配置中设置节区对齐大小
#pragma comment(linker, "/ALIGN:0x10000")
- 在x64环境下调用相关导入表函数多为 CALL + 偏移,而x86环境是直接CALL导入表地址,但是在Unmap原始IMAGE的节区空间之后原先导入表地址访问是不合法的,所以想要代码在x86环境下运行就需要做重定位,使用新VirtualAlloc后申请的地址内容。
- 在属性选项中需要关闭符合模式
0x02 原理介绍
使用未文档化的SEC_NO_CHANGE属性调用NtCreateSection函数创建一个Section
映射Section并复制原始模块代码至映射的Section空间
然后使用NtUnmapViewOfSection把原始IMAGE的节区空间和映射的Section空间给Unmap掉
最后在循环重新映射刚才被Unmap的Section空间到原始模块代码内存地址空间。
0x03 效果
0x04 参考链接
ZwUnmapViewOfSection function (wdm.h)
ZwMapViewOfSection function (wdm.h)
你好,执行这个 "原始IMAGE的节区空间和映射的Section空间给Unmap掉" 重新就崩溃了退出了 这个咋办啊