我有一个调用CreateProcess
的过程。似乎CreateProcess
返回非零表示成功。但是,然后立即设置该过程的HANDLE,表示该过程已退出。当我打电话给GetExitCodeProcess
时,然后返回STATUS_DLL_NOT_FOUND
。
我知道DLL丢失了。我甚至知道究竟是哪一个。但是,我不明白的是如何以编程方式解决这个问题。
我注意到Windows将显示一个对话框,说明该进程无法启动,因为它无法找到指定的DLL(屏幕截图:http://www.mediafire.com/view/?kd9ddq0e2dlvlb9)。在对话框中,Windows指定缺少哪个DLL。但是,我发现无法以编程方式自行获取该信息。
如果进程无法启动并返回STATUS_DLL_NOT_FOUND
,如何以编程方式检索目标进程所链接的库名称,该名称无法找到?这样我就可以在错误报告中自动记录在给定安装中DLL似乎丢失或损坏的内容。
CreateProcess返回0表示成功。
CreateProcess()
返回BOOL
,其中0是FALSE
,又名失败并不成功。
如果进程无法启动并返回STATUS_DLL_NOT_FOUND,如何以编程方式检索目标进程所链接的库名称,该名称无法找到?
不幸的是,没有API。您唯一的选择是手动访问和枚举可执行文件的IMPORTS
表以找出它使用的DLL,然后递归访问和枚举它们的IMPORTS
表,手动检查您找到的每个DLL引用,以查看操作系统搜索中是否存在该DLL文件路径与否。
如果dll是静态链接的,你可以走iat并查看dll是否存在。如果dll是动态加载的,那么启动进程挂起并挂钩LoadLibrary(或者不是挂钩模拟调试器)是我看到的唯一方法。
非常困难的方法是:解析.EXE和.DLL文件并创建.DLL文件的依赖关系树。
我认为没有办法获取丢失的DLL文件列表:当Windows找到一个丢失的DLL文件时,它会停止加载,因此如果缺少一个DLL文件,您将无法找到是否缺少更多的DLL文件。
您可能遇到的另一个问题是旧的DLL版本可能缺少“导出”(函数)。这比依赖树更难检测。
在另一篇文章中找到答案:https://stackoverflow.com/a/475323/358006
它说使用Visual Studio命令提示符(在工具中)和命令:
dumpbin /dependents my-app.exe
最好的方法是使用装载机快照。基本上你使用gflags.exe(windbg附带)来启用加载器快照;然后,运行附加调试器的过程。 Loader快照将使加载程序能够打印出进程的dbg消息,并将打印出故障。
gflags.exe -i yourcode.exe +sls
windbg yourcode.exe
我知道这不是找出问题的“程序化”方法,但是加载器的作用很复杂,而且你真的不想重做它的逻辑来找到失败。这就是发明装载机快照的原因。