📄 dosje.txt
字号:
序何时判断PASSWORD? 如果我们知道了这个时刻,就可在恰当的时间拦截到
其完成判断功能的代码,从而解之。不失一般性,我们可以假设程序总是在我们
输入PASSWORD之后开始判断,那么通常有两种拦截方式。
(a) 热键拦截∶
我们在前面说过,SOFT-ICE具有很强的热键激活能力。因而我们可以
在输入PASSWORD后立即按下热键,如果运气好的话,程序可能还没有判断密
钥,那么你就可以TRACE啦。不过,这种作法随机性太大,而且还有可能受到
DOS或ROM例程的干扰(详见下文"跟踪原则")。为了避免这些缺点,我们也可
采用中断拦截方式。
(b)中断拦截∶
如果大家对DOS及BIOS的中断机制比较熟悉的话,现在就可以派上用
场了。我们知道,不论程序是如何输入密码的,在这段过程中都免不了调用各种
中断。因为DOS、BIOS中断之于DOS程序,就如WINDOWS API之于
WINDOWS程序一样。 如果软件在输入时用键盘,多半要调INT 16;如果用鼠
标,则要调INT 33; 即使是密码输入错误程序准备结束时,也要调INT 21
(AH=4C),如此等等。 如果我们估计到程序在密码输入、判断过程中要调某一
中断,就可用SOFT-ICE的BPINT指令在相应中断上设一段点,从而中断到离
密码判断较近之处,而且可以避免用热键中断时断到ROM或DOS的麻烦。
3)迂回前行式∶
对一般软件,前两种方法已是足够,但一味套用终有碰壁的时候。其实
加密、解密本没有固定的方法,最高明的方法也许就是"没有方法",即随机应变、
具体问题具体分析,解密的过程实际上就是想出一个新方法的过程,当你沿着一
条思路憋住的时候,不妨换个角度,说不定就柳暗花明了呢。 比如说你从头跟
踪理不出头续,就可以中途拦截试试嘛,中途拦截进去还是一头雾水,那就把从
头跟踪得到的结果与中途拦截的结果对照一下,来个"两头加击",没准就能看出
端倪。总之,跟踪的过程常常不是一条"直线",而是一条左折右回的"曲线",我
们就把这最后一条思路称为"迂回前行式"吧。
也许看到这里,你已经跃跃于试了,但真地一跟踪还是一团乱麻,别急,
下面让我们再来谈谈解密跟踪时的几条原则∶
1) 瞄准判转语句∶
因为我们解密的手段从本质上讲是修改软件"密码判断"之后的走向。因
而在程序判断密吗的段落附近,任何与"判断"有关的语句都应得到重视。不过,
要注意,"判断"语句未必都是 "CMP AX,0001", 象下面这些语句都可肩负"
判转"的任务∶
(1) OR AX,AX
JZ XXXX
(2) MOV SI,0100H
MOV DI,0200h
MOV CX,0FH
REPNZ CMPSB
JZ ENTER_GAME
JMP EXIT_GAME
(3) TEST AL,0FFH
JNE DEAD_OUT
JMP CORRECT_BRANCH
(4) SUB AX,0001H
JZ XXXX
(5) ADD AL,0FFH (等价于: CMP AL,01H
JC ALL_RIGHT JZ ALL_RIGHT)
....................
2) 逃离循环体∶
跟踪时最怕掉入一个与"目标"无关的循环体中而白白浪费时间。所以一
旦感到在某几段代码间兜圈圈,要马上找到循环出口"逃离"掉。
3) 注意错误分支∶
当你瞎蒙PASSWORD 时多半会进入错误分支,但要注意一点∶错误分
支的反面可能就是正确分支。
4) KEEP AWAY--ROM代码∶
如果你是用热键断入的,很可能掉入ROM代码中,判断的方法很简单,
只要看当前段址是否为 F000-FFFF之间。这时,不用仔细看了,找一个IRET语
句返回即可。
还有一种可能是掉如DOS或其它驻留内存程序的代码段,判断的方法也
不难, 看看当前地址是否在最后常驻的程序所占内存块之后(用MEM /C/P可在
DOS下查看常驻程序占用的内存块),若在之后则说明没有,否则即是掉了进去,
解决的方法同样是尽快返回。
5) 注意选择"单步"和"步进"∶
用单步可以仔细跟踪每一个子程序,用步进则可节省时间、不至陷入毫
无意义的细节。
6) 善于对跟踪过程的"关键点"作记录∶
跟踪是一件辛苦的工作,每发现一个"可疑"之处都应该作简要记录,免
得最后跟出来了却忘记了跟踪的"路径"。
7) 大处着眼、小处落手∶
有可能的话,要把握程序的整体脉络,"体会"作者的思路,不要只见树
木不见森林,只看到一条一条的机器代码。
应该说跟踪过程还有很多经验可循,但难以一一列出,解密者只有通过
大量的实践才能切身体会到其中的规律。
五 修改∶
如果按照前面所讲的思路跟出了"关键点"、找到了动态将其改动、解密
的方法,那么下一步就是通过静态修改软件的运行文件把这一解密"成果"固定下
来,方法很简单∶
比如我们通过动态分析发现把程序某处的一条JZ 100改为JNZ 100即可
实现解密,那么我们可以记录下来包括JZ 100在内的 JZ100附近的几条汇编指
令的机器代码,以及修改后的相应代码,如∶10 FF 2A 74 2A (修改前),10 FF 2A
75 2A(修改后),然后用PCTOOLS之类有代码串替换功能的工具把该软件的运行
程序作SEARCH/REPLACE即可,上例中即∶把串 10 FF 2A 74 2A替换为 10 FF
2A 75 2A。
0========================0
| DOS下软件解浅谈 (三) |
+========================+
| 清华大学 计算机科学与技术系 何开川
| EMAIL:hyj-dmp@mail.tsinghua.edu.cn
六 破解实例∶
光说不练,是很难提高解密水平的,下面就让我们通过一些简单的例子
来理解文中讲述的方法和思路。
【解拆实例一】∶破COMBAT(魔鬼训练营)之PASSWORD
(1)环境描述∶
COMBAT为一早期PC机上动作游戏,由menu.exe, damn.exe组成主
干,其运行过程是先运行menu.exe让你输入密码,若输入正确则开始游戏,否
则退出。
(2)破解思路∶
在输入密码时直接用CTRL+D断入,首先确认是断在了程序menu.exe
的内存区里, 然后从当前DS所含段址开始搜索断入SOFT-ICE前已输入的密
码(我输入的是father,但注意,我并未按回车),如∶ father,找到了一处地址A。
可推知,menu.exe将来判断密码时必要读取地址A处的若干字节。于是在地址
A设内存断点(bpm A),继续运行,按回车后断点被激活、进入SOFT-ICE。接
下去跟踪,发现有一段程序对A处所存之字符串进行归简运算和一些判断,可
猜想此段程序之后要进入"关键点"了。果然,跟出了这一子程后发现如下代码∶
xxxx:c59 cmp byte ptr [bp-13],0
xxxx:c5d jnz c7b
xxxx:c5f call 95c ;掉入此支路则显示"Incorrect ...."
call 1e7d
call 87a
xxxx:c7b cmp byte ptr [bp-13],0
xxxx:c7f jnz c84
xxxx:c81 jmp 984 ;向前跳,不妙!
xxxx:c84 mov sp,bp
pop bp ;摆好了正常退出的架式,有希望
pop di
pop si
ret
经分析,发现只有当c59和c7b两处判断均"不等"时,才会正确进入游戏,
于是,把c5d处指令改为 jmp c84即可。
【解拆实例二】∶破"欢乐麻将"之PASSWORD
(1)环境描述∶
一上来连考三道题目(麻将知识) ,回答在A-Z之间选(用光标键控制方
向,用<ENTER>选取),三道答错则退到DOS。
(2)破解思路∶
前面提到过GAME BUSTER在解密时也可派上用场,就让我们拿这个例
子作为说明吧。
a.)用GAME BUSTER跟踪光标键控制的"白框"的位置(这对游戏高手们
来说应该不难吧)
b)分析得到两个地址,一个是刷新前坐标,一个是刷新后的坐标,皆用
BPM锁之(设读、写断点)。
c)X<enter>退到游戏后会连续跳出几次断点,因此时尚为按<ENTER>,
故不予理睬,直至按下<ENTER>选中某一字母时,开始关注断点。
d)容易发现弹出某次"读"断点后,程序将该地址内容(即我们所选的答案)
与AX比较,等则跳,实际总是不等,因为我们输入的答案不对,故将该条件转
移改为无条件跳入正确支路即可。
【解拆实例三】∶破GODS(魔法战神)之PASSWORD
(1)环境描述∶
进入后用键盘输入密码(<ENTER>表示输入完成),正确则进入主画面,
否则退出。
(2)破解思路∶
法一∶(中途拦截)
用BPINT 16监视键盘服务例程,掉入INT 16 后,发现该例程为游
戏自己写的键盘服务程序,跟出该例程,找到其处理按键的多路分支,顺着处理
ASCII码13的一路跟进去(想想看,为什么? 提示一下,13H是"回车"的
ASCII码) ,可看到一条CMP指令比较密码是否正确,改之即可。
(2)法二∶(迂回前行法)
考虑到GODS.exe只是一个很短的"子进程",被主进程调用(另一
EXE程序),用来判断密码,若正确则以某种返回码返回主进程,否则退到DOS。.
因而我们是不是可以绕一个圈子,兜过GOD.EXE的密码判断部分、直接返回主
进程(带回正确的返回码)来达到解密目的呢? 答案是肯定的。我们只需在
GODS.EXE的某处(必须在检查密码的代码之前)插入指令∶
MOV AX,4C00
INT 21H
强行返回主进程即可。连断点都不用设,简单吧?
【解拆实例四】破"图象截取软件”(GET。。。) 之密钥盘检查∶
(1) 环境描述∶
该软件有INSTALL.EXE安装,若不是原版盘则安装过程无法进行,程
序亦无法正确解包。
(2) 破解思路∶
此例意在说明解密并不只限于游戏软件,事实上真正意义上的软件解密
往往是破解密钥盘一类的"高级PASSWORD"。
既然要读盘,不妨拦一下INT 13。果然在其读钥盘时断了下来,我
们发现其对INT 13的调用发生在一个子程里,该子程返回后有下列语句∶
CALL 读盘子程
OR AX,AX
JZ 某分支
xxxx: 显示"非原版盘......"
你该知道下面怎么做了吧?
【解拆实例五】破SOURCER 5.04序列号∶
(1) 环境描述∶
软件第一次在新机器上运行时需输入正确的序列号,以后再在同一台机
器上可直接运行,若拷到新机器上运行则仍需输入序列号。
(2) 破解思路∶
既然是从键盘输入序列号,自然想到在INT 16上设断点,断入 INT 16
的调用处后可在附近找到 CMP AL,0D (检测最近输入的字符是不是回车符)
语句,跟入此分支可看到序列号比较部分,密码形式为类似于S123456-ABCD
比较分3段进行,只需动态地让三段比较的结果由不等变为"相等" ,(若理解了
前面的例子,这应不难吧),即可将该软件在此机上"注册",以后只要不换机器
就可直接运行。
然而,这样解密尚不"彻底",若能改成在任何机器上都不需注册就能直
接运行才好。让我们比较一下已"注册"和未"注册"的SR..EXE,发现两者的最后
三个字节不同,且这三个字节的格式正是BIOS日期的"年、月、日"。可猜想软
件运行开始时把当前ROM的日期和上次注册成功后存储的ROM日期做比较,
若相同则直接进入程序,若不同则要求用户输入"序列号"从新注册。于是从新跟
踪程序,用BPM在程序最后三个字节对应的内存地址处设断点,断入后发现程
序果然从ROM中取出日期同程序最后三个字节进行比较,相同时直接运行,那
么我们把此处比较改为"恒等"即可。
此例说明解密的过程有时难以"一次到位",通过换一个角度对已解软件
进行"二次分析",可能会有新的发现。
七、深一步的探讨∶
用本文所述方法可解大多数DOS下软件,特别是GAME软件,但还远
非全部.。有些软件用了动态解码技术,或经过了"压缩"处理,使得用SOFT-ICE
跟出来解法后仍无法对其代码做出"静态"的修改,这时就要编写TSR解密程序
来动态解密;有些游戏用DOS 4GW等保护模式的DOS-EXTENDER接口写成,
无法用SOFT-ICE之类的面对实模式的调试器来跟踪;有些专业级的加密软件采
取了多种反跟踪手段来防止动态分析.......对所有这些解密技术的讨论已超出了
本文的范围。不过,我相信,只要大家多动脑筋并且乐于实践,那么彻底掌握
DOS下的软件解密技术亦非难事。
八 后记:
原来看BBS的时候,发现很多解密方面的文章都是台湾的高手们POST的,在感叹
人家水平不凡的同时,也在想我们大陆不也有很多高手嘛,为什么我们的HACKER版总
有点冷清呢? 想必是我们INTERNET连的晚,BBS也才刚刚建立起来嘛,总有一个过程不
是,我就先带个头,把这篇投校刊(《清华电脑》)的稿子POST上来了,
在下不是什么高手啦,只是想借此文帮助想解密的朋友介绍一下基本思路,同时
也是对自己的一些经验的小小的总结,希望对您有所帮助。 若您发现文中的任何错误
或有任何意见都欢迎给我EMAIL啦,我也特别希望喜欢琢磨加解密的朋友们能够多多交流,
这样大家才能共同提高嘛!
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -