1.首先我們需要一個結構來表示CPU所有的16位和8位寄存器
1 #pragma once
2 #include "..CommonBase.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.然後我們定義一個接口來抽象出分析過程
1 #pragma once
2 #include "..CommonBase.h"
3
4 class CDisasmContext
5 {
6 public:
7 virtual bool Disasm(BYTE*& ptr)=0;
8 protected:
9 enum OpCodeHeader;
10 };Disasm函數用於對機器碼進行分析並確定語義
OpCodeHeader是個枚舉類型用於枚舉每條指令的指令頭
3.我們定義一個Jmp類來對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指令進行分析(見LibraryDisasmMov)
5.最後我們定義一個CDisasm類來驅動整體框架(見LibraryDisasmDisasm.h)
1 class CDisasm
2 {
3 public:
4 bool Disasm(BYTE* ptr,int size);
5 protected:
6 CJmp Jmp;
7 CMov Mov;
8 };其Disasm函數為(見LibraryDisasmDisasm.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 }