免杀基础-RDI
字数 1797 2025-08-29 08:30:06
反射型DLL注入(RDI)技术详解
什么是反射型DLL注入
反射型DLL注入(Reflective DLL Injection, RDI)是一种在远程进程中加载DLL而不依赖Windows API LoadLibrary的技术。该技术由Stephen Fewer开发,项目地址为:https://github.com/stephenfewer/ReflectiveDLLInjection
与传统DLL注入的区别
-
传统DLL注入:
- 使用
LoadLibrary或LoadLibraryEx加载DLL - 依赖Windows API
- 可能被安全软件检测
- 使用
-
反射型DLL注入:
- 不依赖
LoadLibrary - DLL自行完成加载过程
- 更隐蔽,更难被检测
- 不依赖
反射型DLL的工作原理
反射型DLL是一种特殊类型的DLL,能够自行完成加载并在目标进程内存中执行。其核心流程如下:
- 将DLL写入目标进程内存
- 执行DLL的导出函数进行加载
- 加载过程包括:
- PE文件拉伸
- 重定位表修复
- 导入表修复
- 设置内存权限
- 执行DllMain
反射型DLL的特点
- 通常只有一个导出函数(用于加载自身)
- 导出函数必须是位置无关代码(PIC)
- 需要手动解析PEB获取API函数地址
- 不依赖Windows的DLL加载机制
创建反射型DLL
1. 获取关键API函数
由于反射型DLL需要位置无关代码,必须手动解析PEB获取关键API:
// 解析PEB流程
1. 通过FS/GS寄存器获取TEB地址
2. 从TEB获取PEB地址
3. 遍历PEB的LDR链表查找模块
4. 通过比较hash获取指定模块地址(kernel32.dll/ntdll.dll)
5. 解析模块导出表获取函数地址
关键需要获取的API:
LoadLibraryAGetProcAddressVirtualAllocVirtualProtectNtFlushInstructionCache(可选)RtlAddFunctionTable(异常处理需要)
2. PE文件操作
反射型DLL需要处理以下PE结构:
-
PE拉伸:
- 将DLL从磁盘格式转换为内存格式
- 处理节区对齐
-
导入表修复:
- 加载依赖的DLL
- 解析IAT并填充函数地址
-
重定位表修复:
- 处理DLL在内存中的重定位
- 修正地址偏移
-
异常表修复(可选):
- 使用
RtlAddFunctionTable注册异常处理
- 使用
3. 构建导出函数
反射型DLL的导出函数(通常命名为ReflectiveLoader)需要完成以下工作:
DWORD WINAPI ReflectiveLoader(LPVOID lpParameter) {
// 1. 动态获取所需WinAPI
// 2. 申请内存空间存储反射DLL
// 3. 执行PE拉伸
// 4. 修复重定位表
// 5. 修复导入表
// 6. 设置内存权限
// 7. 调用DllMain
// 8. 返回DLL基址
}
注入器(Injector)实现
注入器负责将反射型DLL加载到目标进程:
-
写入DLL到目标进程:
- 使用
VirtualAllocEx分配内存 - 使用
WriteProcessMemory写入DLL数据
- 使用
-
执行反射加载:
- 找到DLL中的
ReflectiveLoader函数地址 - 使用
CreateRemoteThread或类似API执行该函数
- 找到DLL中的
改进的反射型DLL注入技术
Disman提出的改进方案(https://disman.tl/2015/01/30/an-improved-reflective-dll-injection-technique.html)增加了以下功能:
-
支持参数传递:
- 复制参数到DLL后的内存中
- 创建引导shellcode调用
ReflectiveLoader
-
改进的导出函数签名:
DWORD WINAPI ReflectiveLoader(
LPVOID lpParameter, // 原始参数
LPVOID lpLibraryAddress, // DLL内存地址
DWORD dwFunctionHash, // 可选函数hash
LPVOID lpUserData, // 用户数据
DWORD nUserdataLen // 用户数据长度
);
- Shellcode实现:
- x86:压栈传入参数,调用
ReflectiveLoader,执行ExitThread - x64:需要额外分配0x20影子空间
- x86:压栈传入参数,调用
技术优势与防御
优势:
- 不依赖
LoadLibrary,规避API监控 - 无磁盘文件操作,规避文件监控
- 加载过程完全在内存中完成
- 可绕过部分杀毒软件的检测
防御措施:
- 监控异常的内存分配行为
- 检测远程线程创建
- 分析进程内存中的PE结构异常
- 监控反射加载常见的行为模式
实际应用注意事项
-
DllMain中的操作:
- RDI不存在传统DLL加载的死锁问题
- 可以在DllMain中执行任意操作
-
异常处理:
- 如果需要异常处理,必须获取
RtlAddFunctionTable - 否则DLL中的异常将无法正确处理
- 如果需要异常处理,必须获取
-
缓存清除:
- 使用
NtFlushInstructionCache清除执行缓存 - 确保修改后的代码能够正确执行
- 使用
总结
反射型DLL注入是一种强大的代码注入技术,相比传统方法更加隐蔽和灵活。理解其原理不仅有助于红队开发免杀工具,也能帮助蓝队更好地防御此类攻击。在实际应用中,需要根据具体场景调整实现细节,平衡隐蔽性和功能性。