壳与脱壳

February 25, 2019 逆向 访问: 44 次

认识壳

顾名思义,就是在原始程序上附加一个壳,这个壳起到保护程序不被逆向的作用
大致执行过程是,加了壳的程序通过windows加载器载入内存后,先于原始执行,以得到控制权,在执行过程中对原始程序进行解密、还原,还原后把控制权还给原始程序,执行原来的代码。

压缩壳

压缩壳的特点就是减小软件的体积,加密保护不是重点,UPX除了能对目标程序进行加密,也可用于解压缩

UPX

UPX是一个以命令行方式操作的可执行文件压缩程序;
UPX的命令格式如下:

upx [-123456789dlthVL] [-qvfk] [-o filename] file

ASPack

ASPack是一款win32可执行文件压缩软件,可压缩win32可执行文件EXE、DLL、OCX。

加密壳ASProtect

加密壳种类比较多,不同的壳侧重点也不同,一些壳只是保护程序,另一些壳提供了额外的功能,如ASProtect、Armadillo、EXECryptor、Themida。

虚拟机保护软件

原理就是将一系列指令解释称bydecode(字节码)后放在一个解释引擎中执行,从而对软件进行保护

脱壳技术

基础知识

壳的加载过程:
1. 保存入口参数(pushad/popad、pushfd/popfd)
2. 获取壳本身需要使用的API地址
3. 解密源程序各个区块的数据
4. 输入地址表(IAT)的初始化
5. 重定位项的处理
6. Hook API
7. 跳转到程序原入口点(OEP)

寻找OEP

当外壳所保护的程序运行时,会先执行外壳的程序,外壳程序负责在内存中把原程序解压、还原并把控制权还给解压后的真正程序,再跳到原来的程序入口点,这个解压后的程序入口点称为“OEP”
根据跨段指令寻找OEP
绝大多数PE程序在被加壳之后会在程序中加上一个或多个区块,这个区块就是外壳,相当于一个文件加载器,当外壳代码处理完毕后就会跳到程序本身的代码处。所以,根据跨段指令就可以找到真正的程序入口点。如下所示:
壳的加载
外壳的初始化过程中使用了两次跨段转移指令:
1. 从“.pediy”区块跳到外壳的第二部分(调用VirtualAlloc随机分配)
2. 从外壳的第二部分跳到程序本身的代码所处的区块

在Ollydbg中“Ctrl+A”组合键可以强迫OllyDbg重新分析代码,“Alt+M”查看模块的信息

用内存访问断点寻找OEP
外壳先将压缩的代码解压并释放到对应的区块上,处理完毕后再跳转到代码处执行。我们知道OllyDbg有对代码段设置断点的功能,当对某代码段设置内存断点之后,一定会中断再外壳对代码进行读取的那句指令上。
外壳的解压函数是aPLib的aP_depack_asm(),该函数依次将“.text、.rdata、.data、.rsrc”区块解压并放到正确的位置上,将代码段全部解压完毕后,程序返回真正的程序入口点,那么我们现在就可以对.text段设置断点,f9执行程序,就会停在OEP处啦。这个方法的关键是待代码全部解压完毕后再对.text设置断点。如果我们提前设置断点,当外壳解压代码的时候会对.text代码段不断的进行写入,那么就会终端,而一般的壳会以此对“.text、.rdata、.data、rsrc”区块进行解压,所以我们可以先在.rdata或者.data处设置断点,当程序停下的时候,就说明.text已经还原完毕,那么我们再对.text设置断点,运行程序即可达到OEP。
根据栈平衡原理寻找OEP
~~~~
外壳软件必须保证外壳初始化的现场环境(各个寄存器的值)与原程序的现场环境是相同的(主要是ESP、EBP等重要的寄存器)。加壳程序在初始化时要保存各寄存器的值,待外壳执行完毕后恢复各寄存器的值,最后跳到原程序执行:

pushad  #保存现场环境,相当于 push eax/ebx/ecx/edx/edx/esp/ebp/esi/edi
……
popad   #恢复现场环境,相当于 pop eax/ebx/ecx/edx/edx/esp/ebp/esi/edi
JMP OEP #准备跳到入口点

抓取内存映像

抓取内存映像也称为转存(dump),是指把内存制定地址的映像文件读出,用文件的形式将其保存下来的过程。
dump时机
一般情况下,当外壳来到EOP处时进行Dump是正确的。当程序运行起来的时候,由于一些变量已经初始化了,不适合进行Dump。
Test
我尝试这对一个加壳的软件进行脱壳,使用PEtools和loadPE来进行dump后都不能打开,最后使用ollydbg中的dump插件来dump,dump后可以成功的打开。具体方法:在ollydbg中点击插件->ollydbg->脱壳在当前调试的进程->脱壳。

添加新评论