直接系统调用学习记录
字数 1325 2025-08-20 18:17:47

直接系统调用技术详解与实现

1. 直接系统调用概述

直接系统调用(Direct System Call)是Windows系统上的一种技术,允许用户模式程序直接进入内核模式执行特权操作,而无需通过常规的API调用链(kernel32.dll → ntdll.dll → 系统调用)。

核心优势:

  • 绕过EDR(终端检测与响应)在用户层的钩子(Hook)
  • 减少API调用痕迹,提高隐蔽性
  • 直接与内核交互,执行效率更高

2. EDR检测机制分析

现代EDR解决方案通常在Ring 3层(用户模式)实现钩子技术:

  1. 通过修改API函数的前几个字节(操作码和操作数)
  2. 将执行流重定向到EDR的hook.dll
  3. 在hook.dll中分析API调用行为是否恶意

常规调用流程(被EDR监控):

应用程序 → kernel32.dll → ntdll.dll → EDR钩子 → 系统调用

直接系统调用流程(绕过EDR):

应用程序 → 直接系统调用指令 → 内核模式

3. 技术实现原理

系统调用号获取

每个Windows系统函数都有一个唯一的系统调用号(SSN, System Service Number),存储在ntdll.dll中对应函数的第4个字节。

汇编核心代码

mov r10, rcx      ; 将第一个参数保存到r10寄存器
mov eax, SSN      ; 将系统调用号存入eax
syscall           ; 执行系统调用指令
ret               ; 返回

4. 实现步骤详解

