如果可能的话,我希望使用一种在Windows和Linux以及不同类型的CPU上均可使用。
目前性能并不重要,即调试器脚本可以。
我尝试了几件事,但没有设法得到想要的东西:具有内容的访问(有诸如
idc.GetTevRegMem
之类的晦涩功能(请参见此处),但要达到我的目标,事情变得非常复杂。 > GDB:由于无法使用观察点,因此无法选择目前,PANDA似乎是最有前途的选择(请参见PANDA作者的评论)。 PANDA因此无法确定创建合适的PANDA插件会变得多么复杂。例如,一些调试器脚本代码行,一个PIN工具(仅Intel)或一个qemu参数等。
#1 楼
我知道这个问题是在不久前提出的,但是在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可执行文件
DOSBox调试器将在分析DOS可执行文件时记录您想要的所有内容。
例如,从此处下载它。
通过将可执行文件拖放到DOSBox Debugger图标上来启动应用程序。
要开始记录执行跟踪时,按
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
并按Enter。运行
des N
到步骤N
指令(例如des 10
)。使用
dtd > log1
打印追溯到log1
文件的指令。 使用
dte > log2
打印所有内存并注册对log2
文件的访问。这些文件的示例内容如下:
说明:
q 4312010q
和一些相应的内存访问:
当然,最好以OllyDbg的方式列出这些输出,但是需要编写一个脚本,将这两个文件链接在一起,并以更方便的方式显示信息。例如,例如:
可从这些文件创建此类输出的Python脚本在此处提供。用法:
./prettyTraceLog.py file1 file2
,其中
log1
和log2
是默认值。如果您发现任何错误,或由于其他原因想要对其进行修改,请随时执行。感谢@pancake告诉我如何在
radare2
中进行跟踪。
评论
我肯定会使用DBI框架。 PIN可以轻松做到这一点(尽管您只能使用x86 / x64)。检查pinatrace示例源。使用PIN_SafeCopy(在示例中未使用)访问内存,您就完成了。我也想到了DBI,但是PIN(和DynamoRIO)无法跟踪内核空间访问。
您可以查阅这份(PDF)论文报告,特别是第3章
@ExtremeCoders谢谢,他们也正在使用PANDA。如果所有人都想要:不同的CPU,内核+用户空间,不同的操作系统,这似乎真的是可行的方法。
由于valgrind是开源的,所以我想在--trace-mem = yes输出中添加内存内容不会太难。