Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
SysWhispers2 — 通过直接系统调用绕过AV/EDR。 | Kitploit
工具/GitHubGitHub/jthuraisamy/syswhispers2
防御工具IDS/IPS规避Shellcode红队Payload 开发二进制利用
GitHubjthuraisamy/syswhispers2

SysWhispers2

通过直接系统调用绕过AV/EDR。

查看仓库
1.8k2653年前Kitploit 审核通过

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

SysWhispers2

SysWhispers 通过生成植入物可用于进行直接系统调用的头文件/汇编文件,帮助进行规避。

所有核心系统调用均受支持,示例生成文件位于 example-output/ 文件夹中。

SysWhispers 1 和 2 的区别

用法与 SysWhispers1 几乎相同,但无需指定要支持哪些 Windows 版本。大多数更改在底层。它不再依赖 @j00ru 的 syscall tables,而是使用由 @modexpblog 推广的“按系统调用地址排序”技术。这大大减少了系统调用存根的大小。

SysWhispers2 的具体实现是 @modexpblog 代码的一个变体。一个区别是函数名称哈希在每次生成时是随机的。@ElephantSe4l 早期发布过此技术,另一个基于 C++17 的实现也值得一看。

原始的 SysWhispers 仓库仍然存在,但未来可能会被弃用。

介绍

各种安全产品在用户模式 API 函数中放置钩子,从而可以将执行流重定向到其引擎并检测可疑行为。ntdll.dll 中执行系统调用的函数仅由几条汇编指令组成,因此在您自己的植入物中重新实现它们可以绕过触发安全产品钩子。该技术由 @Cn33liz 推广,他的博文中有更多值得阅读的技术细节。

SysWhispers 为红队提供了为内核核心映像 (ntoskrnl.exe) 中的任何系统调用生成头文件/汇编对的能力。头文件还将包含必要的类型定义。

安装

root@kitploit:~
> git clone https://github.com/jthuraisamy/SysWhispers2.git
> cd SysWhispers2
> py .\syswhispers.py --help

使用和示例

命令行

root@kitploit:~
# Export all functions with compatibility for all supported Windows versions (see example-output/).
py .\syswhispers.py --preset all -o syscalls_all

# Export just the common functions (see below for list).
py .\syswhispers.py --preset common -o syscalls_common

# Export NtProtectVirtualMemory and NtWriteVirtualMemory with compatibility for all versions.
py .\syswhispers.py --functions NtProtectVirtualMemory,NtWriteVirtualMemory -o syscalls_mem

脚本输出

root@kitploit:~
PS C:\Projects\SysWhispers2> py .\syswhispers.py --preset common --out-file syscalls_common

python syswhispers.py -p all -a all -l all -o example-output/Syscalls

                  .                         ,--.
