Fancy Blog

  :: 首页 :: 博问 :: 闪存 :: :: 联系 :: 订阅 订阅 :: 管理 ::

计算机加密反跟踪技术密文技术

一)跟踪技术
大家知道DOS中有一个功能强大的动态跟踪调试软件DEBUG,它能够实现对程序的跟踪和逐条运行,其实这是利用了单步中断和断点中断的原因,而且目前的大多数跟踪调试软件都是利用了这两个中断。

单步中断(INT1)是由机器内部状态引起的一种中断,当系统标志寄存器的TF标志(单步跟踪标志)被置位时,就会自动产生一次单步中断,使得CPU能在执行一条指令后停下来,并显示各寄存器的内容。
断点中断(INT3)是一种软中断,软中断又称为自陷指令,当CPU执行到自陷指令时,就进入断点中断服务程序,由断点中断服务程序完成对断点处各寄存器内容的显示。
G命令的执行过程:DEBUG中的G命令是用于运行程序的,但当G命令后面跟有断点参数时,就可使程序运行至断点处中断,并显示各寄存器的内容,这样就可以大大提高跟踪的速度。它的实现是通过调用断点中断来实现的:DE-BUG首先保存设置的断点处指令,改用断点中断INT3指令代替,当程序执行到断点处的INT3指令时,便产生断点中断,并把原先保存的断点处指令重新替代INT3,以完成一个完整的设置断点的G命令。通过对单步中断和断点中断的合理组合,可以产生强大的动态调试跟踪功能,这就对磁盘加密技术造成了巨大的威慑,所以破坏单步中断和断点中断,在反跟踪技术中就显得十分必要,成为反跟踪技术中的"必修课"。

二)反跟踪技术
作为反拷贝技术的保护者反跟踪技术是整个磁盘加密技术中最能显示技术水平的部分,如果它稍有漏洞就会影响到整个磁盘加密技术的可靠性.不过毫无漏洞的反跟踪技术是没有,随着时间的推移、编程工具的更新和经验的积累,反跟踪技术只会向完美逼近,但可以肯定的是:一定不会达到完美,这和哲学中的"绝对和相对"是同一个道理。一个卓越的反跟踪技术虽然肯定有着微小的漏洞,但是它本身其它的技术可以起到弥补和尽可能减小这个漏洞的作用,这就是这个反跟踪技术的卓越之处。一个有效的反跟踪技术应该具有3大特性:

重要程序段是不可跳越和修改的:PROLOK的解密过程是通过修改判读指纹的程序段来实现的,这其实是激光加密系统中反跟踪技术的一个败笔,一个有效的反跟踪技术应该对加密系统中的某些甚至全部程序段进行保护,如果这其中有内容被修改,将导致出错,主要方法有累计、累或和异或和程序段等方法,同时还要保证重要程序段一定要被执行,方法主要有加密程序分段加密,运行时逐层解密,逐层清除的方法,即只有运行了重要的程序段,才能将下一层程序代码从密码形式转换成明码形式;
不通过加密系统的译码算法,密码不可破译:为塑造一个封闭的加密系统,杜绝使用外调自编子程序甚至手工转换密码,规定只能由加密系统的译码程序来转换密码;
加密系统是不可动态跟踪执行的:动态跟踪是对加密系统的窥视,所以反跟踪技术应该绝对禁止对加密系统的动态跟踪。
反跟踪技术主要采用的方法有:

抑制跟踪中断:DEBUG的T和G命令分别要运行系统的单步中断和断点中断服务程序,在系统向量表中这两个中断的中断向量分别为1和3,中断服务程序的入口地址分别存放在0000:0004和0000:000C起始的4个字节中。因此,当这些单元中的内容被修改后,T和G命令将无法正常执行,具体实现方法:
(1)将这些单元作为堆栈使用;
(2)在这些单元中送入软件运行的必要数据;
(3)将软件中某个子程序的地址存放在这些单元中,当需要调用时使用INT1和INT3指令来代替CALL指令;
(4)放入惩罚性程序的入口地址。

