病毒木马查杀实战第015篇:U盘病毒之脱壳研究
前言
因为我们的终于目标是编写出针对于这次的U盘病毒的专杀工具。而通过上次的分析我们知道,病毒有可能在不同的计算机中会以不同的名称进行显示。假设真是如此,那么就有必要在此分析出病毒的命名规律等特征,然后再进行查杀。
对病毒样本进行脱壳
依照常规。首先是对病毒进行查壳的工作,这里我所使用的是“小生我怕怕”版的PEiD,之所以用这个版本号,是因为经过我的实际測试。常规的PEiD或者说其他的查壳工具都难以非常好地对这次的程序所加的壳进行识别:
图1 使用PEiD进行查壳
这里请大家注意的是。将程序加载“小生我怕怕”版的PEiD后。是检測不出什么的,须要单击右下角的“->”,然后选择“核心扫描”才干够。
在上图中能够发现,程序所加的壳的名称为“UpolyXv0.5”,而且还有附加数据(Overlay)。
对于“UpolyX v0.5”来说,经过在网上对于这款壳的检索发现,假设PEiD觉得某个程序加了“UpolyX v0.5”的壳,那么误报的可能性是非常大的,有可能是加了多重壳,有可能是UPX壳并加了混淆的效果。网上说法非常多。但虽然如此,大家对于这个问题的共识是。使用“ESP定律”进行脱壳,那么基本都是能够成功脱壳的。
另外,因为脱壳后的程序是不包括有附加数据的,因此脱壳后还须要将原始程序的附加数据再加入回去。并进行一定的处理。从而保持病毒程序的完整性。因此接下来就须要解决这两个问题。
给病毒程序脱壳
根据“ESP定律”就能够实现我们这次的病毒的脱壳工作。其实“ESP定律”所根据的是堆栈平衡原理。利用这个思想,就能够脱掉非常多的不同种类的壳了。其实,“ESP定律”是一套严格的流程,我们仅仅要根据这个步骤。就能够实现脱壳。
首先我们用OD加载病毒程序:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
图2
注意这里选择“否”,然后按下F8单步执行,这时能够发现,在寄存器窗体中的ESP以及EIP都变成了红色:
图3
说明经过上一步的操作,这两个寄存器中的值发生了变化。
那么如今就在ESP寄存器上单击鼠标右键,选择“数据窗体中尾随”:
图4
然后在数据窗体中的ESP的位置下一个硬件断点:
图5
然后按下F9执行程序。就会在我们下断点的位置停下来:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
图6
然后不断按下F8单步执行,就会来到0x00403C81的位置:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
图7 找到程序入口点
能够发现。这里就是程序的入口点。
可能大家会疑惑,为什么这里是程序的入口点。其实,对于VC++编写的程序来说,它们入口点的反汇编代码是基本一致的,当我们接触得多了。自然而然也就认识了。那么下一步先取消硬件断点。能够在“调试”菜单下选择“硬件断点”。然后将我们刚才下的断点删除掉。
之后在我们所找到的程序入口位置单击鼠标右键,选择“Dump debugged process”:
图8
在上图中能够看到“RebuildImport”这一项。因为壳往往会改动导入表。因此非常多时候在将壳脱掉后,还须要修复导入表,否则程序是不能正常执行的。对于有些壳来说。我们使用OD的这个插件进行修复就能够,也就是说保持打钩的状态,再提取。
可是有些时候这款插件并不能够非常好地实现导入表的修复。所以这时我们一般使用ImportREC这款软件进行导入表的修复。
对于我们这次的病毒样本来说,似乎不管是採用哪种修复方式,都没有显著的不同。
所以这里我会演示这两种方法。有兴趣的朋友能够对照它们的不同。
首先是利用插件进行修复,也就是保持打钩的状态。然后单击“Dump”,给提取出来的文件起一个名字,这里我取的是“unpacked_1.exe”。
然后再又一次提取,将“Rebuild Import”前面的钩去掉。再进行提取,命名为“unpacked_2.exe”。
注意这里须要记住上图中的Modify中的内容,是新的入口点,这里是“3C81”,它是一个偏移地址。
然后打开ImportREC,注意OD不要关闭。在下拉菜单中选择脱壳前的程序:
图9
然后我们输入新的OEP,也就是“3C81”:
图10
然后单击“IAT AutoSearch”button,此时会弹出一个对话框:
图11
这个对话框告诉我们已经找到了一些东西,而且说假设查找错误,那么能够将RVA以及Size进行对应的改动。这里我们能够点击确定。
既然程序已经提示我们,查找可能不准确。那么如今能够在OD中观察一下,看看是不是找到了我们想要的内容。
回到OD,在数据窗体中跳转到0x407000的位置,也就是上图中的RVA与0x400000这个基址相加的结果:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
图12
因为有些壳会在这个地址区域做手脚,因此我们应当浏览一下这个位置上下有没有一些可疑的内容。这里一切都是正常的,说明这个RVA没什么问题。然后回到ImportREC,点击“Get Imports”。
假设说有不合法的结果。能够点击“Show Invalid”查看详细的细节。这次没有不合法的结果。那么就点击“Fix Dump”,并将它附加在“unpacked_2.exe”上面。此时程序会帮我们生成一个名为“unpacked_2_.exe”的文件,就是修复了导入表的文件。至此。我们的脱壳工作就基本完毕了。此时再用PEiD查壳:
图13
能够看到此时PEiD已经检測到它是由VC++编写的了。或者再单击PEiD以下的“>>”button进行进一步的查看:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
图14 利用PEiD进行进一步的检測
能够发现。如今我们的病毒样本确实是无壳的。
附加数据的处理
我们尝试双击执行一下这个病毒程序:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
图15 提示文件里有非法数据
这里提示出错。说明我们还须要对附加数据进行处理。这里首先能够看一下原始病毒样本的附加数据。这里还须要利用PEiD,加载原始样本,查看一下区段表:
图16 查找病毒样本的附加数据
附加数据会放在最后一个区段的后面,对于这个程序来说,最后一个区段是.rsrc,其偏移是0x14000,大小为0x5000,那么附加数据的偏移就是0x14000加上0x5000,也就是0x19000的位置。利用WinHex,加载原始样本,跳到0x19000的位置:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
图17
这个程序的附加数据非常多,从0x19000一直到文件的最后。眼下尚不知道病毒利用附加数据做了什么,我们必须要将附加数据加入到脱壳后的样本中。在WinHex的“编辑”菜单下选择“定义区块”,然后将须要提取的区块定义为“文件里间”的“19000”一直到“文件结尾”:
图18 定义区块
那么这段区块就被选中了,通过复制粘贴,将其加入到脱壳后的病毒样本的后面,就完毕了附加数据的加入。
那么如今另一个问题。那就是我们这样直接把附加数据复制到脱了壳的程序最后,程序能够有效地识别吗?我们最好还是先看一下脱了壳之后的程序的反汇编代码。这里我使用IDA Pro来加载脱壳后的程序。
首先是一个CreateFile函数:
图19 调用CreateFile函数
这里它会将病毒文件自身打开,然后将文件句柄赋给edi寄存器,假设文件能够正常打开,那么以下就调用SetFilePointer函数:
图20 调用SetFilePointer函数
一般来说,假设一个程序须要利用自身的附加数据。那么一般都会在文件打开之后,利用SetFilePointer这个函数来移动文件指针,使其指向想要读取的数据位置。对于这次的程序而言,首先能够看一下上图中的dwMoveMethod这个參数。这里是2。它代表的是FILE_END,也就是说。会从文件最后的位置进行数据的读取。
lpDistanceToMoveHigh表示要移动的距离,这是高32位,这里的值为0。我们就能够先不管它。lDistanceToMove表示低32位要移动的距离,这里是0xFFFFFFF8,它是一个负数。表示向前移动,也就是向前移动8个字节。
总结来说,因为这个程序本身在获取附加数据时,不论程序的大小怎样变化,它都是从文件的最后開始读取的也就是说。仅仅要文件后面的附加数据没有问题。那么这个病毒样本就能够正确获取附加数据的信息,因此这里不存在附加数据不能读取的问题。那么什么情况才须要我们注意呢,那就是假设程序的SetFilePointer是从文件的開始。读取偏移位置为0x19000的内容(原始病毒文件的附加数据处)。那么就须要我们进行改动,将这个偏移改动为当前文件附加数据的位置,才干够保障程序的正常执行。
小结
这次我们演示了一整套脱壳的操作。涉及侦壳、脱壳、修复导入表以及处理附加数据等问题。因为经过这一系列的操作,文件已是无壳的状态,这就有利于我们进行下一步的分析工作。
而对于这个病毒本体的逆向分析,我会在下一次进行分析。
病毒木马查杀实战第015篇:U盘病毒之脱壳研究的更多相关文章
- 病毒木马查杀实战第022篇:txt病毒研究
前言 反病毒爱好者们非常喜欢讨论的一个问题就是,现在什么样的病毒才算得上是主流,或者说什么样的病毒才是厉害的病毒呢?我们之前的课程所解说的都是Ring3层的病毒.所以有些朋友可能会觉得.那么Ring0 ...
- 病毒木马查杀实战第024篇:MBR病毒之编程解析引导区
前言 通过之前的学习,相信大家已经对磁盘的引导区有了充分的认识.但是我们之前的学习都是利用现成的工具来对引导区进行解析的,而对于一名反病毒工程师而言,不单单需要有扎实的逆向分析功底,同时也需要有很强的 ...
- 病毒木马查杀实战第023篇:MBR病毒之引导区的解析
前言 引导型病毒指寄生在磁盘引导区或主引导区的计算机病毒.这种病毒利用系统引导时,不对主引导区的内容正确与否进行判别的缺点,在引导系统的过程中入侵系统,驻留内存,监视系统运行,伺机传染和破坏.按照引导 ...
- 病毒木马查杀实战第025篇:JS下载者脚本木马的分析与防御
前言 这次我与大家分享的是我所总结的关于JS下载者脚本木马的分析与防御技术.之所以要选择这样的一个题目,是因为在日常的病毒分析工作中,每天都会遇到这类病毒样本,少则几个,多则几十个(当然了,更多的样本 ...
- 病毒木马查杀实战第011篇:QQ盗号木马之专杀工具的编写
前言 由于我已经在<病毒木马查杀第004篇:熊猫烧香之专杀工具的编写>中编写了一个比较通用的专杀工具的框架,而这个框架对于本病毒来说,经过简单修改也是基本适用的,所以本文就不讨论那些重叠的 ...
- 病毒木马查杀实战第010篇:QQ盗号木马之十六进制代码分析
前言 按照我的个人习惯,在运用诸如IDA Pro与OllyDBG对病毒进行逆向分析之前,我都会利用一些自动化的工具,通过静态或动态的分析方法(参见<病毒木马查杀第008篇:熊猫烧香之病毒查杀总结 ...
- 病毒木马查杀实战第009篇:QQ盗号木马之手动查杀
前言 之前在<病毒木马查杀第002篇:熊猫烧香之手动查杀>中,我在不借助任何工具的情况下,基本实现了对于"熊猫烧香"病毒的查杀.但是毕竟"熊猫烧香" ...
- 病毒木马查杀实战第020篇:Ring3层主动防御之基本原理
前言 假设说我们的计算机中安装有杀毒软件,那么当我们有意或无意地下载了一个恶意程序后.杀软一般都会弹出一个对话框提示我们,下载的程序非常可能是恶意程序,建议删除之类的.或者杀软就不提示.直接删除了:或 ...
- 病毒木马查杀实战第012篇:QQ盗号木马之逆向分析
前言 在本系列的文章中,对每一个病毒分析的最后一个部分,若无特殊情况,我都会采用逆向分析的手段来为读者彻底剖析目标病毒.但是之前的"熊猫烧香"病毒,我用了三篇文章的篇幅(每篇250 ...
随机推荐
- Thinkphp命名规范
1.类文件都是以.class.php为后缀(这里是指的ThinkPHP内部使用的类库文件,不代表外部加载的类库文件),使用驼峰法命名,并且首字母大写,例如 DbMysql.class.php: 2.类 ...
- STL容器 -- Stack
核心:后进后出, LIFO. 头文件: #include <stack> 常用的构造方法: stack<int> st1; //构造一个空的存放 int 型的栈 stack&l ...
- 循序渐进PYTHON3(十三) --4-- DJANGO之CSRF使用
用 django 有多久,跟 csrf 这个概念打交道就有久. 每次初始化一个项目时都能看到 django.middleware.csrf.CsrfViewMiddleware 这个中间件 每次在模板 ...
- 使用0填充string(构造类似‘00001’的字符串)
今天在对视频进行爬取的时候,发现url最后是000001,然后是000002,依次增加,而且每一个url请求只能得到一个分段了的视频,这种情况下构造url就成了一个问题. python有一个函数可以处 ...
- JSP2 自定义标签
实现步骤 实现自定义标签的处理类继承javax.servlet.jsp.tagext.SimpleTagSupport,并重写doTag方法 建立标签库配置文件 在jsp中使用自定义标签 一个简单的标 ...
- 【tomcat】tomcat远程调试
修改tomcat bin目录下的catalina.sh,增加下面这行: CATALINA_OPTS="-agentlib:jdwp=transport=dt_socket,address=9 ...
- 【模拟退火】poj2420 A Star not a Tree?
题意:求平面上一个点,使其到给定的n个点的距离和最小,即费马点. 模拟退火的思想是随机移动,然后100%接受更优解,以一定概率接受更劣解.移动的过程中温度缓慢降低,接受更劣解的概率降低. 在网上看到的 ...
- (转载)JavaScript中匿名函数,函数直接量和闭包
首先,我们先看看下面几种写法:1.function f(x){return x*x;};f(x);2.(function(x){return x*x;})(x);3.(function(x){retu ...
- ECSHOP中transport.js和jquery冲突的解决方法
jQuery 和global.js 冲突 百度和google多次,根据网上的大多数建议和自己测试,解决办法如下:删除global.js 或者global.js 文件的10-13行屏蔽//Object. ...
- Controller和RestController的区别
1. Controller, RestController的共同点 都是用来表示Spring某个类的是否可以接收HTTP请求 2. Controller, RestController的不同点 @C ...