• X86逆向14:常见的脱壳手法


    本章节内容将介绍软件的脱壳技术。什么是加壳?加壳就是用来压缩或者保护软件不被非法修改破解的一种工具,而脱壳就是将已经加壳的程序从壳中剥离出来,既然能给程序进行加壳,那也就会有相应的脱壳方法,本节课我们将讲解几种常见的脱壳方法,让你能够应对一部分软件的加壳保护。

    压缩壳:upx ,aspack ,fsg ,pecompach

    加密壳:ASProtect ,Armadillo(穿山甲),EXEcryptor,Themida,ZProtect

    虚拟机壳:VMProtect

    接下来我们将使用不同的方法来脱几个常见的壳(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.填写上我们计算好的地址,然后点击【获取输入表】,接着显示无效函数,手动删除无效指针,并保存文件,即可脱壳成功。

    写教程不容易,转载请加出处,您添加出处,是我创作的动力!

  • 相关阅读:
    C#动态编译计算表达式的值 拓荒者
    Microsoft AJAX Library对 Error的扩展 拓荒者
    在分布式事务(MSDTC)中使用OLE DB数据库连接访问数据 拓荒者
    【转】ExtJS DateField 日期控件Format格式化 拓荒者
    自定义 Web 服务器控件 拓荒者
    Microsoft AJAX Library对 Array的扩展 拓荒者
    (转载)IE 浏览器的创新
    XUnit配置Resharper快捷键
    表现层模式MVC
    读Clean Code 数据结构和对象
  • 原文地址:https://www.cnblogs.com/LyShark/p/11190029.html
Copyright © 2020-2023  润新知