X86逆向14:常见的脱壳手法
本章节内容将介绍软件的脱壳技术。什么是加壳?加壳就是用来压缩或者保护软件不被非法修改破解的一种工具,而脱壳就是将已经加壳的程序从壳中剥离出来,既然能给程序进行加壳,那也就会有相应的脱壳方法,本节课我们将讲解几种常见的脱壳方法,让你能够应对一部分软件的加壳保护。
接下来我们将使用不同的方法来脱几个常见的壳(UPX,Aspack,FSG,PECompact)
------------------------------------------------------------
本章难度:★★☆☆☆☆☆☆☆☆
课程课件:CM_14.zip
------------------------------------------------------------
ESP定律脱壳法
ESP定律可谓是脱壳界一大利器,该方法是由国外的一名大牛发现的。你只需学会这个ESP定律,就可以很方便的脱掉市面上大部分的压缩壳,可谓是本世纪破解界最伟大的发现。
ESP定律原理就是会将加壳过程执行一遍之后跳到OEP来执行源程序,当我们找到了OEP的时候就是找到了源程序,即可实现脱壳。
1.首先我们使用OD载入附件中的【Aspack.exe】程序,然后会看到以下代码,第一条指令是Pushad,发现第一条命令是它,就能使用ESP定律搞。
如上图,默认的如果被调试程序被加密了,OD在运行时就会弹出这个提示框,这里点是点否都可以,我就点否了节约时间。
2.接着我们按一下【F8】单步执行一次,会发现右侧寄存器窗口,只有ESP寄存器变成了红色。
3.在ESP寄存器上面按下【右键】选择,【数据窗口中跟随】,立即数。
4.直接到数据窗口,选择第一个DWORD数据,然后右键,【断点】,【硬件访问】。
5.然后直接按下【F9】让程序直接跑起来,这时OD会停在以下代码区域。
6.接着按下【F8】这里按下3次,最后看到下面的代码处,好了已经到OEP的位置了。
7.然后直接脱壳,直接点击右键,然后选择【用OllyDump脱壳调试进程】。
8.直接点击【获取EIP作为OEP】,然后点击【脱壳】,直接保存文件即可完成。
单步跟踪脱壳法
单步跟踪法是软件脱壳中最基础的脱壳技巧,单步跟踪法就是利用OD的单条指令执行功能,从壳的入口一直执行到OEP,最终通过这个OEP将原程序dump出来
在使用单步法的脱壳时,要注意关键的CALL,如果CALL指令步过后程序被运行起来则说明跑飞了,需要重新加载程序,下次运行程序后在跑飞的位置使用F7进入CALL中继续执行,循环往复直到找到正确OEP位置,有时候需要重复执行很多次,沉住气慢慢来。
1.首先我们使用OD载入附件中的【PECompact.exe】程序,然后会看到以下代码。
2.我们直接单步【F8】向下执行,看到哪里程序会跑飞,如下执行到【call ZwContinue】这个CALL时,程序跑飞,我们直接重新载入程序然后【单步F8】,到这个位置之后按下【F7】进入CALL的内部。
3.进入CALL的内部后,我们还是【单步F8】,这次很短暂,第一个CALL的位置就跑飞了,如下。直接重新载入程序,到这里后【F7】进入。
4.进入上图中的CALL的内部以后,我们不用管代码长啥样,直接【单步F8】,执行到下图所示的位置,发现一个JMP指令,继续单步跟踪。
5.然后会发现第二个JMP指令,嗯!直接【单步F8】执行这个跳转,离OEP已经很近了!
6.JMP指令执行跳转以后,会发现已经到达了程序的OEP位置,我们按照上一个案例的方法直接保存文件即可脱壳成功。
二次断点脱壳法
二次断点法也叫做内存镜像法,其流程是首先在程序的.rsrc资源断设置一个断点,然后在程序的.text代码段设置一个断点,或是在00401000处也就是解码段设置断点也可,然后运行程序,能够很快速的定位到程序的OEP位置。
1.首先我们使用OD载入附件中的【UPX.exe】程序,并打开【选项】-> 【调试选项】 -> 【异常】 -> 【忽略所有异常】。
2.不要运行程序,直接按下【Alt+ M】 切换到以下模块,选择.rsrc资源,并下一个【F2】断点。
3.接着按下【Shift+F9】,然后再次按下【ALT+M】,再次来到了这个位置,我们在【00401000】处下一个【F2】断点。
4.下好断点以后,我们直接按下【F9】让程序跑起来,然后程序会自动的断下,如下到达了程序的OEP了,直接保存文件即可。
堆栈返回脱壳法
通过观察程序的堆栈情况,我们同样可以完成脱壳工作,本次我们来脱一个FSG壳,这个壳需要自己查找并计算IAT,工具自动查找出来的地址是有误的,所以稍微有点难度,不过没关系,我们还是可以完美的脱掉它。
1.首先我们使用OD载入附件中的【FSG.exe】程序,这里我们直接运行起来,然后会看到如下图这样的代码。
2.接着我们观察一下堆栈情况,找到【SE 处理程序】,然后选中它,按下【Enter】跟随过去。
3.跟随过去以后,会发现一堆的DB数据,这是OD帮我们分析了代码,我们只需要【右击】选择【分析】然后【从模块中删除分析】,原始的代码就会出现。
4.删除分析以后,再看堆栈会发现,多出来了一个黑条,我们顺着黑条到断首,然后逐一排查。
5.这里有个查找技巧,我们的程序解码段是【00401000】,我们就找离这个地址最近的地址,此处是【0045C945】。
6.在【0045C945】的地址处,按下回车,就可以在反汇编窗口处看到以下代码片段,我们顺着代码向上找,看有没有OEP。
7.嗯!我找到OEP了,那接下来我们就想办法让程序运行后停在这个位置,我们直接在OEP的位置,【右键】,选择【数据窗口中跟随】
8.然后在数据窗口选择,【断点】,【硬件执行】断点,然后重新载入程序,并运行程序。
9.发现程序在运行时会自动断下,直接按下【Ctrl +A】分析代码,如下可以看到我们已经到达了程序的OEP。
10.我们记下【0005C865】,然后在打开【Lord PE】,选择待脱壳进程,然后点击【完整脱壳】。
11.接着打开【Import REC】,填入OEP的地址【0005C865】,点击自动搜索,这里需要注意,找到的RVA和尺寸是错误的,我们需要手动查找,我们记下【0007C170】。
12.这里输入【0047C170】,为啥是0047C170 ?我们的基地址是【00400000】和【0007C170】相加得到的【0047C170】。
13.定位地址以后,然后选择【长型】,选择地址。
14.向上找,观察发现程序的起始输入表地址是【0047C000】,结束地址是【0047C69C】,中间的【7FFFFFFF】则是需要删除的指针。
真实RVA:0007C000
真实尺寸:7C69C - 7C000 = 69C
15.填写上我们计算好的地址,然后点击【获取输入表】,接着显示无效函数,手动删除无效指针,并保存文件,即可脱壳成功。
写教程不容易,转载请加出处,您添加出处,是我创作的动力!
X86逆向14:常见的脱壳手法的更多相关文章
- 未能从程序集 C:\Program Files (x86)\MSBuild\14.0\bin\Microsoft.Data.Entity.Build.Tasks.dll 加载任务“EntityClean”
问题: 未能从程序集 C:\Program Files (x86)\MSBuild\14.0\bin\Microsoft.Data.Entity.Build.Tasks.dll 加载任务“Entity ...
- 逆向工程之App脱壳
http://www.cnblogs.com/ludashi/p/5725743.html iOS逆向工程之App脱壳 本篇博客以微信为例,给微信脱壳."砸壳"在iOS逆向工程中是 ...
- 数据结构和算法(Golang实现)(14)常见数据结构-栈和队列
栈和队列 一.栈 Stack 和队列 Queue 我们日常生活中,都需要将物品排列,或者安排事情的先后顺序.更通俗地讲,我们买东西时,人太多的情况下,我们要排队,排队也有先后顺序,有些人早了点来,排完 ...
- 安卓逆向之基于Xposed-ZjDroid脱壳
http://bbs.pediy.com/thread-218798.htm 前言 之前介绍了普通常见的反编译模式 但对于使用了 360加固 棒棒 爱加密 等等的加固应用就没办法了. 你会发现 ...
- X86逆向5:破解程序的自效验
在软件的破解过程中,经常会遇到程序的自效验问题,什么是自效验?当文件大小发生变化,或者MD5特征变化的时候就会触发自效验暗装,有些暗装是直接退出,而有些则是格盘蓝屏等,所以在调试这样的程序的时候尽量在 ...
- VB程序逆向反汇编常见的函数
VB程序逆向常用的函数 1) 数据类型转换: a) __vbaI2Str 将一个字符串转为8 位(1个字节)的数值形式(范围在 0 至 255 之间) 或2 个字节的数值形式(范围在 -32,7 ...
- X86逆向4:VMP壳内寻找注册码
本节课将讲解一下重启验证,重启验证在软件中也是非常的常见的,重启验证的原理很简单,用户在注册界面输入注册码以后程序会自动将输入的注册信息保存到配置文件中,这里可能保存到注册表,也可能使用INI文件来保 ...
- X86逆向2:提取按钮通杀特征码
本章我们将学习特征码的提取与定位,特征码是软件中一段固定的具有标志性的代码片段,特征码的用途非常广泛,最常见的就是杀毒软件的查杀了,查杀就是根据特征码定位技术实现的,再比如木马的免杀也是修改了特征码的 ...
- iOS逆向工程之App脱壳
本篇博客以微信为例,给微信脱壳."砸壳"在iOS逆向工程中是经常做的一件事情,,因为从AppStore直接下载安装的App是加壳的,其实就是经过加密的,这个“砸壳”的过程就是一个解 ...
随机推荐
- [51nod1789] 跑得比谁都快
题面 题解 设\(f[i]\)为根节点到\(i\)的最小耗时 设\(S\)为\(i\)的祖先集合, 可以得到 \[ f[i] = min(f[j] + (i - j)^p),j \in S \] 对于 ...
- Leetcode题目136.只出现一次的数字(简单)
---恢复内容开始--- 题目描述: 给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次.找出那个只出现了一次的元素. 说明: 你的算法应该具有线性时间复杂度. 你可以不使用额外 ...
- python——装饰器(不定长参数,闭包,装饰器)示例
def func(functionName): print("正在装饰") def func_in(*args, **kargs): print("------func_ ...
- docker安装和基本命令
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口. ...
- 约束布局ConstraintLayout详解
约束布局ConstraintLayout详解 转 https://www.jianshu.com/p/17ec9bd6ca8a 目录 1.介绍 2.为什么要用ConstraintLayout 3.如何 ...
- mysql查询json字段
一张test表里存了一个content字段是json类型的,查询该content里manualNo这个字段 select JSON_EXTRACT (test .content, '$.manualN ...
- Linux环境下warning: no newline at end of file
今天在Windows下VS2012写了一个程序, 然后放在Linux系统下进行编译.Linux下使用的编译器是CC,结果,一编译出现了很多诸如下面的警告信息,似乎每一个.cpp和.h文件都有. Ite ...
- Node.js express模块 http服务
var express = require('express'); var app = express(); app.get('/', function(req, res){ res.send('he ...
- smarty 第一条数据判断
<div class="shangpin_rightdiv2"> <p>颜色</p> <ul id="toggle"& ...
- 侧方、s弯道、坡起相关
侧方: 方向盘上端对准路中箭头直行,当前面箭头头部尖角刚刚消失,停车,挂倒档,倒,当箭头尾部快要消失时右打死,侧身看左后视镜(这时可以稍微踩一下离合控制速度为低速),当出现库底角回正,坐直,当左侧第一 ...