封锁键盘输入:各种跟踪调试软件在工作时,都要从键盘上接收操作者发出的命令,而且还要从屏幕上显示出调试跟踪的结果,这也是各种跟踪调试软件对运行环境的最低要求。因此反跟踪技术针对跟踪调试软件的这种"弱点",在加密系统无须从键盘或屏幕输入、输出信息时,关闭了这些外围设备,以破坏跟踪调试软件的运行环境。键盘信息的输入采用的硬件中断方式,由BIOS中的键盘中断服务程序接收、识别和转换,最后送入可存放16个字符的键盘缓冲区。针对这些过程反跟踪技术可以采用的方法有:
(1)改变键盘中断服务程序、BIOS的键盘I/O中断服务程序的入口地址:键盘中断的中断向量为9,BIOS的键盘I/O中断的中断向量为16H,它们的中断服务程序的入口地址分别存放在内存地址0000:0024H和0000:0058H起始的4个字节中,改变这些地址中的内容,键盘信息将不能正常输入。
(2)禁止键盘中断:键盘中断是一个可屏蔽中断,可通过向8259中断控制器送屏蔽控制字来屏蔽键盘中断。控制键盘的是中断屏蔽寄存器的第1位,只要将该位置1,即可关闭键盘的中断。
INAL,21H
ORAL,02H
OUT21H,AL
需要开放键盘中断时,也要用三条指令:
INAL,21H
ANDAL,FDH
OUT21H,AL

(3)禁止接收键盘数据:键盘数据的接收是由主机板上8255A并行接口完成的。其中端口A用来接收键盘扫描码,端口B的第7位用来控制端口A的接收,该位为0表示允许键盘输入,为1则清除键盘。正常情况下,来自键盘的扫描码从端口A接收之后,均要清除键盘,然后再允许键盘输入,为了封锁键盘输入,我们只须将端口B的第7位置1:
INAL,61H
ORAL,80HOUT61H,AL
当需要恢复键盘输入时,执行以下三条指令:
INAL,61H
ANDAL,7FH
OUT61H,AL

(4)不接受指定键法:在DEBUG中T、P和G都是用于动态跟踪的关键命令,如果加密系统关键命令,如果加密系统在运行时必须从键盘上接收信息(这个时候加密系统容易被各种跟踪调试软件截获,所以应尽量避免),可以通过对键盘中断服务程序的修改扩充,使之不接受T、P和G这些敏感的键码,以达到反跟踪的目的。当然这是一种不得以而采取的方法,因为它有相当大的局限性和漏洞:一是如果加密系统在接受的信息中,可能牵涉到T、P等键码,这种方法就行不通了;二是DEBUG下的动态调试命令是T、P和G,那么其它的跟踪调试软件呢?显然其它的软件就不一定是这些命令了,而且还不乏两个键码、三个键码以及更多键码组成的动态调试命令。
3.设置显示器的显示性能:当加密系统无需在屏幕上显示信息时,可以通过各种方法关闭屏幕,这样可使解密者无法得到跟踪调试软件返回的任何信息,以阻止解密者对加密系统的破译。这种反跟踪技术在实现方法上也有5类:

(1)封锁屏幕显示:可以重新设置屏幕特性,将前景和背景色彩置成同一种颜色,使解密者在跟踪期间无法看见调试信息:
MOVAH,0BH
MOVBH,0
MOVBL,0
INT10H

这时屏幕的背景颜色和字符颜色均被置成黑色,当需恢复屏幕的显示特性时,可将上述第3条指令中的BL值换成1~7,便使字符的颜色变成深蓝、绿和红色等。

2)检查加密系统是否处于被监控状态:各类跟踪调试软件在显示信息时,必然会出现屏幕上卷和换页等操作,因此可以经常检查屏幕上某些位置的状态,若有变化则一定有人在跟踪程序。获取屏幕信息的方法可用以下指令来实现:
MOVAH,02
MOVBH,0
MOVDH,行光标值
MOVDL,列光标值
INT10H
MOVAH,08
INT10H

