调试/故障排除没有源代码的Windows应用程序

时间:2014-05-30 17:34:43

标签: assembly windbg debug-symbols symbol-server

几天前我在工作中遇到了这个问题,我想知道是否有办法从场景中获取更多数据,而不是去微软。有很多这样的情况,我想探索一下,作为一个Windows开发人员,获取大部分信息的最佳/最佳方式就是这种情况。我将描述这种情况:

1)Office应用程序在使用某些设置进行打印时涉及cmyk颜色空间,会引发一个对话框错误,该错误描述不正确。“文件%s因某些其他应用程序被锁定而无法打开”。它不提供文件名,也不提供事件查看器。打印中止。

2)在使用“procmon”时,我们在几个文件中发现“文件锁定错误”,当api“CreatefileMapping”被办公室应用程序,假脱机程序,splwow64.exe等涉及的进程调用时(是的,它是64位)系统和应用程序是32位)。

3)当没有涉及splwow64时问题不存在,意味着在64位操作系统上使用64位应用程序。

我想知道哪些工具对于在这种情况下获取更多信息非常有用。这包括在需要时使用带有windbg的MS符号和调试程序集。基本上我需要锁定的文件名,显示为%s和问题的根源。

谢谢, 考希克

1 个答案:

答案 0 :(得分:3)

没有源代码和没有符号的调试很难。采取的方法因您可以观察到的内容和您可以做出的假设而有很大差异。以下听起来对你的情况来说是合理的。

将64位文件访问与32位版本

进行区分

由于64位版本有效,请查看文件访问的区别。您可以将Process Monitor日志导出为CSV并编写一个分析文件访问的工具。您的分析工具应该

  • 将具有不同偏移量的多个文件读取访问汇总到整个文件的单个文件访问。
  • 忽略阅读顺序,因为顺序似乎不太重要。
  • 首先忽略DLL

也许你甚至可以在Excel中做到这一点。

捕获文件访问调用

首先,我认为使用Process Monitor已经是一个很好的方法。您可以在不了解应用程序的情况下找出应用程序正在执行的操作,因此这将是我的首选。

当然,很难缩小相关文件列表的范围。如有必要,您需要完成所有这些操作,例如在批处理文件的帮助下,找到一个命令行工具,可以帮助查找已打开文件的应用程序。在这种情况下,请查看SysInternals Handle。它是一个命令行实用程序,您可以为其指定文件名。基本上,它是Process Explorer的DOS版本(见下文)。

读取文件和编写文件通常是通过API调用完成的,因此API Monitor是另一种选择。筛选可疑的所有文件访问方法(ReadFile,ReadFileEx,LockFile,LockFileEx,WriteFile,WriteFileEx,...)。

这也可以通过设置断点在WinDbg中实现,但是您可能经常使用它们,因此处理它们可能需要一些自动化。您可以为bp命令指定命令字符串。

幸运

可能会发生用作%s格式字符串参数的文件名在内存中的某处。

  1. 在应用程序显示消息时进行故障转储
  2. 使用SysInternals Strings实用程序转储转储的所有字符串。
  3. 直接输出C:\D:\等输出,方法是将其输出到find命令或将其重定向到文本文件以供日后分析
  4. 这仍然会给你留下很多文件,所以找到罪魁祸首并不比以前的方法容易多了。再次,使用其他工具缩小列表范围,例如: handle

    1. 在应用程序显示消息时进行故障转储
    2. 在WinDbg中打开转储
    3. 转储您在堆栈中找到的某些地址的字符串。由于NTFS中的文件名是Unicode,du <address>在这里应该可以正常工作。
    4. 这绝对需要更多关于内部资料的知识,例如:哪里可以找到好的指针等。

      分析第一次机会例外

      如果应用程序依赖于异常,您可以通过检查第一次机会异常来获得一些洞察力。但是,如果应用程序执行了良好的前置条件检查,则会有更少的异常,从而降低了获取有用内容的机会。

      如果情况再现良好,你可以

      1. 使用Image File Execution Options将WinDbg设置为该流程的调试程序。
      2. 使用.logopen /t /u c:\firstchanceexceptions.log
      3. 打开日志文件
      4. 使用sxe -c ".exr -1;k;g" *转储所有例外。该命令中的g将立即继续,以便应用程序(希望)不会遇到超时。
      5. 继续执行g
      6. 当应用程序终止时,使用.logclose
      7. 关闭日志文件
      8. 查看日志文件以查找有趣的异常/有趣的调用堆栈
      9. 重现错误但此次停止有趣的例外
      10. 查看方法参数和内存是否找到文件名(再次使用du <address>
      11. 查找属于消息框的应用程序

        如果您无法确定哪个应用程序显示错误消息,例如由于消息标题不好,请执行以下操作:

        1. 下载SysInternals Process Explorer并运行它。

        2. 将十字线从工具栏上拖过窗口。

        3. Process Explorer现在突出显示拥有该窗口的可执行文件

        4. 如果打印文件名,则查找锁定应用程序

          如果对话框显示文件名而不仅仅是“%s”:

          1. 还使用Process Explorer

          2. 使用查找/查找句柄或DLL或按Ctrl + F

          3. 键入文件名或文件名部分