-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdepacks.asm
246 lines (174 loc) · 4.24 KB
/
depacks.asm
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
;;
;; aPLib compression library - the smaller the better :)
;;
;; fasm safe assembler depacker
;;
;; Copyright (c) 1998-2014 Joergen Ibsen
;; All Rights Reserved
;;
;; http://www.ibsensoftware.com/
;;
format MS COFF
public aP_depack_asm_safe as '_aP_depack_asm_safe'
; =============================================================
macro getbitM
{
local .stillbitsleft
shl dl, 1
jnz .stillbitsleft
sub dword [esp + 4], 1 ; read one byte from source
jc return_error ;
mov dl, [esi]
inc esi
stc
rcl dl, 1
.stillbitsleft:
}
macro domatchM reg
{
push ecx
mov ecx, [esp + 12 + _dlen$] ; ecx = dstlen
sub ecx, [esp + 4] ; ecx = num written
cmp reg, ecx
pop ecx
ja return_error
sub [esp], ecx ; write ecx bytes to destination
jc return_error ;
push esi
mov esi, edi
sub esi, reg
rep movsb
pop esi
}
macro getgammaM reg
{
local .getmore
mov reg, 1
.getmore:
getbitM
rcl reg, 1
jc return_error
getbitM
jc .getmore
}
; =============================================================
section '.text' code readable executable
aP_depack_asm_safe:
; aP_depack_asm_safe(const void *source,
; unsigned int srclen,
; void *destination,
; unsigned int dstlen)
_ret$ equ 7*4
_src$ equ 8*4 + 4
_slen$ equ 8*4 + 8
_dst$ equ 8*4 + 12
_dlen$ equ 8*4 + 16
pushad
mov esi, [esp + _src$] ; C calling convention
mov eax, [esp + _slen$]
mov edi, [esp + _dst$]
mov ecx, [esp + _dlen$]
push eax
push ecx
test esi, esi
jz return_error
test edi, edi
jz return_error
or ebp, -1
cld
xor edx, edx
literal:
sub dword [esp + 4], 1 ; read one byte from source
jc return_error ;
mov al, [esi]
inc esi
sub dword [esp], 1 ; write one byte to destination
jc return_error ;
mov [edi], al
inc edi
mov ebx, 2
nexttag:
getbitM
jnc literal
getbitM
jnc codepair
xor eax, eax
getbitM
jnc shortmatch
getbitM
rcl eax, 1
getbitM
rcl eax, 1
getbitM
rcl eax, 1
getbitM
rcl eax, 1
jz .thewrite
mov ebx, [esp + 8 + _dlen$] ; ebx = dstlen
sub ebx, [esp] ; ebx = num written
cmp eax, ebx
ja return_error
mov ebx, edi
sub ebx, eax
mov al, [ebx]
.thewrite:
sub dword [esp], 1 ; write one byte to destination
jc return_error ;
mov [edi], al
inc edi
mov ebx, 2
jmp nexttag
codepair:
getgammaM eax
sub eax, ebx
mov ebx, 1
jnz normalcodepair
getgammaM ecx
domatchM ebp
jmp nexttag
normalcodepair:
dec eax
test eax, 0xff000000
jnz return_error
shl eax, 8
sub dword [esp + 4], 1 ; read one byte from source
jc return_error ;
mov al, [esi]
inc esi
mov ebp, eax
getgammaM ecx
cmp eax, 32000
sbb ecx, -1
cmp eax, 1280
sbb ecx, -1
cmp eax, 128
adc ecx, 0
cmp eax, 128
adc ecx, 0
domatchM eax
jmp nexttag
shortmatch:
sub dword [esp + 4], 1 ; read one byte from source
jc return_error ;
mov al, [esi]
inc esi
xor ecx, ecx
shr al, 1
jz donedepacking
adc ecx, 2
mov ebp, eax
domatchM eax
mov ebx, 1
jmp nexttag
return_error:
add esp, 8
popad
or eax, -1 ; return APLIB_ERROR in eax
ret
donedepacking:
add esp, 8
sub edi, [esp + _dst$]
mov [esp + _ret$], edi ; return unpacked length in eax
popad
ret
; =============================================================