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

RegSetValueEx返回998(ERROR_NOACCESS),内存访问无效问题排查

RegSetValueEx返回ERROR_NOACCESS(998)的问题排查与修复

核心问题:数据长度参数错误

你调用RegSetValueEx时最后一个参数传了0,这是致命错误。对于REG_SZ类型的宽字符串(WCHAR),cbData参数必须指定包含终止符\0在内的总字节数。系统需要这个长度来正确读取字符串内容,传0的话,系统会尝试读取无效的内存区域,直接触发ERROR_NOACCESS。

正确的长度计算方式是:(wcslen(path) + 1) * sizeof(WCHAR),其中+1是为了包含末尾的宽字符终止符。

次要问题:权限与错误检查缺失

  • 注册表权限过度申请:用KEY_ALL_ACCESS打开HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run完全没必要,普通用户甚至会因为权限不足导致RegOpenKeyExW失败,后续操作无效的键句柄也会引发异常。只需要申请KEY_SET_VALUE权限即可满足写入需求。
  • 无错误检查:代码里没检查VirtualAlloc、GetModuleFileNameW、RegOpenKeyExW的返回值——如果这些操作失败,后续使用无效指针或键句柄都会导致未定义行为,包括内存访问错误。

修复后的代码示例

LPWSTR path = (LPWSTR)VirtualAlloc(nullptr, MAX_PATH * 2 * sizeof(WCHAR), MEM_COMMIT, PAGE_READWRITE); 
if (!path) {
    // 处理内存分配失败
    return;
}

DWORD copyLen = GetModuleFileNameW(nullptr, path, MAX_PATH);
if (copyLen == 0 || copyLen == MAX_PATH) {
    // 处理路径获取失败或路径被截断
    VirtualFree(path, 0, MEM_RELEASE);
    return;
}

HKEY key;
LSTATUS openStatus = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", 0, KEY_SET_VALUE, &key);
if (openStatus != ERROR_SUCCESS) {
    // 处理注册表键打开失败(比如权限不足)
    VirtualFree(path, 0, MEM_RELEASE);
    return;
}

DWORD dataSize = (wcslen(path) + 1) * sizeof(WCHAR);
LSTATUS return_value = RegSetValueExW(key, RandName(), 0, REG_SZ, (BYTE*)path, dataSize); 

RegCloseKey(key);
VirtualFree(path, 0, MEM_RELEASE);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 12:12:24