这样就可以读取光标处的字符和属性了。
(3)修改显示器I/O中断服务程序的入口地址:显示器I/O中断INT10H的中断入口地址存放在内存地址0000:0040H开始的4个字节中,修改这4个字节中的内容,就可破坏或扩充显示器I/O中断服务程序。
(4)定时清屏:利用对时钟中断的扩充,可以使时钟中断定时清屏。
(5)直接对视屏缓冲区操作:每台机器都有固定位置和长度的视屏缓冲区(具体的位置和长度随显示器的类型而不同),不过各类显示器上的所有信息都是视屏缓冲区中信息的反应。如果软件直接对视屏缓冲区进行操作,可以获得比利用显示中断快得多的显示速度,现在许多先进的跟踪调试软件都采取了这种方法,一是提高速度;二是针对反跟踪技术,所以反跟踪技术仅仅只修改显示中断的入口地址是远远不够的,还要通过对时钟中断的修改扩充,定时频繁地刷新视屏缓冲区中的内容。
检测跟踪法:当解密者利用各种跟踪调试软件对加密系统分析执行时,势必会造成许多与正常执行加密系统不一致的地方,如运行环境、中断入口和时间差异等等。如果在反跟踪技术中对不一致的地方采取一定的措施,也同样可以起到保护加密系统的目的。实现这种方法的关键在于以下两个方面:一是如果检测到加密系统是否被跟踪,二是检测到被跟踪后如何进行处理,前一个方面的实现主要依靠加密者对DOS内核和跟踪调试软件的深入了解,后者则一般是一种死循环、启动机器或提示非法跟踪并停止运行的程序,但也不排除有惩罚性动作的程序,在这里只主要讨论第一方面:(1)定时检测法:一个程序在正常运行和被跟踪运行时,所花的时间是大不相同的,可以想象一个被跟踪运行的程序往往要花费极长的时间,反跟踪技术抓住这个特点,根据执行时间的长短来判断是否被跟踪。这种技术在具体实现时有两点要注意:①确定程序正常运行时所需的时间:这个时间的取值一般比最慢速机器(8088)运行的时间稍微长一些,如果在检测执行时间时发现所用时间还大于定下的时间值,就可以肯定当前的程序是被跟踪执行;②发现执行所用的时间小于定下的时间值,也不能认为是?绝对没被跟踪,这是因为DEBUG的T和G命令在执行时将禁止所有可屏蔽的中断,用以计时的时钟中断也不例外,所以如果用T和P命令对程序进行动态跟踪执行时,会完全停止时钟的计数,有可能出现执行时间远小于规定的时间值的情况(甚至可能出现不用时间的怪事)。解决这个问题的办法除了利用抑制跟踪中断法外,还可通过时间中断1AH来解决:如果发现时钟不走动,则进入死循环。
MOVAH,0

INT1AH;读当前时钟值

MOVBX,DX;读取的时钟低部存入BX

LOOP:MOVAH,0

INT1AH

CMPBX,DX;比较时钟低部是否变动
JZLOOP;时钟未走动则返回重读

另外还存在另一种可能的情况:即解密者简化了加密程序,则也会引起执行所用时间小于规定值的情况,这种方法的对策是在反跟踪技术中加入定时检测关键部位数据是否改变和对代码实施保护法。(2)偶尔检测法:在加密系统中加入判断时间的功能,并且当时间满足某一条件时再对加密系统中的关键部位进行判断,如果关键部位不存在或发现了变化则可判定加密系统已经被破坏,应立即做出相应的反应。象这类反跟踪技术可以出现在加密系统的各处,并为了增加解密难度,还可以使多次出现的这类反跟踪技术紧密联系、环环相扣,以造成一种永远无法解密的感觉。这类技术如果运用于大的程序中可以极大的提高磁盘加密技术的可靠性,甚至几乎不可解密。(3)利用时钟中断法:时钟中断INT8大约每隔55ms就要被执行一次。它主要处理两项任务:一是计时;二是管理软盘驱动器的启闭时间,另外在它执行时,还要再次调用INT1AH和INT1CH中断,这其中的INT1CH中断实质上只是一个空操作的中断,它主要用于用户有某种周期性的工作时,让用户用自己设计的中断服务程序取而代之的。在反跟踪技术中利用时钟中断可以定时检查前台任务执行的情况,如果发现前台的程序被非法跟踪调试,可以立即采取相应的措施,也可以对中断向量表作定时检查、计算程序执行时间、密文的译码操作和前面说到的定时清屏等等。利用时钟中断法是一个非常有效的反跟踪技术,通过对INT1CH中断的扩充,时钟中断可以完成许多任务,但要注意的是,这个扩充程序不宜过大,以免影响前台程序的执行速度。(4)PSP法:每个程序在执行时都必须建立对应的程序段前缀PSP,当程序未被跟踪执行时,PSP中14H与16H开始的两个字节是相同的,当被跟踪运行时,这些内容就不会相同。(5)中断检测法:一个执行的程序如未被跟踪,则INT1和INT3的入口地址相同,且都为哑中断,如被跟踪则相反,所以通过检测INT1和INT3的入口地址即可判断是否被跟踪。

