### ShellCode 免杀方法

1. 改变 ShellCode 特征

这是最基本也是最重要的一步。原始的 ShellCode 往往包含固定的、已知的字节序列，这些序列很容易被杀毒软件识别

- 编码 (Encoding)： 使用各种编码技术，如 XOR、Base64、RC4 等，对 ShellCode 进行加密或混淆。在运行时，ShellCode 会被解码器（Decoder）解密后再执行。这样，静态文件中的 ShellCode 就不再是原始字节，从而绕过了静态查杀
- 多态/自修改 (Polymorphism)： 每次生成 ShellCode 时，都使用不同的加密密钥和解码器代码。这样，即使 ShellCode 本身相同，其外部封装也总是变化的，使签名查杀变得困难
- 分块加载 (Chunking)： 将 ShellCode 分割成多个小块，分散存储在不同的位置。在运行时，再将这些小块按顺序加载到内存中，重新组装成完整的 ShellCode。这可以避免单个大块的恶意代码被检测

2. 改变 ShellCode 加载方式

仅仅改变 ShellCode 的静态特征是不够的，还需要改变其在内存中的加载和执行方式，绕过行为检测

- 反射式 DLL 注入： 不将 ShellCode 直接写入内存，而是将它作为 DLL 文件反射性地加载到目标进程中。这种技术可以绕过一些基于内存特征的检测
- 内存申请方式： 避免使用像 `VirtualAlloc` 这样常用的 API 函数来分配可执行内存。可以尝试使用其他函数，如 `HeapAlloc`，或者通过一些更隐蔽的手段来获取可执行内存
- API 函数混淆： 恶意软件通常会调用一些特定的敏感 API 函数，如 `CreateProcess`、`WriteProcessMemory` 等。可以通过动态解析、哈希查找等方式，避免在代码中直接写出这些函数名，而是运行时再解析得到地址。这可以绕过一些基于 API 调用的行为检测
- 白加黑 (LOLBAS)： 利用 Windows 系统中已有的合法程序（如 `rundll32.exe`, `certutil.exe` 等）来加载和执行恶意代码。这种方式利用了“白名单程序”的信任，使恶意行为看起来像是合法操作