获取执行程序的详细版本信息
Getting detailed version information of the executed program
我正在尝试从故障转储中获取可执行文件的版本信息。这不是那么简单,所以在你想出一个不起作用的答案之前,请阅读整个问题。
lm 虚拟机应用程序名称
基本上我可以lmv
获取版本详细信息,这正是我想要的信息。
如果你不知道如何获取可执行文件的版本信息,你可以google一点,得到this answer,这表明
lm vm appname
(without .exe)
这可能适用于 90% 的情况。但是,它有以下两个问题,我想在自动分析中解决:
- 如果我事先不知道可执行文件,
appname
是什么?
- 在像 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
类型的用户模式故障转储
- 只有一个进程正在调试
正如 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();
}
}
}
我正在尝试从故障转储中获取可执行文件的版本信息。这不是那么简单,所以在你想出一个不起作用的答案之前,请阅读整个问题。
lm 虚拟机应用程序名称
基本上我可以lmv
获取版本详细信息,这正是我想要的信息。
如果你不知道如何获取可执行文件的版本信息,你可以google一点,得到this answer,这表明
lm vm appname
(without .exe)
这可能适用于 90% 的情况。但是,它有以下两个问题,我想在自动分析中解决:
- 如果我事先不知道可执行文件,
appname
是什么? - 在像 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
类型的用户模式故障转储
- 只有一个进程正在调试
正如 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();
}
}
}