随笔-91  评论-137  文章-0  trackbacks-0
1.首先我们需要一个结构来表示CPU所有的16位和8位寄存器(见Library\Struct\Register.h)
 1 #pragma once
 2 #include "..\Common\Base.h"
 3 
 4 struct Register_16_Bit
 5 {
 6     // General Register
 7     struct
 8     {
 9         BYTE AH; // 8Bit
10         BYTE AL; // 8Bit
11     }AX;
12     struct
13     {
14         BYTE BH; // 8Bit
15         BYTE BL; // 8Bit
16     }BX;
17     struct
18     {
19         BYTE CH; // 8Bit
20         BYTE CL; // 8Bit
21     }CX;
22     struct
23     {
24         BYTE DH; // 8Bit
25         BYTE DL; // 8Bit
26     }DX;
27 
28     // Segment Register
29     USHORT CS;
30     USHORT DS;
31     USHORT SS;
32     USHORT ES;
33 
34     // Special Register
35     USHORT IP;
36     USHORT SP;
37     USHORT BP;
38     USHORT SI;
39     USHORT DI;
40     struct
41     {
42         BYTE OF : 1;
43         BYTE DF : 1;
44         BYTE IF : 1;
45         BYTE TF : 1;
46         BYTE SF : 1;
47         BYTE ZF : 1;
48         BYTE AF : 1;
49         BYTE PF : 1;
50         BYTE CF : 1;
51         BYTE Reserve : 7;
52     }FR;
53 
54     Register_16_Bit()
55     {
56         memset(this,0,sizeof(Register_16_Bit));
57     }
58 };
2.然后我们定义一个接口来抽象出分析过程(见Library\Disasm\DisasmContext.h)
 1 #pragma once
 2 #include "..\Common\Base.h"
 3 
 4 class CDisasmContext
 5 {
 6 public:
 7     virtual bool Disasm(BYTE*& ptr)=0;
 8 protected:
 9     enum OpCodeHeader;
10 };
Disasm函数用于对机器码进行分析并确定语义
OpCodeHeader是个枚举类型用于枚举每条指令的指令头(详情见8086指令手册)
3.我们定义一个Jmp类来对Jmp指令进行分析(见Library\Disasm\Jmp)
 1 #pragma once
 2 #include "..\DisasmContext.h"
 3 
 4 class CJmp : public CDisasmContext
 5 {
 6 public:
 7     virtual bool Disasm(BYTE*& ptr);
 8 protected:
 9     enum OpCodeHeader
10     {
11         JMP_SHORT = 0xEB,    // 段内直接短跳
12         JMP_NEAR = 0xE9,    // 段内直接跳
13         JMP_FAR = 0xEA,        // 段间直接跳
14         JMP_IND = 0xFF,        // 段内(外)间接跳
15     };
16 
17     bool Jmp_Short(BYTE*& ptr);
18     bool Jmp_Near(BYTE*& ptr);
19     bool Jmp_Far(BYTE*& ptr);
20 };
其Disasm函数为
1 bool CJmp::Disasm(BYTE*& ptr)
2 {
3     if(Jmp_Short(ptr)) return true;
4     else if(Jmp_Near(ptr)) return true;
5     else if(Jmp_Far(ptr)) return true;
6     else return false;
7 }
4.我们同样定义一个CMov类来对Mov指令进行分析(见Library\Disasm\Mov)
5.最后我们定义一个CDisasm类来驱动整体框架(见Library\Disasm\Disasm.h)
1 class CDisasm
2 {
3 public:
4     bool Disasm(BYTE* ptr,int size);
5 protected:
6     CJmp Jmp;
7     CMov Mov;
8 };
其Disasm函数为(见Library\Disasm\Disasm.cpp)
 1 bool CDisasm::Disasm(BYTE* ptr,int size)
 2 {
 3     BYTE* end = ptr + size;
 4     while(ptr < end)
 5     {
 6         if(Jmp.Disasm(ptr));
 7         else if(Mov.Disasm(ptr));
 8         else return false;
 9     }
10     return true;
11 }

具体的分析过程其实就是查表的过程,这里不一一列举出来了.
目前只翻译了部分Jmp和Mov指令,有兴趣的同学可以查表对其进行扩充.
所有代码及指令手册打包下载
posted on 2011-07-10 12:30 lwch 阅读(3816) 评论(9)  编辑 收藏 引用 所属分类: 操作系统

评论:
# re: 自制虚拟机框架 2011-07-10 18:35 | 千暮(zblc)
这架构太不具备复用性和灵活性了- -。大囧哇大囧   回复  更多评论
  
# re: 自制虚拟机框架 2011-07-10 22:04 | lwch
@千暮(zblc)
你就只会吃屎其他啥也不会..  回复  更多评论
  
# re: 自制虚拟机框架 2011-07-11 08:30 | 欲三更
祝你早日把linux在你的虚拟机上boot起来~  回复  更多评论
  
# re: 自制虚拟机框架 2011-07-11 09:57 | lwch
@欲三更
懒得继续写下去了,太复杂了...  回复  更多评论
  
# re: 自制虚拟机框架 2011-07-11 21:59 | 千暮(zblc)
@lwch
你还不是天天跟着我吃屎,这玩意的虚拟机米啥好实现的。  回复  更多评论
  
# re: 自制虚拟机框架 2011-07-11 22:02 | 千暮(zblc)
而且你把分析层面的东西,搞进了结构里,何其吃屎瓦!!  回复  更多评论
  
# re: 自制虚拟机框架 2011-07-15 17:24 | willbe
貌似这应该叫做模拟器,而不是叫虚拟机  回复  更多评论
  
# re: 自制虚拟机框架 2011-07-15 22:18 | lwch
@willbe
我的本意是用他来分析x86指令结果发现太麻烦了...  回复  更多评论
  
# re: 自制虚拟机框架 2011-10-27 00:02 | coreBugZJ
面向对象似乎被滥用了。。。个人愚见  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理