.586p
.model flat,stdcall
public _Metamorphosize
.code
StartOfEvolutionEngine = $
;变形引擎原理:
; 变形代码由2部分组成:
; 1)一段经过32位key异或加密的代码
; 2)由引擎随机生成的一段对这断加密代码进行解码的模块
;
;标准的解码模块如下所示:
; _____________________________________________________________________
;| |
;| pushad |
;| call @0 |
;|@0: |
;| pop Index_reg |
;| add Index_reg, offset EncryptedData |
;| mov Count_reg, count |
;| mov Key_reg, key |
;|@1: |
;| xor [Index_reg], Key_reg |
;| add Index_reg, 4 |
;| dec Count_reg |
;| jnz @1 |
;| popad |
;|_____________________________________________________________________|
;
;从7个通用寄存器中随机选择3个分别作为index寄存器,key寄存器和counter寄存器。并在
;解密模块的每条有效语句之间随机插入1~3条垃圾代码。
EAX_REG = 0
ECX_REG = 1
EDX_REG = 2
EBX_REG = 3
ESP_REG = 4
EBP_REG = 5
ESI_REG = 6
EDI_REG = 7
; 0 ---- eax
; 1 ---- ecx
; 2 ---- edx
; 3 ---- ebx
; 4 ---- esp
; 5 ---- ebp
; 6 ---- esi
; 7 ---- edi
INDEX_REG = 0
KEY_REG = 1
COUNT_REG = 2
FREE_REG1 = 3
FREE_REG2 = 4
FREE_REG3 = 5
FREE_REG4 = 6
;************************************
;* *
;* Return a random number between *
;* 0~(X-1) *
;* *
;************************************
Random:
;rdtsc
push eax
db 0Fh, 031h
xor edx, edx
div dword ptr [esp+8]
pop eax
ret 4
routine1:
mov byte ptr [edi], 0B8h
mov dl, byte ptr [ebx+ecx]
add [edi], dl
inc edi
ret
;********************************
;* *
;* Generate garbaby statement *
;* *
;********************************
GenerateGarbabyCode:
push eax
push 3 ;<
call Random ;<Decide how many garbaby statement will be generated.
lea ecx, [edx+1] ;<
lp_GenerateGarbabyCode:
push 4 ;<
call Random ;<Decide what register will be used in the statement.
mov eax, edx ;<
push 3 ;<Decide what type of statement will be generated.
call Random ;<
cmp edx, 2
jz lb_$A001
cmp edx, 1
jz lb_$A002
mov byte ptr [edi], 48h ;<
push 1 ;<Generate 'DEC reg'-type statement
jmp lb_$A003 ;<
lb_$A001:
mov byte ptr [edi], 0B8h ;<
push 5 ;<Generate 'MOV REG, DATA'-type statement
jmp lb_$A003 ;<
lb_$A002:
mov word ptr [edi], 0C083h ;<
inc edi ;<Generate 'ADD REG, DATA'-type statement
push 2 ;<
lb_$A003:
add eax, FREE_REG1
mov dl, [ebx+eax]
add [edi], dl
pop eax
add edi, eax
loop lp_GenerateGarbabyCode
pop eax
ret
;*********************************************************************
;*
;* Parameters:
;* [Param1]
;* Size
;* [Param2]
;* Key
;*
;*********************************************************************
RegTable = $
@A = $
db 0, 1, 2, 3, 5, 6, 7
;GenerateDecodeModule:
GenerateDecodeModule PROC
call @0
@0:
pop ebx
lea ebx, [ebx][@A-@0]
;********************************************************************
;* *
;* Randomly array the elements of the register table, then select *
;* the first three ones to use as the index register, the key *
;* register and the counter register *
;* *
;********************************************************************
lb_RandomizeRegisterTableAgain:
mov ecx, 19796
lp_RandomizeRegTable:
push 7
call Random
xchg edx, esi
push 7
call Random
mov al, [ebx+edx]
xchg al, [ebx+esi]
xchg al, [ebx+edx]
loop lp_RandomizeRegTable
;********************************************************************
;* Don't use the EBP register as the index register, because an *
;* statement of 'XOR [EBP], reg2' is 3-byte-length. And for other *
;* registers, a statement of 'XOR [reg1], reg2' is 2-byte-length *
;********************************************************************
cmp byte ptr [ebx][INDEX_REG], EBP_REG
jz lb_RandomizeRegisterTableAgain
;push edi
lea esi, [ebx][GenerateGarbabyCode-@A]
mov [edi], byte ptr 60h
inc edi
call esi ;Generate garbaby code
mov [edi], byte ptr 0E8h
inc edi
push 13
call Random
add edx, 6
mov [edi], edx
add edi, 4
push edi
lea edi, [edi+edx]
mov byte ptr [edi], 58h
mov al, [ebx][INDEX_REG]
add [edi], al
inc edi
call esi ;Generate garbaby code
mov word ptr [edi], 0C083h
inc edi
add [edi], al
inc edi
push edi
inc edi
call esi ;Generate garbaby code
push KEY_REG
pop ecx
call routine1
;mov [edi], dword ptr TOTAL_DWORDS
mov edx, [esp+00000008h][00000008h]
mov [edi], edx
add edi, 4
call esi
push COUNT_REG
pop ecx
call routine1
;mov [edi], dword ptr ENCRYPT_KEY
mov edx, [esp+00000004h][00000008h]
mov [edi], edx
add edi, 4
call esi
push edi
mov word ptr [edi], 0031h
movzx edx, byte ptr [ebx][KEY_REG]
shl edx, 3
add dl, [ebx][INDEX_REG]
inc edi
add [edi], dl
inc edi
call esi
mov dword ptr [edi], 4804C083h
inc edi
add [edi], al
inc edi
inc edi
mov dl, [ebx][COUNT_REG]
add [edi], dl
inc edi
mov dword ptr [edi], 00610075h
lea ecx, [edi+1]
pop eax
sub eax, edi
dec eax
dec eax
mov [ecx], al
inc edi
inc edi
inc edi
pop eax
pop edx
mov ecx, edi
sub ecx, edx
mov [eax], cl
ret 8
GenerateDecodeModule ENDP
SIZE_OF_ENGINE = $-StartOfEvolutionEngine
_Metamorphosize proc
;**************************************************************************
;* *
;* Parameters: *
;* ESI: The start address of the code to be encrypted *
;* ECX: The number of bytes of the code *
;* EDI: The start address of the buffer to store the encrypted code *
;* *
;**************************************************************************
db 0Fh, 031h
push esi
push eax
push ecx
push edi
push eax
push ecx
call GenerateDecodeModule
pop edx
pop ecx
pop eax
pop esi
sub edx, edi
push edx
lp_EncryptData:
mov edx, [esi]
xor edx, eax
mov [edi], edx
add esi, 4
add edi, 4
loop lp_EncryptData
pop eax
ret
_Metamorphosize endp
End