bochs+nasm:调试小技巧
2014-01-06 09:50
197 查看
1、lst文件的妙用
在编译asm文件时,记得同时生成lst文件,这样在调试源程序时,就可以参考lst文件所提供的偏移地址。
2、设置断点b指令和反汇编disasm指令的结合使用
可以使用CS段基址加上lst文件所提供的断点处代码的偏移地址,得到断点的物理地址,然后使用disasm指令对该物理地址反汇编以验证断点设置是否正确。示例如下:
<bochs:4>n
(0) [0x00000000000325c8] 3224:0388 (unk. ctxt): movax, cs
<bochs:5>sreg
cs:0x3224, dh=0x00009303, dl=0x2240ffff,valid=1
Data segment, base=0x00032240, limit=0x0000ffff, Read/Write,Accessed
查看lst文件可知jmp指令的偏移地址,假设须在此设置断点,可以如此计算:0x32240+0x0388+0xEC=0x325c8+0xEC=0x326b4
397 000000008CC8 mov ax, cs
... ...
490 000000EC66EA000000001000 jmp dword SelectorCode32:0
反汇编0x326b4处的指令,确实为jmp指令
<bochs:6>disasm 0x326b4
000326b4:( ): jmp far0010:00000000 ; 66ea000000001000
<bochs:10> b0x326b4
<bochs:11>c
(0) Breakpoint 1, 0x00000000000326b4 in ?? ()
(0) [0x00000000000326b4] 3224:0000000000000474 (unk. ctxt): jmp far0010:00000000
3、全局描述符表GDT基地址、选择子及显示内存
执行指令“lgdt [GdtPtr]”后gdtr寄存器将指向全局描述符表GDT基地址,当使用选择子进行跳转时,可以使用显示内存指令X查看该选择子对应的物理基地址。
<bochs:11>c
(0) Breakpoint 1, 0x00000000000326b4 in ?? ()
(0) [0x00000000000326b4] 3224:0000000000000474 (unk. ctxt): jmp far0010:00000000
选择子为0x0010,即描述符索引为0x10,检查GDT基地址为0x32348
<bochs:12>sreg
gdtr:base=0x0000000000032348, limit=0x3f
显示0x32348处的内存信息
<bochs:13> x/32xb 0x32348
[bochs]:
0x0000000000032348<bogus+ 0>: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x0000000000032350<bogus+ 8>: 0xff 0xff 0x00 0x00 0x00 0x92 0x00 0x00
0x0000000000032358<bogus+ 16>: 0x65 0x00 0xd4 0x26 0x03 0x98 0x40 0x00
0x0000000000032360<bogus+ 24>: 0xff 0xff 0x3c 0x27 0x03 0x98 0x00 0x00
查看对应描述符索引0x10(即bogus+ 16)处对应的描述符,该段描述符对应的段基址为:0x000326d4,即字节7、字节4、字节3和字节2内容串联即可获得段基址。
<bochs:15>disasm 0x326d4
000326d4:( ): mov eax,0xd88e0020 ; 66b820008ed8
<bochs:16>n
(0) [0x00000000000326d4] 0010:0000000000000000 (unk.ctxt): mov ax, 0x0020
反汇编结果和单步执行结果相同。
4、设置内存WatchPoints
lst文件中指令“lodsb”将从内存地址0x32392处读取一个字节,可以在该字节处设置WatchPoints,当程序执行指令"lodsb"时将触发该WatchPoints,类似于断点。
536 00000028AC lodsb
537 0000002984C0 test al, al
<bochs:27>watch read 0x32392
read watchpoint at0x0000000000032392 len=1 inserted
<bochs:30>c
00141741995i[CPU0 ] [141741995] Caught read watchpoint
(0) Caught read watch point at 0x0000000000032392
(0) [0x00000000000326fd] 0010:0000000000000029 (unk. ctxt): testal, al
5、局部描述符表LDT和全局描述符表GDT跟踪
<bochs:31>c
(0) [0x000000000003271c] 0010:0000000000000048 (unk.ctxt): jmp far 0004:00000000
从指令"jmp far0004:00000000"可以看出程序将跳转至LDT(因TI位为1)表中描述符索引为0的局部段,使用指令"sreg"检查LDT和GDT段基址
<bochs:32>sreg
ldtr:0x0030, dh=0x00008203, dl=0x27580007,valid=1
gdtr:base=0x0000000000032348, limit=0x3f
<bochs:33> x/64xb 0x32348
0x0000000000032348<bogus+ 0>: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
... ...
0x0000000000032378 <bogus+ 48>: 0x07 0x00 0x58 0x27 0x03 0x82 0x00 0x00
0x0000000000032380 <bogus+ 56>: 0xff 0xff 0x00 0x80 0x0b 0x93 0x00 0x00
由GDT段基址0x32348及选择子0x30可知LDT段基址为:0x032758
<bochs:34> x/16xb 0x32758
0x0000000000032758<bogus+ 0>: 0x19 0x00 0x60 0x27 0x03 0x98 0x40 0x00
0x0000000000032760<bogus+ 8>: 0x66 0xb8 0x38 0x00 0x8e 0xe8 0xbf 0x80
反汇编0x032758处内存指示的内存地址0x32760,可知LD处的第一条指令
<bochs:35>disasm 0x32760
00032760:( ): mov ax, 0x0038
设置断点执行,与设想的一致
<bochs:37> b0x32760
<bochs:38> c
(0)Breakpoint 3, 0x0000000000032760 in ?? ()
(0) [0x0000000000032760] 0004:0000000000000000 (unk. ctxt): mov ax,0x0038
相关文章推荐
- bochs+nasm:调试小技巧
- nasm : 修改bochs配置, 记录调试屏幕的输出.
- nasm汇编以及bochs调试
- [Cocoa]XCode的一些调试技巧
- Android Studio 常用高级调试技巧
- Microsoft Visual Studio调试技巧(一):添加中断异常类型
- Java程序员应该知道的调试技巧
- [Bochs]Bochs调试技术
- vc 6.0开发工具与调试技巧整理
- 调试技巧之调用堆栈
- Java程序员应该知道的10个调试技巧
- Chrome 中的 JavaScript 断点设置和调试技巧
- Java程序员应该知道的10个调试技巧
- 使用Chrome调试JavaScript的断点设置和调试技巧
- 11个高效的VS调试技巧
- XCode的一些调试技巧
- QT 的基础调试技巧 -- 未完 -- 更新中
- Java程序员应该知道的10个调试技巧
- Eclipse 调试技巧
- Python 代码调试技巧(图文详解)