破坏中断向量表:DOS提供了从0到FFH的256个中断调用(见表1),它们驻留在内存的较低地址中,相应的入口地址位于内存0000:0000至0000:03FFH中,每个入口地址由4个字节组成,其中前两个字节为程序的偏移地址,后两个字节为程序的段地址。DEBUG等跟踪调试软件在运行时大量地使用了DOS提供的各类中断,不仅如此,比DEBUG功能更强大,甚至针对反跟踪技术设计的高级反反跟踪调试软件也调用了DOS中断,典型的例子就是使用其它中断来代替断点中断的反反跟踪技术。破坏中断向量表显然可以从根本上破坏一切跟踪调试软件的运行环境,以达到"以不应万变"的最终目的。DOS和BIOS有个40段的数据区,它位于内存0040:0000至0040:00FFH,这256个字节存放的都是当前系统配置情况,对这些内容的修改也会直接影响到各类跟踪调试软件的正常运行。从LOCK89开始就已经使用了破坏中断向量表和部分40段数据区的反跟踪技术,因为这种技术的卓越表现,直至LOCK93这种反跟踪技术一直被保留延用下来。破坏中断表在其它反跟踪技术中也出现过,如:抑制跟踪中断、改变键盘中断服务程序入口地址和修改显示器中断服务程序入口地址等等,所以破坏中断表是一个涉及面极广、效果极好的反跟踪技术,它能最大程度地阻止解密者对加密系统的直接或间接动态跟踪,使解密技术面临一个全新的问题。
设置堆栈指针法:跟踪调试软件在运行时,会产生对堆栈的操作动作,比如:保存断点。因而在反跟踪技术中对于堆栈指针的运用就显得相当重要了,比如对堆栈指针的值进行设计,并力求使设计的结果具备一定的抗修改性,以免解密者通过再次修改堆栈指针的值来达到继续跟踪的目的。!TB38013100.gif
(1)将堆栈指针设到ROM区:只读存储区ROM是无法保存数据的,堆栈指针如果指向ROM区域,势必不能保存数据,这将会使跟踪调试无法继续进行下去。
(2)设在程序段中:堆栈指针如果设在将要执行的程序段中,那么任何的堆栈操作都会破坏程序代码,使程序不能正常运行。
(3)设在中断向量表内:INT1和INT3是反跟踪技术一定要破坏的中断,所以将堆栈指针设在内存的低地址段内,既可以进行少量的堆栈操作(跟踪调试软件一般需要大量的堆栈来存放数据),还可以破坏单步和断点中断的入口地址。
(4)将堆栈指针移作它用:如果确认没有堆栈操作的话,可以将堆栈指针拿来做其它用途,如保存经常要更换的数据,这样就可以使堆栈指针的值经常更换,从而使它根本无法保存数据。设置堆栈指针法是一个针对动态跟踪设计的反跟踪技术,不过它的运用有着一定的限制:(1)要保证将要执行的程序段不能进行有效的堆栈操作;(2)在要进行堆栈操作时,必须首先恢复正确的堆栈指针。设置堆栈指针不会影响到时钟中断保存数据,因为象时钟和键盘等系统中断保存数据所用的都是系统栈,而不象单步和断点中断是用堆栈来保存断点的。
对程序分块加密执行:为了防止加密程序被反汇编,加密程序最好以分块的密文形式装入内存,在执行时由上一块加密程序对其进行译码,而且在某一块执行结束后必须立即对它进行清除,这样在任何时刻内不可能从内存中得到完整的解密程序代码。这种方法除了能防止反汇编外还可以使解密者无法设置断点,从而从一个侧面来防止动态跟踪。
对程序段进行校验:对一个加密程序的解密工作往往只是对几个关键指令的修改,因此对程序段特别是关键指令的保护性校验是十分必要的,这样可以防止解密者对指令进行非法篡改。具体方法有累计、累减、累或和异或和程序段等方法。
迷惑、拖垮解密者:为了迷惑和拖垮解密者,可以在加密系统中多多设置专门针对解密者的"陷阱",这样既可以消耗解密者的时间和精力,还可以磨灭解密者的斗志和毅力。
(1)设置大循环:程序越简单,就越易读,跟踪也就越方便,便于这个原因,在加密系统中设置大循环,可以在精力上消耗解密者,延长跟踪破译加密系统的时间。这种反跟踪技术已经被广泛应用,而且取得了较好的效果。它的具体实现方法是:在加密程序中设置多重循环,并使上一层循环启动下一层循环,下一层循环启动下下一层循环,如此循环,而且还可以频繁地调用子程序,还要保证不能有一层循环被遗漏不执行。
(2)废指令法:在加密程序中设置适当的无用程序段,而且在这其中设置如大循环等程序,这种方法在反跟踪技术中被称为废指令法。要实现废指令法有三点要保证:①废指令要精心组织安排,不要让解密者识破机关,这是废指令法应具备的基本点,因为它的目的是诱导解密者去研究破解自身,并在破解过程中拖垮解密者,所以废指令法本身的伪装十分重要;②所用的废指令应大量选用用户生疏的指令或DOS内部功能的调用,以最大程度地消耗解密者的精力和破译时间;③要确保不实现任何功能的废指令段不能被逾越,这是废指令法要注意的一个重要问题,因为它如果能被轻易逾越,那么就说明加密系统所采取的废指令法是失败的反跟踪技术。
(3)程序自生成技术:程序的自生成是指在程序的运行过程中,利用上面的程序来生成将要执行的指令代码,并在程序中设置各种反跟踪措施的技术。这样可以使得反汇编的指令并非是将要执行的指令代码,同时还可以隐蔽关键指令代码,但由于实现代价较高,一般只对某些关键指令适用。

