脱壳以及简单练习

脱壳以及简单练习

一 、壳概述

1、壳的概念

正常的软件开发者不对开发的软件进行保护的话,会导致开发的软件源代码很容易的被心怀不轨的人窃取到,而程序的壳便是抵抗第一过程的手段,就如自然界中的昆虫壳的作用一样,程序壳便是保护程序不被非法分子获取甚至破坏的。

2、壳的工作过程

加壳过程是用加壳程序对源程序进行压缩、加密、转换指令等操作,然后一般是在程序的开头加上一段壳程序。当加壳程序运行时,在程序开头的壳程序会对加壳程序进行解压缩、解密代码或者数据、解释执行相应代码等过程,壳程序运行完之后一般会将加壳程序恢复成源程序,加壳程序便依旧可以执行相应的功能。

3、壳的几种分类

压缩壳:UPX 、 ASPack

压缩壳主要是为了让程序文件占用更小的体积,对于程序的加密保护方面侧重性不是很强。

加密壳 : ASProtect 、Armadillo 、EXECryptor 、Themida

加密壳的功能更加侧重安全性,对于加壳后程序的体积大小并不是十分关注,它能够将程序的重要代码、数据等进行加密,甚至可以提供额外的功能,比如注册机制、使用次数、时间限制等。有的加密壳也涉及到了虚拟机保护技术。

二、脱壳技术

1、壳的加载过程

  1. 保存入口参数(pushad/popad pushfd/popfd)

  2. 获取壳本身使用的API地址

    关键函数:

    LoadLibraryA(W)、LoadLibraryExA(W) : 将制定的DLL文件映射进内存,返回模块的句柄

    GetmoduleHandle: 获取已经映射进内存的dll文件的句柄,返回值句柄

    GetProcAddress : 获取dll内制定的函数地址,返回函数地址

  3. 解密源程序的各个区块的数据

  4. IAT的初始化

  5. 重定位项的处理(DLL文件脱壳)

  6. HOOK API

  7. 跳转到OEP

2、脱壳三部曲

  1. 寻找EOP

  2. 抓取内存映像

  3. 重建PE文件

三、脱壳方法

1、单步跟踪法

我们完整运行脱壳程序,跳过循环恢复代码的片段,边调试边观察,确保程序不会略过OEP,让软件实现自动脱壳

要点:

  • 跟踪过程是不修改任何代码的
  • 使用F7[单步步入]、F8[单步步过]、F4[直接执行到指定位置]等功能完整的进行自脱壳的过程
  • 大循环用f4跳过,尽量实现向下jmp
  • 函数载入不远处的call一般选择f7步入
  • 一般如果jmp到很远的地址,那极有可能就是跳到原程序入口(EOP)

练习1:UPX加壳程序

  1. 程序导入OllyDbg,我们开始单步跟踪程序

    img

  2. 循环跳过案例:

    当我们F8运行至0x00409CA1初,我们发现程序会回跳至0x00409C90

    分析这段代码,发现0x00409C98处还有一处跳转

    img

    因此对于这种情况,我们就可以直接在0x00409CA3F4

  3. 当F8指定到0x00409D45JMP 00409C96指令时,我们则可以点击其下一条指令,我们可以看到有跳转语句会跳转至0x00409D4A

    img

    我们继续F4使得程序执行到0x00409D4A处的POP ESI

  4. 我们继续分析,分析看到POPADJMP 00401000,我们已经解压成功

    img

  5. F8执行,到达OEP

2、ESP定律法

堆栈平衡概念

我们知道在执行函数时会涉及到堆栈

对于汇编程序:在函数执行时一般要包含和恢复被执行过程修改的寄存器。

  • 在开始时将寄存器入栈
  • 在返回前将寄存器出栈

函数执行过程:

  1. 函数参数入栈

    函数的参数按照特定的顺序(通常是从右向左的顺序)入栈,

  2. 函数调用指令执行

    将返回地址(也就是跳回调用者的地址)压入栈中

  3. 将EIP跳转至函数段首

函数执行结束:

  1. 计算结果(如果有的话)在寄存器或是某个特定的内存位置中。

  2. 函数参数出栈

    函数调用而压入栈的参数将会从栈中弹出。这个过程有时被称为“清理堆栈”。

  3. 返回地址出栈并跳转,回到调用者的代码中。

ESP定律原理

ESP定律的原理在于程序中堆栈平衡的合理利用。

压缩/加密壳:

  • 将当前寄存器内容压栈,如使用PUSHAD
  • 在解压结束后,会将之前的寄存器值出栈,如使用POPAD

因此我们可以在这些地址设置硬件访问断点,F9运行,当程序中断时,则距离OEP就很近了

记录系统加载时的ESP值,对其设置硬件断点

  • OllyDbg硬件断点快捷命令HW 内存地址
  • 数据窗口区 –>转到内存地址 –>选取 –>右键 –>断点 –>硬件访问–>双字。

练习2:UPX加壳程序

(未完待续)