一、壳的执行流程

逆向——壳应用
文章目录总结
前言
本次实验的主要要求是在理解PE文件以及壳的工作原理基础上,对目的PE文件进行处理,增加节,并写入符合加密壳功能的代码 , 修改PE文件入口地址、修改节属性 , 达到加密壳的功能 。
本次实验用到的工具有、、等 。
提示:以下是本篇文章正文内容,下面案例可供参考
一、壳的执行流程
壳是在可执行程序的外面进行了一次包裹,从而让壳对可执行文件进行保护(这里说的壳指的是压缩壳或加密壳,不包含虚拟指令壳) 。壳通常会在可执行文件执行之前先进行执行,从而更好地获得控制权 。加密壳会在进行一系列的初始化工作之后(可能包括解压缩、解密等,加密壳通常也有压缩功能)也把控制权交还给可执行程序,但是在可执行程序执行的过程中,外壳仍然会对可执行程序进行各种各样的“干涉”,从而达到更好的保护作用 。
从上图中可以看出,在加壳后的可执行程序中多了一个.Pack 节(该名字任意,甚至可以为空) , 该节中存放的是壳的代码或相关的加壳后的数据,当然壳相关的代码或数据可能会放在多个节中,而不是一个节中 。由于壳要首先取得控制权 , 因此程序的入口地址会指向壳的添加的节区(当然不是绝对的 , 也可能入口不变,而是修改入口处的代码),当壳的代码执行完成后,再跳回到原来的入口点进行执行 。
二、模拟壳的工作
初始PE文件的 RVA 与 FOA 相同,使得模拟的时候可以省去各种地址转换的问题 。本节的模拟工作将会在该文件上进行模拟 。以下分析、处理基于EnPE.exe文件 。
2.1、 对原始可执行文件RawPE.exe的代码节进行加密,得到EnPE.exe(已完成);
密码算法:异或;密钥0XCC,与原始可执行文件RawPE.exe比较,分析加密了几个字节?
答:增加了两个字节
【一、壳的执行流程】2.2、增加节(已完成);
与原始可执行文件RawPE.exe比较,增加了几个节,该节大小是多少?
答:原始可执行文件的节表为0003,修改后为0004 , 增加了一个节;该节的大小是1000
2.3、 修改代码节的属性与程序的入口点;
在PE ditor中修改入口点:
使用PE来修改代码节的属性,鼠标点击,然后找到.text,右键,点击edit  , 修改,将它改成可读、可写、可执行,+++=,然后保存 。
知识点:节的属性问题
关于文件属性:

一、壳的执行流程

文章插图
标志(属性块)常用特征值对照如下所示:
[] :包含可执行代码;a
[]:该块包含已初始化的数据;b
[]:该块包含未初始化的数据;c
[]:该块可执行;d
[]:该块可读;e
[]:该块可写;f
代码节的属性一般为,也就是可执行、可读和"节中包含代码"(a+d+e);
数据节的属性 一般为,也就是可读、可写和"包含已初始化数据"(b+e+f);
而常量节(对应源代码中的.const段)的属性为,也就是可读 和 “包含已初始化数据”;
那么为了达到加壳后能正常运行,EnPE.exe的.text节的属性是什么?
知识点:入口点
为了达到加壳后能正常运行,EnPE.exe入口点应改为什么?
答:应该改为
2.4、在增加的节中写入解密代码 。
参照课本P160 代码,解释代码作用
(课本为《逆向分析实战》)
在OD中打开保存好后的文件,打开后如下图所示,发现OD已经停在入口地址为处 , 即可表示修改成功了:
在新的入口点出添加如下代码:
添加完代码之后保存,将新的文件丢到PE里面,将.PACK的属性同上面一样改为可读、可写、可执行 。
保存好后双击打开文件就可以看到如下窗口了:
输入的代码:
MOV ESI,
MOV ECX,2
XOR BYTE PTR DS:[ESI],0CC
INC ESI
LOOPD
POPAD
MOV EAX,
JMP EAX
代码的作用:
在可执行程序装载入内存后,操作系统对进程进行了一系列的初始化工作 , 寄存器都有一些初始值,在解密的过程中会改变寄存器的值,为了保证解密后寄存器的值与可执行程序刚装载入内存时相同,因此先用指令对各个寄存器进行保存 。
MOV ESI,
将值赋给ESI寄存器,也就是将ESI指向地址处 。地址是原来程序的入口点,也就是原来程序代码开始的位置处 。
MOV ECX,2
ECX寄存器有一个特殊的用途,就是用于循环时的计数 。在前面对代码节进行异或加密 时一共加密了0x30字节,因此在解密时也需要循环对0x30字节进行解密 。
XOR BYTE PTR DS:[ESI],0CC
从ESI指向的地址中取出一个字节,与CC进行异或运算后再保存至ESI指向的地址中 。这句就是解密的指令 。
INC ESI
将ESI的地址向后移动一个字节,主要是改变ESI寄存指向的地址 , 因为在解密的时候是逐字节进行解密的 。
LOOPD
Loop指令会首先将ECX寄存器的值减一,然后判断ECX寄存器的值是否大于0 。如果ECX寄存器的值大于0,则跳转到loop指令后跟随的地址处;如果ECX 寄存器不大于0,则执行loop指令后的指令 。在该段程序中,ECX寄存器的值为0x30 , 因此会循环0x30次,也就是逐字节解密需要解密0x30次 。
Popad
在执行完解密代码后,将各寄存器的值恢复为原来的值 。指令和popad指令是成对出现的,用于保存和恢复寄存器环境 。
mov eax,
将地址地址赋值给EAX寄存器 。请记住,地址是原程序的入口点,通常在加壳前的入口点被称为原始入口点,即OEP 。在脱壳时,很关键的一点就是寻找OEP 。
JMP EAX
EAX寄存器中保存了,也就是保存了OEP的地址 。JMP EAX就是跳回到原来的入口点继续执行 。
总结
在本次实验中在了解大致的流程之后主要问题就是出现在添加代码这一块,首先是自己尝试纯手工输入,后来一直报错之后就直接复制粘贴了 。再有就是“MOV ECX,2”这里,一开始就直接跟着书上的直接输入 , 没有考虑到前面对代码节进行异或加密时一共加密了2个字节,在这里循环也应该时对2个字节进行解密 。最后一个问题就是我自己也不知道是哪一个地方出了错误,从头到尾做了三遍 , 最后一遍才成功的 。