You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WOW64程序如何覆盖WMI可读取的自身命令行参数?

问题根因

64位Windows运行32位WOW64程序时,会为进程维护两份独立的PEB结构:

  • 32位PEB:映射在32位地址空间,供32位程序自身、支持WOW64识别的枚举工具(如Process Explorer)读取
  • 64位PEB:存储在64位地址空间,供系统内核、原生64位进程(包括WMI服务)读取
    原有代码仅修改了32位PEB中存储的命令行内容,WMI读取进程信息时直接从64位PEB拉取未修改的原始命令行,因此出现掩码失效。

修复方案

在原有修改32位PEB命令行逻辑的基础上,额外检测当前是否为WOW64运行环境,若是则定位到64位PEB对应的命令行缓冲区,通过WOW64提供的跨地址空间内存写入接口覆写对应内容,即可覆盖所有读取场景。

修复后的完整代码如下:

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

// WOW64跨位宽内存操作NT函数原型定义
typedef NTSTATUS(NTAPI* pfnNtWow64ReadVirtualMemory64)(
    HANDLE hProcess,
    DWORD64 lpBaseAddress,
    LPVOID lpBuffer,
    DWORD64 nSize,
    PDWORD64 lpNumberOfBytesRead
);

typedef NTSTATUS(NTAPI* pfnNtWow64WriteVirtualMemory64)(
    HANDLE hProcess,
    DWORD64 lpBaseAddress,
    LPVOID lpBuffer,
    DWORD64 nSize,
    PDWORD64 lpNumberOfBytesWritten
);

// 64位地址空间下UNICODE_STRING结构内存布局
typedef struct _UNICODE_STRING_64 {
    USHORT Length;
    USHORT MaximumLength;
    DWORD64 Buffer;
} UNICODE_STRING_64;

// 64位结构固定偏移(Windows 7至Win11全版本兼容)
#define PEB64_PROCESS_PARAMS_OFFSET    0x20  // 64位PEB中ProcessParameters指针偏移
#define PARAMS64_CMDLINE_OFFSET        0x70  // 64位进程参数中CommandLine结构偏移

void MaskWow64CommandLine()
{
    BOOL bIsWow64 = FALSE;
    if (!IsWow64Process(GetCurrentProcess(), &bIsWow64) || !bIsWow64)
        return; // 非WOW64场景无需额外处理

    HMODULE hNtdll = GetModuleHandleW(L"ntdll.dll");
    auto NtWow64ReadVirtualMemory64 = (pfnNtWow64ReadVirtualMemory64)GetProcAddress(hNtdll, "NtWow64ReadVirtualMemory64");
    auto NtWow64WriteVirtualMemory64 = (pfnNtWow64WriteVirtualMemory64)GetProcAddress(hNtdll, "NtWow64WriteVirtualMemory64");
    if (!NtWow64ReadVirtualMemory64 || !NtWow64WriteVirtualMemory64)
        return;

    // 获取当前进程的64位PEB基址
    DWORD64 qwPeb64Addr = 0;
    ULONG ulRetLen = 0;
    if (NtQueryInformationProcess(GetCurrentProcess(), ProcessWow64Information, &qwPeb64Addr, sizeof(qwPeb64Addr), &ulRetLen) != 0 || !qwPeb64Addr)
        return;

    // 读取64位PEB中存储的进程参数指针
    DWORD64 qwProcParams64Addr = 0;
    if (NtWow64ReadVirtualMemory64(GetCurrentProcess(), qwPeb64Addr + PEB64_PROCESS_PARAMS_OFFSET, &qwProcParams64Addr, sizeof(qwProcParams64Addr), nullptr) != 0 || !qwProcParams64Addr)
        return;

    // 读取64位进程参数中的命令行UNICODE_STRING结构
    UNICODE_STRING_64 cmdLine64 = {0};
    if (NtWow64ReadVirtualMemory64(GetCurrentProcess(), qwProcParams64Addr + PARAMS64_CMDLINE_OFFSET, &cmdLine64, sizeof(cmdLine64), nullptr) != 0 || !cmdLine64.Buffer || cmdLine64.Length == 0)
        return;

    // 分块覆写64位地址空间中的命令行缓冲区
    const DWORD BLOCK_SIZE = 256;
    wchar_t wszMaskBlock[BLOCK_SIZE];
    wmemset(wszMaskBlock, L'x', BLOCK_SIZE);
    DWORD64 qwTotalChars = cmdLine64.Length / sizeof(wchar_t);
    DWORD64 qwOffset = 0;
    while (qwOffset < qwTotalChars)
    {
        DWORD64 qwWriteChars = min((DWORD64)BLOCK_SIZE, qwTotalChars - qwOffset);
        NtWow64WriteVirtualMemory64(
            GetCurrentProcess(),
            cmdLine64.Buffer + qwOffset * sizeof(wchar_t),
            wszMaskBlock,
            qwWriteChars * sizeof(wchar_t),
            nullptr
        );
        qwOffset += qwWriteChars;
    }
}

// 原始TEB/PEB获取逻辑
#if defined(_M_X64) // x64
PTEB tebPtr = reinterpret_cast<PTEB>(__readgsqword(reinterpret_cast<DWORD_PTR>(&static_cast<NT_TIB*>(nullptr)->Self)));
#else // x86
PTEB tebPtr = reinterpret_cast<PTEB>(__readfsdword(reinterpret_cast<DWORD_PTR>(&static_cast<NT_TIB*>(nullptr)->Self)));
#endif
PPEB pebPtr = tebPtr->ProcessEnvironmentBlock;

int main()
{
    // 覆写32位PEB命令行
    UNICODE_STRING* pCmdLine = &pebPtr->ProcessParameters->CommandLine;
    wmemset(pCmdLine->Buffer, L'x', pCmdLine->Length / sizeof(wchar_t));
    // 覆写WOW64场景下64位PEB命令行
    MaskWow64CommandLine();
    getwchar();
    return 0;
}

补充说明

  • 代码中使用的64位结构偏移在Windows 7及之后所有64位Windows版本中保持固定,无需做系统版本适配
  • 该方案仅修改PEB中存储的命令行内容,不会触发内存保护异常,无进程崩溃风险
  • 若需要覆盖进程内GetCommandLineW接口的读取结果,可在上述逻辑基础上额外覆写该接口返回的缓冲区内容即可。

内容的提问来源于stack exchange,提问作者Joseph Sible-Reinstate Monica

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 09:36:20