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

C#调用kernel32.dll的ReadProcessMemory在Windows11返回错误299

解决Windows 11下ReadProcessMemory返回错误299(ERROR_PARTIAL_COPY)的问题

错误299对应ERROR_PARTIAL_COPY,表示尝试读取的内存中存在无法访问的区域。结合你Win10正常、Win11异常的情况,核心原因大概率是Windows 11的安全机制限制或进程句柄权限不足,以下是具体排查和解决方法:

1. 确保进程句柄拥有足够权限

默认通过Process.Handle获取的进程句柄,权限可能不包含完整的内存读取权限。建议手动调用OpenProcess函数,明确请求PROCESS_VM_READ和PROCESS_QUERY_INFORMATION权限:

修改后的PInvoke代码

// 新增OpenProcess和CloseHandle的PInvoke声明
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr OpenProcess(
    uint dwDesiredAccess,
    bool bInheritHandle,
    int dwProcessId
);

[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CloseHandle(IntPtr hObject);

// 权限常量定义
const uint PROCESS_VM_READ = 0x0010;
const uint PROCESS_QUERY_INFORMATION = 0x0400;

// 原有的ReadProcessMemory声明保持不变
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool ReadProcessMemory(
    [In] IntPtr hProcess,
    [In] IntPtr lpBaseAddress,
    [Out] byte[] lpBuffer,
    [In] UIntPtr dwSize,
    [Out] out UIntPtr lpNumberOfBytesRead
);

使用方式

int targetProcessId = 1234; // 替换为目标进程ID
IntPtr hProcess = OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, false, targetProcessId);

if (hProcess != IntPtr.Zero)
{
    byte[] buffer = new byte[4];
    UIntPtr bytesRead;
    bool success = ReadProcessMemory(hProcess, targetAddress, buffer, (UIntPtr)buffer.Length, out bytesRead);
    
    if (!success)
    {
        int errorCode = Marshal.GetLastWin32Error();
        // 处理错误
    }

    // 用完必须关闭句柄
    CloseHandle(hProcess);
}
else
{
    int errorCode = Marshal.GetLastWin32Error();
    // 处理打开进程失败的错误
}

2. 检查Windows 11内存完整性设置

Windows 11默认开启内存完整性(属于Windows Defender核心隔离功能),该功能会严格限制跨进程内存读取操作,尤其是针对受保护的系统进程或签名进程:

  • 打开「设置」→「隐私和安全性」→「Windows安全中心」→「设备安全性」→「核心隔离详细信息」
  • 临时关闭「内存完整性」选项,重启系统后测试程序是否正常运行
  • 若关闭后恢复正常,说明是该安全机制导致,长期解决方案需调整程序适配(如避免读取受保护进程内存)

3. 验证进程位数兼容性

如果你的程序是32位,而目标进程是64位(或反之),跨位数内存读取可能导致地址解析错误,触发ERROR_PARTIAL_COPY:

  • 在项目属性中设置程序的目标平台为x64或x86,与目标进程位数保持一致
  • 避免使用Any CPU模式,防止运行时位数不匹配

4. 确认目标内存地址有效性

错误299也可能是因为你尝试读取的内存地址本身无效(如已被释放、不属于目标进程的内存空间):

  • 先通过VirtualQueryEx函数验证目标地址是否属于目标进程的有效内存区域
  • 确保读取的内存范围未超出目标进程的可用地址空间

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 21:57:41