|
ko20010214
版主
积分 7294
发帖 1628
注册 2002-10-16
状态 离线
|
『楼 主』:
贴一下TR的帮助文件,这些东西都快在网上失踪了
This File is Write in Chinese.
欢迎使用解释型跟踪调试软件----TR
————刘涛涛
四、汇编指令作为命令
搞汇编语言的人满脑子都是汇编,复杂的调试命令可能不愿去记。能用汇编指
令作为命令当然是个好主意。用R AX 1234当然不错,用MOV AX,1234岂不更有意
思?其它CLI\MOV [WORD 1234],4567\IN AL,21都是不错的命令。
五、允许对调试程序作注解
六、自动跳转
七、历史记录
TR可以把执行过的每一个CS:IP记录下来,以便静态分析。如果程序出错, 可
以查历史记录向前回溯,找到问题所在。更有功能强大的LOGPRO,可以把程序的关
键指令整理出来。被跟踪程序再无任何秘密可言。
参见命令LOG、LOGS、VLOG、LOGPRO。
八、把内存代码写成EXE文件
九、复杂的断点,一次性断点。
(1)BP CONDITIONS
条件断点。如: BP IP>4000 ;代码较长,只跟踪后半部
BP AH=2 DL=80 CH>30
(2)BPINT intnum [CONDITIONS]中断断点
(3)BPXB BYTES [CONDITIONS]
遇到指定指令就停下。如:MOV AX,????的机器码为B8????,可用
BPXB b8
其它:
BPXB cd ;所有中断
BPXB 33 C0 ;XOR AX,AX
(4)BPREG REG|SEG [CONDITIONS]
如果指定的寄存器改变,则暂停。BPREG CS可以找到所有的段跳。
BPREG CS AX=0 ES=# ;#指当前PSP
可以找到带外壳程序的真正开始。
(5)BPM [SEG:]OFFSET
如果访问指定地址则暂停。如BPM 20将使MOV AX,[20]停下。
(6)BPW SEG:OFFSET
如果指定地址改变,则暂停。有些操作(如INT)对内存的改变只有一次次
检查是否改变才能找到。
(7)BPIO port [conditions]
(8)BPKNL [count]
如果发现新的程序内核,则暂停。
特别重要的是,如果一个断点只用一次,把设断点命令前面的'BP'改为'GO'
或'GS'便可直接执行。有了这个一次性断点,一般根本不需要专门设置断点。
作者: 刘 涛 涛
地址: 河南安阳彩玻公司资料室
邮编: 455000
电话: 0372-3932916-2273
EMAIL: ayliutt@hotmail.com
ayliutt@nease.net
主页: http://www.nease.net/~ayliutt
ICQ UIN: 3434573
97.10.21
----------------------------------------------------------------------
须 知
一、TR支持Turber Debuger调拭信息。如果调试一个带调试信息的C语言程序,
可以用g _main快速进入现场。
二、支持32位指令(见命令r32)
三、从TR中退出后,用户程序修改过的所有中断都将被自动恢复,占有的内存
自动释放。
四、如果系统有XMS,TR自动使用,可以节省一些内存空间。
五、所有数字输入均采用十六进制。
运行TR需要386以上的CPU,在DOS下运行,也可以在WINDOWS和WINDOWS95的DOS
窗口中运行,不过速度会更慢。与HIMEM或EMM386或任何其它的XMS/EMS内存管理软
件兼容。可以很好地在SOFT-ICE下运行。TR只会跟踪实模式下的DOS程序,对保护
模式和WINDOWS程序一无所知。
一、寄存器区
屏幕的最上端是寄存器区。缺省为16位方式显示,可以用R32命令改为32 位方
式。
用R命令置寄存器值,如:
R AX 1234
R ebx 12321456
R ch 87
R dl ah
R ip ip+1
R fl z
对标志寄存器用ODISZAPCT,最近改变过的寄存器以不同颜色表示。
二、内存区。
用WD num改变内存区的行数。
内存区有两种显示方式,一种是普通的段不变偏移连续变化的方式,另一种是
段以10H变化,偏移为0的方式。普通方式下,用E命令使光标到内存区, 如果当前
OFFSET小于0F按向上箭头,变为第二种显示方式。用D命令恢复。
三、代码区
屏幕中央是代码区,显示程序的汇编代码。支持386指令, 可以显示标号和注
解,对常用中断进行解释。
四、命令区
用于输入命令。可以按F5键放大,按左、右、上、下、上下翻页、HOME、 END
等键移动光标,用DEL和BACKSPACE修改。
如果要多次执行一条命令,把光标放到那条命令上按ENTER。
五、状态行
显示命令是否正常执行。
六、以上是TR的主要窗口,另处还有F4显示用户屏幕,VIEW命令列文件内容,
STACK命令显示STACK窗,VLOG显示历史窗等等。
----------------------------------------------------------------------
常用按键
<F8> 执行一句汇编指令,等同于命令T。
<F10> 执行一个过程,等同于命令P。
<F4> 显示用户屏幕,等同于命令RS。
<F6> 命令窗<-->代码窗。
<F7> 如果光标在代码窗,执行到光标位置(HERE)。
<F5> 最大当前窗口。当前窗口可以是命令窗、代码窗、内存窗。
<F9> 如果光标在代码窗,设置(或清除)光标所在位置为断点。
Ctrl+D 暂停程序的运行,返回TR。注意,TR只会停留在被跟踪程序的代码中,
而不会停留在系统代码中,所以按热键Ctrl+D后有时不会马上返回。
----------------------------------------------------------------------
常用符号
<$>:
在TR的命令中,可以用美元符'$'代表当前的CS:IP。命令
D CS:IP
与命令
D $
是等效的。命令U $可以用命令.来代替。
<*>:
在TR的命令中,星号'*'代表当前指令的操作地址。如果当前的CS:IP为
****:**** mov ax,[di] ;1234:5678=****
并且此时DS=1234,DI=5678,则命令 D *
与命令 D DS:DI
或 D 1234:5678 等效。
<@>:
取地址的指针。比如,如果
1234:5678 11 22 33 44
则@1234:5678表示4433:2211。
可以用@0:21*4表示中断21的地址。
如果刚刚进入一个CALL FAR或INT,可以用@ss:sp返回。
<#>:
在TR的命令中,井号'#'代表当前程序的PSP值。
例: D #:0
<;>:
分号';'代表注解,命令中分号后面的部分将不被解释。
AUTORUN.TR:
每次TR运行,都会自动执行当前目录下文件AUTORUN.TR中的命令。把你总是要
执行的命令加入AUTORUN.TR。如R32,AUTOINT1 ON等。
---------------------TR定制命令--------------------
COLOR [01 02 03 04 05 06 07 08 09 10]
如果不带参数,显示当前TR的颜色设置。如果带参数,必须是9个值,分别
表示
1:寄存器区 寄存器名
2:寄存器区 寄存器值
3:寄存器区 改变过的寄存器值
4:代码区 一般代码
5:代码区 当前CS:IP
6:代码区 标号或注解
7:代码区 断点
8:命令区 一般命令
9:命令区 注解
a:状态栏
如:color 7 b e 7 e 2 4 17 36 76
MSG [x y]
显示信息窗。主要用在DO命令文件中作演示用。以后的命令都作为要显示的
信息,空回车返回。X,Y为信息框的位置,-1为自动右上角,-2为居中。例:
msg 20 5
this is first line message
THIS IS SECOND LINE
And third
;空回车
VER
显示版本信息。
R32
16位寄存器/32位寄存器切换。如果是16位状态,寄存器窗口显示为
AX=1234 BX=1234 CX=1234 DX=1234 SP=1234 BP=1234 SI=1234 DI=1234
DS=1234 ES=1234 SS=1234 CS=1234 IP=1234 o d i s z a p c t
32位状态的显示为:
EAX=12345678 EBX=12345678 ECX=12345678 EDX=12345678 SP=1234
EBP=12345678 ESI=12345678 EDI=12345678 FS=1234 GS=1234
DS=1234 ES=1234 SS=1234 CS=1234 IP=1234 o d i s z a p c t
无论何种状态,都不影响系统运行。缺省为16位,如果你喜欢32位状态,
把R32加入文件AUTORUN.TR。
REDRAW
屏幕重画。
WD [lines]
设定内存窗口的行数。
---------------------输入/输出 命令--------------------
A [address]
汇编。虽然代码窗能够识别32位代码,A命令暂时不能处理32位代码。
将在以后的版本改进。可以直接用'BEGIN:'的方法定义标号。
A cs:0
start: ;define label
mov ax,bx ;any asm code
;return to command mode
D [address|range] [>filename]]
以十六进制和ASCII码方式显示内存,加‘>’号把结果输出到文件,
如: D cs:ip
D *
D 1234:5678>myfile.txt
D cs:0lffff>file
D >file
如果指定文件不存在,则自动生成;如果已经存在,则追加。
缺省长度40H。
E [[ptr] bytes]
内存修改。如果不带参数,光标移到数据区,这时可以按左、右、上、下、
上下翻页、HOME、END等键移动光标,按字母数字键修改内存,按TAB键十六
进制ASCII码转换。例:
E cs:0 12 23 45 'abc'
E b800:200 36 24
E 234 'def',0d,0a,'$'
缺省段为DS。
F range bytes
填充。把内存区域用给定字串填充,如
F cs:0,ffff 12 23 45 'abc'
F b800:0L200 36 24
F 234 'def',0d,0a,'$'
如果未指定长度,给定字串至少填充一次,相当于E命令。
缺省段为DS。
L [[SEG]:OFFSET] [FILENAME]
读文件到内存。注意与RELOAD的区别,L仅仅是把文件读到指定内存区,而
RELOAD是找到一块空闲内存调入,建立PSP,设置寄存器,准备执行。
缺省段为DS,缺省地址DS:100。
例: N c:\autoexec.bat
L 100
N c:\command.com
L 200
L DS:300 MYFILE.BIN
L [SEG]:OFFSET DRIVE STARTSECTER SECTERS
从指定物理驱动器读取指定物理扇区。
例: L 100 0 0 1 ;读A盘BOOT区
L 100 2 0 1 ;读C盘BOOT区
N [filename]
如果不带参数,显示当前文件名。如果带参数,置文件名。如:
N MYFILE.EXT
参见:W,L,RELOAD
RELOAD [filename]
重新调入文件。如果文件名已被N命令修改,则调入新文件。
重置所有中断向量、内存区、寄存器。
有时程序上一次申请的内存不能完全释放,导致调入失败。可以
退出TR再进,EXE2,RELOAD,仍然可以MKEXE。
U [address|range] [>filename]]
反汇编,加‘>’号把反汇编结果输出到文件,如:
u cs:ip
u $
u 1234:5678>myfile
u cs:0lffff>file
u >file
如果不给出反汇编长度,缺省20H。
如果指定文件不存在,则自动生成;如果已经存在,则追加。
W
W [SEG]:OFFSET
W [SEG]:OFFSET filename
W [SEG]:OFFSET length filename
写内存到文件。文件长度为BX:CX或length。
缺省段为DS,缺省地址DS:100。
例: N test.com
W 200
W es:300 myfile.com
W cs:ip dx test.com
W [SEG]:OFFSET DRIVE STARTSECTER SECTERS
向指定物理驱动器写指定物理扇区。
例: W 100 0 0 1 ;写A盘BOOT区
WREG filename
把当前寄存器区内容写入文件。如文件存在则追加。
WMEM filename
把当前内存窗口内容写入文件。如文件存在则追加。
WCOD filename
把当前代码窗口内容写入文件。如文件存在则追加。
WCMD filename
把当前命令窗口内容写入文件。如文件存在则追加。
---------------------RUNTIME 命 令--------------------
DELAY [time]
用于DO命令文件中,起延时作用。如果命令文件中改变了DELAY状态,切
记在文件尾用DELAY 0恢复。
注意设定延时为16进制。
DO filename *新概念*
执行批处理。指定一个文本文件,里面可以包含所有合法的TR命令(甚至
另一个DO),让TR自动执行。每次TR运行,都会自动执行当前目录下文件
AUTORUN.TR中的命令,相当于每次TR启动,都会自动执行一个
DO AUTORUN.TR
在批处理文件中,如果一个命令行以空格开始,TR直接处理该命令而不在
命令窗口显示(第一个空格被去掉)。
特别用法:把一个汇编程序前面加个A〈回车〉,让TR去汇编。
参见:DELAY,KEY
KEY num
用于DO批处理文件中,模拟按键。给定的值为MOV AX,0\INT 16返回的值,
如: KEY 1C0D ;回车
---------------------其 它 命 令--------------------
所有汇编指令
TR支持几乎所有汇编指令作为命令。虽然我们不一定非要这么做,但有时候
确实很方便,试试下面命令:
mov ah,4c
jmp 200
cli
定义标号或过程名:
命令行中,输入一个字串加冒号,定义当前的CS:IP为给定标号。
在A命令后的汇编状态中,定义的是当前正在汇编的地址。
例,如当前IP=100,输入‘START:’,则CS:100为START,所有JMP 100都将
译为JMP START。
在命令行中,这是‘LABEL CS:IP labelname’的简写。
参见:LABEL,CMT
.
在代码窗显示当前CS:IP。
相当于U CS:IP或U $。
? [expresion]
帮助。如果不带参数,TR自动ZOOM命令窗口,简要显示每一条命令的语法和
功能。可以用Up/Down/PageUp/PageDown上下滚动窗口,F5恢复。
如果带参数,TR对参数计算后显示结果,如:
? ax 显示AX内容
? cx+dx 显示CX+DX的结果
? # 显示当前PSP
? @0:21*4
? $+5 显示CS:IP+5
CMT [SEG:]OFFSET COMMENT_STRING *新概念*
对程序进行注解。
地址如果不提供段址,默认当前CS。如果地址小于PSP:0或大于PSP+2000:0,
认为是相对地址,否则认为是绝对地址。
注解串可以是任意长度的字串,但命令总长度不能超过79。如果包含空格或
保留小写,请用单引号‘’括住。
对程序所作注解全部存入文件‘当前文件名.cmt’,这是一个文本文件,可
以直接编辑。下次TR调入程序时自动装入。
如果定义当前CS:IP名,可直接用‘标号名:’。
例:
cmt cs:200 'This is my comment string'
PROC1:
参见:LABEL,SYMBOLS
LABEL [SEG:]OFFSET LABEL_NAME *新概念*
定义标号或过程名。
如果定义了标号或过程名,代码窗中将在该地址前留一行显示其名子,并把
所有JMP和CALL到该过程的语句翻译为‘CALL 过程名’而不是通常那样
‘CALL ????’。
程序标号全部存入文件‘当前文件名.cmt’,这是一个文本文件,可以直接
编辑。下次TR调入程序时自动装入。
例:
LABEL cs:200 file_open
参见:cmt,SYMBOLS
LOG [ON|OFF] *新概念*
是否记录历史。如果LOG ON,则TR将把以后执行的每条指令地址记录下来,
可以用VLOG命令查看。本命令只记录最后25条地址,如果要所有记录,请
用LOGS命令。
利用TR的LOG功能可以使用一种新的分析程序的方法,那就是“走后门”。
比如一个程序错误退出,如果用通常的办法从程序开始进行跟踪,要走很
长的路才能找到问题所在。而用TR的LOG功能,就可以在程序异常退出后分
析程序最后执行的什么过程,快速找到关键。
LOGS [ON|OFF] *新概念*
是否记录历史。如果LOGS ON,则TR将在当前目录下建一文件LOG.DAT,
并把以后执行的每条指令地址以十六进制存入该文件。方便以后分析程序
流程。视程序复杂度,该文件可能会很长。请使用专门的十六进制浏览器
浏览该文件,或用TR的VIEW命令。
当LOGS ON时,因为执行每一条指令都会有一次存盘,速度较慢,一般情况
下,用LOG ON就足够了。LOGS ON时,LOG自动为ON。
LOGPRO [0|1|2|f] *新概念*
功能:把程序执行过的关键代码记录下来,便于分析。特别适合于正确
流程和错误流程的比较。
如果不带参数,则显示当前选项。各选项的意义:
0: 不LOG
1: 只LOG以下几条指令call,ret
2: 只LOG以下几条指令call,ret,condition jmp,jmp far
注意:对CONDITION JMP只有条件为真时才LOG
f: LOG所有指令
LOGPRO把LOG的指令存到文件LOGPRO.DAT,每条记录长16字节,格式:
位置 大小 意义
0 DW IP
2 DW CS
4 DW SP
6 DB ?
7 DB ?
8 8 byte 指令码
在DOS提示符下执行LOGPRO.EXE,读取LOGPRO.DAT,生成LOGPRO.TXT。
这就是程序的关键代码。
特别感谢LX首先提出这个思想。
M RANGE [SEG]:OFFSET
内存复制。如:
M $L200 8000:100 ;复制CS:IP开始长度200到8000:100
M DS:0,800 ES:200 ;复制DS:0,800到ES:200
Q
退出TR。也可以按ALT+X。
用户程序修改过的所有中断都将被自动恢复,占有的内存自动释放。
R REG [num]
改寄存器值。可以是8位16位32位通用寄存器、标志寄存器FL或段寄存器。
对标志寄存器的操作可以是ODISZAPCT。
例: R ax 1234
R ebx 12321456
R ch 87
R dl ah
R fl z
RS
显示用户屏幕(Restore Screen),热键F4。按任意键返回。
S range bytes
在内存中查找指定内容,如:
s cs:0,ffff 12 34 45 ;在CS:0到ffff中寻找12 34 45
s ds:200l100 23 ;在DS:200长度100中寻找23
SYM [ON|OFF]
是否调入EXE文件的调试信息。缺省为ON。如果不想调入文件的调试信息,
先不带参数执行TR,然后:
SYM OFF
N myfilename
RELOAD
因为有些错误的调试信息会使TR发疯。
SYMBOLS
如果程序带有调试信息或用label,cmt命令自定义了符号,则显示所有符号名。
参见:CMT,LABEL
VLOG
显示LOG ON或LOGS ON命令记录的历史信息。
VIEW filename.ext
浏览文件。可以以十六进制和ASCII方式查看文件内容。
STACK *新概念*
显示当前子程序嵌套状况。
比如,可以用GOIO 378找到关键指令,用STACK看当前CS:IP是经过几次
CALL过来的,迅速找到关键子程序。
参见:PRET
---------------------------------------------------------------------
跟踪执行命令
G
G [seg:]offset
G conditions *新概念*
执行程序,也可以用命令GO。如果条件满足,则暂停。
注意:在程序中加入INT3并不能使G命令的运行中止。
特别推荐:G OFFSET。只要程序执行中IP等于设定的OFFSET,就会停下。你
不用担心段址在哪儿,代码是否动态生成。只要知道它会经过那儿,就会停
下。例:
G 100
G CS:100
G BX
G AH=4C
G AX=0 BX=0 CX=0
G IP>400
参见:GS
GO??? *新概念*
任何设置断点的命令BP???都可以用GO???来使用,用为一次性断点。
例: GOREG CS
GOINT 21 AH=30
GOW ES:DI
GOXB CD 13 AH=2
参见:GS???
GS
G命令在执行前会恢复用户屏幕,执行结束后再保存用户屏幕。有些程序破
坏了BIOS,这样保存的屏幕信息无法正常恢复,对此问题TR还找不到好的解
决方法,于是增加了一个GS命令。GS命令相当于G命令,只是不恢复屏幕。
等价于执行多个T。
GS???
同GO???命令,只是不恢复屏幕。参见:GS GO???
T
执行一句汇编指令,相当于按F8。
注意,TR的T命令与其它调试器不太一样。TR并不会真的去执行这条指令,
而是完成每条指令的功能而已。如果遇到了TR无法识别的指令,只有用TT
命令了。
如果遇到INT指令,T命令不会进入系统的中断例程,因为我认为我们一般感
兴趣的是被跟踪程序,而不是系统。如果程序修改了INT地址,T命令会进入
被改后的地址。如果真是需要进入中断,可以用GG,如
GG @0:21*4 ;进入INT21
GG [[SEG:]OFFSET]
无条件执行,TR不对执行过程作任何控制。
缺省段为CS。如果指定地址,那么TR在指定地址插入CALL FAR指令,然后JMP
到应用程序中去,希望它能执行到这个CALL FAR由TR重新控制。之所以不用
INT3是为了防止应用程序修改INT3中断向量。
因为这时程序的执行已不是TR的解释执行,所以运行速度正常。
仍然可以希望CTRL+D能回到TR的控制。
P
执行一个过程(F10)。如果当前指令是一条CALL或CALL FAR,则执行整个过
程直到返回。如果是其它指令,同T。
如果确实想执行到下一步为止,比如遇到一个LOOP,请用命令PP。
PP
执行直到下一条指令。相当于G IP+本指令长度。
PRET
执行程序直到RET、RETF或IRET指令。用于快速退出子程序。
参见:STACK
TT
使用单步中断执行一条指令。
不推荐使用。
参见:int1
AUTOINT1 [ON|OFF]
这是一个标志,可以设为ON或OFF。缺省为OFF。
当为ON时,如果TR遇到一条不可识别指令,则自动用INT1单步中断去执行。
参见:TT,INT1
INT1 [ON|OFF]
这是一个标志,可以设为ON或OFF。缺省为OFF。
当为ON时,TR不再解释每一条指令,而是用INT1单步中断去执行。
不推荐使用ON的状态。如果你确认TR对某条指令的解释有误,可用状态ON
继续执行。如果只在此状态下执行一条指令,用命令TT。
影响命令:T,G,P等
参见:TT,AUTOINT1
AUTOJMP [ON|OFF] *新概念*
设置是否自动跳转。如果为ON,在执行过程中TR将不显示JMP指令,而把JMP
后的指令直接放在JMP指令原来的位置,并在该指令前加“—〉”符号以示区别。
这样在一些JMP过多的场合能使你容易保持清醒。如果你不习惯,让它OFF。
缺省为ON。
---------------------------------------------------------------------
断点命令
**** 如果断点只使用一次,把BP????改为GO????或GS???? ****
BL
列出所有断点。最多可设8个断点。
实际上是9个断点,断点0被GO系列命令占用。
BC [NUM]
清除所有断点或指定断点。
BD [NUM]
DISABLE所有或指定断点。
BE [NUM]
允许所有或指定断点。
BPW segment:offset *新概念*
监视内存变化,如果指定位置的字(WORD)发生改变,则暂停。
如果设定此类断点,TR每执行一条语句都会进行一次比较。
BP [seg:]offset *新概念*
如果执行到CS:IP=SEG:OFFSET或IP=OFFSET,则暂停。
用BP seg:offset时,TR不会象通常的调试程序那样,插入一个INT3,TR从
来不那样做,所以不用担心应用程序会发现或破坏INT3地址而不能返回。
用BP offset是个好主意,这样就不用关心它的段址是如何变化,在此之前
有多少代码的扭曲,断点区是否动态生成,都不用去管它。只要程序执行
过程中IP=offset,就会停下来。
这个断点实际上是下面BP conditions的一种特殊情况,也可以写作
BP ip=?? cs=??
TR把它们作为一种情况进行处理。
惯用法:对COM文件脱壳,用BP 100或直接G 100。
例: bp cs:200
bp $+20
bp dx
BP ip>200
BP conditions *新概念*
如果指定条件满足,则暂停,如
bp ax=1234 ;当ax等于1234H时停
bp ax=0 bx=0 cx=0 ;当AX,BX,CX同时为0时停
bp ah=3 dx=80
可同时设定3个条件,只有同时满足时,才有效。
条件判断可用=,!=,>,<,>=,<=。第一个参量用寄存器,可以用任何8位16位
寄存器或段寄存器,第二个参量用立即数(如果用寄存器,则取值)。
BPREG REG|SEG [conditions]
如果指定寄存器改变,并且条件满足,则暂停。
可以指定任意16bit通用寄存器或段寄存器。
特别推荐使用bpreg cs AX=0 DX=0 ES=#,一般可用来快速查找加外壳程序
真正的开始。
条件设置参见BP。
BPXB bytes [conditions]
如果执行到批定的机器码,则暂停。如,因NOP的机器码是90H,所以
BPXB 90
在运行过程中遇到NOP会停下。又如,MOV AX,????的机器码为B8????,可用
BPXB b8
其它:
BPXB cd ;所有中断
BPXB 33 C0 ;XOR AX,AX
指定机器码长度不要超过8个字节。还可以加条件,如
BPXB cd 13 ah=3
条件设置参见BP。
BPINT intnum [conditions]
中断断点。如果执行指定中断,则暂停。如:
BPINT 21 AH=30
BPINT 13 AX=201 CH>30 DX=1
BPKNL [count] *新概念*
如果AX=BX=SI=DI=BP=0,DS=ES=<PSP>,IP=0或IP=100或CS刚发生变化
(意味着刚有过一次JMP FAR或RET FAR),则暂停。一般用于寻找有外
壳的程序内核。注意有些加壳软件并不严格符合这个条件,用此方法可
能会漏掉。如果你有比此更好的主意,请告诉我。
万能的办法常常不是最好的办法。
---------------------------------------------------------------------
其它命令
EXE1
EXE2
WEXE1
WEXE2
GETKNL [count]
参见下面《如何输出EXE文件》
---------------------------------------------------------------------
如何输出EXE文件
有时我们跟踪一个外壳型程序,我们不仅希望能跟踪到文件的真正开始,
还希望能够恢复源文件。为此,TR提供了生成EXE文件的功能。因为COM文件
比较简单,只要用W写内存到文件即可。下面重点介绍生成EXE文件的过程。
一、手工完成
首先,要把内存中的代码写成文件,应该知道文件的大小。为了达到这
个目的,先用命令EXE1把内存清掉,再用RELOAD重新调入,这样写盘时被使
用过的内存区域就是要存文件。
然后,用各种跟踪命令跟踪程序,对一般的外壳,用
goreg cs ax=0 bx=0
或 goknl
几次都能找到真正的文件头,用WEXE1存盘,生成文件MEM1.DAT。
为了处理EXE文件的重定位,需要把程序换个内存地址调入以进行比较。
使用命令EXE2,把内存挤掉一点并清除,RELOAD。
仍然用上面的跟踪步骤跟踪到文件头,用WEXE2存盘,生成文件MEM2.DAT。
用Q命令退出TR,执行文件MKEXE,自动读取MEM1.DAT和MEM2.DAT中的信息,
生成EXE文件MEM.EXE,你可以试着执行了!
二、让TR自动完成
用TR把程序调入,用命令
GETKNL [count]
其中count为脱几层外壳,缺省为1。TR会自动运行:
exe1
reload
goknl count
wexe1
exe2
reload
goknl count
wexe2
q
TR生成两个文件mem1.dat和mem2.dat并退出。在DOS提示符下运行
mkexe [orgfile.exe]
会生成文件mem.exe,这就是脱壳后的文件!
之所以把MKEXE单独作为一个文件而不是把它做到TR中去,是为了给大家
扩充的机会。如果你对MKEXE感兴趣,可以索取MKEXE的源程序(C++)。
MEM1.DAT和MEM2.DAT包含一个0x20长的文件头:
偏移 大小 内容
00 word 0xac,0xbc标志
02 word PSP+0x10,是程序代码在内存中的开始段址
MEM1.DAT和MEM2.DAT应该不同以便确定重定位
04 word CS-PSP-0x10,代码段偏移,两文件应相等。
06 word IP值,两文件应相等。
08 word SS-PSP-0x10,堆栈段偏移,两文件应相等。
0a word SP值,两文件应相等。
0c word 程序内存块长度,以节(10H)为单位
dw 09h dup(0) 其余为0
后面接内存中代码。
不要希望MKEXE生成的EXE文件与源文件一模一样,那是不可能的。它们在
功能上是一样的。如果你选择生成EXE的时机不太好,不正好是程序原来的开始,
你还需要加一段代码恢复各寄存器值。
如果原文件带有OVERLAY,或在执行过程中检查自身,新的EXE文件可能不能
直接执行。可以让MKEXE在EXE前加一段代码,修改环境块,使程序认为是那个未
脱壳的程序在运行。用法:MKEXE ORGFILE.EXE,文件名不要带路径。执行时,把
脱壳前文件与脱壳后文件放一个目录中执行。
特别用法:你可以打开一个COM文件,
tr mycom.com
exe1
reload
wexe1
exe2
reload
wexe2
q
mkexe
ren mem.exe myexe.exe
这就是COM2EXE,把一个COM文件变为EXE文件!
|
ko20010214
=================================
大功告成,打个Kiss!
ko20010214@MSN.com
神州优雅Q300C
Intel CeleronM 370处理器 | 256MbDDR内存
40G硬盘 | USB2.0 | IEEE 1394
13.3 ' WXGA 宽屏(16:10) | COMBO光驱
10/100M网卡 | 四合一读卡器
|
|
2008-10-21 17:04 |
|
|
ko20010214
版主
积分 7294
发帖 1628
注册 2002-10-16
状态 离线
|
『第
2 楼』:
好久没有用TR了,里面的命令都忘光了,
以前有Win98的情况下还会用一用它。
这几年机器上都是装的XP
98已淡出视界了。
虽然软件自带有一点简单的帮助
还是看文本的帮助比较舒服,呵呵。
在网上搜了一下,
几乎都绝迹了,
还好以前的硬盘里有,
翻出来贴出来,
以后要找的话也许还能在这找到。
另,Tr.exe还带有mkexe.exe这个工具,
不知道还能不能在网上找到。
俺硬盘里没收。
|
ko20010214
=================================
大功告成,打个Kiss!
ko20010214@MSN.com
神州优雅Q300C
Intel CeleronM 370处理器 | 256MbDDR内存
40G硬盘 | USB2.0 | IEEE 1394
13.3 ' WXGA 宽屏(16:10) | COMBO光驱
10/100M网卡 | 四合一读卡器
|
|
2008-10-21 17:08 |
|
|
lianjiang2004
金牌会员
积分 3946
发帖 1884
注册 2006-1-20
状态 离线
|
『第
3 楼』:
补上1-3:
欢迎使用解释型跟踪调试软件----TR
如果你用过DEBUG,SYMDEB,TD(TURBO DEBUG),CV(CODE VIEW )或 SOFT-ICE, 你应该试试TR。
TR(将)具有以上调试软件的一切功能,支持它们的所有命令。而且,最重要的是,TR提出了九大新的思想:
一、解释跟踪
TR对程序是解释执行的。TR就象是一个CPU, 能读懂每一句程序代码并正确解释执行,不需要使用INT1,INT3,不需要使用386调试寄存器DR0-DR7,不需要进入保护模式(是不会)。理论上,TR永远不会被应用程序发现,永远不会有跟踪不下去的程序。因为所有的程序都要交给CPU去解释执行,只要CPU认识的指令,TR也要认识,TR会想象CPU 处在这种状态会怎么作,那我也那么去作。如果你发现TR作错了,那是TR还尚待完善。
传统的跟踪方式有太多的弊病:
(1)那些使用单步中断INT1的调试软件,因为它们独占INT1和TF,所以那些需要INT1的应用程序便无法跟踪,应用程序也可以通过检测TF来发现自己是否正在被跟踪。
(2)那些使用断点中断INT3的调试软件, 需要在应用程序中插入代码INT3(0CCH),如果应用程序破坏INT3的中断向量,或检测自身代码便无法跟踪。
(3)SOFT-ICE不使用以上两种方法,而是用386硬件中断, 效果要好多了。跟踪那些对386一无所知的程序不成问题。但许多要求EMM386、DPMI、DOS4GW 等的软件的运行受到了极大的限制,甚至根本不能在SOFT-ICE 下执行。 更重要的是,SOFT-ICE很容易被发现。
总之,现有跟踪调试软件都是利用INTEL的CPU手册上提供的规范的调试方法进行工作,它们只适合调试那些规规矩矩的、愿意被跟踪调试的程序。如果应用程序不予合作,便不能跟踪。TR则不同,TR要跟踪所有CPU能处理的程序,甚至TR 能嵌套跟踪另一个TR。
另一方面,传统的跟踪方法是设置好一些断点(不管是何种断点),然后GO到应用程序中去执行,并期望程序运行到适当地方,CPU能产生一个中断, 返回主程序。至于能否返回,或返回前程序干了些什么,只有天知道。用解释的方法跟踪,控制权永远牢牢掌握在TR的手中,监控着所有程序流程,并由此才能设置一些高度复杂的断点。
解释跟踪是TR与其它调试软件的最本质的区别。也是TR高性能的根本所在。
二、批处理
尽管批处理的概念很早就有,在各种软件中应用极为广泛,却无人把它作到调试软件中。在TR中,可以把要执行的命令序列放到一个文本文件中,用DO命令执行。当然还有自动批处理AUTORUN.TR。
三、G OFFSET
对G 100命令,大家都知道是执行到100停下,其它的调试软件认为是到当前段的100停下,TR却不管段址如何,只要IP是100 便停下。 这样一般的COM外壳只要一条G 100便解决。这个功能看起来简单,却极为有用。有了这条命令,再也不用去记复杂的跟踪路径,只要把当前跟踪到的IP记下,下一次一G便到。
四、汇编指令作为命令
|
Windows 一键还原
http://www.yjhy.com |
|
2008-10-21 19:37 |
|
|
ko20010214
版主
积分 7294
发帖 1628
注册 2002-10-16
状态 离线
|
『第
4 楼』:
THKS.
原来保存这文章时删除了前面那三节。因为调试要用到的主要在后面这几节里。
没想到楼上的也有这篇文章。这样就完整了!呵呵。。。
既然有文章,
请问有没有完整的TR软件包啊?
能不能上传上来共享一下?
|
ko20010214
=================================
大功告成,打个Kiss!
ko20010214@MSN.com
神州优雅Q300C
Intel CeleronM 370处理器 | 256MbDDR内存
40G硬盘 | USB2.0 | IEEE 1394
13.3 ' WXGA 宽屏(16:10) | COMBO光驱
10/100M网卡 | 四合一读卡器
|
|
2008-10-22 01:00 |
|
|
lianjiang2004
金牌会员
积分 3946
发帖 1884
注册 2006-1-20
状态 离线
|
|
2008-10-22 09:43 |
|
|
lianjiang2004
金牌会员
积分 3946
发帖 1884
注册 2006-1-20
状态 离线
|
|
2008-10-22 09:44 |
|
|
lianjiang2004
金牌会员
积分 3946
发帖 1884
注册 2006-1-20
状态 离线
|
|
2008-10-22 10:16 |
|
|
lianjiang2004
金牌会员
积分 3946
发帖 1884
注册 2006-1-20
状态 离线
|
|
2008-10-27 08:03 |
|
|
aaos
初级用户
积分 24
发帖 11
注册 2010-6-24
状态 离线
|
『第
9 楼』:
刚刚了解到TR,我太孤陋寡闻了,呵呵。
用了一下,TR真的是太好了,功能很强劲。
可以跟踪很多加密外壳。
我想TR这么厉害,那如何反TR的跟踪呢。
说下想法。
========================
TR程序用解释目标程序来运行。
本小程序使用大跳转JMP far XXXX:XXXX来实现
程序下一条语句的转移。下一条语句绝对不是
紧跟着的下条代码,TR程序无法解释下一条执行
语句是在哪里,故而出错,无法继续跟踪。
在TR解释jmp far xxxx:xxxx的语句时,有时候会
直接跳转到xxxx:xxxx的地方跟踪执行,比如在
Xxxx:xxxx的地方跟踪到retf,然后再返回,这样
TR就不会把程序跟丢了。
然而,有时候,jmp far xxxx:xxxx,TR并不继续
跟踪jmp以后到底执行了什么语句,而是似乎在
jmp far 的原地附近,比如在下一条语句处寻找
断点,显然是找不到的,jmp far以后,肯定不会
返回原地。
所以,这个jmp far xxxx:xxxx 的地址是摸索出来的。
我有几次jmp far 以后的地址,TR仍然跟踪了过去,
赫然显示一条RETF语句,让我很吃惊。
但经过摸索修改,目前的程序中,跳转到父进程,
似乎是TR判断为Xxxx:xxxx是系统区,就不继续
跟踪而期待其自然返回,然而利用这一点,我不是
自然返回到原地,很容易就让TR跟踪跟丢了。
实际jmp far跳转到一条retf语句,事先在堆栈中
放好retf返回的地方(绝对不是返回到jmp far的
下一条,而可以故意返回到隔几条语句,甚至
返回到很远的地方。),TR面对jmp far 无法知道
下一条语句在堆栈中。因而@$!@%@#%,TR他是一个
解释机器,他没有人脑聪明,他无法继续解释......
对此,TR只能使用GG强制运行。
要知道GG是直接执行目标程序,而不是解释执行。
GG执行也就无法设置复杂的断点了。
本程序对直接执行程序不进行反跟踪,可以结合其他
很多种直接运行目标程序的反跟踪代码壳,结合我的
小程序,既可以反TR也可以反其他调试程序的跟踪。
其实,在使用jmp far转移的时候,把jmp far替换为
retf,甚至iret,或者call到很远的地方,然后返回来
不是call语句的下一条语句。如果TR不能跟踪call
以后的逐条语句,那就会发生错误。有些情况是不能
进入call以后的子程序的,这时候子程序搞鬼不返回
call的下条,TR就会出错。或者用一些其他莫名其妙
的跳转,也会让TR解释运行时出现困难。
=============================
反TR跟踪程序下载
http://upload.cn-dos.net/img/1879.rar
|
|
2010-6-25 15:04 |
|
|
aaos
初级用户
积分 24
发帖 11
注册 2010-6-24
状态 离线
|
『第
10 楼』:
TR毕竟是在DOS系统装入内存以后,对应用程序来说并非完全不可见。
比如可以模仿sofo-ice一样,应用程序先在dos启动以后装入lock.sys.
装入一个加锁的sys程序,这在以前实际使用dos的年代没人这么做过,
而我只是提一点纯技术的想法而已。
应用程序在lock.sys之间来回无规则跳转,或者调用lock.sys接口产生一个
随机跳转地址。那么这对于TR来说,都无法继续解释执行。因为TR只解释
应用程序的每条语句,而对于lock.sys的功能,他认为是系统调用而不可能
每条都跟踪的,那么lock.sys产生的随机跳转地址,TR就无法跟踪。
假设TR对系统调用也跟踪的话。那是不可能的,很容易造成系统崩溃。
比如,如果TR对int 21h也跟踪的化,很容易造成DOS不可重入的错误,
还有堆栈发生错误等等。
另外,应用程序还可以对相关的内存进行检查,如果发现mov,movsb,等等,
汇编代码的字符串,还有int,cli,sti,可以说所有的汇编代码字符串,都在检查
范围,如果内存中有这些字符串,毫无疑问是内存中驻留有反汇编,调试程序。
因为一个调试程序要有U命令反汇编的话,不可能不在数据区保留这些汇编代
码字符串的。所以,一旦检查到这些字符串,加密程序就拒绝执行。也就达到反
调试跟踪的目的。
|
|
2010-6-26 09:49 |
|
|
aaos
初级用户
积分 24
发帖 11
注册 2010-6-24
状态 离线
|
『第
11 楼』:
这毕竟是十年以前的程序。
现在,我认为虚拟机如果提供调试接口,那将是最好的调试跟踪反加密的方法。
比如VM workstation,只要提供接口,提供虚拟机所有寄存器的值,另一个接口,
提供访问虚拟机内存的接口。那很容易编写一个调试程序,你甚至可以调试虚拟机
的BIOS模块。对于在虚拟机内执行的程序而言,你的调试程序就相当于插接在
虚拟机上的一个硬件调试卡,虚拟机内的程序对此完全一无所知。
|
|
2010-6-26 09:56 |
|
|
Vista2008
版主
积分 707
发帖 287
注册 2010-1-13 来自 尖竹汶府
状态 离线
|
『第
12 楼』:
没有多大使用价值......
|
弟控才是王道阿 |
|
2010-7-4 07:03 |
|
|
enjoyer
中级用户
部落守望者
积分 351
发帖 140
注册 2006-6-19
状态 离线
|
『第
13 楼』:
网上下的2.52版里带有mkexe.exe这个工具,楼主如果需要的话可以传给你
|
一切从底层开始 |
|
2010-7-4 12:02 |
|
|
aaos
初级用户
积分 24
发帖 11
注册 2010-6-24
状态 离线
|
『第
14 楼』:
虚拟机调试器:BOCHS
==============
用Bochs调试NTLDR
对一台安装了Windows NT 系列操作系统的PC来说,按下电源开关之后,CPU中首
先开始运行的是Bios,然后是MBR,接着是引导扇,然后就是NTLDR。ntoskrnl.exe和
hal.dll 都是由NTLDR来加载的。也就是说,运行NTLDR的时候,系统中还没有任何应
用程序或者驱动,当然也就没有任何基于软件的调试器可用。当然,无所不能的硬件
调试器肯定是可以的,可惜我们没有硬件调试器。
幸好有了Bochs。Bochs是一个基于LGPL的开源x86 虚拟机软件。Bochs的CPU指令
是完全自己模拟出来的,这种方式的缺点是速度比较慢;优点是具有无以伦比的可移
植性:有Gcc的地方就可以有Bochs。甚至已经有了跑在PocketPC上的Bochs。
现在的Bochs 已经实现了一定程度的调试功能,虽然在易用性和功能上还无法和
WinDbg、SoftICE相比,但优势也是很明显的:对跑在Bochs里面的代码来说,这就是
“硬件调试器”。
对Windows 版本的Bochs来说,安装目录下的bochsdbg.exe就是Bochs的调试版本。
用它来运行Bochs虚拟机就可以进行“硬件调试”。
Bochs的调试命令风格是按照GDB习惯来设计的,这对于用惯了WinDbg的人来说无
疑是痛苦的,好在这是个开源软件,看着不顺眼可以考虑自己改改。
目前版本的Bochs(Version 2.1.1)支持的调试命令如下:
[注意]
1、Bochs的文档和帮助信息中的使用说明与真实情况之间存在很大的差错和缺失,
下面的命令说明根据源码作了很多补充和修正。
2、其中涉及到的seg(段)、off(偏移)、addr(地址)、val(值)等数字,
可以使用十六进制、十进制或者八进制,但必须按照如下形式书写:
十六进制 0xCDEF0123
八进制 01234567
十进制 123456789
尤其要注意,Bochs不能自动识别16进制的数字,也不接受12345678h这种写法。
[执行控制]
c|cont 向下执行,相当于WinDBG的“g”。
s|step|stepi [count] 单步执行,相当于WinDBG的“t”,count 默认为 1。
p|n|next 单步执行,类似于WinDBG的“p”。
q|quit|exit 退出调试,同时关闭虚拟机。
Ctrl-C 结束执行状态,返回调试器提示符。
Ctrl-D if at empty line on command line, exit
(至少在Windows版本中我没有发现Ctrl-D有什么功能)
[执行断点]
vb|vbreak [seg:off] 在虚拟地址上下断点。
lb|lbreak [addr] 在线性地址上下断点,相当于WinDBG的“bp”。
pb|pbreak|b|break [addr] 在物理地址上下断点。(为了兼容GDB的语法,地址前
可以加上一个“*”)。
blist 显示断点状态,相当于WinDBG的“bl”。
bpd|bpe [num] 禁用/启用断点,WinDBG的“be”和“bd”。num是断
点号,可以用blist命令查询。
d|del|delete [num] 删除断点,相当于WinDBG的“bc”。mum是断点号,可
以用blist命令查询。
[读写断点]
watch read [addr] 设置读断点。
watch write [addr] 设置写断点。
unwatch read [addr] 清除读断点。
unwatch write [addr] 清除写断点。
watch 显示当前所有读写断点。
unwatch 清除当前所有读写断点。
watch stop|continue 开关选项,设置遇到读写断点时中断下来还是显示出来但
是继续运行。
[内存操作]
x /nuf [addr] 显示线性地址的内容
xp /nuf [addr] 显示物理地址的内容
n 显示的单元数
u 每个显示单元的大小,u可以是下列之一:
b BYTE
h WORD
w DWORD
g DWORD64
注意: 这种命名法是按照GDB习惯的,而并不是按照inter的规范。
f 显示格式,f可以是下列之一:
x 按照十六进制显示
d 十进制显示
u 按照无符号十进制显示
o 按照八进制显示
t 按照二进制显示
c 按照字符显示
n、f、u是可选参数,如果不指定,则u默认是w,f默认是x。如果前面使用过x或
者xp命令,会按照上一次的x或者xp命令所使用的值。n默认为1。addr 也是一个
可选参数,如果不指定,addr是0,如过前面使用过x或者xp命令,指定了n=i,
则再次执行时n默认为i+1。
setpmem [addr] [size] [val] 设置物理内存某地址的内容。
需要注意的是,每次最多只能设置一个DWORD:
这样是可以的:
<bochs:1> setpmem 0x00000000 0x4 0x11223344
<bochs:2> x /4 0x00000000
[bochs]:
0x00000000 <bogus+ 0>: 0x11223344 0x00000000 0x00000000 0x00000000
这样也可以:
<bochs:1> setpmem 0x00000000 0x2 0x11223344
<bochs:2> x /4 0x00000000
[bochs]:
0x00000000 <bogus+ 0>: 0x00003344 0x00000000 0x00000000 0x00000000
或者:
<bochs:1> setpmem 0x00000000 0x1 0x20
<bochs:2> x /4 0x00000000
[bochs]:
0x00000000 <bogus+ 0>: 0x00000020 0x00000000 0x00000000 0x00000000
下面的做法都会导致出错:
<bochs:1> setpmem 0x00000000 0x3 0x112233
Error: setpmem: bad length value = 3
<bochs:2> setpmem 0x00000000 0x8 0x11223344
Error: setpmem: bad length value = 8
crc [start] [end] 显示物理地址start到end之间数据的CRC。
[寄存器操作]
set $reg = val 设置寄存器的值。现在版本可以设置的寄存器包括:
eax ecx edx ebx esp ebp esi edi
暂时不能设置:
eflags cs ss ds es fs gs
r|reg|registers reg = val 同上。
dump_cpu 显示完整的CPU信息。
set_cpu 设置CPU状态,这里可以设置dump_cpu所能显示出来的
所有CPU状态。
[反汇编命令]
u|disas|disassemble [/num] [start] [end]
反汇编物理地址start到end 之间的代码,如
果不指定参数则反汇编当前EIP指向的代码。
num是可选参数,指定处理的代码量。
set $disassemble_size = 0|16|32 $disassemble_size变量指定反汇编使用的段
大小。
set $auto_disassemble = 0|1 $auto_disassemble决定每次执行中断下来的
时候(例如遇到断点、Ctrl-C等)是否反汇
编当前指令。
[其他命令]
trace-on|trace-off Tracing开关打开后,每执行一条指令都会将反汇编的结果
显示出来。
ptime 显示Bochs自本次运行以来执行的指令条数。
sb [val] 再执行val条指令就中断。val是64-bit整数,以L结尾,形
如“1000L”
sba [val] 执行到Bochs自本次运行以来的第val条指令就中断。val是
64-bit整数,以L结尾,形如“1000L”
modebp 设置切换到v86模式时中断。
record ["filename"] 将输入的调试指令记录到文件中。文件名必须包含引号。
playback ["filename"] 回放record的记录文件。文件名必须包含引号。
print-stack [num] 显示堆栈,num默认为16,表示打印的条数。
?|calc 和WinDBG的“?”命令类似,计算表达式的值。
load-symbols [global] filename [offset]
载入符号文件。如果设定了“global”关键字,则符号针
对所有上下文都有效。offset会默认加到所有的symbol地
址上。symbol文件的格式为:"%x %s"。
[info命令]
info program 显示程序执行的情况。
info registers|reg|r 显示寄存器的信息。
info pb|pbreak|b|break 相当于blist
info dirty 显示脏页的页地址。
info cpu 显示所有CPU寄存器的值。
info fpu 显示所有FPU寄存器的值。
info idt 显示IDT。
info gdt [num] 显示GDT。
info ldt 显示LDT。
info tss 显示TSS。
info pic 显示PIC。
info ivt [num] [num] 显示IVT。
info flags 显示状态寄存器。
info cr 显示CR系列寄存器。
info symbols 显示symbol信息。
info ne2k|ne2000 显示虚拟的ne2k网卡信息。
弄明白了调试命令,接下来就可以着手进行NTLDR的调试工作了。下面所进行的工
作都是在Windows版Bochs 2.1.1上实现的。我们假设读者了解Bochs的基本使用方法和
术语。
首先要安装一个Windows NT 4的Bochs虚拟机。
1、创建虚拟硬盘。
运行bximage.exe,创建一个500M、flat模式的虚拟硬盘文件“C.img”。
2、创建一个Windows NT安装光盘的ISO文件“nt.iso”
如果你打算直接用光盘安装,也可以省去这一步。
3、创建bochsrc.txt
内容可参考下面:
###############################################################
megs: 32
romimage: file=$BXSHARE\BIOS-bochs-latest, address=0xf0000
vgaromimage: $BXSHARE\VGABIOS-lgpl-latest
ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14
ata0-master: type=disk, path="C.img", mode=flat, cylinders=1015, heads=16, spt=63
ata0-slave: type=cdrom, path="nt.iso", status=inserted
newharddrivesupport: enabled=1
boot: cdrom
log: nul
mouse: enabled=1
clock: sync=realtime, time0=local
###############################################################
4、创建start.bat
内容如下:
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::假设你的Bochs安装在D:\Program\Bochs
set BXSHARE=D:\Program\Bochs
%BXSHARE%\bochs.exe -q -f bochsrc.txt
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
把C.img、nt.iso、bochsrc.txt、start.bat放到同一个目录下,运行start.bat,
进行Windows NT的安装。
事实上,如果只是为了调试MBR、引导扇和NTLDR 的话,并没有必要安装完整的操
作系统,只要根目录下有ntldr等那几个文件就可以了。这里之所以安装Windows NT而
不是Windows 2000或者更高版本,一方面是考虑速度问题,另一方面,Windows NT 是
可以在Bochs上确保顺利完成安装的。如果要调试Windows 2000/XP/2003 的NTLDR,只
需用这些操作系统的ntldr文件替换Windows NT的即可。
安装完Windows NT之后,可以进行NTLDR的调试了。把start.bat中的“bochs.exe”
换成“bochsdbg.exe”。然后运行start.bat。
下面是操作的屏幕拷贝:
========================================================================
Bochs x86 Emulator 2.1.1
February 08, 2004
========================================================================
00000000000i[ ] reading configuration from bochsrc.txt
00000000000i[ ] installing win32 module as the Bochs GUI
00000000000i[ ] Warning: no rc file specified.
00000000000i[ ] using log file nul
Next at t=0 //启动bochsdbg.exe,会自动停在Bios的第一条指令上。
(0) context not implemented because BX_HAVE_HASH_MAP=0
[0x000ffff0] f000:fff0 (unk. ctxt): jmp f000:e05b ; ea5be000f0
<bochs:1> b 0x00007c00 //MBR和引导扇都会加载在0000:7c00。
<bochs:2> c
(0) Breakpoint 1, 0x7c00 in ?? () //第一次会在MBR上中断下来。
Next at t=772567
(0) [0x00007c00] 0000:7c00 (unk. ctxt): cli ; fa
<bochs:3> c
(0) Breakpoint 1, 0x7c00 in ?? () //第二次会在引导扇上中断。
Next at t=773872
(0) [0x00007c00] 0000:7c00 (unk. ctxt): jmp 0x7c5d ; eb5b
<bochs:4>b 0x00020000 //ntldr会加载在2000:0000,事实上无论是CDFS、NTFS还是FAT,
//Windows加载启动文件都是这个地址。
<bochs:5> c
(0) Breakpoint 2, 0x20000 in ?? () //在NTLDR的第一条指令上断下来了,可以开始进行调试。
Next at t=861712
(0) [0x00020000] 2000:0000 (unk. ctxt): jmp 0x1f6 ; e9f301
现在,我们可以像上帝俯看芸芸众生一样,看着操作系统一步一步启动起来,一
切尽在眼底,甚至可以看到系统启动过程中实模式切换到保护模式的情景:
(0).[28734582] [0x00020247] 2000:0247 (unk. ctxt): opsize or eax, 0x1 ; 6683c801
(0).[28734583] [0x0002024b] 2000:024b (unk. ctxt): mov cr0, eax ; 0f22c0
(0).[28734584] [0x0002024e] 2000:0000024e (unk. ctxt): xchg bx, bx ; 87db
(0).[28734585] [0x00020250] 2000:00000250 (unk. ctxt): jmp 0x253 ; eb01
(0).[28734586] [0x00020253] 2000:00000253 (unk. ctxt): push 0x58 ; 6a58
(0).[28734587] [0x00020255] 2000:00000255 (unk. ctxt): push 0x259 ; 685902
(0).[28734588] [0x00020258] 2000:00000258 (unk. ctxt): retf ; cb
|
|
2010-7-6 21:22 |
|
|
flexdm
新手上路
积分 12
发帖 5
注册 2005-12-25
状态 离线
|
『第
15 楼』:
HOHO
<b>today is my last working day in foxconn</b>
|
|
2010-7-7 01:05 |
|