首页
社区
课程
招聘
7
[原创]一个32位长度反汇编引擎以及对xfish LDE的进一步优化
发表于: 2009-8-10 23:08 9070

[原创]一个32位长度反汇编引擎以及对xfish LDE的进一步优化

2009-8-10 23:08
9070

这里有两个主题,不过都是关于LDE的,所以放在一起了。

主题一:一个32位长度反汇编引擎
和xfish的那个不同,这里的解析过程是模仿CPU解码。这个代码实际上是ASM Community窥来的,只是稍作修改。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
#include "lde.h"
 
int LDE(const unsigned char *func)
{
    int operandSize = 4;
    int FPU = 0;
    const unsigned char* pOrigin = func;
     
    //跳过F0h,F2h,F3h,66h,67h,2Eh,26h,36h,3Eh,64h,65h等前缀,
    //以及D8h-DFh等ESC(转移操作码) 
    while (*func == 0xF0 ||
           *func == 0xF2 ||
           *func == 0xF3 ||
           *func == 0x66 ||
           *func == 0x67 ||
           *func == 0x2E ||
           *func == 0x3E ||
           *func == 0x26 ||
           *func == 0x36 ||
           *func == 0x64 ||
           *func == 0x65 ||
           (*func & 0xF8) == 0xD8   //D8-DF
          )
    {
        if (*func == 0x66)
        {
            operandSize = 2;
        }
        else if ( (*func & 0xF8)==0xD8 )
        {
            FPU = *func++;
            break;
        }
         
        func++;
    }
     
    //跳过双字节操作码转义字节0Fh
    bool twoByte = false;
    if (*func == 0x0F)
    {
        twoByte = true;
        func++;
    }
     
    //跳过主操作码
    unsigned char opcode = *func++;
     
    //跳过ModR/M字节
    unsigned char modRM = 0xFF;
    if (FPU)
    {
        if ( (opcode & 0xC0) != 0xC0 )
        {
            modRM = opcode;
        }
    }
    else if (!twoByte)
    {
        if ((opcode & 0xC4) == 0x00 ||
            (opcode & 0xF4) == 0x60 && ((opcode & 0x0A) == 0x02 || (opcode & 0x09) == 0x9) ||
            (opcode & 0xF0) == 0x80 ||
            (opcode & 0xF8) == 0xC0 && (opcode & 0x0E) != 0x02 ||
            (opcode & 0xFC) == 0xD0 ||
            (opcode & 0xF6) == 0xF6
            )
        {
            modRM = *func++;
        }
    }
    else
    {
        if ((opcode & 0xF0) == 0x00 && (opcode & 0x0F) >= 0x04 && (opcode & 0x0D) != 0x0D ||
            (opcode & 0xF0) == 0x30 ||
            opcode == 0x77 ||
            (opcode & 0xF0) == 0x80 ||
            (opcode & 0xF0) == 0xA0 && (opcode & 0x07) <= 0x02 ||
            (opcode & 0xF8) == 0xC8
            )
        {
            // No mod R/M byte
        }
        else
        {
            modRM = *func++;
        }
    }
     
    //跳过SIB字节
    if ( (modRM & 0x07) == 0x04 && (modRM>>6 & 3) != 3  )
    {
        unsigned char SIB = *func;
        func += 1;
        if ((SIB & 0x7) == 5)
        {
            func += 4;  // disp32
        }
    }
    if ( (modRM & 0xC5) == 0x05 )
    {
        func += 4;   // disp32, no base
    }
    if ( (modRM & 0xC0) == 0x40 )
    {
        func += 1;   // disp8
    }
    if ( (modRM & 0xC0) == 0x80 )
    {
        func += 4;   // disp32
    }
     
    //跳过立即数
    if (FPU)
    {
        // Can't have immediate operand
    }
    else if (!twoByte)
    {
        if ((opcode & 0xC7) == 0x04 ||
            (opcode & 0xFE) == 0x6A ||   // PUSH/POP/IMUL
            (opcode & 0xF0) == 0x70 ||   // Jcc
            opcode == 0x80 ||
            opcode == 0x83 ||
            (opcode & 0xFD) == 0xA0 ||   // MOV
            opcode == 0xA8 ||            // TEST
            opcode == 0xB0 ||            // MOV
            (opcode & 0xFE) == 0xC0 ||   // RCL
            opcode == 0xC6 ||            // MOV
            opcode == 0xCD ||            // INT
            (opcode & 0xFE) == 0xD4 ||   // AAD/AAM
            (opcode & 0xF8) == 0xE0 ||   // LOOP/JCXZ
            opcode == 0xEB ||
            opcode == 0xF6 && (modRM & 0x30) == 0x00   // TEST
            )
        {
            func += 1;
        }
        else if( (opcode & 0xF7) == 0xC2 )
        {
            func += 2;   // RET
        }
        else if( (opcode & 0xFC) == 0x80 ||
                 (opcode & 0xC7) == 0x05 ||
                 (opcode & 0xFE) == 0xE8 ||      // CALL/Jcc
                 (opcode & 0xFE) == 0x68 ||
                 (opcode & 0xFC) == 0xA0 ||
                 (opcode & 0xEE) == 0xA8 ||
                 opcode == 0xC7 ||
                 opcode == 0xF7 && (modRM & 0x30) == 0x00
                )
        {
            func += operandSize;
        }
    }
    else
    {
        if ( opcode == 0xBA ||          // BT
             opcode == 0x0F ||          // 3DNow!
             (opcode & 0xFC) == 0x70 ||  // PSLLW
             (opcode & 0xF7) == 0xA4 ||  // SHLD
             opcode == 0xC2 ||
             opcode == 0xC4 ||
             opcode == 0xC5 ||
             opcode == 0xC6
            )
        {
            func += 1;
        }
        else if((opcode & 0xF0) == 0x80)
        {
            func += operandSize;   // Jcc -i
        }
    }
     
    return func-pOrigin;
}

[注意]看雪招聘,专注安全领域的专业人才平台!

上传的附件:
收藏
免费 7
支持
分享
赞赏记录
参与人
雪币
留言
时间
Youlor
为你点赞~
2024-2-25 02:49
伟叔叔
为你点赞~
2024-1-4 04:46
QinBeast
为你点赞~
2023-12-11 00:33
shinratensei
为你点赞~
2023-10-30 05:11
PLEBFE
为你点赞~
2023-10-11 00:32
心游尘世外
为你点赞~
2023-9-28 04:25
飘零丶
为你点赞~
2023-9-22 00:00
最新回复 (2)
雪    币: 204
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
有技术含量啊. 怎么没有人关注?

不过第一种方法的代码编译出来 (vc6, O1) 的尺寸是 747 字节. 可能在尺寸上没有太多优势.
2009-8-17 11:02
0
雪    币: 558
活跃值: (43)
能力值: ( LV12,RANK:220 )
在线值:
发帖
回帖
粉丝
3
谢谢关注!
第一个是模拟CPU解码,不是一般的表查询,因为不附带表,可以用在一般的场合。

另一个问题是早几天才看了mlde32,才发现原来已经有了一个index-compressed优化的版本,不过和上面写的这个是不一样的。

附mlde32 mlde32.zip
上传的附件:
2009-8-17 12:06
0
游客
登录 | 注册 方可回帖
返回

账号登录
验证码登录

忘记密码?
没有账号?立即免费注册