[转载]解释型跟踪调试软件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 便到。
四、汇编指令作为命令
搞汇编语言的人满脑子都是汇编,复杂的调试命令可能不愿去记。能用汇编指令作为命令当然是个好主意。用 R AX 1234 当然不错,用 MOV AX , 1234 岂不更有意思?其它 CLI\MOV [WORD 1234],4567\IN AL,21 都是不错的命令。
五、允许对调试程序作注解
CALL 7F2E 看起来当然没有 CALL OPEN_FILE 容易理解,但跟踪调试却不得不面对大串的莫名其妙的代码。即使某个过程经过跟踪已经知道是干什么的,也只能写到纸上。如果能把跟踪结果写到屏幕上,那是什么概念!整个程序变成了你手上的一篇文章,可以对它任意地圈圈点点。每一次跟踪都添加一些新的见解,最后,整个程序一目了然。参见命令 LABEL 和 CMT 。
是这个功能使跟踪变成了一项真正可以做的工作。
六、自动跳转
最近加密界出现了一种新的技术,用 JMP 指令把代码扯乱。这样跟踪者一次只能看到一条指令和一个 JMP ,看不见来路也看不见去路,跟踪工作变得异常 " 艰难困苦 " 。 TR 的自动跳转技术使得在执行过程中不显示 JMP 指令,而把 JMP 后的指令直接放在 JMP 指令原来的位置。经过 TR 的重组,提高了代码的可读性。
参见命令 AUTOJMP 。
七、历史记录
TR 可以把执行过的每一个 CS:IP 记录下来,以便静态分析。如果程序出错, 可以查历史记录向前回溯,找到问题所在。更有功能强大的 LOGPRO ,可以把程序的关键指令整理出来。被跟踪程序再无任何秘密可言。
参见命令 LOG 、 LOGS 、 VLOG 、 LOGPRO 。
八、把内存代码写成 EXE 文件
从内存中重构 EXE 文件的技术已经十分成熟,各种万能脱壳软件到处都是,但都是盲目地脱。随便拿到一个文件在 INT21\AH=30 处脱一下是不能解决问题的。脱壳应该是跟踪调试软件的一项功能,跟踪到了,再脱,万无一失。
九、复杂的断点,一次性断点。
各种调试软件所能设置的断点都是 INTEL 当初设计 CPU 时就想好的几种,远远不能满足高级跟踪的要求。 TR 创造性地提出了许多断点:
( 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' 便可直接执行。有了这个一次性断点,一般根本不需要专门设置断点。
以上这些新增的断点,千百倍地提高了跟踪的效率,再也不需要苦苦地跟踪了!
TR 是真正的跟踪调试软件!尽管我们上面提到了 DEBUG,SYMDEB,TD,CV,S-ICE ,但哪一个是真正的跟踪调试软件? DEBUG 和 SYMDEB 当然不能算是, 因为我想跟踪软件至少应该是全屏幕的。 TD 居然没有命令行输入,没有什么鼠标操作能比一行命令 F CS:DX,DX+CX 00 更能简单准确地表达你的意图。在 DEBUG 中至少还可以 L100 0 01 检查软盘 BOOT 区,可以 L400 或 W400 把一个文件调入指定内存或把内存写成文件, 在 SYMDEB 中还可以用一个 > 号把反汇编结果存起来, 可惜这些非常有用的功能其它软件都做不到。 TD 和 CV 不象是专门的调试软件,更象是为了对各自的C语言排错用的。 S-ICE 应该算是一个不错的跟踪调试软件了,但总是感觉 386CPU 的调试功能就是为 S-ICE 而留,而 S-ICE 也就是仅仅为了演示 386CPU 的调试功能。只有TR,真正为跟踪者着想,就软件的跟踪技术提出了九大新的思想,第一次使程序跟踪成为了一项真正可以为之的工作,TR是真正的跟踪调试软件!
TR 现在不支持 386 保护模式,不能处理 WIN95 程序。如果你要跟踪 DOS 保护模式程序, 16 位 Windows 程序, 32 位 Windows95 程序,请使用 TR for Win95:
[url]http://trw.yeah.net[/url]
在以后的版本中,这些问题将一一解决。
我一直在努力使 TR 达到完美,每天 TR 都有大的改变。请与我联系,你将获得最新版本。
作者 : 刘 涛 涛
地址 : 河南安阳彩玻公司资料室
邮编 : 455000
电话 : 0372-3932916-2273
EMAIL: [email]liutt@iname.com[/email]
[email]ayliutt@nease.net[/email]
主页 : [url]http://tr.kstar.com[/url]
[url]http://www.nease.net/~ayliutt[/url]
ICQ UIN: 3434573
98.3.3
--------------------------------------------------------------------------
须 知
一、 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 程序,请使用 TR for Win95 。
----------------------------------------------------------------------
TR 的屏幕显示
EAX=00003000 EBX=00000000 ECX=00000000 EDX=00002755 SP=007E
EBP=00000000 ESI=00000000 EDI=00000000 FS=0000 GS=0000
DS=2640 ES=2640 SS=2785 CS=2650 IP=000A o d I s z a p c t
2640:0000 CD 20 FF 9F 00 9A F0 FE-1D F0 1E 44 FD 07 6D 01 ............
2640:0010 13 06 78 01 13 06 13 06-01 01 01 00 02 FF FF FF ..x.........
2650:0000 BA5527 MOV DX,2755
2650:0003 2E89168B02 MOV [CS:DGROUP@],DX
2650:0008 B430 MOV AH,30
2650:000A CD21 INT 21 Get MS-DOS Version Number
2650:000C 8B2E0200 MOV BP,[0002]
2650:0010 8B1E2C00 MOV BX,[002C]
2650:0014 8EDA MOV DS,DX
2650:0016 A37D00 MOV [007D],AX
2650:0019 8C067B00 MOV [__psp],ES
2650:001D 891E7700 MOV [__envseg],BX
2650:0021 892E9100 MOV [0091],BP
2650:0025 E85101 CALL 0179
2650:0028 A17700 MOV AX,[0077]
2650:002B 8EC0 MOV ES,AX
2650:002D 33C0 XOR AX,AX
Super Program Trace (test version), Written by Ld. 06/16/97
Press '?' for Help
r32
Welcome !!! Tel:0372-3932916-2273 EMAIL: [email]ayliutt@hotmail.com[/email]
以上是 TR 的典型屏幕显示。主要有寄存器区、内存区、代码区、命令区、状态行。
一、寄存器区
屏幕的最上端是寄存器区。缺省为 16 位方式显示,可以用 R32 命令改为 32 位方式。
用 R 命令置寄存器值,如:
R AX 1234
R ebx 12321456
R ch 87
R dl ah
R ip ip+1
R fl z
对标志寄存器用 ODISZAPCT ,最近改变过的寄存器以不同颜色表示。
二、内存区。
内存区以十六进制和 ASCII 码方式显示内存内容。可以用 E 命令把光标转到内存区编辑,可以按左、右、上、下、上下翻页、 HOME 、 END 等键移动光标, 按字母数字键修改内存,按 TAB 键十六进制 ASCII 码转换。也可以用 e offset 'content' 直接修改。
用 WD num 改变内存区的行数。
内存区有两种显示方式,一种是普通的段不变偏移连续变化的方式,另一种是段以 10H 变化,偏移为 0 的方式。普通方式下,用 E 命令使光标到内存区, 如果当前 OFFSET 小于 0F 按向上箭头,变为第二种显示方式。用 D 命令恢复。
三、代码区
屏幕中央是代码区,显示程序的汇编代码。支持 386 指令, 可以显示标号和注解,对常用中断进行解释。
四、命令区
用于输入命令。可以按 F5 键放大,按左、右、上、下、上下翻页、 HOME 、 END 等键移动光标,用 DEL 和 BACKSPACE 修改。
如果要多次执行一条命令,把光标放到那条命令上按 ENTER 。
五、状态行
显示命令是否正常执行。
六、以上是 TR 的主要窗口,另处还有 F4 显示用户屏幕, VIEW 命令列文件内容, STACK 命令显示 STACK 窗, VLOG 显示历史窗等等。
----------------------------------------------------------------------
常用按键
执行一句汇编指令,等同于命令 T 。
执行一个过程,等同于命令 P 。
显示用户屏幕,等同于命令 RS 。
命令窗 <--> 代码窗。
如果光标在代码窗,执行到光标位置 (HERE) 。
最大当前窗口。当前窗口可以是命令窗、代码窗、内存窗。
如果光标在代码窗,设置(或清除)光标所在位置为断点。
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= , 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 文件!
---------------------------------------------------------------------
后 话
TR 比其它跟踪程序提供了许多新的功能,只要一个程序能在 TR 内用 G 执行,对它解密是一件非常简单的事。如果你发现一个程序 TR 不能正常处理(暂不考虑保护模式和 WINDOSE 程序),请送给我,我会马上送上新版 TR !
用解释的方法进行程序跟踪,是对程序进行虚拟机仿真执行。我相信,这种方法能够处理所有的计算机程序。
我会为之努力,我将更加努力。
页:
[1]