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
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
|
; LDE32 -- Length-Disassembler Engine
; FREEWARE
;
; programmed by Z0MBiE, http://z0mbie.cjb.net
;
; release 1.00 8-12-99
; release 1.01 9-12-99
; release 1.02 17-03-00 0xF6/0xF7 'test' opcode bugfixed
; release 1.03 21-04-00 bugfix: some prefixes before 0F were cleared
; bugfix: error in MODRM analysis
; CD 20 now is 6 bytes length
; release 1.04 1-05-00 AAM & AAD bugfixed (was 1-byte len)
; release 1.05 xx-xx-xx special edition, flags changed
; release 1.06 3-01-01 partially rewritten, __cdecl
; some very small mods/changes by scut to compile under nasm
C_ERROR equ -1 ; never change it
C_MEM1 equ 0x0001 ; |
C_MEM2 equ 0x0002 ; |may be used simultaneously
C_MEM4 equ 0x0004 ; |
C_DATA1 equ 0x0100 ; |
C_DATA2 equ 0x0200 ; |may be used simultaneously
C_DATA4 equ 0x0400 ; |
C_67 equ 0x0010 ; used with C_PREFIX
C_MEM67 equ 0x0020 ; C_67 ? C_MEM2 : C_MEM4
C_66 equ 0x1000 ; used with C_PREFIX
C_DATA66 equ 0x2000 ; C_66 ? C_DATA2 : C_DATA4
C_PREFIX equ 0x0008 ; prefix. take opcode again
C_MODRM equ 0x4000 ; MODxxxR/M
C_DATAW0 equ 0x8000 ; opc&1 ? C_DATA66 : C_DATA1
; void __cdecl lde_init(void* tableptr);
BITS 32
GLOBAL lde_init
lde_init:
pusha
mov edi, [esp+32+4]
cld
; Huffman-compressed 2048-byte table
xor eax, eax
push eax
push eax
push eax
push dword 0x002AAA800
push dword 0x03FFF687F
push dword 0x0FFE6DEA0
push dword 0x0DBD5FFFF
push dword 0x0FFFEAAAA
push dword 0x0AAAAAAAA
push dword 0x0AAAA0000
push eax
push eax
push eax
push eax
push eax
push eax
push dword 0x000000154
push dword 0x041FFF555
push dword 0x055DEDDAA
push dword 0x019955111
push dword 0x011111FFF
push dword 0x0FA11FFAA
push dword 0x08E60CF96
push dword 0x0FC72D6AA
push dword 0x0AAAAAA88
push dword 0x0888888D5
push dword 0x0528D559B
push dword 0x0366CD553
push dword 0x0355555FF
push dword 0x0FFFED6F9
push dword 0x068888888
push dword 0x088888888
push dword 0x08D5347CA
push dword 0x0DCC67BDF
push dword 0x0AAAAAAAA
push dword 0x0AAAAAAAA
push dword 0x0ABA94FFD
push dword 0x0D4A7FEEA
push dword 0x053FF7529
push dword 0x0FFA4A7FE
push dword 0x0929FFA4A
push dword 0x07FE929FF
mov ecx, 512
xor ebx, ebx
cycle: xor eax, eax
call tree
stosd
loop cycle
popa
retn
getbit: or ebx, ebx
jnz skip
pop ebp
pop esi
pop edx
push esi
push ebp
mov bl, 32
skip: dec ebx
shr edx, 1
retn
; Huffman-tree, compiled into decompressor code
tree: call getbit
jnc tree0
tree1: call getbit
jnc tree10
tree11: mov ah, (C_MODRM >> 8)
retn
tree10: call getbit
jc tree101
tree100:
call getbit
jnc tree1000
tree1001:
call getbit
jnc tree10010
tree10011:
call getbit
jc tree100111
tree100110:
call getbit
jnc tree1001100
tree1001101:
mov al, C_MEM67
retn
tree1001100:
call getbit
jnc tree10011000
tree10011001:
mov ax, C_DATA66+C_MEM2
retn
tree10011000:
call getbit
jnc tree100110000
tree100110001:
mov ax, C_PREFIX+C_66
retn
tree100110000:
mov ah, ((C_DATA2+C_DATA1) >> 8)
retn
tree100111:
call getbit
jnc tree1001110
tree1001111:
mov ah, ((C_MODRM+C_DATA66) >> 8)
retn
tree1001110:
call getbit
jnc tree10011100
tree10011101:
mov al, C_PREFIX+C_67
retn
tree10011100:
mov ah, (C_DATA2 >> 8)
retn
tree10010:
mov ah, (C_DATAW0 >> 8)
retn
tree1000:
mov ah, (C_DATA1 >> 8)
retn
tree101:
call getbit
jnc tree1010
tree1011:
call getbit
jnc tree10110
tree10111:
mov al, C_PREFIX
retn
tree10110:
mov ah, ((C_MODRM+C_DATA1) >> 8)
retn
tree1010:
mov ah, (C_DATA66 >> 8)
retn
tree0: call getbit
; jc tree01
adc al, 0
tree00: dec eax
tree01: retn
; int __cdecl lde_dis(void* opcodeptr, void* tableptr)
; {
; returns opcode length in EAX or -1 if error
GLOBAL lde_dis
lde_dis:
pusha
mov esi, [esp+32+4] ; tableptr
mov ecx, [esp+32+8] ; param = opcode ptr
xor edx, edx ; flags
xor eax, eax
prefix: and dl, ~C_PREFIX
mov al, [ecx]
inc ecx
or edx, [esi+eax*4]
test dl, C_PREFIX
jnz prefix
cmp al, 0xf6
je btest
cmp al, 0xf7
je btest
cmp al, 0xcd
je bint
cmp al, 0x0f
je b0F
cont: test dh, (C_DATAW0 >> 8)
jnz dataw0
dataw0done:
test dh, (C_MODRM >> 8)
jnz near modrm
exitmodrm:
test dl, C_MEM67
jnz mem67
mem67done:
test dh, (C_DATA66 >> 8)
jnz data66
data66done:
mov eax, ecx
sub eax, [esp+32+8]
and edx, C_MEM1+C_MEM2+C_MEM4 + C_DATA1+C_DATA2+C_DATA4
add al, dl
add al, dh
exit: mov [esp+7*4], eax
popa
retn
btest: or dh, (C_MODRM >> 8)
test byte [ecx], 00111000b ; F6/F7 -- test
jnz cont
or dh, (C_DATAW0 >> 8)
jmp cont
bint: or dh, (C_DATA1 >> 8)
cmp byte [ecx], 0x20
jne cont
or dh, (C_DATA4 >> 8)
jmp cont
b0F: mov al, [ecx]
inc ecx
or edx, [esi+eax*4+1024] ; 2nd half
cmp edx, -1
jne cont
error: mov eax, edx
jmp exit
dataw0: xor dh, (C_DATA66 >> 8)
test al, 00000001b
jnz dataw0done
xor dh, ((C_DATA66+C_DATA1) >> 8)
jmp dataw0done
mem67: xor dl, C_MEM2
test dl, C_67
jnz mem67done
xor dl, C_MEM4+C_MEM2
jmp mem67done
data66: xor dh, (C_DATA2 >> 8)
test dh, (C_66 >> 8)
jnz data66done
xor dh, ((C_DATA4+C_DATA2) >> 8)
jmp data66done
modrm: mov al, [ecx]
inc ecx
mov ah, al ; ah=mod, al=rm
and ax, 0xc007
cmp ah, 0xc0
je near exitmodrm
test dl, C_67
jnz modrm16
modrm32:
cmp al, 0x04
jne a
mov al, [ecx] ; sib
inc ecx
and al, 0x07
a: cmp ah, 0x40
je mem1
cmp ah, 0x80
je mem4
cmp ax, 0x0005
jne near exitmodrm
mem4: or dl, C_MEM4
jmp exitmodrm
mem1: or dl, C_MEM1
jmp exitmodrm
modrm16:
cmp ax, 0x0006
je mem2
cmp ah, 0x40
je mem1
cmp ah, 0x80
jne near exitmodrm
mem2: or dl, C_MEM2
jmp exitmodrm
|