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

诊断CRYPT32.DLL中DPAPI.DLL的延迟导入失败问题

问题:CryptProtectData调用失败与DPAPI.DLL加载异常分析

初始问题场景

开发了一个仅调用CryptProtectData()的程序:

CryptProtectData(...);

调用返回FALSE,GetLastError()返回127(0x7F),即ERROR_PROC_NOT_FOUND。

通过PE Explorer查看发现,CryptProtectData()所在的CRYPT32.DLL会延迟导入DPAPI.DLL中的CryptProtectDataNoUI()函数,推测这是问题根源。

仅添加一行代码后执行成功:

LoadLibrary("dpapi.dll");
CryptProtectData(...);

但移除LoadLibrary()调用后,CryptProtectData()再次失败。

存在疑问:

  • 无LoadLibrary()时,调试器无DPAPI.DLL加载通知,说明CRYPT32.DLL未成功加载它,且该问题与GetProcAddress()无关(从未调用该函数)
  • 原以为不是DLL搜索路径问题,因为直接调用LoadLibrary("dpapi.dll")能成功加载
  • 询问为何CRYPT32.DLL无法加载DPAPI.DLL,以及是否有简便诊断方法(不想跟踪复杂的NTDLL.DLL.ResolveDelayLoadedAPI())

调试更新信息

初步分析显示,两种场景下LdrpLoadDllInternal()均收到"DPAPI.dll"字符串,调用栈如下:

ntdll.dll LdrpLoadDllInternal
ntdll.dll LdrpLoadForwardedDll
ntdll.dll LdrpGetDelayloadExportDll
ntdll.dll LdrpHandleProtectedDelayload
ntdll.dll LdrResolveDelayLoadedAPI
crypt32.dll CryptProtectData

LdrpLoadDllInternal()调用LdrpFastpthReloadedDll()的结果:

  • 成功场景(含LoadLibrary()):返回0,表明DLL已加载
  • 失败场景(无LoadLibrary()):返回0xC0000135(STATUS_DLL_NOT_FOUND),表明DLL未加载

测试仅调用LoadLibrary("dpapi.dll")的场景(代码#3),与失败场景对比:

  • 两者LdrpFastpthReloadedDll()均返回0xC0000135,执行继续
  • 后续调用LdrpFindOrPrepareLoadingModule(),两者均返回0xC0000135,进而调用LdrpProcessWork(),该函数调用LdrpMapDllSearchPath():
    • 代码#3中LdrpMapDllSearchPath()返回0
    • 失败场景中LdrpMapDllSearchPath()返回0xC0000135

查看LdrpMapDllSearchPath()内部,它调用LdrpSearchPath(),返回结果与前者一致。

基于此做进一步测试:

SetDllDirectory("C:\\Windows\\System32\\");
CryptProtectData(...); // 执行成功

以及

SetDllDirectory(NULL);
CryptProtectData(...); // 执行失败

确认问题与DLL搜索路径相关,但仍不清楚:

  • 具体为何搜索路径会导致该差异
  • 为何直接调用LoadLibrary()能成功加载DPAPI.DLL

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 20:43:13