解密软件RCOPY03应用指导 1995-01-06 RCOPY03是一个用于将内存中的二进制代码重建为EXE文件的通用工具软件。 我们知道,一个可执行文件(即EXE或COM文件),在执行过程中任一时刻的走向,仅与内存当时的状态有关,而与程序早期的遍历无关,因而根据这一点,把内存当时的有关现状保留下来便不难在往后恢复程序的运行。早期的RCOPY02程序就根据这一原理而设计,并得到了广泛的应用。但是,由于RCOPY02保存现场的时刻是由人为敲键控制,并且是单纯地保留现场,因而被其保留的现场只能在相同的硬件环境下使用,使RCOPY02的应用受到了很大的限制。 为了说明RCOPY03的工作原理,以使你能更得心应手地运用该软件,我们且先来看看什么是“加壳”软件(没有统一名称,姑且称为“加壳”软件)。 当我们用常规的C、PASCAL、汇编等语言编制了一个应用程序之后,最后都将编释成一个可执行的EXE或COM文件,这种文件的执行流程若非人工精心地打“补丁”,很难修改。这样,当一些文件型病毒或加密工具等对其进行感染或加密时,只能是先将这种二进制代码进行复杂的变换,然后另外加上一段自己的用于逆变换的程序,这段程序通常是防跟踪的。这样,你要执行原来的程序,必须得先执行这段附加的程序,我们把这段附加的程序称之为程序的“壳”。对病毒程序而言,这种“壳”通常的作用在于设置一些中断,以便于往下感染其他的可执行文件或干脆在运行“壳”时感染其他文件。而对于加密工具来说,“壳”的作用就在于读软、硬盘上的“指纹”、各种软件狗或加密上的“密码”等。一但“壳”运行正常,再解码原来的可执行文件,才能使之正常执行。 显然,作为“壳”的作者来说,为了使其的“加壳”程序通用,不可能对被加壳程序提出过高的环境要求,也不可能改变被加壳程序的结构。而且不管“外壳”包得如何严密,它最终在内存中必需老老实实地把原程序自动还原。否则,被“加壳”的程序便不能运行。因而,这就使RCOPY03有了可趁之机,RCOPY03就是在被加壳程序运行到已解码的适当阶段,把内存中的二进制代码整理出一个EXE文件来,从而得到一个已去“壳”的可执行程序。以后这个已去壳的程序运行时,就无需再经过这段“壳”程序的运行过程了,从而达到杀毒或解密的目的。 那么,RCOPY03如何选择程序已去壳并已解码的关键点呢?我们知道,DOS操作系统为我们提供了丰富的中断功能,一般应用程序必须输入、输出或显示。这些操作通常都是调用DOS或BIOS的中断来实现,RCOPY03就是通过在目标程序运行的过程中截取指定的目标程序所使用的任何一个中断,来截获内存中的已解码程序。为了便于选择合适的中断点,RCOPY03也提供了观察目标程序中断调用序列的手段。这样,在选择好一个合适的中断点后,RCOPY03便会在该中断点处开始,重建一个可执行的EXE文件,从而自动完成对“加壳”程序的“去壳”过程。 由于RCOPY03重建的是一个可重定位的EXE文件,因而,只要所选择的中断截取点足够早,则经RCOPY03解码的文件可在任何与原程序相同的其他环境下使用,不再象RCOPY02所拷贝的副本那样,只能在和原来一样的环境下使用。 熟谙解密的用户可能注意到,有些加密工具(如各种软件狗)还提供了供用户链接到源文件中的OBJ加密模块。这样的程序显然不能企图通过RCOPY03一次性地解密,但是,由于这种程序在经RCOPY03去壳之后,一般不再具有防跟踪的性能(OBJ模块除外),因而对这种程序,只要先用RCOPY03去壳,然后再用一般调试工具进行调试,找到OBJ模块的调用口,轻易地绕过去即可。当然,对于这类链接了OBJ模块的程序,已不属于“由工具对可执行程序加密的程序”的范围,但RCOPY03为种程序的解密也提供了极大的方便,因为它已删除了程序中最难处理的防跟踪外壳。 知道了RCOPY03的工作原理后,我们再来看下面各项操作步骤的含义便容易理解了。 二、菜单操作说明 在DOS提示符下键入RCOPY后,屏幕上将出现RCOPY03的主菜单如下: ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ ┃RCOPY utility program Ver 3.00 Copyrigth(C) by Xiong Yan 04/94 ┃ ┠─────────┬─────────────┬─────────┨ ┃ HELP │ CREATE │ UNSHELL ┃ ┠─────────┴─────────────┴─────────┨ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ 在这个菜单下敲“Esc”键,则可退回到DOS提示符下。 主菜单共有三栏,用左、右箭头的键选定菜单后,再敲回车键,便可以弹出相应的二级菜单。以下分述各级菜单参数设置的含义。 (1)HELP 这是显示RCOPY03各级菜单含义简短说明的帮助屏幕,共有三屏,可用PageUp键及PageDown键翻阅。 (2)CREATE 这是用于建立一个中断现场观察文件的选择菜单。 由于RCOPY03主要是通过截取目标文件的中断来取得解码的控制权。目标文件运行时,可能使用各种中断,如INT10H、INT21H、INT16H等来处理其各种输入、输出。而究竟截取目标文件中的哪一号中断才能顺利地解码,这是整个解码过程是否能成功的关键。显然,由于被解码的目标文件千变万化,我们不可能在一个通用的软件中固定地指定某一个中断号作为截取点,因而RCOPY03提供这一菜单,以便于建立不同中断号的中断现场观察文件,最后由用户根据具体情况自己选择截取点。 选中本级菜单敲回车键后,将弹出如下的二级菜单: ┌────────'Esc':RETURN───────┐ │EXECUTE FILE: │ │OUTPUT FILE: │ │INTERRUPT NO: 21 (HEX) │ │BUFFER NO: 1 (DEC) │ └────'F1':START, 'F2':CREATE ───┘ 这个二级菜单中共有如下四栏选单: 1)EXECUTE FILE 本栏选单让你输入目标文件名,目标文件名必须是以EXE或COM为后缀的可执行文件,本栏中既可以含路径地输入文件名,也可以在文件名后带命令行参数。 2)OUTPUT FILE 本栏选单让你输入你所欲建立的观察文件名,文件名前可以带路径。这实际上也就是你所建立的观察文件保存的路径。 特别地,本栏也允许你什么也不输入。在这种情况下,RCOPY03把建立的观察文件直接显示在屏幕上。即在目标程序执行完并退到DOS中时,敲任意键即可显示观察文件。 3)INTERRUPT NO. 这是选择中断号的选单,其后的(HEX)表示本栏选单输入的应为十六进制数,其中我们预设了21H作为其默认值,这是因为绝大多数需解码的程序都可以通过截取INT 21H而获得成功。 当然,根据不同的情况,你可以选择其他的中断号。 把光棒移到本栏后再敲回车键,便会出现闪烁的光标,这时你就可以输入你所选择中断号的十六进制数值了。例如,输入16,则表示欲建立观察目标程序中所有INT 16H调用现场的ASCII码文件。 4)BUFFER NO. 这是选择保留中断现场数据的缓冲区号的选单。其后面的(DEC)表示本栏选单输入的应为十进制数。其中我们预设值为1,是因为通常只需取第一缓冲区的数据观察即可。 通常当我们解码一个文件时,要使解码成功,必须选择尽可能早的中断入口,因而取第一号缓冲区的数据观察,即可找到合适的截取点。一般地,一个缓冲区大约能保留193个左右的中断现场数据。如果我们不是为了解码,而是为了某种其他目的,需要观察目标文件整个执行过程中调用某一中断的序列,则可以分多次执行RCOPY03,依次保存1、2、3...各次缓冲区的ASCII码文件,最后把各次的文件顺序连结起来,即可得到一个完整的中断调用序列各次现场信息的大文件。 RCOPY03在工作中,当设置的缓冲区号已满,尚未完全记录所有的中断现场信息时,便会发出三声报警,这预示着你如果对后面的中断现场感兴趣的话,必须重新执行RCOPY03,并把缓冲区号设大一号。如果你仅仅是对程序结束时的中断调用现场信息感兴趣,则可以一开始就设置一个足够大的缓冲区号,例如:65535,这样,RCOPY03就会自动保留最后一次缓冲区的数据。 另外,各级菜单中还定义了如下几个功能键: ESC__本键的作用在于不执行菜单中的功能,退回到上一级菜单之中。 F1__作用在于根据菜单中设置的参数,执行本级菜单的功能,也就是说,当本级菜单中的参数设置完后,敲F1键即可开始工作。 F2__这个键的作用在于建立一个命令行文件。当本级菜单各参数设置完后,敲F2键,可弹出下一级菜单,即第三级菜单,该菜单只有一栏,COMMAND FILE NAME。当你确认后敲回车键,再敲F1键,RCOPY03便会将你在第二级菜单中所设置的各参数存入你刚才所建立的命令行文件中。此后,敲Esc键,又可退回到第二级菜单中。 为什么要建立命令行文件呢?这是因为有些程序的运行,要在特定的环境下执行,这时,用RCOPY03解码时,如果仍然是通过主菜单,第二级菜单等一级级地设置的话,可能会破坏程序执行的环境,在这种情况下,便可以通过建立命令行文件的办法先建立一个命令行文件,然后在DOS提示符下直接敲入RCOPY及设立的命令行文件名,就可以不进入RCOPY03主菜单屏幕而直接执行该命令文件所保存的该二级菜单的功能,再敲F1键使RCOPY03开始工作。 (3)UNSHELL 本级菜单用于设置RCOPY03所欲截取中断点的各参数,并开始执行对目标程序的解码。其界面如下: ┌─────────'ESC':RETURN ────────────────┐ │EXECUIE FILE: │ │OUTPUT FILE: │ │INTERRUPT NO.: 21 (HEX) FREE BYTES: 588166 (DEC) │ │ REGISTER (HEX) │ │AX= BX= CX= DX= │ │BP= SP= SI= DI= │ │DS= ES= SS= CS= │ │AH= AL= BH= BL= │ │CH= C= DH= DL= │ │IP= │ │CPIMT= 1 (DEC) MODE=2 (1,2 OR 3) │ └───────'F1':START, 'F2':CREATE ───────────┘ 当从RCOPY03建立的观察文件中选择好了一个中断截取点后(如何选择中断截取点,可参见后面的相应说明),应把该截点处的有关参数设置到本级菜单中,然后敲F1键,RCOPY03便可以自动地完成解码工作了。本级菜单中除中断号INTERRUPT NO.,执行文件名EXECUTE FILE及输出文件名OUTPUT FILE三栏必须输入外,其余各栏根据情况可输入参数,亦可不输入任何参数。各栏菜单的含义如下: 1)EXECUTE FILE 此栏输入欲解码的执行文件名,该文件名必须是以EXE或COM为后缀的可执行文件。此处的执行文件名可以包含路径。 2)OUTPUT FILE 此栏输入被你解码、去壳以后的目标文件名。文件名前也可以包含路径。 有一点需要特别指出的是,当用RCOPY03来为染上了外壳型病毒的程序去壳杀毒时,由于RCOPY03执行时必须要运行这种带毒程序,而许多病毒程序运行时自动感染所有带EXE后缀的可执行文件,这样就有可能在你刚为原来的病毒程序去壳杀毒,建立新的EXE文件后,又被继续感染。因此,在这情况下,正确的操作方法应该是使输出文件名不带后缀,待去壳杀毒后再拷入干净的盘中,由干净的操作系统启动以后再将文件名改回到以EXE为后缀的可执行文件名。 3)INTERRUPT NO. 此栏选择所截取的中断号,其后的(HEX)表示中断号应以十六进制表示,我们预设默认值为21H,根据具体情况可设置任何中断值。 4)FREE BYTES 此栏是RCOPY03提供给被解码程序使用的自由空间字节数,应以10进制输入。 由于RCOPY03是不加区分地把内存中目标程序之后的内容都作为被解码的程序写入被解码的文件中。而有些目标程序往往要使用内存后部,这样,就会使被RCOPY03解码后的目标程序变得很大。为此,设置这一栏菜单,其目的是给你提供一个选择。当你发现在默认状态下解码出的文件长度远远大于原文件长度,甚至比此栏所显示的长度略长时,则一般表明此程序使用到了内存后部。此时你就可以重新进入此菜单把此栏的字节数选择得小一些,从而可以使被解码的文件长度缩小。 5)REGISTER 本栏一共有21个寄存器条件供选择输入,其输入的数据应为十六进制数。其选择的含义是指RCOPY03所截取中断入口处寄存器值应满足的条件。例如,如果我们在前面INTERRUPT NO栏中输入21,在此处AH栏中输入19,IP栏中输入8E3。这就是说要求RCOPY03截取INT21H,并且仅当INT21H指令入口点处的AH寄存器值为19H,IP指针为8E3H时才开始建立解码文件。当然,根据需要本栏也可以一个数据都不输入。这样,所截取到的就是第一个指定中断的入口。实际上,本级菜单的所有条件间是“与”的关系,如果选择的条件不合适或条件过多,则RCOPY03将找不到截取点,因此,在可能的情况下,应尽量减少输入条件。 6)COUNT 本栏是计数器条件,以十进制数输入。它是指在满足中断条件和寄存器条件之后的计数条件。当同样的寄存器条件有几个,而我们欲选择其中某一个时,则使用这一计数器条件便可唯一地指定。 7)MODE 本栏是工作方式选择,它只能选择三种工作方式之一。三种工作方式的差别在于被解码文件中对原目标文件所设置中断向量恢复的多少。 我们已知道,RCOPY03主要是通过截取中断入口点来取得目标文件被去壳、解码以后的原码。这样,有可能在RCOPY03截取的入口点以前,目标程序已经把某些原中断向量地址取入到程序中,然后与其新设置的中断向量相链接。这些已取入到程序中的原中断向量,是在当前的DOS版本环境下的地址,而被RCOPY03解码的“去壳”文件今后可能在不同的DOS版本下运行,如果仍由其与原地址链接,则毫无疑问将会产生“死机”现象。于是,RCOPY03必须对这些已经链入程序中的向量地址进行处理,使其在新的环境下运行时要换以新的地址。这就是通常RCOPY03对中断向量的处理。 但是,我们必须注意,原目标程序所设置的中断向量并不总是对解码程序有必要的。例如,一些文件型病毒程序在一开始运行时便替换系统的中断,其目的是便于它把病毒传染以其他程序中,也就是说既不处理病毒程序取入的老中断地址,也不设置病毒程序所设置过的新地址,只有这样,才能保证“去壳”后的程序不再会传染其他程序,完成RCOPY03的杀毒作用。 还有一种情况,就是有些目标程序,并未按正常方式先取老中断地址,然后设置新中断向量以使它们能链接执行,而是仅仅取入老中断向量,并不设置新中断入口,在往后的程序运行过程中通过JMP,CALL之类的指令来执行中断功能,这样,RCOPY03处理时就不管目标程序是否设置了新中断,必须在解码程序运行时找出原目标程序取入的所有老中断向量地址并以新环境下的地址替换之。 综上,我们可知,RCOPY03对中断向量的处理实际上应分成三种情况。这就导致我们设置这一工作方式的三种选择,即: 工作方式一:RCOPY03不处理并恢复任何改变了的中断向量,在使用RCOPY03杀病毒时通常应采用这一方式。 工作方式二:RCOPY03仅处理被目标程序设置过的中断向量,这是我们预设的默认工作方式,一般用高级语言编译的可执行文件都可采用这一方式。 工作方式三:RCOPY03处理所有可能的中断。 三、观察文件的格式及截取点的选择 中断截取点选择的恰当与否,是解码是否能成功的关键。一般中断截取点选择得越早,解码后的文件就越贴近原程序。当然,截取点选择得太早又不行,这样截取点将落入目标程序的外壳中,以致于既达不对目标程序“去壳”的目的,又往往会造成解码过程中的“死机”现象。如何使截取点选择得尽早而不落入欲去壳的外壳程序中呢?RCOPY03所建立的观察文件为我们提供了几个直观的准则。为此,我们先看看观察文件的格式。 观察文件是一个ASCII码文件,可以用任何编辑程序把它调入观看,如用WORDSTAR、WPS等,均可调入。当然,也可以在DOS提示符下用TYPE命令观看。为方便,我们随盘提供了一个编辑程序QE.EXE,用其调入观看即可。观察文件的第一行,是一行分隔符“****......******”,从第二行开始的连续四行,就是RCOPY03所提供的一个中断入口的现场信息,在这四行中的前两行显示了该中断入口处所有寄存器的十六进制数值,熟悉DEBUG程序的用户可以注意到此处寄存器显示与排列的格式和DEBUG显示标志位的地方,显示着“---21---”和“<00001>”,前者表示这个中断现场是INT 21H的入口,后者则是序号,表示这是第几个INT 21H的中断。当然,如果观察文件不是通过设置21H中断得来的,而是由10H得来的,则此处显示的就是“---10---”等。一般正常情况下,在一个观察文件中的这一数值是不变的,但是在一些加密程序的外壳中,加密程序往往不采用INT××的方式调用中断,而是用诸如CALL这类的指令来调用中断,此时,RCOPY03则在此处“---NI---”显示,而不是显示“---XX---”。由此,实际上也提供了一个判别该中断入口是否是在外壳中的参考依据。 观察文件中的各中断入口现场信息按顺序排列,它反映出了目标程序调用该中断的序列过程,在这个序列中,每当RCOPY03发现中断入口现场的段地址发生变化,就会以一行分隔符“***...***”把变化前后的序列分开。迄今为止,几乎所有的加壳程序从“壳”中转入解码后的原程序中时都会产生段跳跃(但也有个别例外,例如,由BITLOK所生成的某些加密外壳)。因此,RCOPY03提供的这一行分隔符也就成了选择截取点的最重要的依据,根据这一点,在参照前面两个参考依据的情况下,选择特定中断号的截取点也就不难了。 前面讲过,绝大多数由高级语言编译的可执行文件加壳后都可以通过截取INT 21H来解码。有趣的是,常见的用TURBO C V2.0所编译的可执行文件,其前面都有一段固定的INT 21H的调用序列。这个序列入口处AX的值依次是3000、3500、3504、3505、3506、2500、4A××,而且其中AX=3000,即第一个INT 21H的入口处程序指针都是IP=000A,该条指令位于程序开始的第四条指令处,显示应该说是最早、且又不属于壳内的截取点了,选择这一截取点所解码的程序最贴近原程序。当然,一般来说,反过来看,如果我们在某个观察文件中见到上述这个INT 21H的调用序列,也可以认为该程序是由TURBO C语言编程的。这个具有特征的调用序列实际上为我们提供了一个重要的选择截取点的依据。同样地,通过分析你也不难发现其它高级语言如PASCAL、BASIC、C++等不同版本所编译的目标程序对某些中断调用的固定序列。 由此,我们得出选择截取点的一般过程就是,首先根据目标程序的情况选择一个中断号,这一般首选INT 21H,也可选择INT 10H、INT 16H等,但如果目标程序可能首先使用扩展内存的话,也可选择INT 67H、INT 15H等试试。 然后通过RCOPY03的CREATE菜单建立一个观察文件。在建立观察文件的菜单中设置好参数后敲F1键,即可看到目标文件被执行。此时应该注意,一旦目标文件执行进入到主界面,则表示其外壳程序已执行完毕。此时在有可能的情况下,便可使目标文件退出,没有必要全部运行完目标程序。因为此时我们已经取得了目标文件由外壳进入原程序的调用序列,其用于去壳解码已足够,无需更多的信息。当然,在目标程序不便退出的时候,让其执行完也可以。 在建立了观察文件后,我们再在DOS提示符下用编辑程序调入观察文件,逐屏观察,寻找由分隔符“***…***”分开的中断入口现场信息。首先找到文件中第二次出现分隔符的地方(文件第一行的分隔符即是第一次出现的分隔符),抄下紧着该分隔符下面那个中断现场的某几个寄存器数据,作为选定的截取点的条件。注意这时选好的寄存器条件最好是唯一的, 也就是说,该条件在分隔符以前的各现场信息中未曾出现过,当然如果找不到这种具有唯一性的条件,也可以使用前面曾出现过的条件,但是要查出该条件在前面曾出现过几次,由此我们可以在用UNSHELL菜单执行解码时使用其中的计数器条件COUNT。 另外,在选择寄存器条件时需注意,有些寄存器数据,如DS,ES等段地址寄存器,在程序每次执行时会随内存环境的不同而不同,因此,这类数据就不能取来作截取点的条件,其他一些寄存器数据是否能用来作为条件也往往要看你截取的是哪个中断号以及该寄存器数据是否与内存地址有关。一般来说,被截取的中断所要使用的寄存器往往都可以来作为条件,例如,当你截取INT 21H时,由于AH是其调用时的功能号,所以可用来作为条件,为使其条件唯一,IP寄存器的条件也可以使用,如果你对中断调用较熟悉,选择这种寄存器条件就容易了。但要注意,条件的选择应尽量少些,能表达该中断入口的特征即可。 在选好了截取点并记下了有关条件后,再重新启动RCOPY,进入UNSHELL菜单,把截取点的条件填入该菜单中,最后敲F1键,RCOPY03就会为你解码了。 这里要注意的一点就是,选择第二次出现分隔符的后面作为截取点,解码时出现死机或解码后的程序不能正常运行,则可能该截取点仍在“壳”程序中,这时你应该试着继续往下寻找第三次分隔符或第四次分隔符处选截取点,因为有些目标程序往往可能经过了几次的“加壳处理”,或者有的“加壳”程序本身就会多次产生段跳跃。如何一次就能选准截取点,这也就取决于你使用RCOPY03所积累的经验了。 四、应用实例 本节我们将列举1个具有典型意义的应用实例,并对每例子进行详细的讲解。 例:作为应用之一,我们先来看看如何用RCOPY03把一些具有压缩“外壳”的程序“去壳”,以便于修改。RCOPY03原盘上配有一个辅助应用程序UNDISP.EXE,这个程序的作用主要是将经RCOPY03解码以后的程序压缩并去除目标程序运行前的一段广告文字。 在DOS提示符下直接键入UNDISP,就可以显示UNDISP程序使用方法的提示如下: Usage: UNDISP filename [.exe] 实际上这只是UNDISP程序的简易用法,正常的用法规则如下: UNDISP [options] [d:] [/path] Infile [d:] [/path] Outfile] 也就是说UNDISP可以把待处理的文件Infile变换到另一个文件Outfile中,并保留原文件。现在假设我们欲把UNDISP程序的使用提示信息行修改成正常用法提示,该如何操作呢? 在正常情况下,我们修改一个程序的提示信息往往是用诸如PCTOOLS之类的工具对被修改的文件进行搜索,以找到欲修改字符的ASCII码字符串,然后用新的字符串替换之即可,但在此例中却不可。因为UNDISP程序本身是经过了压缩处理的,也就是说该程序被包上了一层压缩“外壳”,在你手上没有相应的解压缩程序时,我想是不太容易对它进行修改的。在这种情况下,RCOPY03就能“大显身手”了。 我们可以首先用RCOPY03对其进行脱除压缩外壳的处理,让欲修改的字符串出现原形,其后就可以用正常方法进行修改了。 假设我们已把RCOPY03原盘中的所有文件拷入了C盘(或C盘的某个子目录下),并且你的三英寸软驱是B驱动器,则往下的具体操作步骤及说明如下(还需假设你的硬盘没有病毒): A) C:\>SET KEY=3 这条命令的作用在于便于硬盘中的RCOPY03运行时到B驱动器中去读取“密钥”,因为RCOPY03程序本身是被加了密的,虽然其本身可以拷贝到硬盘中运行,但是运行时必需到软驱中去寻找原盘中的“密钥”。在默认的情况下,RCOPY03会到A驱动器中寻找含有“密钥”的KEY盘,所以如果你把RCOPY03的原盘插入B驱动器而在其他盘符下运行RCOPY03的话,就必须预先设置这一命令。 B) C:\>RCOPY 执行RCOPY03程序。敲入此命令,RCOPY03在确认了软驱中的原盘后,将显示出如下的主菜单屏幕。 ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ ┃RCOPY utility program Ver 3.00 Copyrigth(C) by Xiong Yan 04/94┃ ┠────────────┬───────────┬────────┨ ┃ HELP │ CREATE │ UNSHELL ┃ ┠────────────┴───────────┴────────┨ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ C)用光标键把主菜单上的光棒移到CREATE一栏,并敲回车键。 选取这一菜单的目的是,我们为了使UNDISP.EXE程序脱壳,必须先选择好截取点,为此,先建立一个观察文件。 D)经过(C)步后,主屏面将弹出一个二级菜单,并且菜单中的光棒定位在EXECUTE FILE这一栏中。再敲一次回车键后,便可在此栏中看到一个闪烁的光标,此时你就可以输入你欲取得的观察文件的可执行文件名了。此例中我们输入的可执行文件名是UNDISP.EXE。 E)此时光棒位于OUTPUT FILE一栏,如果(D)步是以敲回车键而使光棒移到此栏,则此时必需再敲一次回车键才会出现闪烁光标。此栏的作用是让你确立所欲建立的观察文件的名字,我们姑且把这名字定为UU,在键入UU字符后,再把光棒移到下一栏。 F)此栏INTERRUPT NO.是输入你所选择欲截取点的中断号。其默认值是21H。此处我们就使用其默认值,无需重设,继续把光棒移入下一栏。 G)BUFFER NO.栏是保留中断点现场信息的内部缓冲区号。 由于我们的目的只是要使用UNDISP.EXE程序“脱壳”,也就是要求截取点越早越好,因此,我们只要取其默认值1,即取第一个缓冲区便可以了。此处无需另外输入,只需敲回车键,于是光棒自动返回到第一栏中。H)至此,CREATE菜单栏已全部设置完毕,菜单显示如下: ┌─────'ESC':RETURN ─────┐ │EXECUTE FILE: UNDISP.EXE │ │OUIPUT FILE: UU │ │INTERRUPT NO.: 21 (HEX) │ │BUFFER NO.: 1 (DEC) │ └─'F1': START, 'F2': CREATE ──┘ 此时,敲F1键,程序开始工作。 I)程序工作结束,返回到DOS提示符下,此时屏幕上有两行信息,第一行是: Usage: UNDISP filename [.exe] 这是UNDISP.EXE程序执行的结果。第二行是红底黄字的: THE END 几个字,这是RCOPY03在屏幕上显示的结果,表示RCOPY03正常工作结束。 J)此时,我们在DOS提示符下敲入DIR UU将看到盘中新建立的ASCII码文件UU,其长度是5177字节(如不然,则考虑你的硬盘是否带有病毒)。 K) C:\>QE UU 我们用QE.EXE编辑器调入UU文件观看。可以看到如下的观察文件表: ******************************************* ********************************* AX=3000 BX=0000 CX=0000 DX=0000 SP=0800 B0=0000 SI=0000 DI=0000 DS=0AFC ES=0AFC SS=1979 CS=0B0C IP=2776 ---21 --- <00001> 01--> 0070:06F4 03--> 0070:06F4 03--> 0432:003C 09 --> 0677:01D6 10--> C93C:0CDE 13--> 02B7:0530 1C--> 0677:0134 21 --> 073A:3234 AX=4A01 BX=13E8 CX=0004 DX=0000 SP=B14A BP=0000 SI=1EE4 DI=0EE4 DS=0AFC ES=0AFC SS=0EE4 CS=0B0C IP=27EB ---21--- <00002> 01--> 0070:06F4 03--> 0070:06F4 08 --> 0432:003C 09 -->0677:01D6 10--> C93C:0CDE 13--> 02B7:0530 1C --> 0677:0134 21 -->073A:3234 ...... ...... ...... ...... ...... ...... AX=2500 BX=0001 CX=0000 DX=0163 SP=B123 BP=B12E SI=1094 DI=1094 DS=073A ES=0EE4 SS=0EE4 CS=0B0C IP=29C2 ---21--- <00016> 01 --> 0070:06F4 03 --> 0070:06F4 03 --> 0432:003C 09 --> 0677:01D6 10 --> C93C:0CDE 13 --> 02B7:0530 1C --> 0677:0134 21 --> 073A:3234 AX=4C01 BX=0001 CX=0000 DX=0163 SP=B12E BP=B12E SI=1094 DI=1094 DS=0EE4 ES=0EE4 SS=0EE4 CS=0B0C IP=29A7 ---21--- <00017> 01 --> 0070:06F4 03 --> 0070:06F4 03 --> 0432:003C 09 --> 0677:01D6 10 --> C93C:0CDE 13 --> 02B7:0530 1C --> 0677:0134 21 --> 073A:3234 表中的参数有不少是与内存当时的运行环境有关的,如此处第一个中断现场数据中的DS=0AFC、ES=0AFC、SS=1979、CS=0B0C这些段寄存器的值,以及01-->0070:06F4、03-->0070:06F4...21-->0731:3234这些中断向量的地址值。这些值在不同的DOS版本或内存环境下都会有不同的值,但有些值却是不随环境而变化的。如此处,由于我们截获的是INT 21H的入口,而AH寄存器中是INT 21H调用的功能号,所以,此处第一个中断点现场中AX=3000,即AH=30是确定不变的。另外,此处的程序指针IP=2776也肯定是不随环境而变的。 对于本例来说,我们纵观全部UU文件,中间并未发生段跳跃(即,中间未出现由***...***符号分隔开的中断点),因此一般选择第一个中断点作为截取点即可。 在第一个截取点,我们可以选择AH=30及IP=2776作为特征参数。需提出特别注意的一点是,第一个中断点现场信息中是AX=3000,但是我们不宜就以AX=3000作为特征参数,因为,INT 21H的30H号功能调用并未要求AL为某一确定值。这些中断功能调用的寄存器值可能会随环境的不同而不同,如果把这种不确定的寄存器值选作特征参数,将有可能使随后的解码操作因找不到匹配的特征参数而告失败。 L) C:\>RCOPY 重新执行RCOPY03程序。 通过前面几步,我们确立了截取UNDISP.EXE程序的中断号为21H,特征值为AH=30、IP=2776后,再由此重新启动RCOPY03以进行脱壳处理。 M)在进入RCOPY的主菜单后,把光棒移到UNSHELL一栏,即进入脱壳处理的一栏,然后敲回车键,使主屏幕中弹出二级菜单窗口。 N)在二级菜单窗口中,光棒首先位于EXECUTE FILE一栏。敲回车键。使该栏出现闪烁的光标,此时键入我们欲对之进行脱壳处理的文件名UNDISP.EXE,然后把光棒移入下一栏。 O)第二栏为OUTPUT FILE,在这一栏中应输入脱壳解码以后所形成的目标文件名,在此,我们假设定名为UNDISP1.EXE,并把这一名字输入到此栏,然后把光棒移入下一栏。 P)第三行有两栏,我们就取它们的默认值即可。 Q)再往下是REGISTER栏,此栏共包含六行,全部是寄存器的输入参数。按照前面我们所选定的参数AH=30,IP=2776,把光棒移入AH=项中输入30,再把光棒移入IP=项中输入2776,并敲回车键。 R)二级菜单中的最后一行的两个输入参数COUNT和MODE可以就取它们的默认值即可。 S)至此,UNSHELL菜单中的全部项目均已输入完毕,显示结果如下: ┌─────────'ESC': RETURN ────────┐ │EXECUTE FILE: undisp.exe │ │OUTPUT FILE: undispl.exe │ │INTERRUPT NO.: 21 (HEX) FREE BYTES: 588166 (DEC) │ │ REGISTER (HEX) │ │AX= BX= CX= DX= │ │BP= SP= SI= DI= │ │DS= ES= SS= CS= │ │AH=30 AL= BH= BL= │ │CH= CL= DH= DL= │ │IP=2776 │ │COUNT=1 (DEC) MODE=2 (1,2 OR 3) │ └─────'F1': START, 'F2': CREATE ─────┘ 菜单中共有八项绿底白字的设定参数,其中四项为系统的默认值。 敲F1键,则程序脱壳过程开始进行。此时屏幕上清屏并依次显示: Decryption...*****************OK! THE END 最后回到DOS提示符下,于是整个脱壳工作完毕。 T)在DOS提示符下用DIR UNDISP1.EXE命令,可以见到脱壳以后的UNDISP1.EXE长度为75490字节,比原UNDISP.EXE的27767字节长了不少,这是因为原UNDISP.EXE是经过了压缩的,而UNDISP1.EXE则已解了压缩,并且凡经RCOPY03解码以后的程序都要被增加一些内容(如,初始化程序及广告信息等),所以程序量增大了。U)在DOS提示符下试执行解码以后的程序UNDISP1.EXE,键入UNDISP1命令后,屏幕上将显示一屏中文广告信息。待广告出现后,再敲任一键,即可进入原UNDISP程序的运行中。 V)以下我们可以用PCTOOLS工具对已解码的UNDISP1.EXE进行搜索。结果在相对34扇区处的388字节偏移处找到UNDISP.EXE的提示信息。据此,便可按照我们的意图,直接对其修改即可。 W)UNDISP1.EXE修改完后,在DOS提示符下重新执行一遍,验证修改无误后。就可以对其本身进行压缩并去除运行时的广告信息了,操作方法是敲入如下命令: C:\>UNDISP UNDISP1.EXE 至此,全部操作完毕,所得到的UNDIPS1.EXE文件长度为30095字节,再运行它时,可以见到提示信息已经过修改。 实际上,RCOPY03用于解密时,其操作方法和例1)的一般操作方法没多大差别。可以说,对于一些通用性好的加密工具所加密的目标程序,用RCOPY03对其解密时的操作方法和例1)完全一样,只是选择截获点时要多加注意并多试几次。而有些通用性欠佳的加密工具,其对被加密程序的运行环境有一定要求,这样就要在RCOPY03的使用时,采取一点变通的方法。 对某些加密工具所加密的程序,如果在解码时发生死机现象,则可以用COMMAND程序来间接调用。因为有不少加密工具所加密的程序在运行时,要求其父进程必须是COMMAND程序否则便会死机,对于这种情况,只要在二级菜单的EXECUTE FILE一栏中加入COMMAND.COM/C或C:COMMAND.COM/C到被解码的文件名前面即可。当然,采用这种方法所生成的目标文件会有所偏大,因为目标文件多包含了一些COMMAND程序的代码。对此,在一般情况下是不碍事的,如果你对EXE文件的结构也很熟悉,那么你完全可以对目标文件进行人工修整,删除那些对目标程序的正常执行已无作用的COMMAND程序的代码及广告信息。 RCOPY03还可以用来消除文件型病毒,其用于杀病毒的操作过程与我们所举的这两个例子基本相同,不同之处仅在于选择脱除病毒外壳以后的目标文件名时不宜加上EXE后缀,而应在解码以后,在干净的环境下再把它的文件名加上EXE后缀。另外根据截取点的不同,一般在UNSHELL二级菜单的MODE一栏应选择工作方式一。当然,用RCOPY03来杀毒并不很方便,使用上远不如常用的CLEAN,KILL等专用杀毒软件那么简单。但是,当你手上的某个重要文件染上一种新未知病毒后,并不一定能及时找到可以消毒 的新版杀毒软件,这样,相对于你用手工来分析、杀毒,RCOPY03就方便多了。 五、进一步的应用 经RCOPY03脱壳的程序,不能完全恢复成其加壳以前的模样,这是RCOPY03作为一个通用工具软件所难以办到的,正因为如此,RCOPY03在生成目标文件时,并不顺便进行压缩处理,而是把解码后的文件“透明”地提供给用户,目的是便于让用户对目标文件进行人工修改,增删。为此,RCOPY03在目标文件的开头生成了一段广告文字,这段广告文字的目的,更主要的还是为了向用户提供一些空间,以便于对生成的目标文件进行再修改。 熟悉汇编程序的用户不难看到,RCOPY03在脱壳后的EXE程序的开始部分增加了一些预处理部分,即:①显示广告信息②处理命令行参数结尾字符③恢复原来的内存申请状态④恢复原来所设置和链接到程序中的中断向量⑤最后用一个长跳转,转入原中断截取点的入口。 实际上,上述预处理部分并非对每一个目标程序都必要,这样,你就完全可以根据实际情况,对脱壳以后的程序进行人工地再修改。 首先,对于每一个目标文件都无作用的广告信息部分占据了程序入口的前面近2000个字节,这一部分空间你完全可以随心所欲地用你自己的程序把它覆盖,例如,你可以把它改成你自己的广告信息、注意事项、操作方法提示符内容,也可以添加一段口令字检测程序,使得这一被脱壳的程序只有在正确回答口令后才能运行,还可以加上计数器等指令,这些添加的部分可以使你的程序运行时更具特色。 对于有些目标程序,其一开始就把命令行参数取入到程序里面。而RCOPY03并没有对命令行参数进行细致地处理,只是简单地处理了一下命令行参数的结尾字符,这样就有可能使得某些脱壳以后 的程序不能正确地处理命令行参数,对于这种情况,你也可以利用脱壳以后程序前面的空间来根据实际情况进行人工处理。 还有些程序,例如用TURBO C V2.0编译的程序,如我们前面所说过的,通过INT 21H的AH=30H号功能,可以截 到目标程序脱壳以后的第四条指令。对这种脱壳以后的程序,RCOPY03为其增加的所有预处理部分,包括内存申请及中断向量处理,都毫无作用。这样,脱壳以后的程序前面可以被你直接使用的空间将可达到5000左右字节数。当然,你也完全可以通过修改EXE文件头部信息的办法把程序入口指针直接向原截取点,甚至指向原截取点之前,然后把被RCOPY03增加的预处理部分删除。经过这些人工的处理,你甚至可以使脱壳的程序修改得和原程序几乎一模一样! 脱壳以后程序的预处理部分中哪些有用,哪些无用,你完全可以用调试工具对它进行分析得出结论,从而实施你自己对程序的修改计划。最后,你也可以对修改好的程序进行再压缩或加密。