PE文件结构//
自修改代码
Self-Modifying Code
自修改代码(Self-Modifying Code),指在一段代码执行前对它进行修改。把代码以加密的形式保存在可执行文件中(或静态资源中),然后在程序执行的时候进行动态解密。这样我们在采用静态分析时,看到的都是加密的内容,从而减缓甚至阻止静态分析。
原理与示例
SMC思路:
1 | if (运行条件满足) { |
SMC静态分析对抗示例:
正常程序:
1 |
|
在 VS 中 Release 32 位下编译(关闭随机基址),放入 IDA 中查看:
1 | unsigned char _check__YAHH_Z[] = |
现在我们想把 check 函数保护起来,先把其机器码摘出来进行加密:
1 |
|
加密后:
1 | c5 1b 7c c1 11 ed 98 a9 a0 90 90 e5 99 57 d5 6c 91 90 90 90 7b 97 57 d5 6c 90 90 90 90 1b d5 6c 1b 75 cd 53 |
修改初始代码:
1 |
|
重新编译后,在 16 进制编辑器中找到并修改 check 函数的机器码为加密后的数据
一个具备 SMC 属性的可执行文件已经构造完成了,现在再用 IDA 进行分析:
发现原始逻辑已经被很好地隐藏了。
另一种常见的实现方法是通过新增一个具备 RWX 属性的程序段,将需要保护的代码书写在其中,这样就可以避免调用 VirtualAlloc / VirtualProtect / mprotect 这类 API 来暴露 SMC 的意图。
1 |
|
可以在 IDA 中看到新增了一个段:
对抗思路
能动态调试最好直接动态调试,因为在程序运行的某一时刻,它一定是解密完成的,这时也就暴露了,使用动态分析运行到这一时刻即可过掉保护。
其次是根据静态分析获得解密算法,写出解密脚本提前解密这段代码。
解密得到的机器码可以通过 IDAPython 的 patch_byte 接口很方便地写回。