首 页文章中心黑客软件黑客动画绿色软件私服技术私服下载本站论坛
您当前的位置:黑客之家文章中心脱壳破解基础知识 → 文章内容 退出登录 用户管理
本类热门文章
相关文章
站内广告
Asprotect 中的 X86 虚拟机代码分析
作者:佚名  来源:不详  发布时间:2008-1-10 16:29:18

减小字体 增大字体

作    者: blackeyes

1.  起因:

    最近跟踪一 Asprotect 保护的程序, 发现 stolen code 都是在 Asprotect 自己的虚拟机中执行, 

非常不利于跟踪与分析, 于是把 Asprotect 的虚拟机代码进行了分析. 


2.  代码处理概述

还是用例子来说明吧, 原始的一段 CODE 如下:

00D6FC1C    55              PUSH EBP
00D6FC1D    8BEC            MOV EBP,ESP
00D6FC1F    83C4 E0         ADD ESP,-20
...
00D6FD48    8BE5            MOV ESP,EBP
00D6FD4A    5D              POP EBP
00D6FD4B    C2 0C00         RETN 0C

Asprotect 将上面的每一行机器代码分析处理, 然后每一行保存到一个固定大小的结构中,

运行的时候这段代码就只需要下面四行:

00D6FC1C    68 00000000     PUSH 0
00D6FC21    68 1CFCD600     PUSH 0D6FC1C
00D6FC26    68 B432E600     PUSH 0E632B4
00D6FC2B    E8 18960000     CALL 00D79248

其中:
 00D6FC1C ----- 代码起始地址
 00E632B4 ----- 一结构起始地址, 包含处理后的代码信息
 00D79248 ----- X86 虚拟机 Function 地址


3.  机器代码分析

每一行机器代码被分析处理后, 会分解成 10 项 保存到结构中, 如下:

   1   -   第 1 个 机器码的内存起始地址;

   2   -   机器码的第 1 个 BYTE, 如果不是前缀机器码, 就是真正的机器码的第 1 个 BYTE;

   3   -   机器码的第 2 个 BYTE, 并且前面是前缀机器码, 它是真正的机器码的第 1 个 BYTE;

   4   -   机器码中的立即数是否要调整, 相当于重定位, 例如;

               00400000  68 34124000   PUSH 00401234
     
     如果希望这行代码在 00500000 是这样工作的:

               00500000  68 34125000   PUSH 00501234

           即表示机器码中的立即数是随段起始地址而调整的.

   5   -   机器码中的 第 1 个 立即数;

   6   -   机器码中的 第 2 个 立即数;

   7   -   机器码中的算术/逻辑操作;

    0:ADD, 1:OR, 2:ADC, 3:SBB, 4:TEST, 5:SUB, 6:XOR, 7:CMP

   8   -   机器码中的 ModRM 操作码;

   9   -   机器码中的 SIM 操作码;

   10  -   机器码中的 Displacement 操作码;

     每一项都由一 Function 读出, 其中一些还要做一些变换.

     并不是每一项都存在于每一行机器码. 


4.  机器代码数据结构

每一行机器代码对应的结构如下:

typedef struct {
  BYTE    FirstOpcode_0;
  BYTE    Unknown1;
  BYTE    SecondImmediateData;
  BYTE    Unknown2[5];
  BYTE    SIMOpcode;
  BYTE    Unknown3[2];
  DWORD   DisplacementOpcode;
  BYTE    Unknown4;
  
  BYTE    FirstOpcode_1; // if FirstOpCode is a prefix
  BYTE    Unknown5[3];
  DWORD   ImmediateDataOpcode;
  DWORD   Unknown6;
  BOOL    bAdjustValueFlag;
  BYTE    Unknown7;
  DWORD   EncryptedEIPAddress; //+1E , EncryptedEIPAddress + baseAddress + randxx ==>EIPAddress
  BYTE    Unknown8[2];
  BYTE    Math

[1] [2]  下一页

[] [返回上一页] [打 印]
关于本站 - 网站帮助 - 广告合作 - 下载声明 - 友情连接 - 网站地图 - 文章投稿 - 软件发布 - 购物资讯网 - _