我有一个保存为原始二进制文件的运行内存转储。这不是一个独立的可执行文件——它实际上只是运行内存的快照。
我正在寻找一种工具来帮助我识别这个二进制文件中的汇编指令。有这样的工具吗?
我知道你可以使用 OllyDebug 或 IDAPRO 来分析可执行文件。然而,由于这是一个完整的内存转储,我不清楚这些工具是否仍然适用。对于原始内存转储,没有 IDA 可以开始的明确入口点。
任何建议都会非常有帮助。谢谢!
我有一个保存为原始二进制文件的运行内存转储。这不是一个独立的可执行文件——它实际上只是运行内存的快照。
我正在寻找一种工具来帮助我识别这个二进制文件中的汇编指令。有这样的工具吗?
我知道你可以使用 OllyDebug 或 IDAPRO 来分析可执行文件。然而,由于这是一个完整的内存转储,我不清楚这些工具是否仍然适用。对于原始内存转储,没有 IDA 可以开始的明确入口点。
任何建议都会非常有帮助。谢谢!
您可以在 WinDbg 中的任何内存地址进行反汇编,例如
0:067> db 000007fe`ff4d0000
000007fe`ff4d0000 4d 5a 90 00 03 00 00 00-04 00 00 00 ff ff 00 00 MZ..............
000007fe`ff4d0010 b8 00 00 00 00 00 00 00-40 00 00 00 00 00 00 00 ........@.......
000007fe`ff4d0020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
000007fe`ff4d0030 00 00 00 00 00 00 00 00-00 00 00 00 e0 00 00 00 ................
000007fe`ff4d0040 0e 1f ba 0e 00 b4 09 cd-21 b8 01 4c cd 21 54 68 ........!..L.!Th
000007fe`ff4d0050 69 73 20 70 72 6f 67 72-61 6d 20 63 61 6e 6e 6f is program canno
000007fe`ff4d0060 74 20 62 65 20 72 75 6e-20 69 6e 20 44 4f 53 20 t be run in DOS
000007fe`ff4d0070 6d 6f 64 65 2e 0d 0d 0a-24 00 00 00 00 00 00 00 mode....$.......
0:067> u 000007fe`ff4d0000 L1
advapi32!WmipBuildReceiveNotification <PERF> (advapi32+0x0):
000007fe`ff4d0000 4d5a pop r10
但是正如您所看到的,这或多或少是无用的(在我的示例中,对于反汇编MZ
DLL 标头的魔术字节是无用的)。
因此,找到正确的拆卸起点是关键部分。
代码应该主要在 DLL 或 EXE 中(在 WinDbg 中称为图像或模块)。要在内存转储(内核或用户模式)中找到它们,您可以运行 WinDbg 命令
.imgscan
从 WinDbg 帮助:
.imgscan 命令扫描虚拟内存中的图像头。
.imgscan 命令显示它找到的任何图像标题和标题类型。标头类型包括可移植可执行 (PE) 标头和 Microsoft MS-DOS MZ 标头。
我能够在用户模式下验证这一点,但是使用我目前唯一的 Windows XP 内核模式转储,它不会输出任何内容。
用户模式转储的示例输出:
MZ at 000007fe`ff4d0000, prot 00000004, type 00020000 - size db000
Name: ADVAPI32.dll
因此,获取 DLL 的所有必要信息都可用。如果我使用了用户模式转储
.writemem <FileName> <Range>
将 DLL 写入磁盘并稍后分析。
<Range>
是根据地址和范围语法,例如
.writemem advapi32.dll 000007fe`ff4d0000 Ldb000
这可能不适用于内核模式转储,因为模块的某些部分可能已交换到磁盘,因此内存中的 DLL 不再完整。
这种方法也不会找到即时生成的代码。
可以执行的代码必须驻留在executable
设置了标志的内存块中。
不幸的是命令
!address -f:<filter>
在 WinDbg 6.2.9200 中已损坏。它应该在用户模式转储中工作并输出可执行的起始和结束地址列表。
目前我只得到
0:067> !address -f:PAGE_EXECUTE
BaseAddress EndAddress+1 RegionSize Type State Protect Usage
------------------------------------------------------------------------------------------------------------------------
0:067> !address -f:PAGE_EXECUTE_READ
Invalid filter arguments. Type !address -? to get the list of supported parameters
0:067> !address -f:PAGE_EXECUTE_READWRITE
Invalid filter arguments. Type !address -? to get the list of supported parameters
0:067> !address -f:PAGE_EXECUTE_WRITECOPY
Invalid filter arguments. Type !address -? to get the list of supported parameters
虽然我有一个完整的内存转储
0:067> .dumpdebug
...
Flags 40002
0002 MiniDumpWithFullMemory
40000 MiniDumpWithTokenInformation
但是你明白了这个想法,也许可以将它应用到其他工具中。
如果您知道处理器类型以及它的小端或大端,您可以搜索函数中使用的常见操作码。
例如在 x86 中,常见的有:
push ebp
mov ebp, esp
add esp ...
它是二进制的 55 8B EC 83 C4,然后在转储中搜索它。
如果您会发现包含高密度操作码的区域,则它可能是代码。