指令流队列法:CPU为了提高运行速度,专门开辟了一个指令流队列,以存放将要执行的指令,这样就节省了CPU为了取指令而等待的时间。不过通过对它的利用也可以达到迷惑解密者和阻止动态跟踪加密程序的目的。在程序正常执行时,其后续指令是存放在指令流队列中的,而跟踪调试程序时就完全不同了,因为它牵涉到动态修改程序指令代码(包括后续指令)的原因,所以无论后续指令是否被存放在指令流队列中,被修改的指令都将被执行(包括后续指令),这一点和程序正常执行时是相反的,因为正常执行时,CPU只从指令流队列中读取指令,即使后续指令刚刚被正在执行的指令修改过。这是一个构思十分巧妙的反跟踪技术,现列出一个基于此原理的反跟踪程序:
JMPS2

S1:JMPS1;死循环

S2:LEASI,S1

LEADI,S3

PUSHCS

PUSHCS

POPDS

POPES

CLD

LODSW
STOSW

;设计在S3处存放S1处的指令,如果在正常执行时,由于S3处的其它指令已经被存入指令流队列中,所以它会正常运行,反之则执行S1处的死循环指令S3:其它指令.
9.逆指令流法:指令代码在内存中是从低地址向高地址存放的,CPU执行指令的顺序也是如此,这个过程是由硬件来实现的,而且这个规则已经被人和跟踪调试软件牢牢接收。针对这个方面逆指令流法特意改变顺序执行指令的方式,使CPU按逆向的方式执行指令,这样就使得解密者根本无法阅读已经逆向排列的指令代码,从而阻止解密者对程序的跟踪。因为顺序执行指令是由硬件决定的,所以如果用软件的方式设计CPU按逆向执行指令,就显出相当困难和繁琐了,不过逆指令流法是一个非常有吸引力和使用前景的反跟踪技术,如果能把这种技术成功地运用在磁盘加密技术中,势必会给解密者造成巨大的压力和威慑。近些年来各种报刊对这种反跟踪技术进行过深入的讨论,本文就摘取其中的精华给大家介绍一下逆指令流法的实现方法。单步中断是DOS提供跟踪程序的手段,这个中断普遍被运用于跟踪调试软件,是反跟踪技术的"死敌",但是如果运用恰当,它同样也可以成为"朋友",逆指令流法就是一例:由于顺序执行指令是由硬件来控制的,所以用软件方式改变这种规律的方法只有通过以下两点:①使指令代码在内存中逆向排列,即从高地址向低地址排列;②执行某条指令时,再将该指令按正常顺序排列,以适应硬件的要求。前者是静态的,在设计时就可安排妥当,而后者则较复杂了,一是如何在连续执行指令的同时,把指令代码从逆向捋顺为顺向;二是指令的长度各不相同,如何迅速了解下一条要捋顺的指令代码到底有多长?这就要利用设置单步中断标志和修改单步中断服务程序来完成。