准备工作

  1. 获取SysWhispers2项目(https://github.com/jthuraisamy/SysWhispers2)
  2. 主要使用其中的syscalls.h和汇编文件

C++实现流程

  1. 获取ntdll.dll的模块句柄
HMODULE hNtdll = GetModuleHandleA("ntdll.dll");
  1. 获取目标函数地址并读取系统调用号
FARPROC pFunc = GetProcAddress(hNtdll, "NtAllocateVirtualMemory");
DWORD ssn = *((PDWORD)((PBYTE)pFunc + 4));  // 第4字节为SSN
  1. 为所有需要的函数重复上述操作

  2. 使用汇编代码执行直接系统调用

MASM汇编实现

EXTERN用于全局访问变量 包含了对应的SSN

5. 关键注意事项

  1. 系统兼容性:不同Windows版本的系统调用号可能不同
  2. 参数传递:必须严格按照x64调用约定准备参数
  3. 错误处理:直接系统调用不会设置LastError,需要自行处理
  4. 检测规避:现代EDR可能监控syscall指令的使用,需要进一步混淆

6. 防御对抗演进

随着直接系统调用技术的普及,EDR厂商已发展出新的检测手段:

  • 监控异常的系统调用来源(非ntdll.dll发起的syscall)
  • 分析调用栈的完整性
  • 检测syscall指令的上下文

应对方法包括:

  • 动态生成syscall存根
  • 混合使用直接和间接调用
  • 调用栈混淆

7. 实际应用示例

以下是一个简化的直接系统调用实现框架:

#include <windows.h>

// 定义函数类型
typedef NTSTATUS(NTAPI* pNtAllocateVirtualMemory)(
    HANDLE ProcessHandle,
    PVOID* BaseAddress,
    ULONG_PTR ZeroBits,
    PSIZE_T RegionSize,
    ULONG AllocationType,
    ULONG Protect);

// 获取SSN的函数
DWORD GetSSN(LPCSTR funcName) {
    HMODULE hNtdll = GetModuleHandleA("ntdll.dll");
    FARPROC pFunc = GetProcAddress(hNtdll, funcName);
    return *((PDWORD)((PBYTE)pFunc + 4));
}

// 直接系统调用执行函数
extern "C" NTSTATUS DirectNtAllocateVirtualMemory(
    HANDLE ProcessHandle,
    PVOID* BaseAddress,
    ULONG_PTR ZeroBits,
    PSIZE_T RegionSize,
    ULONG AllocationType,
    ULONG Protect) {
    
    DWORD ssn = GetSSN("NtAllocateVirtualMemory");
    
    __asm {
        mov r10, rcx
        mov eax, ssn
        syscall
        ret
    }
}

int main() {
    // 使用直接系统调用分配内存
    PVOID baseAddr = nullptr;
    SIZE_T size = 0x1000;
    DirectNtAllocateVirtualMemory(
        GetCurrentProcess(),
        &baseAddr,
        0,
        &size,
        MEM_COMMIT | MEM_RESERVE,
        PAGE_EXECUTE_READWRITE);
    
    // 使用分配的内存...
    
    return 0;
}

8. 进阶技术方向

  1. 动态SSN解析:运行时解析ntdll.dll获取最新SSN,提高兼容性
  2. 间接系统调用:通过合法模块中的syscall指令间接执行
  3. 硬件断点绕过:使用硬件断点检测EDR的监控并规避
  4. VDSO调用:利用Linux风格的vDSO机制进行系统调用

9. 资源推荐

  1. SysWhispers2:https://github.com/jthuraisamy/SysWhispers2
  2. HellsGate:动态SSN解析技术
  3. HalosGate:针对HellsGate的改进版
  4. FreshyCalls:另一种直接系统调用实现方式

10. 法律与道德声明

直接系统调用技术本身是中性的,但可能被用于恶意目的。本技术文档仅用于安全研究和防御技术研究,任何使用此技术进行的未经授权系统访问均属违法。安全研究人员应在合法授权范围内进行相关测试和研究。

直接系统调用技术详解与实现 1. 直接系统调用概述 直接系统调用(Direct System Call)是Windows系统上的一种技术,允许用户模式程序直接进入内核模式执行特权操作,而无需通过常规的API调用链(kernel32.dll → ntdll.dll → 系统调用)。 核心优势: 绕过EDR(终端检测与响应)在用户层的钩子(Hook) 减少API调用痕迹,提高隐蔽性 直接与内核交互,执行效率更高 2. EDR检测机制分析 现代EDR解决方案通常在Ring 3层(用户模式)实现钩子技术: 通过修改API函数的前几个字节(操作码和操作数) 将执行流重定向到EDR的hook.dll 在hook.dll中分析API调用行为是否恶意 常规调用流程(被EDR监控): 直接系统调用流程(绕过EDR): 3. 技术实现原理 系统调用号获取 每个Windows系统函数都有一个唯一的系统调用号(SSN, System Service Number),存储在ntdll.dll中对应函数的第4个字节。 汇编核心代码 4. 实现步骤详解 准备工作 获取SysWhispers2项目(https://github.com/jthuraisamy/SysWhispers2) 主要使用其中的syscalls.h和汇编文件 C++实现流程 获取ntdll.dll的模块句柄 获取目标函数地址并读取系统调用号 为所有需要的函数重复上述操作 使用汇编代码执行直接系统调用 MASM汇编实现 5. 关键注意事项 系统兼容性 :不同Windows版本的系统调用号可能不同 参数传递 :必须严格按照x64调用约定准备参数 错误处理 :直接系统调用不会设置LastError,需要自行处理 检测规避 :现代EDR可能监控syscall指令的使用,需要进一步混淆 6. 防御对抗演进 随着直接系统调用技术的普及,EDR厂商已发展出新的检测手段: 监控异常的系统调用来源(非ntdll.dll发起的syscall) 分析调用栈的完整性 检测syscall指令的上下文 应对方法包括: 动态生成syscall存根 混合使用直接和间接调用 调用栈混淆 7. 实际应用示例 以下是一个简化的直接系统调用实现框架: 8. 进阶技术方向 动态SSN解析 :运行时解析ntdll.dll获取最新SSN,提高兼容性 间接系统调用 :通过合法模块中的syscall指令间接执行 硬件断点绕过 :使用硬件断点检测EDR的监控并规避 VDSO调用 :利用Linux风格的vDSO机制进行系统调用 9. 资源推荐 SysWhispers2 :https://github.com/jthuraisamy/SysWhispers2 HellsGate :动态SSN解析技术 HalosGate :针对HellsGate的改进版 FreshyCalls :另一种直接系统调用实现方式 10. 法律与道德声明 直接系统调用技术本身是中性的,但可能被用于恶意目的。本技术文档仅用于安全研究和防御技术研究,任何使用此技术进行的未经授权系统访问均属违法。安全研究人员应在合法授权范围内进行相关测试和研究。