获取已执行程序的详细版本信息

时间:2019-05-23 13:22:55

标签: windbg

我正在尝试从故障转储中获取可执行文件的版本信息。这不是那么简单,所以请在阅读不正确的答案之前先阅读整个问题。

lm vm appname

基本上,我可以执行lmv来获取版本详细信息,而这正是我想要的信息。

如果您不知道如何获取可执行文件的版本信息,则可以在Google上搜索一下并获得this answer,这表明

  

lm vm appname(不带.exe)

这可能在90%的情况下有效。但是,它具有以下两个问题,我需要在自动分析中解决:

  1. 如果我事先不知道可执行文件,appname是什么?
  2. 在诸如Notepad ++之类的特殊情况下,模块名称不是notepad++而是notepad__

现在,我可以使用|找出可执行文件的名称,但是从输出中提取可执行文件的名称并不容易。

在模块列表中找到exe

可以使用以下命令在模块列表中找到可执行文件

.shell -ci "lmf" findstr "\.exe"

然后我们可以提取地址并使用

列出详细信息
.foreach /ps 9999 (exe {.shell -ci "lmf" findstr "\.exe"}) {lmva exe}

仍然存在问题:.NET进程可以加载不是DLL而是EXE的程序集。在这种情况下,如果第一个结果不是主可执行文件,而是稍后加载的EXE,则输出可能是错误的。

模块列表

可以使用lm1m获取模块列表。通常,该列表中的第一个是可执行文件。

然后可以提取第一行并获取其详细信息。命令看起来像

.foreach /ps 9999 (exe {lm1m}) { lm vm ${exe}}

不幸的是,不能保证可执行文件是第一个模块。模块按地址排序。恕我直言,可能会将可执行文件加载到更高的地址。

问题

如何可靠地获取主要可执行文件的lmv信息。

可以做出的假设:

    类型为/ma
  • 用户模式故障转储
  • 仅调试一个进程

1 个答案:

答案 0 :(得分:0)

Jeroen Mostert的评论中所述,合适的命令可能是

lmv a $exentry

之所以可行,是因为lm足够聪明,可以接受模块内的地址。 $exentry给出第一个可执行文件的入口点。

您可以使用伪寄存器语法找到描述:

  

$ exentry:当前进程的第一个可执行文件的入口点的地址。

[来源:WinDbg帮助]

对于C#部分,我们可以使用以下代码进行测试:

using System;
using System.IO;
using System.Reflection;

namespace exentry
{
    class Program
    {
        static void Main()
        {
            var fullExe = Assembly.GetEntryAssembly().Location;
            var path = Path.GetDirectoryName(fullExe);
            var newexe = Path.Combine(path, "exentry2.exe");
            File.Copy(fullExe, newexe);

            Assembly.LoadFrom(newexe);
            Console.WriteLine("Debug now");
            Console.ReadLine();
        }
    }
}