You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

关于NtWow64AllocateVirtualMemory64无效句柄问题的技术咨询及测试代码

排查NtWow64AllocateVirtualMemory64无效句柄问题

从你的代码和问题描述来看,出现无效句柄错误的核心原因是进程句柄的使用不符合Wow64环境下的函数要求,另外还有参数类型不匹配的问题,下面详细拆解并给出解决方案:

问题原因分析

  • 错误的进程句柄传递:你在代码里定义了NtCurrentProcess()但实际调用时用了GetCurrentProcess()。在32位Wow64进程中,NtWow64AllocateVirtualMemory64这类跨位函数要求使用内核认可的特殊伪句柄(HANDLE)-1(也就是NtCurrentProcess()的定义),而GetCurrentProcess()返回的是32位进程的伪句柄,在64位内核调用上下文里会被解析成无效句柄。
  • 参数类型不匹配:你用PVOID pvBaseAddress来存储64位基地址,但32位进程的PVOID是32位指针,无法完整容纳64位地址值。函数的第二个参数PULONG64要求传入指向64位整数的指针,用来接收分配的64位基地址,用32位指针类型强制转换会导致地址截断或参数解析错误。

解决方法

  1. 替换进程句柄为NtCurrentProcess():直接使用你已经定义的NtCurrentProcess()作为第一个参数,不要用GetCurrentProcess()
  2. 修正基地址的参数类型:用ULONG64类型变量来存储64位基地址,而不是PVOID,确保能完整接收64位地址值。
  3. 补全函数参数:确保MEM_COMMIT搭配正确的内存分配类型(比如MEM_RESERVE),以及合理的内存保护属性(比如PAGE_READWRITE)。

修正后的测试代码示例

typedef NTSTATUS(NTAPI *ntalloc64t)(
    HANDLE ProcessHandle,
    PULONG64 BaseAddress,
    ULONG64 ZeroBits,
    PULONG64 RegionSize,
    ULONG AllocationType,
    ULONG Protect
);

#define NtCurrentProcess() ((HANDLE)(LONG_PTR)-1)

int _tmain(int argc, _TCHAR* argv[]) {
    ULONG64 dwSize = 0x1000;
    ULONG64 baseAddr = 0; // 用64位变量存储基地址

    ntalloc64t ntalloc64f = (ntalloc64t)GetProcAddress(
        GetModuleHandleA("ntdll"), 
        "NtWow64AllocateVirtualMemory64"
    );

    if (!ntalloc64f) {
        // 处理函数获取失败的情况
        return 1;
    }

    NTSTATUS status = ntalloc64f(
        NtCurrentProcess(),       // 使用正确的伪句柄
        &baseAddr,                // 传入64位地址的指针
        0,
        &dwSize,
        MEM_COMMIT | MEM_RESERVE, // 补全分配类型
        PAGE_READWRITE            // 指定内存保护属性
    );

    if (NT_SUCCESS(status)) {
        // 分配成功,baseAddr就是64位的内存基地址
        // 注意:32位进程无法直接访问这个64位地址,通常用于后续的Wow64内存操作
    } else {
        // 处理错误,比如打印status值
    }

    return 0;
}

额外注意事项

  • 32位进程无法直接访问NtWow64AllocateVirtualMemory64分配的64位地址空间,这个函数通常是配合其他Wow64系列函数(比如NtWow64WriteVirtualMemory64)来操作64位进程的内存,或者用于特殊的内存场景。
  • 确保你的程序是以32位编译的,因为这个函数只存在于32位的ntdll.dll中,64位进程不需要调用它。

内容的提问来源于stack exchange,提问作者sdevae

火山引擎 最新活动