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

NtAllocateVirtualMemory调用失败,错误码0xC0000005技术求助

解决NtAllocateVirtualMemory触发0xC0000005错误的问题

错误原因分析

  • 类型不匹配导致内存大小错误:NtAllocateVirtualMemory的RegionSize参数实际要求是PULONG_PTR(32位系统对应ULONG,64位系统对应ULONG_PTR),你使用unsigned int类型的buffer_len强制转换为PULONG,在64位系统下会造成参数截断,导致分配的内存大小不符合预期,后续访问时触发访问违规。
  • 内存执行权限问题:分配内存时使用PAGE_READWRITE权限,然后直接创建线程执行该内存区域,现代Windows的DEP(数据执行保护)会拦截这种无执行权限的内存执行操作,触发访问违规。

修复方案

  1. 修正参数类型:将buffer_len的类型改为ULONG_PTR,确保在32/64位系统下都能正确传递内存大小参数。
  2. 调整内存权限:分配内存时直接使用PAGE_EXECUTE_READWRITE权限,或者分配后调用NtProtectVirtualMemory修改权限为可执行。
  3. 修正函数指针定义:确保NtAllocateVirtualMemory的RegionSize参数类型为PULONG_PTR,避免类型不匹配问题。

修正后的代码

#include <Windows.h>

#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)

unsigned char buffer[] = {
    0x90,       // NOP
    0x90,       // NOP
    0xcc,       // INT3
    0xc3        // RET
};
ULONG_PTR buffer_len = sizeof(buffer); // 使用ULONG_PTR适配32/64位系统

// 修正NtAllocateVirtualMemory的函数指针定义,RegionSize为PULONG_PTR
typedef NTSTATUS(NTAPI* pNtAllocateVirtualMemory)(
    HANDLE             ProcessHandle,
    PVOID*             BaseAddress,
    ULONG              ZeroBits,
    PULONG_PTR         RegionSize,
    ULONG              AllocationType,
    ULONG              Protect
); 
typedef NTSTATUS(NTAPI* pNtWriteVirtualMemory)(
    HANDLE ProcessHandle,
    PVOID BaseAddress,
    PVOID Buffer,
    SIZE_T BufferSize,
    PSIZE_T NumberOfBytesWritten
);

int main()
{
    PVOID exec_mem = NULL;
    HANDLE rt = NULL;

    pNtAllocateVirtualMemory ntAllocateVirtualMemory = 
        (pNtAllocateVirtualMemory)GetProcAddress(GetModuleHandleA("ntdll"), "NtAllocateVirtualMemory");
    if (!ntAllocateVirtualMemory) {
        return -1;
    }

    NTSTATUS status = ntAllocateVirtualMemory(
        GetCurrentProcess(),
        &exec_mem,
        0,
        &buffer_len,
        MEM_COMMIT | MEM_RESERVE,
        PAGE_EXECUTE_READWRITE // 直接分配带可执行权限的内存
    );
    if (!NT_SUCCESS(status)) {
        return -1;
    }

    pNtWriteVirtualMemory ntWriteVirtualMemory = 
        (pNtWriteVirtualMemory)GetProcAddress(GetModuleHandleA("ntdll"), "NtWriteVirtualMemory");
    if (!ntWriteVirtualMemory) {
        return -1;
    }
    
    SIZE_T bytesWritten = 0; 
    status = ntWriteVirtualMemory(
        GetCurrentProcess(),
        exec_mem,
        buffer,
        sizeof(buffer),
        &bytesWritten
    );
    if (!NT_SUCCESS(status) || bytesWritten != sizeof(buffer)) {
        return -1;
    }

    rt = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)exec_mem, 0, 0, 0);
    if (rt) {
        WaitForSingleObject(rt, INFINITE);
        CloseHandle(rt);
    }

    return 0;
}

额外说明(可选安全优化)

如果不想直接分配可执行内存,可先分配PAGE_READWRITE权限内存,写入数据后再调用NtProtectVirtualMemory修改为可执行权限,示例代码如下:

// 在写入内存后添加以下代码
typedef NTSTATUS(NTAPI* pNtProtectVirtualMemory)(
    HANDLE ProcessHandle,
    PVOID* BaseAddress,
    PULONG_PTR RegionSize,
    ULONG NewProtect,
    PULONG OldProtect
);

pNtProtectVirtualMemory ntProtectVirtualMemory = 
    (pNtProtectVirtualMemory)GetProcAddress(GetModuleHandleA("ntdll"), "NtProtectVirtualMemory");
if (ntProtectVirtualMemory) {
    ULONG oldProtect = 0;
    ULONG_PTR protectSize = sizeof(buffer);
    status = ntProtectVirtualMemory(
        GetCurrentProcess(),
        &exec_mem,
        &protectSize,
        PAGE_EXECUTE_READ,
        &oldProtect
    );
    if (!NT_SUCCESS(status)) {
        return -1;
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 20:52:10