This File is Write in Chinese.
欢迎使用解释型跟踪调试软件----TR
————刘涛涛
四、汇编指令作为命令
搞汇编语言的人满脑子都是汇编,复杂的调试命令可能不愿去记。能用汇编指
令作为命令当然是个好主意。用R AX 1234当然不错,用MOV AX,1234岂不更有意
思?其它CLI\MOV ,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 中断断点
(3)BPXB BYTES
遇到指定指令就停下。如:MOV AX,????的机器码为B8????,可用
BPXB b8
其它:
BPXB cd ;所有中断
BPXB 33 C0 ;XOR AX,AX
(4)BPREG REG|SEG
如果指定的寄存器改变,则暂停。BPREG CS可以找到所有的段跳。
BPREG CS AX=0 ES=# ;#指当前PSP
可以找到带外壳程序的真正开始。
(5)BPM OFFSET
如果访问指定地址则暂停。如BPM 20将使MOV AX,停下。
(6)BPW SEG:OFFSET
如果指定地址改变,则暂停。有些操作(如INT)对内存的改变只有一次次
检查是否改变才能找到。
(7)BPIO port
(8)BPKNL
如果发现新的程序内核,则暂停。
特别重要的是,如果一个断点只用一次,把设断点命令前面的'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, ;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
如果不带参数,显示当前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
显示信息窗。主要用在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
设定内存窗口的行数。
---------------------输入/输出 命令--------------------
A
汇编。虽然代码窗能够识别32位代码,A命令暂时不能处理32位代码。
将在以后的版本改进。可以直接用'BEGIN:'的方法定义标号。
A cs:0
start: ;define label
mov ax,bx ;any asm code
;return to command mode
D ]
以十六进制和ASCII码方式显示内存,加‘>’号把结果输出到文件,
如: D cs:ip
D *
D 1234:5678>myfile.txt
D cs:0lffff>file
D >file
如果指定文件不存在,则自动生成;如果已经存在,则追加。
缺省长度40H。
E 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 :OFFSET]
读文件到内存。注意与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 :OFFSET DRIVE STARTSECTER SECTERS
从指定物理驱动器读取指定物理扇区。
例: L 100 0 0 1 ;读A盘BOOT区
L 100 2 0 1 ;读C盘BOOT区
N
如果不带参数,显示当前文件名。如果带参数,置文件名。如:
N MYFILE.EXT
参见:W,L,RELOAD
RELOAD
重新调入文件。如果文件名已被N命令修改,则调入新文件。
重置所有中断向量、内存区、寄存器。
有时程序上一次申请的内存不能完全释放,导致调入失败。可以
退出TR再进,EXE2,RELOAD,仍然可以MKEXE。
U ]
反汇编,加‘>’号把反汇编结果输出到文件,如:
u cs:ip
u $
u 1234:5678>myfile
u cs:0lffff>file
u >file
如果不给出反汇编长度,缺省20H。
如果指定文件不存在,则自动生成;如果已经存在,则追加。
W
W :OFFSET
W :OFFSET filename
W :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 :OFFSET DRIVE STARTSECTER SECTERS
向指定物理驱动器写指定物理扇区。
例: W 100 0 0 1 ;写A盘BOOT区
WREG filename
把当前寄存器区内容写入文件。如文件存在则追加。
WMEM filename
把当前内存窗口内容写入文件。如文件存在则追加。
WCOD filename
把当前代码窗口内容写入文件。如文件存在则追加。
WCMD filename
把当前命令窗口内容写入文件。如文件存在则追加。
---------------------RUNTIME 命 令--------------------
DELAY
用于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 $。
?
帮助。如果不带参数,TR自动ZOOM命令窗口,简要显示每一条命令的语法和
功能。可以用Up/Down/PageUp/PageDown上下滚动窗口,F5恢复。
如果带参数,TR对参数计算后显示结果,如:
? ax 显示AX内容
? cx+dx 显示CX+DX的结果
? # 显示当前PSP
? @0:21*4
? $+5 显示CS:IP+5
CMT 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 OFFSET LABEL_NAME *新概念*
定义标号或过程名。
如果定义了标号或过程名,代码窗中将在该地址前留一行显示其名子,并把
所有JMP和CALL到该过程的语句翻译为‘CALL 过程名’而不是通常那样
‘CALL ????’。
程序标号全部存入文件‘当前文件名.cmt’,这是一个文本文件,可以直接
编辑。下次TR调入程序时自动装入。
例:
LABEL cs:200 file_open
参见:cmt,SYMBOLS
LOG *新概念*
是否记录历史。如果LOG ON,则TR将把以后执行的每条指令地址记录下来,
可以用VLOG命令查看。本命令只记录最后25条地址,如果要所有记录,请
用LOGS命令。
利用TR的LOG功能可以使用一种新的分析程序的方法,那就是“走后门”。
比如一个程序错误退出,如果用通常的办法从程序开始进行跟踪,要走很
长的路才能找到问题所在。而用TR的LOG功能,就可以在程序异常退出后分
析程序最后执行的什么过程,快速找到关键。
LOGS *新概念*
是否记录历史。如果LOGS ON,则TR将在当前目录下建一文件LOG.DAT,
并把以后执行的每条指令地址以十六进制存入该文件。方便以后分析程序
流程。视程序复杂度,该文件可能会很长。请使用专门的十六进制浏览器
浏览该文件,或用TR的VIEW命令。
当LOGS ON时,因为执行每一条指令都会有一次存盘,速度较慢,一般情况
下,用LOG ON就足够了。LOGS ON时,LOG自动为ON。
LOGPRO *新概念*
功能:把程序执行过的关键代码记录下来,便于分析。特别适合于正确
流程和错误流程的比较。
如果不带参数,则显示当前选项。各选项的意义:
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 :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
改寄存器值。可以是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
是否调入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 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 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。缺省为OFF。
当为ON时,如果TR遇到一条不可识别指令,则自动用INT1单步中断去执行。
参见:TT,INT1
INT1
这是一个标志,可以设为ON或OFF。缺省为OFF。
当为ON时,TR不再解释每一条指令,而是用INT1单步中断去执行。
不推荐使用ON的状态。如果你确认TR对某条指令的解释有误,可用状态ON
继续执行。如果只在此状态下执行一条指令,用命令TT。
影响命令:T,G,P等
参见:TT,AUTOINT1
AUTOJMP *新概念*
设置是否自动跳转。如果为ON,在执行过程中TR将不显示JMP指令,而把JMP
后的指令直接放在JMP指令原来的位置,并在该指令前加“—〉”符号以示区别。
这样在一些JMP过多的场合能使你容易保持清醒。如果你不习惯,让它OFF。
缺省为ON。
---------------------------------------------------------------------
断点命令
**** 如果断点只使用一次,把BP????改为GO????或GS???? ****
BL
列出所有断点。最多可设8个断点。
实际上是9个断点,断点0被GO系列命令占用。
BC
清除所有断点或指定断点。
BD
DISABLE所有或指定断点。
BE
允许所有或指定断点。
BPW segment:offset *新概念*
监视内存变化,如果指定位置的字(WORD)发生改变,则暂停。
如果设定此类断点,TR每执行一条语句都会进行一次比较。
BP 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
如果指定寄存器改变,并且条件满足,则暂停。
可以指定任意16bit通用寄存器或段寄存器。
特别推荐使用bpreg cs AX=0 DX=0 ES=#,一般可用来快速查找加外壳程序
真正的开始。
条件设置参见BP。
BPXB bytes
如果执行到批定的机器码,则暂停。如,因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
中断断点。如果执行指定中断,则暂停。如:
BPINT 21 AH=30
BPINT 13 AX=201 CH>30 DX=1
BPKNL *新概念*
如果AX=BX=SI=DI=BP=0,DS=ES=<PSP>,IP=0或IP=100或CS刚发生变化
(意味着刚有过一次JMP FAR或RET FAR),则暂停。一般用于寻找有外
壳的程序内核。注意有些加壳软件并不严格符合这个条件,用此方法可
能会漏掉。如果你有比此更好的主意,请告诉我。
万能的办法常常不是最好的办法。
---------------------------------------------------------------------
其它命令
EXE1
EXE2
WEXE1
WEXE2
GETKNL
参见下面《如何输出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为脱几层外壳,缺省为1。TR会自动运行:
exe1
reload
goknl count
wexe1
exe2
reload
goknl count
wexe2
q
TR生成两个文件mem1.dat和mem2.dat并退出。在DOS提示符下运行
mkexe
会生成文件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文件!
THKS.
原来保存这文章时删除了前面那三节。因为调试要用到的主要在后面这几节里。
没想到楼上的也有这篇文章。这样就完整了!呵呵。。。
既然有文章,
请问有没有完整的TR软件包啊?
能不能上传上来共享一下?
没有多大使用价值......