【加密与解密】第二章④

调试过程

WDG支持多种调试模式,既可以以打开,附加的方式调试应用,也可以分析Dump文件,还可以进行远程调试,内核调试。内核调试分为NET,USB,1394,COM和本地调试,前四种是双机调试,名称指明了双机间的连接方式。附加进程时的非入侵模式调试,Dump文件调试,本地内核调试都是非实时调试模式,不能直接控制应用的中断与执行,一般用来观察内存,分析数据结构,也可以修改内存数据。本节介绍应用层实时调试。

1.开始调试

按ctrl+e可以打开一个应用程序并指定运行参数进行调试。按f6可以从对话框中选择当前运行的附加进程进行调试。
WDG调试程序的时候,反汇编代码默认停留在ntdll.dll系统断点处,不会停在程序入口处可以在命令窗口输入指令“g@exentry”转到程序入口处。

2.控制目标程序执行命令

快捷键如下。

伪寄存器\(ra代表当前函数的返回地址,所以一部分pa或者ta命令加上@\)ra走出当前函数,即“pa $ra”。
可以举一个例子。pc和tc指令用于执行到下一个call指令。count指的是遇到call指令的个数,假设count的值是3,那就是遇见到第三个call指令为止。这两者的区别就是tc是遇到call指令就进入,pc不会。如果count为1,而且当前的指令不是call,那么两者等价。

断点指令

1.软件断点

WDG有三条命令用于设置软件断点(int3),分别是bp,bu和bm。bp指令最常用。格式如下


bu命令是对某个符号下断点,例如“bu kernel32!GetVersion”,bu所设断点是与符号关联,如果符号地质改变,断点还是会与原符号保持联系。bp命令所设断点与地址联系,假设地址的内容发生变化,断点还是在这个地址。而且bu断点会自动保存,下次启动会自动设置断点。
bm支持设置含通配符。(通配符:包含“”,“?”,简单来讲用途就是当我们要找一个文件但是不记得全部,只记得他是print开头时,就可以print来查找)bm可以以此创建一个或者多个bu或bp断点。比如我们想要对msvcr80d模块中所有以print开头的函数设断,命令就是bm msvcr80d!print*
值得注意的是如果我们想要设置断点bp kernel32!GetVersion,直接设置会显示无效,是因为没有加载kernel32符号文件,所以要先运行ld kernel32用lm指令查看符号加载的情况,再运行bp kernel32!GetVersion"r eax"程序就会中断后显示eax的情况。

2.硬件断点

数量有限,但可以实现软件断点无法实现的功能,例如监视I/O访问。命令设置如下。

软件断点理论可以设置无数个,但出于性能考虑,WDG在内核态最多是支持32个软件断点,用户态支持任意。硬件断点取决于处理器,例如x86支持4个断点。设置软件断点需要修改相应代码,所以不能挑食flash和rom的只读代码,而硬件断点没有限制。

3.条件断点

软件断点和硬件断点都支持条件断点。格式如下,两者等价。

如下有一个实例。

这是一条不完备的命令。目的就是要在GetVersion检测eax寄存器,如果他的值是0x12ffc4就中断,否则使用gc继续。但是不完备体现于在内核态,MASM会对eax中的值进行符号扩展,就会变成“0xFFFFFFFFc012ffc4”这时就可以用“&”对eax高位清零。
如下

4.管理断点

使用bl列出当前断点,命令bc,bd和be分别用来删除禁止和启用断点。断点号可以用通配符匹配

栈窗口

观察和分析栈是重要的调试手段。
因为call指令会将函数的返回地址记录在栈内,所以可以遍历栈帧来追溯函数调用过程。使用WDG的k系列指令可以查看栈回溯(通过回溯栈帧)。栈命令格式就是“k[b|p|P|v|d]”区分大小写。
打开esp.exe,按“F8”单步到相应的call函数,一直到0040115Eh处,执行相应的k指令。如下

运行基本k命令。结果清单如下。

清单每一行都描述当前线程的一个栈帧,00行描述的是当前中断所在的函数(call),01行描述的是调用00行中函数的上一级函数,以此类推,以横向来看,第一列是栈帧的基地址,因为x86系统用EBP寄存器来记录栈帧的基地址,为“ChildEBP”,第二列为函数的返回地址,这个地址是调用本行函数那个条call指令的下一条指令的地址(简单来讲就是出来的那一行地址),对三列是函数名和执行位置。

kb与k命令的区别在于中间的三列是子函数的参数,分别是是ebp+8h,ebp+Ch,ebp+10h,要是要第四个,就执行“dd ebp+14h”查看。

内存命令

内存存放数据和代码

1.查看内存

d命令用于显示指定地址的内存数据,格式如下

2.搜索内存

s命令可以在指定范围搜索字符串。


例如s -u 400000 40300"pediy"表示在40000h和403000h之间搜索pediy,s -a 0x00000000 L?7fffffff mytest实在目标孔建伟2gb的usermode内存空间搜索mytest,对应上面两种搜索格式。

3.修改内存

e命令用于修改指定的内存数据,有两种格式,一个是按照字符串

za和zu指的是ASC2和Unicode字符串且以玲姐为,a和u表示不以零结尾。例如eza 298438“pediy”表示在298438h写上字符串“pediy”以零结尾。
另一个以数值编辑

a为ASC,b为BYTE,d为DWORD,D为DOUBLE,f为FLOAT,q为8字节,u为Unicode,w为Word,例如“eb 298438 70 65 64 69 79”与上面同义。

4.观察内存属性

是“!address”显示指定内存的内存属性。

脚本

WDG脚本是一种语言。WDG作为解释器执行脚本里的语句。运行.echo"Hello,World!,会显示“Hello,World!”,将之村委c:\test.txt然后在WDG输入$$><c:\test.txt,就会显示结果。

1.伪寄存器

用于脚本命令中作为临时变量使用。在表达式中使用伪寄存器必须加转义字符“@”。

posted @ 2023-01-03 15:05  Corax0o0  阅读(87)  评论(0编辑  收藏  举报