我知道这个问题是前一段时间被问到的,但这里有适用于 Windows 的解决方案。
注意: 请参阅本答案的最后一部分以获取适用于其他系统和架构的解决方案。
x86 32 位文件
OllyDbg2是可用于记录每条汇编指令以及内存读取和写入的工具。下面提供了如何记录它的简短指南:
- 运行 OllyDbg。
- 选择
Options
-> Options...
(或使用Alt
+o
快捷方式)。将显示选项窗口。
- 搜索
Run trace
部分并选择下图中指定的选项:
当然,如果您不希望 Olly 记录系统 DLL 中的所有字符串指令或代码,您可以只选择两个相关的框。此外,如果要将日志转储到文件,您可以选择较小的跟踪缓冲区大小。
- 现在,打开您的目标应用程序,但先不要启动它。
- 选择
View
-> Run trace
。
- 右键单击出现的窗口,然后选择要在跟踪中使用的内存和寄存器选项。
- 再次右键单击该窗口并选择
Log to file...
选项并选择要写入整个运行跟踪的文件。
- 按
Ctrl
+F11
开始跟踪。
- 当您希望它停止时,单击暂停按钮(或
F12
)以暂停执行。
- 您将看到登录
Run trace
窗口的说明。
- 右键单击
Run trace
窗口并选择Stop logging
选项。这将关闭并保存跟踪文件。
而已!您现在可以打开并分析该文件(不过它可能会很大)。
下面给出了这样一个文件的一小段摘录(它只显示修改过的寄存器,不进入系统 DLL):
main <ModuleEntryPoint> JMP SHORT 00401012
main 00401012 MOV EAX,[DWORD DS:4F61EF] [004F61EF]=0 EAX=00000000
main 00401017 SHL EAX,2
main 0040101A MOV [DWORD DS:4F61F3],EAX [004F61F3]=0
main 0040101F PUSH EDX [0019FF80]=0 ESP=0019FF80
main 00401020 PUSH 0 [0019FF7C]=0 ESP=0019FF7C
main 00401022 CALL <JMP.&KERNEL32.GetModuleHandleA> EAX=00400000, ECX=DC5CD787, ESP=0019FF80
main 00401027 MOV EDX,EAX EDX=00400000
main 00401029 CALL 004E7210 ESP=0019FF7C
main 004E7210 MOV EAX,EDX
main 004E7212 CMP [BYTE DS:4F61E0],0 [004F61E0]=00
main 004E7219 JNE SHORT 004E7240
main 004E721B CMP [BYTE DS:4F61E1],0 [004F61E1]=00
main 004E7222 JE SHORT 004E7238
main 004E7238 MOV ECX,[DWORD DS:57D7D4] [0057D7D4]=ollydbg.0061B108 ECX=0061B108
main 004E723E MOV [DWORD DS:ECX],EAX [0061B108]=0
main 004E7240 MOV EAX,[DWORD DS:57D7D8] [0057D7D8]=ollydbg.0061B131 EAX=0061B131
main 004E7245 MOV [BYTE DS:EAX],1 [0061B131]=00
DOS 可执行文件
当您分析 DOS 可执行文件时,DOSBox Debugger将记录您想要的所有内容。
- 例如从这里下载。
- 通过将可执行文件拖放到 DOSBox 调试器图标上来启动应用程序。
- 在您想要开始记录执行跟踪的那一刻按
Alt
+ Pause
- 应用程序将冻结。
- 切换到调试器窗口。你会看到这样的事情:
- 类型
logl n
,其中n
是要记录的(十六进制)指令数;例如:logl ffff
。
- 日志文件已经创建,应该与 DOSBox 调试器位于同一目录中 - 它会有
LOGCPU.txt
名字。
下面给出了几行结果文件:
01A2:00004654 mov ax,si 8B C6 EAX:0000002A EBX:0000002A ECX:00000A00 EDX:00000000 ESI:00000004 EDI:00000004 EBP:0000FFE2 ESP:0000FFDE DS:26EF ES:A000 FS:0000 GS:0000 SS:26EF CF:1 ZF:0 SF:1 OF:0 AF:1 PF:1 IF:1 TF:0 VM:0 FLG:00007293 CR0:00000000
01A2:00004656 mov dx,000E BA 0E 00 EAX:00000004 EBX:0000002A ECX:00000A00 EDX:00000000 ESI:00000004 EDI:00000004 EBP:0000FFE2 ESP:0000FFDE DS:26EF ES:A000 FS:0000 GS:0000 SS:26EF CF:1 ZF:0 SF:1 OF:0 AF:1 PF:1 IF:1 TF:0 VM:0 FLG:00007293 CR0:00000000
01A2:00004659 imul dx F7 EA EAX:00000004 EBX:0000002A ECX:00000A00 EDX:0000000E ESI:00000004 EDI:00000004 EBP:0000FFE2 ESP:0000FFDE DS:26EF ES:A000 FS:0000 GS:0000 SS:26EF CF:1 ZF:0 SF:1 OF:0 AF:1 PF:1 IF:1 TF:0 VM:0 FLG:00007293 CR0:00000000
01A2:0000465B mov bx,ax 8B D8 EAX:00000038 EBX:0000002A ECX:00000A00 EDX:00000000 ESI:00000004 EDI:00000004 EBP:0000FFE2 ESP:0000FFDE DS:26EF ES:A000 FS:0000 GS:0000 SS:26EF CF:0 ZF:0 SF:1 OF:0 AF:1 PF:1 IF:1 TF:0 VM:0 FLG:00007296 CR0:00000000
01A2:0000465D cmp word [bx+56F6],0001 ds:[572E]=0000 83 BF F6 56 01 EAX:00000038 EBX:00000038 ECX:00000A00 EDX:00000000 ESI:00000004 EDI:00000004 EBP:0000FFE2 ESP:0000FFDE DS:26EF ES:A000 FS:0000 GS:0000 SS:26EF CF:0 ZF:0 SF:1 OF:0 AF:1 PF:1 IF:1 TF:0 VM:0 FLG:00007296 CR0:00000000
01A2:00004662 jne 00004678 ($+14) (down) 75 14 EAX:00000038 EBX:00000038 ECX:00000A00 EDX:00000000 ESI:00000004 EDI:00000004 EBP:0000FFE2 ESP:0000FFDE DS:26EF ES:A000 FS:0000 GS:0000 SS:26EF CF:1 ZF:0 SF:1 OF:0 AF:1 PF:1 IF:1 TF:0 VM:0 FLG:00007296 CR0:00000000
01A2:00004678 inc si 46 EAX:00000038 EBX:00000038 ECX:00000A00 EDX:00000000 ESI:00000004 EDI:00000004 EBP:0000FFE2 ESP:0000FFDE DS:26EF ES:A000 FS:0000 GS:0000 SS:26EF CF:1 ZF:0 SF:1 OF:0 AF:1 PF:1 IF:1 TF:0 VM:0 FLG:00007296 CR0:00000000
每个或几乎每个架构和系统
radare2是可用于您的目的的工具,无论系统和架构如何(此处提供了它们的完整列表)。
- 运行
r2 -c aei -d programToDebug
。
- 在要开始跟踪的地址处放置一个断点(
db address_in_hex
例如使用)。
- 运行
dc
以继续,直到遇到断点。
- 键入
e dbg.trace=1
并按回车键。
- 运行
des N
到步骤N
说明(例如des 10
)。
- 使用
dtd > log1
打印追溯到说明log1
文件。
- 使用
dte > log2
打印所有存储器和寄存器访问log2
文件。这些文件的示例内容如下:
说明:
以及一些相应的内存访问:
当然,以 OllyDbg 那样的方式列出这些输出会更好,但它只需要编写一个脚本将这两个文件链接在一起并以更方便的方式显示信息。像这样,例如:
此处提供了用于从这些文件创建此类输出的 Python 脚本。用法:
./prettyTraceLog.py file1 file2
, 其中log1
和log2
是默认值。如果您发现任何错误,或者由于其他原因想要修改它,请随时进行。
感谢@pancake 告诉我如何在radare2
.