zoukankan      html  css  js  c++  java
  • 脱壳1

    概述

    脱壳是一项综合技术,结合PE文件格式、汇编指令的分析,调试加密的程序并将其还 原的一个过程。

    壳一般分为两种,加密壳和压缩壳,里面所使用的技术有,压缩算法、对代码加密、 对IAT加密、对资源加密。

    我们从简单入手­压缩壳

    关于压缩算法

    1. 有损压缩 一个像素点:RGB 红绿蓝 一个图片:(3,4,5),(4,5,3),(5,4,3) 压缩后:(4,4,4),3

    2. 无损压缩 一个文件:0,0,0,0,0,0,0 压缩后:0,7

    脱壳三步法

    1. 寻找原始OE

    2. dump内存到文件

    3. 修复文件

    脱壳三步法­寻址OEP技巧

    1. 堆栈平衡法(ESP定律) 壳代码就像一个函数,进入时会开辟堆栈、保存寄存器环境,退出时会恢复堆 栈、恢复寄存器。所以应该是堆栈平衡的,那我们可以在壳代码操作了堆栈后对 堆栈设置访问或写入断点,然后运行程序,当断点命中的时候,应该就是退出壳 代码的时候。在其附近单步几次,应该就能到达程序的原始OEP。

    2. 特征定位法 在我们熟悉的程序中,我们可以使用特征来定位程序原始OEP。特征有几种: ① 二进制特征 比如release版的VS2013是: E8????????E9 ② API特征 比如release版的VS2013的第一个API调用是: GetSystemTimeAsFileTime 比如vc6.0的第一个API调用是: GetVersion 比如Delphi程序第一个API调用是: GetModuleHandleA

    3. 单步跟踪法 这种方法一般使用在分析自己加壳的程序或者是练习分析壳时。

    脱壳­0.aspack.exe

    1. 用010Editor把重定位关闭

    2. 寻址OEP ESP定律

    3. 跑到入口点的位置再dump

    4. dump内存

       

    1. 修复文件

     

    RVA这个测试程序用的是0.

    注意:如果程序有随机基址,脱壳后需要把随机基址标志位置0.

    壳代码的基本流程

    ① 保存寄存器环境

    ② 加载一些必要的API

    ③ 解密代码和数据

    ④ 修复重定位

    ⑤ 填充IAT

    ⑥ 恢复寄存器环境

    分析壳代码­0.aspack.exe

    ① 壳OEP

     

    ② 加载必要API

     

    ③ 解密解压缩代码

     

    ④ 修复重定位

     

    修复重定位的公式:

    重定位表中存储两个有用字段:

    1. 需要重定位的分页地址

    2. 需要重定位的分页偏移

      重定位分为两步:

    3. 计算出 重定位地址,要重定位的地址=模块基地址+分页地址+分页偏移

    4. 修复要重定位的地址中数据,[要重定位的地址] ­ 默认模块基地址 + 当前模块基 地址

    5. 填充IAT

      原理:

      ① 从导入表中获取dll名称

      ② 从导入表中的INT,获取函数名称或者序号 ③ 通过GetModuleHandleA或者LoadLibraryA获取模块基地址 通过GetProcAddress获取函数地址

      ④ 将函数地址填充到对应IAT数组中

    001D726F    03F2          ADD ESI,EDX                        ; esi=导 入表结构 
    001D7271 8B46 0C MOV EAX,DWORD PTR DS:[ESI+0xC] ; 获取模 块DLL名称RVA
    001D7274 85C0 TEST EAX,EAX 001D7276 0F84 0D010000 JE 00_aspac.001D7389
    001D727C 03C2 ADD EAX,EDX ; 加上基 地址,字符串VA
    001D727E 8BD8 MOV EBX,EAX
    001D7280
    50 PUSH EAX
    001D7281 FF95 A90F0000 CALL DWORD PTR SS:[EBP+0xFA9] ; 获取模 块基地址
    001D7287 85C0 TEST EAX,EAX
    001D7289 75 07 JNZ SHORT 00_aspac.001D7292 001D728B 53 PUSH EBX 001D728C FF95 AD0F0000 CALL DWORD PTR SS:[EBP+0xFAD]
    001D7292 8985 A9050000 MOV DWORD PTR SS:[EBP+0x5A9],EAX ; 保存模 块基地址
    001D7298 C785 AD050000>MOV DWORD PTR SS:[EBP+0x5AD],0x0
    001D72A2 8B95 88040000 MOV EDX,DWORD PTR SS:[EBP+0x488] ; 获取基 地址
    001D72A8 8B06 MOV EAX,DWORD PTR DS:[ESI] ; 获取指 向OrignalFirstThunk RVA 001D72AA 85C0 TEST EAX,EAX
    001D72AC
    75 03 JNZ SHORT 00_aspac.001D72B1
    001D72AE 8B46 10 MOV EAX,DWORD PTR DS:[ESI+0x10]
    001D72B1 03C2 ADD EAX,EDX ; 计算出 OrignalFirstThunk VA 001D72B3
    0385 AD050000 ADD EAX,DWORD PTR SS:[EBP+0x5AD] ; 0
    001D72B9 8B18 MOV EBX,DWORD PTR DS:[EAX] ; 获取 INT中的数据,即指向函数名称的 RVA 001D72BB 8B7E
    10 MOV EDI,DWORD PTR DS:[ESI+0x10] ; 获取 FirstThunk
    001D72BE 03FA ADD EDI,EDX ; 计算得 出 IAT 地址
    001D72C0 03BD AD050000 ADD EDI,DWORD PTR SS:[EBP+0x5AD] ; 0 001D72C6 85DB TEST EBX,EBX ; 判断结 束
    001D72C8 0F84 A5000000 JE 00_aspac.001D7373
    001D72CE F7C3
    00000080 TEST EBX,0x80000000 ; 判断是 否是序号
    001D72D4 75 04 JNZ SHORT 00_aspac.001D72DA
    001D72D6 03DA ADD EBX,EDX ; 指向函 数字符串结构=INT[i]+模块基地址 001D72D8 43 INC EBX ; 减去 2,跳过字符串结构的序号
    001D72D9 43 INC EBX
    001D72DA 53 PUSH EBX ; 保存寄 存器环境
    001D72DB 81E3 FFFFFF7F AND EBX,0x7FFFFFFF
    001D72E1 53 PUSH EBX ; 压入字 符串或是序号
    001D72E2 FFB5 A9050000 PUSH DWORD PTR SS:[EBP+0x5A9]
    001D72E8 FF95 A50F0000 CALL DWORD PTR SS:[EBP+0xFA5] ; 获取函 数地址
    001D72EE 85C0 TEST EAX,EAX
    001D72F0 5B POP EBX ; 恢复寄 存器环境 ​

    ⑤ 修改属性,跳转原始OEP

     

  • 相关阅读:
    Android UI设计规范之常用单位
    Git Clone报错
    Android Studio导入项目,报错 Error:Unsupported method: BaseConfig.getApplicationIdSuffix().
    图片的旋转、缩放操作的分类
    输入和输出
    Python的交互模式和命令行模式
    认识Python
    内存泄漏
    查看服务器的内存使用量
    MAC的VMWare CentOS 6.8命令笔记
  • 原文地址:https://www.cnblogs.com/ltyandy/p/11269928.html
Copyright © 2011-2022 走看看