(1)设置单步中断标志使CPU每执行完一条指令后都转去执行INT1中断服务程序,并同时修改INT1的中断服务程序,使它能完成逆向指令的顺向及修改CS:IP的值、使IP指针人为递减的功能。设置单步中断的标志,即是将标志寄存器的第8位T置为1,程序如下:
PUSHF

POPAX

ORAX,0100HPUSHAX

POPF

(2)修改CS:IP的值:设X地址处的指令执行后,由硬件自动完成了IP值的递增修改(顺序执行),将IP的值改为Y(Y>X),指向了下一条要执行的指令(正常情况下)。那么根据X和Y的值就可判断出X地址处的指令代码的确切长度(Y-X),从而推出逆向时下一条指令的地址Z(Z<X):Z=X-(Y-X)=2X-Y,知道了逆向时的下一条指令的地址,就可在INT1中断服务程序中将保护的中断现场中的IP从Y改成Z。
(3)指令顺向:首先为了保证系统的速度,再者为了减少修改扩充的INT1中断服务程序的长度,在具体确定顺向指令代码的长度时,以PC机最长的指令代码6字节计算。决定了指令代码的长度,剩下的就是指令代码的顺向:由于CPU只能顺向执行指令,所以必须将Z地址前面的5个字节的内容复制到Z地址后面的单元中,并且为了避免破坏其中的信息,要将Z地址后面的5个单元中的内容暂时保存起来,以便下次予以恢复。逆指令流法实现过程中应注意的问题:①由于指令流队列的存在,使得第一次进入INT1的地址各不相同,这是因为指令流队列的大小随CPU的不同而不同:8088CPU的指令流队列空间为4个字节,80286为6个字节,80386为16个字节,所以指令流队列中的后续指令的条数也各不相同,这样就导致了不同的CPU,首次调用INT1的地址各不相同的现象。它的解决方法是在设置完单步中断标志后,不要立即安排执行指令,而应插入适当的空操作命令NOP(90);②如果逆指令流程序中有软中断指令(以指令代码CDH打头的),必须恢复正常的顺序执行指令状态,否则在软中断服务程序中也将使程序逆向运行。并在软中断指令执行完毕后,再设置成逆指令流运行方式。
混合编程法:破译加密系统的首要工作是读取程序和弄清程序思路,并针对其中的弱点下手。为了阻挠解密者对加密程序的分析,可以尽量将程序设计得紊乱些,以降低程序的可读性。这种方法具体在反跟踪技术中使用的就是混合编程法等,因为高级编译语言的程序可读性本身就较差(如编译过的BASIC、COBOL程序等),如果再将几种高级语言联合起来编写使用,一定会极大的降低程序的可读性。
自编软中断13技术:由于反拷贝技术制作的指纹一般都存在于软盘上,所以现在的磁盘加密系统都存在着一个明显的外部特征:即都要通过调用INT13来判断软盘上指纹的真伪。由于要调用INT13,所以应保证中断表(至少部分中断表,如与INT13有关的INT40和INT1E等等)的正确性,即使先前使用了破坏中断表等反跟踪技术,到这个时候都必须恢复中断表的内容,这就过早地暴露了自己的弱点,加上INT13中断的入口参数是公开的,通过入口参数便可发现加密程序具体读取的是哪些扇区或哪个磁道,甚至可以发现加密系统采取的是何种反拷贝技术,这就给解密者以可乘之机,对加密系统造成巨大的威胁

posted on 2005-07-24 19:31  F4ncy Blog  阅读(1478)  评论(0编辑  收藏  举报