发信人: Reinhard.bbs@bbs.sjtu.edu.cn (摘星的人), 信区: cnhacker
标 题: DOS下软件解浅谈 (二) -- Alex 整理(转寄)
发信站: 饮水思源站 (Fri Apr 25 20:08:47 1997)
转信站: Lilac!ustcnews!ustcnews!sjtunews!sjtubbs
出 处: bbs.sjtu.edu.cn
发信人: kevin@SMTH (老人与海), 信区: Hacker
标 题: DOS下软件解浅谈 (二)
发信站: 水木清华 (Fri Nov 10 16:24:51 1995)
转信站: SMTH
DOS下软件解浅谈 (二)
| 清华大学 计算机科学与技术系 何开川
| EMAIL:hyj-dmp@mail.tsinghua.edu.cn
四、解密 = 跟踪 ?
如果要用两个字概括解密的实质的话,那就是∶跟踪;是的,就是跟踪。
我们在调试一般程序的时候也需要跟踪,但两者的目的是不尽相同的。后者是为
了排错、而前者是为了窥探,具体地说,就是找出程序在哪儿加的密、如何加的,
从而找到"修改点",以便将其改为解密版。
先介绍解密的几条思路∶
1)从头至尾式∶
拿到一个软件,从第一条指令开始,逐条跟踪,直至找到"修改
点",这就是最基本的解密方法。但要注意,跟踪过程中应采取"先粗后细,偶
而回溯"的方针。比如下面一段程序∶
* * *
Initialize
|
V
Call Module1
|
V
Call Module2-->Call Module3
| |
V V
... Call Module4 -> Call Module 5
|
|
V
检查Password Or ax,ax
我们要找的修改点 ======> jz 游戏入口
jnz 显示"Password" 不对
...
* * *
我们要找的"修改点"藏在Module 4里面,如果我们从Module1开始一条一条
跟的话,恐怕要看几千条指令,但如果我们按"先粗后细"的原则,先用P 命令,
即Step方式跟踪,当发现Step过Module2时,游戏已检查过Password,说明跟"过"
了,于是用"偶而回溯"策略,从新执行程序,这次跟入Module2, 再用P粗
线条跟踪,发现Step过Module4后又错过了"修改点",于是返回头来跟入Module4,
这次终于发现在一处由 Or ax,ax / jz XXXX 产生的分支与程序是否"认
为"Password正确直接相关,不妨试着把jz XXXX改为jmp XXXX--成功了,
游戏已正常进入主画面。这说明我们找到了"修改点",解密的主要工作也就完成
了,关于如何把这一修改"固化"下来,参见后文。
2)中途拦截式∶
抗日影片《铁道游击队》中,机警勇敢的游击队战士在同日寇交锋时常
常不是正面进攻,而是早早地埋伏在铁路旁,等敌人的火车经过时,给它来个"
中途拦截",从而达到出其不意的制胜效果。 在软件解密的过程中亦有同样的战
术∶拿到一个软件后,先不忙着从头跟起,而是考虑一下,有没有办法跳过程序
的初始化部分,直接切入程序判断密钥的"关键点"或是"关键点"附近的部分。若
是存在这样的捷径,就可省去不少跟踪之苦。
这里,仅以解拆游戏PASSWORD为例。让我们思考这样一个问题∶程
序何时判断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。
[未完待续]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\ | / .--- *** Soft Art Is the True Art***
{ . .} | ]
\ - | . . / He Kaichuan //// Email:hyj-dmp@mail.tsinghua.edu.cn
=== !
O ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`
--
沉默的人
Reinhard Young
※ 来源:·饮水思源站 bbs.sjtu.edu.cn·[FROM: 202.96.212.29]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:2.883毫秒