如何使用 ProcMon 检查 Win32 CreateProcess() 失败的原因。排除 GetLastError()

Posted

技术标签:

【中文标题】如何使用 ProcMon 检查 Win32 CreateProcess() 失败的原因。排除 GetLastError()【英文标题】:How to check Win32 CreateProcess() failed reason using ProcMon. exclude GetLastError() 【发布时间】:2020-03-17 10:36:35 【问题描述】:

我在检查 CreateProcess() 失败原因时遇到问题,生产中的代码在 CreateProcess() 失败时不记录 GetLastError() 所以我正在运行 ProcMon 来检查原因但无法找到原因(procMon 是否会记录失败原因,例如“C:\dummy.exe 路径未找到或权限被拒绝”?)。

有没有办法(工具?)在不考虑 GetLastError() 的情况下检查 CreateProcess() 失败的原因?

我无法调试客户环境(无法访问我),但我可以更改代码并提供新版本,并且由于流程原因需要很长时间。我目前正在寻找可用的快速选项。以下是示例代码,不是确切的生产代码。

int main()

    STARTUPINFO info =  sizeof(info) ;
    PROCESS_INFORMATION processInfo;

    TCHAR dymmypath[_MAX_PATH] = _T("C:\\dummy.exe");
    static TCHAR TempPathString[_MAX_PATH];

    STARTUPINFO         si =  sizeof(si) ;        //default set up
    PROCESS_INFORMATION pi;                     //data structure for CreateProcess

    si.dwFlags = STARTF_USESHOWWINDOW;
    si.wShowWindow = SW_SHOWMINIMIZED;

    if (!CreateProcess(dymmypath, NULL, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, TempPathString, &si, &pi))
    
        printf("Failed");
    
    else 
        printf("Success");
    

    return 0;

【问题讨论】:

你不能只附加一个调试器吗? @tenfour 已在生产环境中发布版本。 发布版本仍然可以调试。在kernel32!CreateProcessW上设置断点,跳出,查看错误码。 @RbMm "" 不是有效路径 @tenfour - 是的,无效。并且使用此代码调用必须总是 失败并出现文件名、目录名或卷标语法不正确。 错误。但我只说TempPathString 实际上是零初始化的。不是说这个正确 【参考方案1】:

我正在运行 ProcMon 来检查原因,但找不到原因(procMon 会记录失败原因,例如“C:\dummy.exe 路径未找到或权限被拒绝”吗?)。

仅当请求到达文件系统时,即查找 EXE 文件,在您的情况下,它听起来好像没有这样做,可能是因为 CreateProcess() 在到达文件系统之前无法验证您的输入参数.

有没有办法(工具?)在不考虑 GetLastError() 的情况下检查 CreateProcess() 失败的原因?

正如其他人所说,您可以尝试将调试器附加到正在运行的应用程序,并在 CreateProcess 函数本身中放置一个断点。

另一种选择是使用API Monitor 之类的工具,它会向您显示您的程序进行的实际 API 调用、它们的参数值是什么、报告的错误代码等。

我无法调试客户环境(无法访问我),但我可以更改代码并提供新版本

那是你应该做的。修复您的代码以正确记录错误代码,不要再忽略它们。

由于处理需要很长时间。

嗯,那是你自己的错,因为你没有更好地优化你的构建过程,或者把你的应用分解成更易于管理的部分,等等。

【讨论】:

【参考方案2】:

乍一看,我看到TempPathString 被初始化为"",这不是一个有效的路径。因此,当您解决该问题时,您就有机会添加适当的错误处理。

您正在寻找的工具是调试器。你应该附加你选择的调试器,在CreateProcess的返回上设置一个断点,然后检查那里的错误。

除了调试和错误处理(记录等)之外,您还必须发挥创造力。例如,将工作环境与生产环境进行比较。

【讨论】:

调试器,是 WinDbg 还是 Visual Studio 调试器? @NDestiny 都可以。如果您想避免在生产系统上安装 Visual Studio,WinDbg 的重量会更轻。但听起来你有能力只更改代码,所以一个选项是构建足够的错误处理,如果这很麻烦,你不需要调试器。 TempPathString 初始化为 0,因为它是静态的。当然,如果这段代码完全相关 如果您无法调试,也无法更改代码,那么您就是在问不可能。如果它在其他环境中工作,但至少你有一个做最后手段的起点:随机猜测和测试。接下来,您将告诉我们您无权访问 repro :D “那你问的是不可能的事”——这就是说别无他法

以上是关于如何使用 ProcMon 检查 Win32 CreateProcess() 失败的原因。排除 GetLastError()的主要内容,如果未能解决你的问题,请参考以下文章

在 win32 服务 (C++) 中生成 casablanca http_listener 的问题

如何检查用户是不是在win32中具有本地管理员权限

如果某个任务正在任务管理器中运行,我如何在 python 中使用 pywin 或 win32com.client 检查?

选择/取消选择所有复选框 WIN32

win32 api - 如何检查远程机器上的用户权限

[No000017F]如何监控注册表的修改