分类: 网络与安全
2011-05-04 10:53:53
第3章 动态分析技术
第二节 SoftICE与TRW2000操作入门
由于TRW2000命令和操作完全兼容SoftICE,因此如不特殊说明,在本文对SoftICE的叙说都适合TRW2000。
SoftICE的所有操作都发生在一个可以随时可激活的调试窗口中,在这个窗口中可以监视Windows应用程序和系统的运行。
一、 调试窗口简介
我们假设你的SoftICE己经正常运行,此时在Windows里按"Ctrl+D"键就可以呼出SoftICE的调试窗口,当需要返回到
Windows系统时,再按"Ctrl+D"键,也可使用X命令或按F5键。激活的调试窗口如图2.14所示,分为寄存器窗口、数据窗口、代码窗口、浮点
窗口和命令窗口等部分。
如是在TRW2000环境下,激活是按"CTRL+N",和SoftICE不同的是TRW2000中没有浮点窗口,不过有一个堆栈窗口。
(图一)SoftICE或TRW2000调试截图
1、寄存器窗口
在这里可以观察到各种寄存器的当前值,如数据寄存器EAX、EBX、ECX、EDX和控制寄存器(EIP和PSW)等,
有一点要注意了,由于我们是在Windows平台下,所以看到的都是80386寄存器集,其与16位寄存器差别在前多了一字符"E",意为16位寄存器扩
展。
2、数据窗口
在数据窗口显示指定内存处中的数据,以十六进制和ASCII同时显示,这可以说是我们的眼睛,因此有必要了解一下各部分的含义。
(图二)
①号位置的0030:这是段选择器。
在Windows的保护模式下CS、DS、ES、SS、FS和GS不叫段寄存器,叫段选择器。在保护模式中,内存分为了好多的段,在TRW200下用GDT就可以看到段的编号、类型、开始物理地址、大小、属性。让我们看看编号0030是什么东西:
(图三)
这个段是32位数据类型,长度为4G
,我们还可以看到很多的段,它们有可能会指向同一个物理地址,但它们的类型,属性可能不同。如一些段指向的地址是不可读写的,但另外一个段指向的同一物理
地址是可读写的!如果我们通过不可写的那段的编号放到段选择器,然后进行读写操作,肯定死掉了。
但换了另外一个段对同一个地方读写那就没问题!保护模式的内存管理挺有趣的,感兴趣的不妨看看这方面的书,当然作为初学者只需稍微了解就可。
②号位置00000000:此处表示内存的虚拟地址。
③号位置的值是当前内存的数据,以十六进制表示。
④号位置的值是"③"处值的另一种表示方法:ASCII码。
3、代码窗口
此处显示的是当前程序的代码,因为不管是什么程序,最终在CPU执行时都是以机器语言方式,而汇编语言和机器语言是一一对应的,因此SoftICE为了方便我们理解,把所监视的代码以汇编代码形式显示在我们面前。例如:
(图四)
①段选择器;
②虚拟地址;
③机器码:这就是CPU执行的机器代码,此处是以十六进制表示。你可用Code on/off打开或关闭这项的显示。
④汇编指令:和机器码对应的程序代码。
4、堆栈窗口
这个是TRW2000特有的,通过它很方便监视堆栈的状况。
5、命令窗口
这是各种命令执行的地方,在屏幕底部的动作状态行显示执行命令的各种提示,以及可提供指令语法帮助。
6、程序领空
所谓领空,实际上是指:在某一时刻,CPU 的 CS:IP(EIP)
所指向的某一段代码的所有者所在的区域。此例中SoftICE所停下来时光标所指的那一句代码是属于KERNEL32.DLL的,因此就叫
KERNEL32.DLL领空,在图2.14中,可看到的领空名是KERNEL32!.text,那我怎么知道它就是KERNEL32.DLL文件呢?这
个主要是经验,KERNEL32.DLL是Windows系统文件,在SoftICE里显示领空名时不显示扩展名,只是显示前一部份。
二、SoftICE常用命令简介
由于SoftICE命令操作较多,在此就把几个常用的命令介绍一下,其它详细说明请参考附录的"SoftICE手册"。
1、 G命令
语法:G [=start-address] [break-address]
作用:执行程序,后面如果加地址,则执行到该地址为止。
注意: TRW2000 中G命令与SoftICE稍有不同,SoftICE中G命令必须是在当前段中,这时IP(EIP)为指定值才中断;而TRW2000则不管段址如何,只要IP(EIP)是指定的值便停下,TRW2000这个特性大大方便我们的操作。
2、P命令
语法: P [ret]
作用:单步执行程序。
只执行P时,相当于按下F10键。在汇编模式中,当遇到 CALL、INT、LOOP、REP指令时,P将不跟踪进去,直到这些指令执行完毕,控制才返回SoftICE,换句话说,P命令是"跨"过这些指令的。
P
RET 命令相当于快捷键
F12。SoftICE将一直单步执行直到它找到一条返回语句(RET、RETF),也就是说让SoftICE一直执行代码,直到出现 RET
(XXXX) 命令,再跳出来拦截,这时,当前 IP(EIP) 会是停在 RET (XXXX) 后的某一条语句上,通常是在某一个CALL
XXXXXXXX 后面。由于我们通常用SoftICE在某些底层的Windows函数上设置断点,所以 F12
是很管用的。因为程序的作者用的是高级语言,Windows又是提倡"透明",不希望程序员知道底层的操作,而只提供给他们高层的接口,而相当多的高级函
数调用某个一定的底层函数,所以当你在底层函数上下断点,再用F12,就可以知道他用的是什么函数了。
3、T命令
语法:T [=start-address] [count]
start-address:执行起始地址;
count:指定SoftICE将单步跟踪多少次才停止。
作用:单步跟踪。
T命令相当于功能键F8,如没指定起始地址,将从CS:IP(EIP)指向的指令开始执行,此时当遇到 CALL、LOOP等指令时,T将跟踪进去。
注意: F8和F10功能键的主要差别就在这,遇到 CALL、LOOP等指令时,F10是路过,而F8是跟进去。
4、BPX命令
语法:BPX [address] [IF expression] [DO "command1;command2;..."]
address :断点所在的线性地址;
IF expression:条件表达式,只有条件为"真"时,SoftICE才在断点处弹出;
Do command:当SoftICE弹出时,自动执行的一些命令。
作用:在可执行语句上设置(或清除)断点。
BPX 用来在指令处下断点,程序一旦执行到此,SoftICE就会弹出。当光标在代码窗口中时,直接打入BPX就会在光标所在语句处设断点,再打BPX 就取消。BPX的快捷键是 F9,当光标在代码窗口中时,按F9就是设定(取消)。
BPX 也可用函数名来作地址参数:格式为"BPX 函数名"。
这个函数名可以是任意一个API函数、虚拟机指令、DLL文件的引出函数等等,功能强劲。例:
:bpx messageboxa(不用区分大小写)//只要程序调用了此函数,SoftICE将中断;
:bpx GetWindowTexta if EAX==8 // 当调用GetWindowTexta函数时EAX=8,SoftICE将中断;
:BPX GetWindowTexta do "d EAX"// 当 GetWindowTexta被中断,自动显示EAX的值。
注
意: TRW2000与SoftICE条件格式有点不同,如在SoftICE下的是:bpx loadlibrarya do "dd
esp->4",而相同的用法在TRW2000中是:bpx loadlibrarya do "dd *(esp+4)"
。另外SoftICE中用鼠标双击指令行可设断,而TRW2000中不行,只能按F9.
5、BPM命令
语法:BPM[size] address [条件表达式] DO[执行的命令]
size:内存单元大小,B为字节(默认);W 为字;D 为双字;
verb:所进行的操作,R为读;W为写;RW为读写(默认);X 为执行。
作用:设置内存访问断点。
注意: BPM用了DR3-DR0寄存器,所以最多只能设四个断点。
6、BMSG命令
语法:BMSG window-handle [条件表达式] DO[执行的命令]
window-handle:消息发向的窗口句柄,即消息名
作用:在Windows的消息上下断点。
Windows本身是由消息驱动的, 所以跟踪一个消息会得到相当底层的答案。如:
我们执行记事本程序(Notepad),然后Ctrl+D激活SoftICE输入:
:bmsg wm_char
:g
然后回到Notepad中,随便按一个键,SoftICE就激活了;原因在于我们在按键消息上设置了断点(退出SoftICE别忘下命令"BC *"清除刚才下的断点)。
7、BL命令
语法:BL
作用:显示当前所设的断点
注意: SoftICE会把所有断点按从0开始的编号列出,而TRW2000是从1开始编号列出。
8、BC命令
语法:BC list | *
list:可以清除指定编号的断点,多个时中间用空格或逗号隔开。
* :清除所有的断点。
作用:清除一个或多个断点
9、BD命令
语法: BD list | *
list:可以是单个,也可以是一系列断点,中间用空格或逗号隔开。
* :禁止所有的断点
作用:使一个或多个断点失效。
10、BE命令
语法:BE list | *
作用:使一个或多个断点恢复有效。
用来恢复前次用 BD 命令使之失效的断点。 (每当新定义断点或编辑断点时,系统自动将其置为有效)
11、BPE命令
语法:BPE index_number(断点索引号)
作用:编辑一个已存在的断点。
12、R命令
语法:R 寄存器名
作用:显示或更改寄存器的内容。
其可更改所有的寄存器的值。此命令较常用的一个功能是更改状态寄存器(PSW )的值,格式:R FL 标志位。比如当前 Z标志位(零位)为置位状态,执行"r fl z"之后会被清除;如果C标志位为清除状态,那么"r fl c"将使之置位。
注意: 利用此命令很方便在一些跳转指令上改变方向。
13、A命令
语法:A [地址]
作用:进入小汇编状态,可直接写入汇编代码。
如
不加地址值,直接在当前CS:IP(EIP)处汇编。用SoftICE内置的汇编器在内存中写入汇编代码。汇编器支持标准的80x86指令集,包括
386、486、Pentium、Pentium-Pro、MMX协处理器,新版的SoftICE还支持AMD的3D
Now!、PII、PIII的特有指令集。
14、D命令
语法:D[size] [address [l length]]
size:B 字节;W 字;D 双字; S 短实型;L 长实型;T 10b长实型
作用:显示某内存区域的内容。
15、S命令
语法:S [-cu][address L length data-list]
address:搜索的起始地址
length :搜索的长度(字节长)
data-lis:可以是一系列字节,也可以是字符串,字符串可以用单引号,也
可以用双引号括住.
-c :使查找区分大小写
-u :查找Unicode 编码的字符串.
作用:在内存中搜寻特定数据,如果找到数据,那将在数据窗口中显示出来,如果在找到后,你还要继续查找,使用不带参数的S命令。由于S命令忽略不在内存中的页面,因此你可以使用32位平面地址数据段描述符30h在整个4GB(0~FFFFFFFFh )空间查找。如:
s 30:0 l FFFFFFFF "78787878" //在此令在内存中查找字串"78787878"位置。
注意: TRW2000中S命令的字串应是单引号(而SoftICE皆可)。如:s 30:0 l FFFFFFFF '78787878'.
16、E命令
语法:E[size] [address [data-list]]
作用: 修改内存单元
17、U命令
语法:U [address [l length]] | [symbol-name]
address :段:偏移量或选择符:偏移量
symbol-name:将从指定的函数开始反汇编
length :反汇编的长度(字节)
作用: 反汇编指令
你
可以利用此命令抓取汇编代码,运行LOADER32后,将历史缓冲区(history
buffer)调大些(默认为256,不能放足够多的缓冲数据)。然后切换到SoftICE调试画面下,来到你要抓取的地方,反汇编这些代码,如:U
CS:EIP L 1000 ,立即按Ctrl+D返回到Windows环境,再次来到symbol loader程序,选择"File/Save
SoftICE History As…"。
注意: 在TRW2000下可以直接反汇编代码输出到一个文件:
u 401000,402000 >路径/myfile。
18、FAULTS命令
语法:FAULTS [on | off]
作用:打开或关闭错误跟踪功能
由于SoftICE做为一个DEBUGGER,FAULTS 默认为ON,所以一旦CPU有非法指令,SoftICE就会不停地弹出。
19、?命令
语法:? 表达式
作用:计算一个表达式的值
一个非常高级的计算器,另外由于可以显示ASCII,所以可以很方便地在各种数制之间察看。
20、.命令
语法: .
作用:在代码窗口中定位当前指令
当你在代码窗口中上下浏览时,有可能走得很远,那么这时一个"."命令会让你在下一瞬间回到SoftICE当前所在的CS:EIP处。
21、EXP命令
语法: EXP [函数名]
作用: 显示DLL中的出口函数
函
数名可以指定出其前几个字符,
可以用?来做替代不定字符,这样你就可查找相关函数及其是哪个DLL文件了。这对于你在Win2K系统上非常实用,Win2K系统的
KERNEL32.DLL中许多函数形式和Windows 9x可能不同,用此命令你就可找到正确的函数名了。
22、PMODULE命令(TRW2000特有命令)
作用:'pret'(相当于按<F12>) 直至CS:EIP位于模块中,但比F12更实用,其可以快速回到你的当前程序领空,不用按多次F12了
23、SUSPEND命令(TRW2000特有命令)
作用: 暂停当前的线程,并退出 TRW2000,按热键返回,此命令相当方便。
24、ver blue命令(TRW2000特有命令)
如你的TRW2000背景颜色很暗,可通过此命令来调整背景。