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

Getting detailed version information of the executed program

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

lm 虚拟机应用程序名称

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

如果你不知道如何获取可执行文件的版本信息,你可以google一点,得到this answer,这表明

lm vm appname (without .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 信息。

可以做出的假设:

正如 Jeroen Mostert 在评论中提到的,合适的命令可能是

lmv a $exentry

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

你在伪寄存器语法中找到描述:

$exentry: The address of the entry point of the first executable of the current process.

[来源: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();
        }
    }
}