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

如何修复Rust调用NtAllocateVirtualMemory时的0xc0000005 STATUS_ACCESS_VIOLATION错误

问题根因分析

1. 参数传递存在两处致命错误

你触发访问违规的核心原因是完全不符合NtAllocateVirtualMemory的参数传递约定,先看该函数的标准原型:

NTSYSAPI NTSTATUS NtAllocateVirtualMemory(
  [in]      HANDLE    ProcessHandle,
  [in, out] PVOID     *BaseAddress,
  [in]      ULONG_PTR ZeroBits,
  [in, out] PSIZE_T   RegionSize,
  [in]      ULONG     AllocationType,
  [in]      ULONG     Protect
);

你代码里的错误点:

  • 第二个参数要求传入存储基地址的变量的二级指针,你写的*buffer是对空指针直接解引用,内核尝试写入空地址直接触发0xc0000005错误
  • 第四个参数要求传入存储分配大小的变量的二级指针,你直接把0x1000强转为指针传入,内核会尝试往0x1000这个非法用户地址写入实际分配大小,也是访问违规的诱因
  • 还存在语法错误:0x1000 as *mut _后漏写逗号,编译阶段就会触发语法告警

2. 为什么VirtualAllocEx可以正常工作

VirtualAllocEx是kernel32.dll封装的上层接口,内部已经帮你完成了Nt系列接口的参数适配:你传入给VirtualAllocEx的是直接的地址和大小数值,它内部会自动在栈上申请临时变量存储这两个值,再把变量的二级指针传给底层的NtAllocateVirtualMemory,调用完成后再把分配结果返回给上层,你不需要自行处理二级指针的传递逻辑,自然不会踩到参数传递的坑。

修复后的可运行代码

Cargo.toml不需要修改,直接替换main.rs内容即可:

use ntapi::ntmmapi::NtAllocateVirtualMemory;
use ntapi::ntpsapi::NtCurrentProcess;
use winapi::um::winnt::{MEM_COMMIT, MEM_RESERVE, PAGE_READWRITE};
use winapi::shared::ntdef::NT_SUCCESS;
use std::ptr::null_mut;

fn main() {
    unsafe {
        let mut buffer = null_mut();
        let mut region_size = 0x1000;
        let status = NtAllocateVirtualMemory(
            NtCurrentProcess,
            &mut buffer,
            0,
            &mut region_size,
            MEM_COMMIT | MEM_RESERVE,
            PAGE_READWRITE,
        );

        if !NT_SUCCESS(status) {
            println!("Allocation Fails, status: {:#x}", status);
        } else {
            println!("Allocation Success, base address: {:p}, size: {:#x}", buffer, region_size);
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 20:24:03