,-. . . ,-. . , , |-. o ,-. ,-. ,-. ,-. ,-.    /
`-. | | `-. |/|/  | | | `-. | | |-' |   `-. ,-'
`-' `-| `-' ' '   ' ' ' `-' |-' `-' '   `-' `---
     /|                     |  @Jackson_T
    `-'                     '  @modexpblog, 2021

SysWhispers2: Why call the kernel when you can whisper?

All functions selected.

Complete! Files written to:
        example-output/Syscalls.h
        example-output/Syscalls.c
        example-output/SyscallsStubs.std.x86.asm
        example-output/SyscallsStubs.rnd.x86.asm
        example-output/SyscallsStubs.std.x86.nasm
        example-output/SyscallsStubs.rnd.x86.nasm
        example-output/SyscallsStubs.std.x86.s
        example-output/SyscallsStubs.rnd.x86.s
        example-output/SyscallsInline.std.x86.h
        example-output/SyscallsInline.rnd.x86.h
        example-output/SyscallsStubs.std.x64.asm
        example-output/SyscallsStubs.rnd.x64.asm
        example-output/SyscallsStubs.std.x64.nasm
        example-output/SyscallsStubs.rnd.x64.nasm
        example-output/SyscallsStubs.std.x64.s
        example-output/SyscallsStubs.rnd.x64.s
        example-output/SyscallsInline.std.x64.h
        example-output/SyscallsInline.rnd.x64.h

经典的 CreateRemoteThread DLL 注入的前后对比示例

root@kitploit:~
py .\syswhispers.py -f NtAllocateVirtualMemory,NtWriteVirtualMemory,NtCreateThreadEx -o syscalls
root@kitploit:~
#include <Windows.h>

void InjectDll(const HANDLE hProcess, const char* dllPath)
{
    LPVOID lpBaseAddress = VirtualAllocEx(hProcess, NULL, strlen(dllPath), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
    LPVOID lpStartAddress = GetProcAddress(GetModuleHandle(L"kernel32.dll"), "LoadLibraryA");
	
    WriteProcessMemory(hProcess, lpBaseAddress, dllPath, strlen(dllPath), nullptr);
    CreateRemoteThread(hProcess, nullptr, 0, (LPTHREAD_START_ROUTINE)lpStartAddress, lpBaseAddress, 0, nullptr);
}
root@kitploit:~
#include <Windows.h>
#include "syscalls.h" // Import the generated header.

void InjectDll(const HANDLE hProcess, const char* dllPath)
{
    HANDLE hThread = NULL;
    LPVOID lpAllocationStart = nullptr;
    SIZE_T szAllocationSize = strlen(dllPath);
    LPVOID lpStartAddress = GetProcAddress(GetModuleHandle(L"kernel32.dll"), "LoadLibraryA");
	
    NtAllocateVirtualMemory(hProcess, &lpAllocationStart, 0, (PULONG)&szAllocationSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
    NtWriteVirtualMemory(hProcess, lpAllocationStart, (PVOID)dllPath, strlen(dllPath), nullptr);
    NtCreateThreadEx(&hThread, GENERIC_EXECUTE, NULL, hProcess, lpStartAddress, lpAllocationStart, FALSE, 0, 0, 0, nullptr);
}

常用函数

使用 --preset common 开关将创建包含以下函数的头文件/汇编对:

点击展开函数列表。
  • NtCreateProcess (CreateProcess)
  • NtCreateThreadEx (CreateRemoteThread)
  • NtOpenProcess (OpenProcess)
  • NtOpenThread (OpenThread)
  • NtSuspendProcess
  • NtSuspendThread (SuspendThread)
  • NtResumeProcess
  • NtResumeThread (ResumeThread)
  • NtGetContextThread (GetThreadContext)
  • NtSetContextThread (SetThreadContext)
  • NtClose (CloseHandle)
  • NtReadVirtualMemory (ReadProcessMemory)
  • NtWriteVirtualMemory (WriteProcessMemory)
  • NtAllocateVirtualMemory (VirtualAllocEx)
  • NtProtectVirtualMemory (VirtualProtectEx)
  • NtFreeVirtualMemory (VirtualFreeEx)
  • NtQuerySystemInformation (GetSystemInfo)
  • NtQueryDirectoryFile
  • NtQueryInformationFile
  • NtQueryInformationProcess
  • NtQueryInformationThread
  • NtCreateSection (CreateFileMapping)
  • NtOpenSection
  • NtMapViewOfSection
  • NtUnmapViewOfSection
  • NtAdjustPrivilegesToken (AdjustTokenPrivileges)
  • NtDeviceIoControlFile (DeviceIoControl)
  • NtQueueApcThread (QueueUserAPC)
  • NtWaitForMultipleObjects (WaitForMultipleObjectsEx)

导入到 Visual Studio

  1. 将生成的 H/C/ASM 文件复制到项目文件夹中。
  2. 在 Visual Studio 中,转到 项目 → 生成自定义... 并启用 MASM。
  3. 在 解决方案资源管理器 中,将 .h 和 .c/.asm 文件分别作为头文件和源文件添加到项目中。
  4. 进入 x86 ASM 文件的属性。
  5. 从 配置 下拉菜单中选择 所有配置。
  6. 从 平台 下拉菜单中选择 Win32。
  7. 设置以下选项:
    • 从生成中排除 = 否
    • 内容 = 是
    • 项类型 = Microsoft Macro Assembler
  8. 点击 应用
  9. 从 平台 下拉菜单中选择 x64。
  10. 设置以下选项:
    • 从生成中排除 = 是
    • 内容 = 是
    • 项类型 = Microsoft Macro Assembler
  11. 点击 应用,然后点击 确定。
  12. 进入 x64 ASM 文件的属性。
  13. 从 配置 下拉菜单中选择 所有配置。
  14. 从 平台 下拉菜单中选择 Win32。
  15. 设置以下选项:
    • 从生成中排除 = 是
    • 内容 = 是
    • 项类型 = Microsoft Macro Assembler
  16. 点击 应用
  17. 从 平台 下拉菜单中选择 x64。
  18. 设置以下选项:
    • 从生成中排除 = 否
    • 内容 = 是
    • 项类型 = Microsoft Macro Assembler
  19. 点击 应用,然后点击 确定。

使用 MinGW 和 NASM 编译

以下示例演示如何使用 MinGW 和 NASM 汇编器将上述示例程序编译为 EXE 和 DLL:

x86 示例 EXE

root@kitploit:~
i686-w64-mingw32-gcc -c main.c syscalls.c -Wall -shared
nasm -f win32 -o syscallsstubs.std.x86.o syscallsstubs.std.x86.nasm
i686-w64-mingw32-gcc *.o -o temp.exe
i686-w64-mingw32-strip -s temp.exe -o example.exe
rm -rf *.o temp.exe

x86 示例 DLL(含导出)

root@kitploit:~
i686-w64-mingw32-gcc -c dllmain.c syscalls.c -Wall -shared
nasm -f win32 -o syscallsstubs.std.x86.o syscallsstubs.std.x86.nasm
i686-w64-mingw32-dllwrap --def dllmain.def *.o -o temp.dll
i686-w64-mingw32-strip -s temp.dll -o example.dll
rm -rf *.o temp.dll

x64 示例 EXE

root@kitploit:~
x86_64-w64-mingw32-gcc -m64 -c main.c syscalls.c -Wall -shared
nasm -f win64 -o syscallsstubs.std.x64.o syscallsstubs.std.x64.nasm
x86_64-w64-mingw32-gcc *.o -o temp.exe
x86_64-w64-mingw32-strip -s temp.exe -o example.exe
rm -rf *.o temp.exe

x64 示例 DLL(含导出)

root@kitploit:~
x86_64-w64-mingw32-gcc -m64 -c dllmain.c syscalls.c -Wall -shared
nasm -f win64 -o syscallsstubs.std.x64.o syscallsstubs.std.x64.nasm
x86_64-w64-mingw32-gcc-dllwrap --def dllmain.def *.o -o temp.dll
x86_64-w64-mingw32-strip -s temp.dll -o example.dll
rm -rf *.o temp.dll

使用 MinGW 和 GNU 汇编器 (GAS) 编译

x86 示例 EXE

root@kitploit:~
i686-w64-mingw32-gcc -m32 -Wall -c main.c syscalls.c syscallsstubs.std.x86.s -o temp.exe
i686-w64-mingw32-strip -s temp.exe -o example.exe

x86 示例 DLL(含导出)

root@kitploit:~
i686-w64-mingw32-gcc -m32 -Wall -c dllmain.c syscalls.c syscallsstubs.std.x86.s -o temp.dll
i686-w64-mingw32-dllwrap --def dllmain.def *.o -o temp.dll
i686-w64-mingw32-strip -s temp.dll -o example.dll

x64 示例 EXE

root@kitploit:~
x86_64-w64-mingw32-gcc -m64 -Wall -c main.c syscalls.c syscallsstubs.std.x64.s -o temp.exe
x86_64-w64-mingw32-strip -s temp.exe -o example.exe

x64 示例 DLL(含导出)

root@kitploit:~
x86_64-w64-mingw32-gcc -m64 -Wall -c dllmain.c syscalls.c syscallsstubs.std.x64.s -o temp.dll
x86_64-w64-mingw32-dllwrap --def dllmain.def *.o -o temp.dll
x86_64-w64-mingw32-strip -s temp.dll -o example.dll

使用 LLVM/Clang

SysWhispers2 输出一个与 clang 兼容的 .s 文件,其中包含 ASM 存根。这可以与 llvm 一起编译您的代码。例如,使用上面的 CreateRemoteThread DLL 注入示例:

root@kitploit:~
clang -D nullptr=NULL main.c syscall.c syscallstubs.std.x64.s -o test.exe

仅内联头文件

inlinegas 输出选项将生成仅包含头文件的 Syswhispers2 版本,可用于 BOF 的编译。只需在项目中包含该头文件即可。

随机系统调用跳转

通过使用随机系统调用跳转例程,可以避免“系统调用标记”。汇编存根调用一个新函数 SW__GetRandomSyscallAddress,该函数在 ntdll.dll 中搜索并选择一个干净的 syscall 指令。通过这样做,同样可以避免触发用户态系统调用指令。

要使用随机系统调用跳转,您需要在编译程序时定义 RANDSYSCALL,并使用 SysWhispers2 输出的 rnd 版本。以下示例演示使用 GNU 汇编器存根。

x86 示例 EXE - 使用随机系统调用跳转

root@kitploit:~
i686-w64-mingw32-gcc main.c syscalls.c syscallsstubs.rnd.x86.s -DRANDSYSCALL -Wall -o example.exe

x64 示例 EXE - 使用随机系统调用跳转

root@kitploit:~
x86_64-w64-mingw32-gcc main.c syscalls.c syscallsstubs.rnd.x64.s -DRANDSYSCALL -Wall -o example.exe

注意事项与限制

  • 不支持来自图形子系统 (win32k.sys) 的系统调用。
  • 已在 Visual Studio 2019 (v142) 和 Windows 10 SDK 上测试。

故障排除

  • 类型重定义错误:如果 syscalls.h 中的 typedef 已经定义,项目可能无法编译。
    • 确保只包含所需的函数(即很少需要 --preset all)。
    • 如果另一个已使用的头文件中已定义了 typedef,则可以将其从 syscalls.h 中移除。

致谢

由 @Jackson_T 和 @modexpblog 开发,但建立在许多其他人的工作之上:

  • @FoxHex0ne 以机器可读格式整理了多个函数原型和 typedef。
  • @PetrBenes、NTInternals.net 团队和 MSDN 提供了额外的原型和 typedef。
  • @Cn33liz 提供了最初的 Dumpert POC 实现。

相关文章和项目

  • @modexpblog: Bypassing User-Mode Hooks and Direct Invocation of System Calls for Red Teams
  • @hodg87: Malware Mitigation when Direct System Calls are Used
  • @Cn33liz: Combining Direct System Calls and sRDI to bypass AV/EDR (Code)
  • @0x00dtm: Userland API Monitoring and Code Injection Detection
  • @0x00dtm: Defeating Userland Hooks (ft. Bitdefender) (Code)
  • @mrgretzky: Defeating Antivirus Real-time Protection From The Inside
  • @SpecialHoang: Bypass EDR’s memory protection, introduction to hooking (Code)
  • @xpn 和 @domchell: Silencing Cylance: A Case Study in Modern EDRs
  • @mrjefftang: Universal Unhooking: Blinding Security Software (Code)
  • @spotheplanet: Full DLL Unhooking with C++
  • @hasherezade: Floki Bot and the stealthy dropper
  • @hodg87: Latest Trickbot Variant has New Tricks Up Its Sleeve

对 SysWhispers 的引用

  • @JFaust_: Process Injection Part 1, Part 2, and Alaris loader project (Code)
  • @0xPat: Malware Development Part 2
  • @brsn76945860: Implementing Syscalls In The CobaltStrike Artifact Kit
  • @Cn33liz 和 @_DaWouw: Direct Syscalls in Beacon Object Files (Code)

许可证

本项目采用 Apache License 2.0 许可。

下载工具