DEF分析与打造其脱壳软件 初来贵地.献析文一篇. 请高手勿笑 . 我不知道有这么个地方, 以后请大家多指教. 我写的不怎么好的地方,请大家指正. 我不怎么懂脱壳,请不要大家找我脱壳。。。
作者:牛博威
Email:advice107@sina.com
http://nboy.cnwlt.com/
qq: 343538175 加壳软件一种可以对别的程序进行修改但是不影响其使用的工具软件。程序员经常利用加壳软件对自己的软件进行加壳,以加密或者压缩自己的软件。加壳后的软件一般来说难以被逆向分析,因此,脱壳软件应运而生。从某种角度来说,了解加壳和脱壳技术的原理是很有必要的。
下面我以Def为例说明其加壳原理,同时,我们改造Def使其具有针对自身的脱壳功能。
Def是一款源码开放的小型加壳软件,精炼易懂,便于学习。其源代码和程序可以去http://protools.cjb.net下载。
首先根据其源代码分析其加壳原理。它的加壳流程主要如下:
1、 以文件内存映象方式打开被加壳文件,并判断是否是有效的PE文件且不是Dll文件;
2、 遍历所有节表,根据节表名判断是否是输入表,资源节表或者其他节表,如果不是,定位到该节区,根据本节区大小对该节区的内容进行简单的异或加密,加密方式如下:
_encrypt: ;加密该节区
xor byte ptr[esi],al ;进行异或加密
inc esi ;esi指向节区下一个字节
dec eax ;判断是否到节区尾部,同时也是下一次异或操作的变量
jne _encrypt
然后把节表名称修改为.def,对未进行加密的节表,添加未加密标志,具体见下文;
3、 为被加壳文件添加自解密部分,用于被加壳文件运行时候自行解密。这一段可以参考源代码中的_loader部分。这段自解密代码被添加到文件节表的后面,同时修改文件的入口地址为此处的偏移地址。添加自解密部分的代码如下:
mov esi,offset _loader ; 初始化_loader的偏移地址
mov ecx,_loader_size ; 初始化loader部分的大小
rep movsb ; 把loader部分拷贝到被加壳文件的节表尾部
;其实这里最好判断一下是否有足够空间放置本段代码
4、 最后关闭文件内存映象;
根据上面的流程分析,再仔细研究一下其代码,相信你可以很快明白它的具体工作方式。下面我们来修改def,使其具有脱壳功能。
Def手工脱壳很简单,我以脱去Def自身的壳为例,说明其脱壳流程:
1、 用Trw载入Def;
2、 F10单步运行至xxxx:400244 push dword ptr 00401000 处,其中00401000为Def原来的入口地址。下命令Suspend,将进程挂起,F5回到windows界面;
3、 打开Peditor,点task,选择被挂起的Def进程,点右键dump(full),保存为unDef;
4、 用Peditor修改unDef文件的入口地址为00001000,注意这里是00401000减去00400000得到的。
好了,这样unDef就是Def的脱壳文件。我们现在要修改Def为自身的脱壳程序,也就是要对unDef进行处理。
首先,脱壳程序应该可以判断一个文件是否被Def加壳,利用Def的判断方式,判断第一个节表名称是否为.def便可以。故此,修改:
:00401091 813A2E646566 cmp dword ptr [edx], 6665642E ;.def ?
:00401097 0F858B000000 je 00401128
为:
:00401091 813A2E646566 cmp dword ptr [edx], 6665642E
:00401097 0F848B000000 jne 00401128 ;如果第一个节表名不为.def则跳出
;请注意这里最好不要改成jmp
现在就可以对加壳文件进行脱壳了,由于def采用了简单的异或加密,因此解密部分不需要修改。找个加壳文件实验一下,竟然发生异常。为什么这样呢?因为Def并不是把所有的节表都加密,对于引入表,资源节表等,def是不处理的。但我们的unDef会把所有的节表都进行解密,因此当然会发生错误。也许你会问,在程序中不是有call _is_encryptable(也就是:004010A7 call 004011A0)用来判断是否应该被加密么?不错,虽然如此,但是仔细再看一下_is_encryptable这个函数,它通过节表名来判断节表的修改合法性,而被加壳的文件所有节表名称都被改成了.def。因此,对这个函数来说加壳文件中所有的节表都应该被修改。
难道我们就没有办法判断了么?当然不是,仔细研究一下加壳文件的引导部分,也就是Def源代码中的_loader部分,在程序自身解密的时候有cmp byte ptr [esi+07], 00,其中esi指向节表头,如果[edx+07]=0 则跳过解密部分,否则进行解密。这样一来,我们修改unDef的解密部分。从VA=004010A7开始,修改后如下:
:004010A7 807A0700 cmp byte ptr [edx+07], 00 ;判断节区修改标志
:004010AB 90 nop ;保证文件后面的内容不变
:004010AC 90 nop
:004010AD 90 nop
:004010AE 740F je 004010BF ;如果不该解密,便跳过解密部分
到这里,就可以把所有加密部分恢复。但是脱壳文件仍然无法运行,因为我们还没有把文件的入口地址修改过来。看一下def如何修改入口地址,你可以很容易编写恢复入口地址的代码,如下:
:004010D6 50 push eax
:004010D7 8B4225 mov eax, dword ptr [edx+25] ;edx指向节表最后
;[edx+25]为真正的入口地址
:004010DA 2D00004000 sub eax, 00400000 ;入口地址的RVA->eax
;减去imagebase,我这里图省事,直接减去00400000H,正规的应该从文件中读取
:004010DF 894728 mov dword ptr [edi+28], eax ;edi+28指向入口地址
:004010E2 58 pop eax
:004010E3 E92B000000 jmp 00401113 ;跳转到添加_loader处
:004010E8 90 nop ;保证原来的文件内容不变
最后,修改_loader处的代码为自己的信息(这就是上面为何跳到401113)。把 "The Undef Made by NBW QQ:37122085 http://nboy.cnwlt.com"的ASCII码覆盖到文件地址1154处,同时要修改:
:00401118 B92A000000 mov ecx, 0000002A
因为这个地方定义了添加的新代码的长度,如下:
:00401118 B93A000000 mov ecx, 00000036 ;36H就是我添加的信息的长度
到此,我们的unDef就制作完毕了,找一个被Def加壳的程序,用unDef进行脱壳,OK!很好用。
最后再多说几句,上面的这些地址除注明外都是程序的虚拟地址,在修改unDef的时候,不妨用Hiew打开,按F3,再按F2进入Asm修改状态,你可以直接输入汇编程序进行修改,但是由于Hiew支持的Asm代码不全面,因此有些语句还需要在16进制状态进行修改。从这个修改过程也可以看到,由于加壳软件对原文件的破坏,我们做的脱壳软件并不可能100%地恢复加壳软件原状,至少节表的名称和属性没有修改过来。因此,一些软件被专家级别的加壳软件所加壳,在脱壳的时候出现较大偏差是很正常的。
1 2 3 4 5 下一页 |