summaryrefslogtreecommitdiff
path: root/other/burneye/src/stub/lde32.asm
blob: 4eacf3a89ec36570e437b3caf2d80c82845cc1f2 (plain)
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