Insane Reality issue #7 - (c)opyright 1995 Immortal Riot               File 024 


% AV-SECTION %

--------------

Here's the AV-section of Insane Reality :-). It includes quite a great 
deal of code to removers/scanners & monitors programs, in all kinda 
computer-languages (well, atleast asm/pas/c).



Here's a little index of the code presented in this file.... 


 Manzon.... remover by Bugsy written mainly in pascal (+inline ASM).... 
 Replicator remover by Bugsy written mainly in pascal.................. 
 Taipan.... remover by Bugsy written solely in pascal.................. 
 Taipan.... scanner by Rilo  written solely in pascal.................. 
 Taipan.... scanner by Rilo  written solely in C++..................... 
 K-Bravo... cleaner by Rilo  written solely in C++..................... 
 Taipan.... remover by Dooz  written solely in ASM..................... 
 Hybris.... remover by TUIR  written solely in ASM..................... 
 Swe_virus  blocker by Aron  written solely in ASM..................... 


I think this article can be a gain for a lot of our readers, 
so don't rag on me for "converting the IR-zine into an AV-tabloit" :). 
Code is always knowledge of some kind and there you have a good 
exchause for publishing this :-).



The persons who has written the code presented in this article is people 
I really respect, so don't go mess around with their programs and don't 
even think about trojanizing their software!



Greetings & Multiple orgasms to: Bugsy, Rilo, Freaking Dooz & Aron. 
- The Unforgiven.



% Bugsy's Manzon remover %

--------------------------

Here's version 1.2 of Bugsy's Manzon remover!



The special thing about it is that it can remove two manzon variants 
(which F-prot 2.19 failed with because they're very much alike), which 
of course is very strange since we only did release the 1404 variant! 


This version is by the way modified by me so you can get it working 
right away. I removed the self-checking and a weird overlay check for 
the sake of compability.



The latter 'problem' seems to be a fix so the remover shouldn't be 
infected with Replicator by Darkman of VLAD (you would have to alter the 
EXE-file yourself after compiling).



Well, here it is anyway, and enjoy!

- The Unforgiven.

==================================================================
============== 


{$A+,B-,D+,E+,F-,G+,I-,L+,N-,O-,P-,Q-,R-,S-,T-,V+,X+,Y+}

{$M 64000,0,0}  {BP 7.0 compiler options}



{ FREEWARE 1995 by BUGSY & SPAWN of OBSESSiON                                } 
{ This is the Manzon nuker source-code.                                      } 
{ Do with it as you like, just remember who made it.                         } 
{                                                                            } 
{ Contact us if you like. Coders are :                                       } 
{                                                                            } 
{ Benjamin Petersen                                                          } 
{ Nybrovej 304, F48                                                          } 
{ 2800 Lyngby, Denmark                                                       } 
{ Phone # : +45 45974348                                                     } 
{ Internet mail address : ben@ktas.dk                                        } 
{                                                                            } 
{ Michael Skovslund                                                          } 
{ Stationsvej 2                                                              } 
{ 4681 Herfoelge, Denmark                                                    } 
{ Phone # : +45 56275314                                                     } 
{                                                                            } 
{            Well, sorry about missing comments in the source code!          } 
{                                                                            } 
{                          BUGSY & SPAWN of ...                              } 
{                                                     }

{                                                       }

{                                                            } 
{                                                    }

Program NukeManzon;



Uses

  Crt,

  Dos;



Const

  UnExpInt21h  = 0;

  InsFound     = 1;

  LoadError    = 2;

  EnvError     = 3;

  FreeError    = 4;

  BrokenFile   = 5;

  UnknownVer   = 6;

  MyFileSize   = 22064 + 2;                 {Remember to change this one} 
  MyFileName   = 'NUKEMANZ.EXE';

  NameOfVirus  = 'MANZON';

  MinVirusSize = 1000;                   {Remember to change this one} 
  InsTabel     : Array [0..19] Of Byte =
(0,$E8,$8B,$8B,$81,$B9,$E8,$2E,$46,$E2,$C3,$58,$C3,$E8,$5E,$56,$1E,$0E,$1F,$B8); 


Type

  ExeHeaderType    = Record

    ExeSign        ,

    ByteOnLastPage ,

    FileSizeDIV512 ,

    NumberOfRel    ,

    HeaderSizeInP  ,

    MinMemInP      ,

    MaxMemInP      ,

    _SS            ,

    _SP            ,

    ChkSum         ,

    _IP            ,

    _CS            ,

    RelocTabel     ,

    Overlay        : Word;

  End;



  LoadAndExecType = Record

    Environment ,

    OfsParam    ,

    SegParam    : Word;

    FCB         : Array [1..4] Of Word;

    _SP         ,

    _SS         ,

    _IP         ,

    _CS         : Word;

  End;



Var

  RetFFound   ,

  In1Decrypt  ,

  CxWasZero   ,

  CXWasZero2  : Byte;



  OldSS       ,

  OldSP       ,



  InsCount    ,

  InsTabelCt  ,



  VirVersion  ,

  FileError   ,

  ChildePSP   ,

  H           ,

  M           ,

  S           ,

  Hund        ,

  SubCt       : Word;



  NumOfFile   ,

  NumOfVirF   ,

  NumOfVirR   ,

  EntryPtr    : LongInt;



  OldDir      ,

  FileNameStr ,

  MyPathStr   ,

  MyDir       ,

  TempPath    ,

  ExecName    ,

  Parameter   ,

  Buffer      : String;



  Always      ,

  ComFile     ,

  ESC         ,

  DoSub       ,

  Beep        ,

  NoClean     ,

  Debug       ,

  Prompt      : Boolean;



  Path        : PathStr;

  Dir         : DirStr;

  Name        : NameStr;

  Ext         : ExtStr;



  InFile      : File of Byte;

  HdrInFile   : File Of ExeHeaderType;



  DirInfo     : SearchRec;

  ExeHeader   : ExeHeaderType;

  LoadAndExec : LoadAndExecType;

  OrgComCode  : Array [1..3] Of Byte;



Function ErrorText : String;

Begin

  Case FileError Of

    1   : ErrorText := 'Invalid function number.';

    2   : ErrorText := 'File not found.';

    3   : ErrorText := 'Path not found.';

    4   : ErrorText := 'Too many open files.';

    5   : ErrorText := 'File access denied.';

    6   : ErrorText := 'Invalid file handle.';

    12  : ErrorText := 'Invalid file access code.';

    15  : ErrorText := 'Invalid drive number.';

    16  : ErrorText := 'Cannot remove current directory.'; 
    17  : ErrorText := 'Cannot rename across drives.';

    18  : ErrorText := 'No more files.';

    100 : ErrorText := 'Disk read error.';

    101 : ErrorText := 'Disk write error.';

    102 : ErrorText := 'File not assigned.';

    103 : ErrorText := 'File not open.';

    104 : ErrorText := 'File not open for input.';

    105 : ErrorText := 'File not open for output.';

    106 : ErrorText := 'Invalid numeric format.';

    150 : ErrorText := 'Disk is write-protected.';

    151 : ErrorText := 'Bad drive request struct length.'; 
    152 : ErrorText := 'Drive not ready.';

    154 : ErrorText := 'CRC error in data.';

    156 : ErrorText := 'Disk seek error.';

    157 : ErrorText := 'Unknown media type.';

    158 : ErrorText := 'Sector Not Found.';

    159 : ErrorText := 'Printer out of paper.';

    160 : ErrorText := 'Device write fault.';

    161 : ErrorText := 'Device read fault.';

    162 : ErrorText := 'Hardware failure.';

    200 : ErrorText := 'Division by zero.';

    201 : ErrorText := 'Range check error.';

    202 : ErrorText := 'Stack overflow error.';

    203 : ErrorText := 'Heap overflow error.';

    204 : ErrorText := 'Invalid pointer operation.';

    205 : ErrorText := 'Floating point overflow.';

    206 : ErrorText := 'Floating point underflow.';

    207 : ErrorText := 'Invalid floating point operation.'; 
    208 : ErrorText := 'Overlay manager not installed.';

    209 : ErrorText := 'Overlay file read error.';

    210 : ErrorText := 'Object not initialized.';

    211 : ErrorText := 'Call to abstract method.';

    212 : ErrorText := 'Stream registration error.';

    213 : ErrorText := 'Collection index out of range.';

    214 : ErrorText := 'Collection overflow error.';

    215 : ErrorText := 'Arithmetic overflow error.';

    216 : ErrorText := 'General Protection fault.'

  Else

    ErrorText := 'Not found.';

  End;

End;



Procedure Error (Err : Byte);

Begin

  Write ('Error (',Err,') : ');

  Case Err Of

    1 : WriteLn ('No files found.');

    2 : WriteLn ('Can''t find directory.');

    3 : Begin

          WriteLn (NameOfVirus,' virus is resident in memory !'); 
          WriteLn ('            Boot from a clean floppy and try again.'); 
          WriteLn ('            Please reinstall this killer, because it can be infected.'); 
        End;

    4 : WriteLn (MyFileName, ' has been changed !. Virus ?'); 
    6 : WriteLn ('Can''t seek into file.');

    7 : WriteLn ('Can''t read from file.');

    8 : WriteLn ('Can''t close file.');

    9 : WriteLn ('Can''t open file.');

   10 : WriteLn ('Can''t write to file.');

   11 : WriteLn ('Can''t truncate file.');

   12 : WriteLn ('Can''t get directory.');

   14 : WriteLn ('Remember to add a 2 byte (HA) overlay.');{ Internal        } 
                                                           { Use any hex file} 
                                                           { editor to add a } 
                                                           { 2 byte overlay  } 
                                                           { in the exefile  } 
                                                           { The overlay MUST} 
                                                           { be 'HA'         } 
                                                           { This is done to } 
                                                           { prevent replicat} 
                                                           { to infect this  } 
                                                           { nuker           } 
  Else

    WriteLn ('Not defined, programmer forgot this one !');   {hmmmmm....} 
  End;

  If OldDir <> '' Then ChDir(OldDir);

  If IOResult <> 0 Then;

  Window (1, 1, 80, 25);

  GotoXY (1, 24);

  Halt (1);

End;



Procedure WriteHelpScr;

Var

  OldX, OldY : Byte;



Begin

  GotoXY (WhereX, WhereY-1);

  WriteLn
('
Ŀ');

  WriteLn ('USAGE : Nukemanz [path]filename.ext [/nc] [/b] [/s] [/p] STAiRWAY TO
HEAVEN '); 
  WriteLn ('                                             Ĵ   +45 747-263-o3   ');

  WriteLn ('You can use ANY valid dos wildcard.          The groupe   +45 747-2oo-56  
'); 
  WriteLn ('                                              named IR     Call now for    '); 
  WriteLn ('/NC no clean  /P prompt before cleaning file    made          newest       ');

  WriteLn ('/B  beep      /S search subdirectory           MANZON   OBSESSiON releases
'); 
  WriteLn
('
Ĵ');

  WriteLn ('        Coded by BUGSY & SPAWN of..  E-MAIL us  This is a killer for
the  '); 
  WriteLn ('--                                   at      two variants of the virus '); 
  WriteLn ('             ben@ktas.dk
MANZON.1404 & MANZON.1416 '); 
  WriteLn (' |              Ĵ
------------------------- '); 
  WriteLn ('                                  HEY TU, why don''t you
tell'); 
  WriteLn ('                         xxx-x/xx that
he should do'); 
  WriteLn (' If you want to contact us, our addresses are  :  his coding job insted of  ');

  WriteLn
('
Ĵ making those LAME viruses ');

  WriteLn (' Benjamin Petersen       Michael Skovslund       ------------------------- ');

  WriteLn (' Nybrovej 304, F48       Stationsvej 2           Feel free to contact me,  ');

  WriteLn (' 2800 Lyngby, Denmark    4681 Herfoelge, Denmark if you wanna get the
src! '); 
  WriteLn (' Phone # : +45 45974348  Phone # : +45 56275314      Yours
BUGSY/OBSESSiON '); 
  WriteLn
('
');

  OldX := WhereX;

  OldY := WhereY;

  TextColor (LightRed);

  GotoXY (51, 9);

  Write ('A');        {HE he got ya RED-A/IR ... + 1 + 2 + 3 + 4....} 
  TextColor (LightGreen);

  GotoXY (29,13);

  Write ('');

  GotoXY (OldX, OldY);

  Halt (1);

End;



Function VirusIsInMem : Boolean; Assembler;

Asm

  mov  ax, 0DCBAh                       {Virus id word}

  int  21h

  cmp  dx, ax

  mov  ax, 0

  jne  @NOVirus

  mov  ax, 1

@NOVirus:

End;



Function TestForVir : Boolean;

Var

  TempByte : Byte;

  TempWord : Word;



Begin

  TestForVir := False;

  Read (InFile, TempByte);

  If IOResult <> 0 Then Error (7);

  If TempByte = $B9 Then Begin              {mov cx, ???? opcode} 
    Read (InFile, TempByte);

    If IOResult <> 0 Then Error (7);

    Read (InFile, TempByte);

    If IOResult <> 0 Then Error (7);

    Read (InFile, TempByte);

    If IOResult <> 0 Then Error (7);

    If TempByte = $BE Then Begin                 {mov si, ???? opcode} 
      TestForVir := True;

      GotoXY (WhereX-1, WhereY);

      Write (', infected with ',NameOfVirus);

      TestForVir := True;

    End;

  End;

End;



Procedure DelFile (InName : String);

Var

  Ch   : Char;

  DelF : File;



Begin

  Write ('Delete the file (Y/N/A) ? ');

  If NOT Always Then Ch := Upcase (ReadKey) Else Ch := 'Y'; 
  If Ch = 'A' Then ALWAYS := True;

  If (Ch = 'Y') OR ALWAYS Then Begin

    WriteLn ('Y');

    Assign (DelF, InName);

    Erase (DelF);

    If IOResult <> 0 Then;

  End Else

    WriteLn ('N');

End;



Function ChkFile : Boolean;

Var

  Ct        ,

  TempByte  : Byte;

  TempWord  : Word;



Begin

  FileMode := 0;   {ReadOnly mode}

  ChkFile := False;



  If DirInfo.Name[Length(DirInfo.Name)] = '.' Then Exit;

  If DirInfo.Attr AND Directory = Directory Then Exit;

  If DirInfo.Attr AND VolumeID = VolumeID Then Exit;

  Inc (NumOfFile);

  If MyDir[Length(MyDir)] = '\' Then

    Write (MyDir,DirInfo.Name,' ')

  Else

    Write (MyDir,'\',DirInfo.Name,' ');



  If DirInfo.Size < MinVirusSize Then Begin

    ChkFile := False;

    WriteLn;

    Exit;

  End;



  Assign (InFile, DirInfo.Name);



  Reset (InFile);

  If IOResult <> 0 Then Begin

    WriteLn (' ERROR : Can''t open file, share violation ?'); 
    ChkFile := False;

    Exit;

  End;



  {Test if EXE-file}

  ComFile := False;

  Read (InFile, TempByte);

  If IOResult <> 0 Then Error (7);

  If (TempByte = Byte('M')) OR (TempByte = Byte('Z')) then Begin 
    Read (InFile, TempByte);

    If IOResult <> 0 Then Error (7);

    If (TempByte = Byte('M')) OR (TempByte = Byte('Z')) then Begin 
      {Get EXE-header}

      Assign (HdrInFile, DirInfo.Name);

      Reset (HdrInFile);

      If IOResult <> 0 Then Error (9);

      Read (HdrInFile, ExeHeader);

      If IOResult <> 0 Then Error (7);

      Close (HdrInFile);

      If IOResult <> 0 Then Error (8);

      {Seek To Code}

      TempWord := ExeHeader._CS + (ExeHeader._IP SHR 4);

      EntryPtr := LongInt (TempWord) * $10 + (ExeHeader._IP AND $000F) +
(ExeHeader.HeaderSizeInP * $10); 
      If DirInfo.Size < (EntryPtr + 3) Then Begin

        WriteLn ('Entry point to code is out of size!.');

        WriteLn ('File does NOT work! (The virus fucked it up!)'); 
        DelFile (DirInfo.Name);

      End Else Begin

        Reset (InFile);

        Seek (InFile, EntryPtr);

        If IOResult <> 0 Then Error (6);

        ChkFile := TestForVir;

      End;

    End;

  End Else Begin

    {Assume COM-file}

    ComFile := True;

    Reset (InFile);

    Read (InFile, TempByte);

    If IOResult <> 0 Then Error (7);

    If TempByte = $E9 then Begin                  {Jump opcode} 
      Read (InFile, TempByte);                    {read jump location} 
      If IOResult <> 0 Then Error (7);

      TempWord := TempByte;

      Read (InFile, TempByte);

      If IOResult <> 0 Then Error (7);

      TempWord := TempWord + (TempByte*256) + 3;  {+3 for opcode size} 
      EntryPtr := TempWord;

      If Dirinfo.Size <= (EntryPtr  + 3) Then Begin

        WriteLn ('Entry point to code is out of size!.');

        WriteLn ('File does NOT work! (The virus fucked it up!)'); 
        DelFile (DirInfo.Name);

      End Else

      Begin

        Reset (InFile);

        Seek (InFile, TempWord);

        If IOResult <> 0 Then Error (6);

          ChkFile := TestForVir;

      End;

    End;

  End;

  Close (InFile);

  WriteLn;

  FileMode := 2;       {Read/Write mode}

End;



Procedure NewInt01; ASSEMBLER;

Asm

  pusha

  push    es

  push    ds



  mov     ax, Seg OldSS                 {Setup our datasegment} 
  mov     ds, ax



  mov     bp, sp

  mov     al, 3

  or      ss:[bp+14h+5], al  {set trap and interruptflag on return} 


  les     di, ss:[bp+14h]



@TestVirusIns:

  cmp     CXWasZero2, 1

  je      @TheCXWasZero2



  cmp     CXWasZero, 1

  je      @TheCXWasZero



  cmp     RetFFound, 1

  je      @TheRetFFound



  cmp     byte ptr es:[di], 0cbh        {retf opcode}

  jne     @NextIns

  mov     RetFFound, 1

  jmp     @NextIns



@TheRetFFound:

  cmp     InsCount, 5

  je      @TestForCXZero

  inc     InsCount

  jmp     @NextIns



@TestForCXZero:

  cmp     cx, 0

  jne     @NextIns



  mov     CXWasZero, 1

  mov     InsCount, 0

  jmp     @NextIns



@TheCXWasZero:

  inc     InsCount

  cmp     InsCount, 7

  jb      @CXNOTZero



  cmp     cx, 0

  je      @SetCXWasZero2

  cmp     InsCount, 10

  jne     @CXNOTZero

  mov     InsCount, 7

  jmp     @CXNOTZero



@TheCXWasZero2:

  inc     InsCount



@SetCXWasZero2:

  mov     CXWasZero2, 1



@CXNOTZero:

  mov     bx, InsCount

  mov     si, offset InsTabel

  mov     al, es:[di]             {Virus opcode}



  xchg    bx, dx

  cmp     dx, 19

  mov     bl, InsFound

  je      @GetOut

  xchg    dx, bx



  cmp     al, [si+bx]             {test for same in tabel} 
  mov     bl, BrokenFile

  je      @NextIns



@GetOut:

  mov     ax, Seg OldSS

  mov     ds, ax

  cli

  mov     ss, OldSS

  mov     sp, OldSP

  sti



  cmp     byte ptr es:[di+8h], 61h

  jne     @ChkVersion2



  mov     VirVersion,  1416



  cmp     word ptr es:[di-2a4h], 0100h

  je      @Version1Com



@Version1Exe:

  mov     ax, es:[di-2ach]

  mov     Exeheader._CS, ax

  mov     ax, es:[di-2aah]

  mov     Exeheader._IP, ax

  mov     ax, es:[di-2a8h]

  mov     Exeheader._SS, ax

  mov     ax, es:[di-2a6h]

  mov     Exeheader._SP, ax

  sub     word ptr ExeHeader.MinMemInP, 0071h

  retf



@Version1Com:

  mov     al, byte ptr es:[di-2B2h]

  mov     byte ptr OrgComCode[0], al



  mov     al, byte ptr es:[di-2B2h+1]

  mov     byte ptr OrgComCode[1], al



  mov     al, byte ptr es:[di-2B2h+2]

  mov     byte ptr OrgComCode[2], al

  retf



@ChkVersion2:

  cmp     byte ptr es:[di+8h], 5Ch

  jne     @UnknownVersion



  mov     VirVersion, 1404

  cmp     word ptr es:[di-2a1h], 0100h

  je      @Version2Com



@Version2Exe:

  mov     ax, es:[di-2a9h]

  mov     Exeheader._CS, ax

  mov     ax, es:[di-2a7h]

  mov     Exeheader._IP, ax

  mov     ax, es:[di-2a5h]

  mov     Exeheader._SS, ax

  mov     ax, es:[di-2a3h]

  mov     Exeheader._SP, ax

  sub     word ptr ExeHeader.MinMemInP, 0070h

  retf



@Version2Com:

  mov     al, byte ptr es:[di-2afh]

  mov     byte ptr OrgComCode[0], al



  mov     al, byte ptr es:[di-2afh+1]

  mov     byte ptr OrgComCode[1], al



  mov     al, byte ptr es:[di-2afh+2]

  mov     byte ptr OrgComCode[2], al

  retf



@UnknownVersion:

  mov     bl, UnknownVer

  retf



@NextIns:

  pop     ds

  pop     es

  popa

  iret

End;



Function TraceFile : Byte;

label TrapReturn;

Var

  Ct       : Byte;

  OldInt01 : Procedure;



Begin

  RetFFound  := 0;

  CxWasZero  := 0;

  CxWasZero2 := 0;

  InsCount   := 0;



  GetIntVec ($01, @OldInt01);

  SetIntVec ($01, @NewInt01);

  ExecName := DirInfo.Name + ' ';



  ExecName[Length (ExecName)] := #0;

  Parameter[0] := #$00;

  Parameter[1] := #$0D;



  With LoadAndExec Do Begin

    Environment := $0000;

    OfsParam := ofs (Parameter);

    SegParam := seg (Parameter);

    For Ct := 1 To 4 Do FCB[Ct] := $FFFF;

  End;

  SwapVectors;

  FileError := 0;

  asm

    push     bp

    mov      dx, offset ExecName + 1

    push     ds

    pop      es

    mov      bx, offset LoadAndExec

    mov      ax, 4B01h

    int      21h



    mov      FileError, ax

    mov      @result, LoadError

    jc       @Error



@NoError:

    mov      ah, 62h

    int      21h

    mov      ChildePSP, bx



    push     cs

    push     offset TrapReturn



    mov      OldSS, ss

    mov      OldSP, sp



    mov      al, 1

    pushf

    mov      bp, sp

    or       ss:[bp+1], al

    popf



    cli

    mov      ss, LoadAndExec._SS

    mov      sp, LoadAndExec._SP

    sti

    mov      es, ChildePSP



    push     LoadAndExec._CS

    push     LoadAndExec._IP



    mov      ds, LoadAndExec._CS



    cld

    xor      ax, ax

    mov      bx, ax

    mov      cx, ax

    mov      dx, ax

    mov      si, ax

    mov      di, ax

    mov      bp, ax



    retf

    {set trap flag and retf}



TrapReturn:

    pop      bp

    mov      @result, bl



    mov      ah, 50h

    mov      bx, PrefixSeg

    int      21h



    mov      ax, ChildePSP

    mov      es, ax



    push     es

    mov      es, es:[2ch]

    mov      ah, 49h

    int      21h

    jnc      @NoEnvError

    mov      @result, EnvError

    jmp      @GetOut



@NoEnvError:

    pop      es

    mov      ah, 49h

    int      21h

    jnc      @GetOut

    mov      @result, FreeError



@Error:

    pop      bp



@GetOut:

  end;

  SwapVectors;

  SetIntVec ($01, @OldInt01);

End;



Procedure CleanComFile;

Var

  Ct : Byte;



Begin

  Assign (InFile, DirInfo.Name);

  Reset (InFile);

  For Ct := 1 To 3 Do

    Write (InFile, OrgComCode[Ct]);

  If IOResult <> 0 Then Error (9);

  Seek (InFile, EntryPtr);

  If IOResult <> 0 Then Error (6);

  Truncate (InFile);

  If IOResult <> 0 Then Error (11);

  Close (InFile);

  If IOResult <> 0 Then Error (8);

End;



Procedure CleanExeFile;

Begin

  ExeHeader.FileSizeDIV512 := EntryPtr DIV $200;

  ExeHeader.ByteOnLastPage := EntryPtr MOD $200;

  If ExeHeader.ByteOnLastPage <> 0 Then Inc (ExeHeader.FileSizeDIV512); 
  Assign (HdrInFile, DirInfo.Name);

  Reset (HdrInFile);

  If IOResult <> 0 Then Error (9);

  Write (HdrInFile, ExeHeader);

  If IOResult <> 0 Then Error (10);

  Close (HdrInFile);

  If IOResult <> 0 Then Error (8);



  Assign (InFile, DirInfo.Name);

  Reset (InFile);

  If IOResult <> 0 Then Error (9);

  Seek (InFile, EntryPtr);

  If IOResult <> 0 Then Error (6);

  Truncate (InFile);

  If IOResult <> 0 Then Error (11);

  Close (InFile);

  If IOResult <> 0 Then Error (8);

End;



Procedure CleanFile;

Var

  Ct       : Byte;

  SndCt    : Word;

  Ch       : Char;



Begin

  Inc (NumOfVirF);

  If Beep Then

    For Ct := 1 To 2 Do Begin

      For SndCt := 0 To 100 Do Begin

        Sound(1000+(8*SndCt));

        Delay(1);

      End;

      For SndCt := 100 DownTo 0 Do Begin

        Sound(1000+(8*SndCt));

        Delay(1);

      End;

      NoSound;

      NoSound;    {Just in case, I really hate that beeper} 
    End;



  If NoClean Then Exit;



  If Prompt Then Begin

    Write('Do you wish to clean this file (Y/N/A) ? ');

    If NOT Always Then Ch := Upcase (ReadKey) Else Ch := 'Y'; 
    If Ch = 'A' Then ALWAYS := True;

    If (Ch = 'Y') OR Always Then

      WriteLn (Ch)

    Else Begin

      WriteLn ('N');

      Exit;

    End;

  End;



  Write ('Tracking virus : ');

  Case TraceFile of

    UnExpInt21h  : Begin

                     WriteLn ('Unexpeted interrupt occured, file ^properly^ not infected!'); 
                     WriteLn ('Press almost any key');

                     ReadKey;

                   End;

    InsFound     : Begin

                     WriteLn ('ok, virus decrypted. Version ', VirVersion ); 
                   End;

    LoadError    : Begin

                     WriteLn ('Can''t load file : ', ErrorText); 
                     DelFile (Dirinfo.Name);

                     Exit;

                   End;

    EnvError     : Begin

                     WriteLn ('Can''t free enviroment');

                     WriteLn ('Press almost any key');

                     ReadKey;

                   End;

    FreeError    : Begin

                     WriteLn ('Can''t free file');

                     WriteLn ('Press almost any key');

                     ReadKey;

                   End;

    BrokenFile   : Begin

                     WriteLn ('File might be infected, but does NOT work!'); 
                     DelFile (DirInfo.Name);

                     Exit;

                   End;

    UnknownVer   : Begin

                     WriteLn ('This is a unknown version of the MANZON virus'); 
                     DelFile (DirInfo.Name);

                     Exit;

                   End;

  Else

    WriteLn ('Unknown Error! (BUGSY you''r a jerk!)');

  End;



  Write ('Cleaning file, ');

  If DirInfo.Attr AND ReadOnly = ReadOnly Then Begin

    WriteLn ('BAD. ------> read only <------');

    WriteLn ('Press almost any key.');

    ReadKey;

    Exit;

  End;



  If ComFile Then CleanComFile

  Else CleanExeFile;



  WriteLn ('Done.');

  Inc (NumOfVirR);

End;



Procedure OneDir;

Var

  Ch : Char;



Begin

  GetDir(0, MyDir);

  If IOResult <> 0 Then Error (12);

  FindFirst (FileNameStr, Anyfile, DirInfo);

  While (DosError = 0) AND (ESC = False) Do Begin

    If Keypressed Then Begin

      Ch := ReadKey;

      If Ch = #27 Then

        ESC := True;

    End;

    If ChkFile Then CleanFile;

    FindNext(DirInfo);

  End;

End;



Procedure DoSubDir (SubDirInfo : SearchRec);

Begin

  If ESC Then Exit;

  If SubCt <> 0 Then Begin

    ChDir (SubDirInfo.Name);

    If IOResult <> 0 Then Error (2);

  End;

  Inc (SubCt);



  If DosError = 0 Then Begin

    FindFirst ('*.*', AnyFile, SubDirInfo);

    If (SubDirInfo.Attr AND Directory = Directory) And (SubDirInfo.Name[1] <> '.') Then

      DoSubDir (SubDirInfo);

    While DosError = 0 Do Begin

      FindNext (SubDirInfo);

      If DosError <> 0 Then Break;

      If (SubDirInfo.Attr AND Directory = Directory) And (SubDirInfo.Name[1] <> '.')Then

        DoSubDir (SubDirInfo);

    End;

    Dec (SubCt);



    GetDir (0, TempPath);

    If IOResult <> 0 Then Error (2);

    OneDir;

    DosError := 0;

    If SubCt <> 0 Then Begin

      ChDir ('..');

      If IOResult <> 0 Then Error (2);

    End;

  End;

End;



Procedure FindVirus;

Var

  TempStr   : String[2];

  TempByte  : Byte;

  TimeUsed  : LongInt;



Begin

  Always := False;

  GetTime (H,M,S,Hund);

  TimeUsed := ((H * 3600) + (M * 60) + S);

  Window (1, 7, 80, 22);



  If NOT Debug Then Begin

    If VirusIsInMem Then Error (3);

    FindFirst (ParamStr(0), AnyFile, DirInfo);



(* Errorcheck 4 = removed. - TU *)

(*  If (DirInfo.Size <> MyFileSize) OR (DirInfo.Name <> MyFileName) Then Error (4); *)



    TempStr := '--';

    Assign (InFile, ParamStr(0));

    Reset (InFile);

    Seek (InFile, DirInfo.Size-2);

    Read (InFile, Byte(TempStr[1]));

    Read (InFile, Byte(TempStr[2]));

    Close (InFile);



(* Replicator-infector-preventer removed - TU *)

(*  If TempStr <> 'HA' Then Error (14); *)

  End;



  GetDir (0, OldDir);

  If MyPathStr <> '' Then Begin

    ChDir(MyPathStr);

    If IOResult <> 0 Then Error (2);

  End;



  If DoSub Then Begin

    SubCt := 0;

    DirInfo.Name := FileNameStr;

    DosError := 0;

    DoSubDir (DirInfo)

  End Else

    OneDir;



  If MyPathStr <> '' Then Begin

    ChDir (OldDir);

    If IOResult <> 0 Then Error (2);

  End;



  GetTime (H,M,S,Hund);

  TimeUsed := ((H * 3600) + (M * 60) + S) - TimeUsed;



  WriteLn;

  WriteLn ('Infected files : ', NumOfVirF);

  WriteLn ('Repaired files : ', NumOfVirR);

  WriteLn ('Files checked  : ', NumOfFile);

  If TimeUsed <> 0 Then Begin

    WriteLn ('Files/second   : ', (NumOfFile/TimeUsed):0:2); 
    WriteLn ('Timed used     : ', TimeUsed DIV 60,' Min ', (TimeUsed - (TimeUsed DIV 60 *
60)):0,' Sec.'); 
  End;

  WriteLn;



  If ESC Then

    Write ('Terminated by user !')

  Else

    Write ('All files done !');



  Window (1, 1, 80, 25);

  GotoXY (1, 24);

End;



Procedure UpcaseStr (Var Str : String);

Var

  Ct : Byte;



Begin

  For Ct := 1 to Length (Str) Do

    Str[Ct] := Upcase(Str[Ct]);

End;



Procedure ChkParam;

Var

  Ct         : Byte;

  MyParamStr : String;



Begin

  ESC        := False;

  DoSub      := False;

  Beep       := False;

  NoClean    := False;

  Debug      := False;

  Prompt     := False;

  MyParamStr := '';

  OldDir     := '';

  NumOfFile  := 0;

  NumOfVirF  := 0;

  NumOfVirR  := 0;



  If ParamCount < 1 Then WriteHelpScr;



  If POS ('/',ParamStr(1)) <> 0 Then WriteHelpScr;

  For Ct := 1 To ParamCount Do

    MyParamStr := MyParamStr + ParamStr(Ct) + ' ';

  UpcaseStr (MyParamStr);



  If Pos ('/B ' , MyParamStr) > 0 Then Beep    := True;

  If Pos ('/NC ', MyParamStr) > 0 Then NoClean := True;

  If Pos ('/S ' , MyParamStr) > 0 Then DoSub   := True;

  If Pos ('/D ' , MyParamStr) > 0 Then Debug   := True; {undoc param HA!} 
  If Pos ('/P ' , MyParamStr) > 0 Then Prompt  := True;



  SubCt       := 0;

  Ct          := 0;

  MyPathStr   := '';

  FileNameStr := '';

                                                {Split path and filename} 
  MyParamStr := ParamStr(1);                    {[path]Filename} 
  UpcaseStr(MyParamStr);



  FSplit (MyParamStr, Dir, Name, Ext);



  MyPathStr   := Dir;

  If MyPathStr[Length(MyPathStr)] = ':' Then {Patch for : 'c:'} 
    MyPathStr := MyPathStr + '\'

  Else

    If MyPathStr[Length(MyPathStr)] = '\' Then

      If (MyPathStr[Length(MyPathStr) - 1] <> ':') AND (Length(MyParamStr) <> 1) Then

        Delete (MyPathStr, Length(MyPathStr), 1); {Patch for : 'c:\' and patch for :
'c:\test\tmpdir\'} 


  FileNameStr := Name + Ext;

  If FileNameStr = '' Then

    FileNameStr := '*.*';



  WriteLn ('Path        : ', MyPathStr);

  WriteLn ('Filename    : ', FileNameStr);

  WriteLn
('
');

  GotoXY (1, 23);

  WriteLn
('
');

End;



Begin

  Clrscr;

  WriteLn;

  WriteLn ('-> Nuke ',NameOfVirus,' virus v 1.2 FREEWARE anno 1995 by BUGSY &
SPAWN of OBSESSiON. <-'); 
  WriteLn;

  ChkParam;

  FindVirus;

End.

==================================================================
============== 


% Bugsy's Replicator remover %



Replicator was written by Darkman of VLAD, and if you're really 
intereresting how this remover works, better take a look at 
replicator first (Vlad#4 - Article.5_1).



{ FREEWARE 1995 by BUGSY of OBSESSiON                                        } 
{ This is the REPLICATOR nuker source-code.                                  } 
{ Do with it as you like, just remember who made it.                         } 
{                                                                            } 
{ Contact me if you like.                                                    } 
{                                                                            } 
{ Benjamin Petersen                                                          } 
{ Nybrovej 304, F48                                                          } 
{ 2800 Lyngby, Denmark                                                       } 
{ Phone # : +45 45974348                                                     } 
{ Internet mail address : ben@ktas.dk                                        } 
{                                                                            } 
{                                                                            } 
{            Well, sorry about missing comments in source code!              } 
{                                                                            } 
{                                                     }

{                                                       }

{                                                            } 
{                                                    }



Program NukeReplicator;

{$A+,B-,D+,E+,F-,G-,I-,L+,N-,O-,P-,Q-,R-,S+,T-,V+,X+,Y+}

{$M 64000,0,655360}  {BP 7.0 compiler options}



Uses

  Crt,

  Dos;



Const

  MyFileSize   = 10290+2;                  {Remember to change this one} 
  MyFileName   = 'NUKEREPL.EXE';

  NameOfVirus  = 'Replicator';

  SomeOfVirus  =
#$E8#$00#$00#$5d#$81#$ed#$03#$00#$1e#$06#$b8#$04#$63#$cd#$21; 


Var

  InFile      : File of Byte;



  DirInfo     : SearchRec;



  Ct          : Byte;

  H           ,

  M           ,

  S           ,

  Hund        ,

  VirusSize   ,

  SubCt       : Word;



  NumOfFile   ,

  NumOfVirF   ,

  NumOfVirR   : Longint;



  Path        : PathStr;

  Dir         : DirStr;

  Name        : NameStr;

  Ext         : ExtStr;



  OldDir      ,

  FileNameStr ,

  MyPathStr   ,

  MyDir       ,

  TempPath    ,

  Buffer      : String;



  ESC         ,

  DoSub       ,

  Beep        ,

  NoClean     ,

  Debug       ,

  Prompt      : Boolean;



Procedure Error (Err : Byte);

Begin

  WriteLn;

  Write ('Error (',Err,') : ');

  Case Err Of

    1 : WriteLn ('No files found.');

    2 : WriteLn ('Can''t find directory.');

    3 : Begin

          WriteLn (NameOfVirus,' virus is resident in memory !'); 
          WriteLn ('Don''t worry, ',NameOfVirus,' can''t infect this file.'); 
          WriteLn ('Boot from a clean floppy and try again.'); 
        End;

    4 : WriteLn (MyFileName, ' has been changed !. Virus ?'); 
    5 : WriteLn ('Remember to add a 2 byte (HA) overlay.');    { Internal         } 
                                                          { Use any hex file } 
                                                          { editor to add a  } 
                                                          { 2 byte overlay   } 
                                                          { in the exefile   } 
                                                          { The overlay MUST } 
                                                          { be 'HA'          } 
                                                          { This is done to  } 
                                                          { prevent replicat } 
                                                          { to infect this   } 
                                                          { nuker            } 
    6 : WriteLn ('Can''t seek into file.');

    7 : WriteLn ('Can''t read from file.');

    8 : WriteLn ('Can''t close file.');

    9 : WriteLn ('Can''t open file.');

   10 : WriteLn ('Can''t write to file.');

   11 : WriteLn ('Cat''t truncate file.');

   12 : WriteLn ('Can''t get directory.');

  Else

    WriteLn ('Not defined, programmer forgot this one !');   {hmmmmm....} 
  End;

  If OldDir <> '' Then ChDir (OldDir);

  If IOResult <> 0 Then;

  Window (1, 1, 80, 25);

  GotoXY (1, 24);

  Halt (1);

End;



Procedure WriteHelpScr;

Begin

  GotoXY (WhereX, WhereY-1);

  WriteLn
('
Ŀ');

  WriteLn (' USAGE : Nukerepl [path]filename.ext [/nc] [/b] [/s] [/p]                    '); 
  WriteLn ('                                                                             '); 
  WriteLn (' You can use ANY valid dos wildcard.                                         '); 
  WriteLn ('                                                                             '); 
  WriteLn (' /NC no clean  /P prompt before cleaning file                                '); 
  WriteLn (' /B  beep      /S search subdirectory                                        '); 
  WriteLn
('
Ĵ');

  WriteLn ('            Coded by BUGSY of ..                   Here is some info about '); 
  WriteLn (' --                                             the virus :             '); 
  WriteLn ('                           
Replicator.649 & 651    '); 
  WriteLn ('  |                                                   
'); 
  WriteLn ('                                    Resident EXE infector. 
'); 
  WriteLn ('                          
Unencrypted, semi-      '); 
  WriteLn (' If you want to contact us, our addresses are  :    stealth virus with an   '); 
  WriteLn
('
Ĵ error handler. Infects  ');

  WriteLn (' Benjamin Petersen       Michael Skovslund         all EXE files in the    '); 
  WriteLn (' Nybrovej 304, F48       Stationsvej 2             current directory when  ');

  WriteLn (' 2800 Lyngby, Denmark    4681 Herfoelge, Denmark   the user changes
drive  '); 
  WriteLn (' Phone # : +45 45974348  Phone # : +45 56275314    or directory.           ');

  WriteLn
('
');

  Halt (1);

End;



Function VirusIsInMem : Boolean; Assembler;

Var

  TempByte : Boolean;

Asm

    mov  TempByte, 0

    mov  ax, 6304h                      {Virus id word}

    int  21h

    cmp  ax, bx

    Jne  @NoVirus

    mov  TempByte, 1

@NoVirus:

    mov  al,TempByte

    xor  ah,ah

End;



Function TestForVir : Boolean;

Var

  Ct       ,

  TempByte : Byte;



Begin

  Buffer := '';

  While Length (Buffer) < Length(SomeOfVirus) do

    Buffer := Buffer + ' ';

  For Ct := 1 to Length (SomeOfVirus) Do Begin

    Read(InFile, TempByte);

    If IOResult <> 0 Then Error (7);

    Buffer[Ct] := Chr (TempByte);

  End;

  Close (InFile);

  If IOResult <> 0 Then Error (8);



  If Buffer = SomeOfVirus Then Begin

    TestForVir := True;

    WriteLn (', INFECTET WITH ',NameOfVirus,'.',VirusSize); 
  End Else Begin

    TestForVir := False;

  End;

End;



Function ChkFile : Boolean;

Var

  Ct       ,

  TempByte : Byte;

  ErrCode  : Integer;



Begin

  Inc (NumOfFile);

  FileMode := 0;   {ReadOnly mode}

  If MyDir[Length(MyDir)] = '\' Then

    Write (MyDir,DirInfo.Name)

  Else

    Write (MyDir,'\',DirInfo.Name);



  Assign (InFile, DirInfo.Name);

  Reset (InFile);

  If IOResult <> 0 Then Begin

    WriteLn (' ERROR : Can''t open file, share violation ?'); 
    ChkFile := False;

    Exit;

  End;



  VirusSize := 649;

  Seek (InFile, DirInfo.Size - VirusSize);

  If IOResult <> 0 Then Error (6);

  If TestForVir Then Begin

    ChkFile := True;

    FileMode := 2;       {Read/Write mode}

    Exit;

  End;



  VirusSize := 651;

  Reset (InFile);

  Seek (InFile, DirInfo.Size - VirusSize);

  If IOResult <> 0 Then Error (6);

  If TestForVir Then Begin

    ChkFile := True;

    FileMode := 2;       {Read/Write mode}

    Exit;

  End;

  ChkFile := False;

  WriteLn;

End;



Procedure CleanFile;

Var

  Ch       : Char;

  TempByte : Byte;

  Restore  : Array [1..8] of Byte;

  Bolp     ,

  Pif      : Word;

  RealSize : LongInt;

  Ct       : Byte;

  SndCt    : Word;



Begin

  Inc (NumOfVirF);

  If Beep Then

    For Ct := 1 To 2 Do Begin

      For SndCt := 0 To 100 Do Begin

        Sound(1000+(8*SndCt));

        Delay(1);

      End;

      For SndCt := 100 DownTo 0 Do Begin

        Sound(1000+(8*SndCt));

        Delay(1);

      End;

      NoSound;

      NoSound;    {Just in case}

    End;



  If NoClean Then Exit;



  If Prompt Then Begin

    Write('Do you wish to clean this file (y/n) ? ');

    Ch := Upcase (ReadKey);

    If Ch = 'Y' Then

      WriteLn (Ch)

    Else Begin

      WriteLn ('N');

      Exit;

    End;

  End;



  Write ('Cleaning file, ');

  If DirInfo.Attr AND ReadOnly = ReadOnly Then Begin

    WriteLn ('BAD. ------> read only <------');

    WriteLn ('Press almost any key!');

    ReadKey;

    Exit;

  End;



  Assign (InFile, DirInfo.Name);

  Reset (InFile);

  If IOResult <> 0 Then Error (9);



  Seek (InFile, DirInfo.Size - VirusSize + $8F);             {Read original SS:SP, CS:IP}

  If IOResult <> 0 Then Error (6);



  For Ct := 7 To 10 Do Begin

    Read (InFile, Restore[Ct]);

    If IOResult <> 0 Then Error (7);

  End;



  Restore[5] := 0;

  Restore[6] := 0;



  For Ct := 1 To 4 Do Begin

    Read (InFile, Restore[Ct]);

    If IOResult <> 0 Then Error (7);

  End;



  Seek (InFile, 14);                            {Restore SS:SP, CS:IP} 
  If IOResult <> 0 Then Error (6);

  For Ct := 1 to 10 Do Begin

    Write(InFile, Restore[Ct]);

    If IOResult <> 0 Then Error (7);

  End;



  Bolp := (DirInfo.Size - VirusSize) MOD $0200;

  Pif  := (DirInfo.Size - VirusSize) DIV $0200;

  If Bolp <> 0 Then Inc (Pif);



  Seek (InFile, 2);

  If IOResult <> 0 Then Error (6);

  TempByte := Bolp MOD $100;                    {Write original filesize} 
  Write(InFile, TempByte);

  If IOResult <> 0 Then Error (10);

  TempByte := Bolp DIV $100;

  Write(InFile, TempByte);

  If IOResult <> 0 Then Error (10);

  TempByte := Pif MOD $100;

  Write(InFile, TempByte);

  If IOResult <> 0 Then Error (10);

  TempByte := Pif DIV $100;

  Write(InFile, TempByte);

  If IOResult <> 0 Then Error (10);



  Seek (InFile, DirInfo.size - VirusSize);

  If IOResult <> 0 Then Error (6);

  Truncate (InFile);                             {Delete virus from file} 
  If IOResult <> 0 Then Error (11);

  Close (InFile);

  If IOResult <> 0 Then Error (8);

  WriteLn ('Done !');

  Inc (NumOfVirR);

End;



Procedure OneDir;

Var

  Ch : Char;



Begin

  GetDir(0, MyDir);

  If IOResult <> 0 Then Error (12);

  FindFirst (FileNameStr, anyfile, DirInfo);

  While (DosError = 0) AND (ESC = False) Do Begin

    If Keypressed Then Begin

      Ch := ReadKey;

      If Ch = #27 Then

        ESC := True;

    End;

    If (DirInfo.Size >= VirusSize+2) AND (DirInfo.Name <> '.') AND (DirInfo.Name <> '..')
Then 
      If ChkFile Then

        CleanFile;

    FindNext(DirInfo);

  End;

End;



Procedure DoSubDir (SubDirInfo : SearchRec);

Begin

  If ESC Then Exit;

  If SubCt <> 0 Then Begin

    ChDir (SubDirInfo.Name);

    If IOResult <> 0 Then Error (2);

  End;

  Inc (SubCt);



  If DosError = 0 Then Begin

    FindFirst ('*.*', AnyFile, SubDirInfo);

    If (SubDirInfo.Attr AND Directory = Directory) And (SubDirInfo.Name[1] <> '.') Then

      DoSubDir (SubDirInfo);

    While DosError = 0 Do Begin

      FindNext (SubDirInfo);

      If DosError <> 0 Then Break;

      If (SubDirInfo.Attr AND Directory = Directory) And (SubDirInfo.Name[1] <> '.')Then

        DoSubDir (SubDirInfo);

    End;

    Dec (SubCt);



    GetDir (0, TempPath);

    If IOResult <> 0 Then Error (2);

    OneDir;

    DosError := 0;

    If SubCt <> 0 Then Begin

      ChDir ('..');

      If IOResult <> 0 Then Error (2);

    End;

  End;

End;



Procedure FindVirus;

Var

  TempStr   : String[2];

  TempByte  : Byte;

  TimeUsed  : LongInt;



Begin

  GetTime (H,M,S,Hund);

  TimeUsed := ((H * 3600) + (M * 60) + S);

  Window (1, 7, 80, 22);

  If VirusIsInMem Then Error (3);



  If NOT Debug Then Begin

    FindFirst (ParamStr(0), AnyFile, DirInfo);

    If (DirInfo.Size <> MyFileSize) OR (DirInfo.Name <> MyFileName) Then Error (4);



    TempStr := '--';

    Assign (InFile, ParamStr(0));

    Reset (InFile);

    Seek (InFile, DirInfo.Size-2);

    Read (InFile, Byte(TempStr[1]));

    Read (InFile, Byte(TempStr[2]));

    Close (InFile);

    If TempStr <> 'HA' Then Error (5);

  End;



  GetDir (0, OldDir);

  If MyPathStr <> '' Then Begin

    ChDir(MyPathStr);

    If IOResult <> 0 Then Error (2);

  End;



  If DoSub Then Begin

    Ct := 0;

    DirInfo.Name := FileNameStr;

    DosError := 0;

    DoSubDir (DirInfo)

  End Else Begin

    OneDir;

  End;



  If MyPathStr <> '' Then Begin

    ChDir (OldDir);

    If IOResult <> 0 Then Error (2);

  End;



  GetTime (H,M,S,Hund);

  TimeUsed := ((H * 3600) + (M * 60) + S) - TimeUsed;



  WriteLn;

  WriteLn ('Files checked  : ', NumOfFile);

  WriteLn ('Infectet files : ', NumOfVirF);

  WriteLn ('Repaired files : ', NumOfVirR);

  If TimeUsed <> 0 Then Begin

    WriteLn ('Files/second   : ', (NumOfFile/TimeUsed):0:2); 
    WriteLn ('Timed used     : ', TimeUsed DIV 60,' Min ', (TimeUsed - (TimeUsed DIV 60 *
60)):0,' Sec.'); 
  End;

  WriteLn;



  If ESC Then

    Write ('Terminated by user !')

  Else

    Write ('All files done !');



  Window (1, 1, 80, 25);

  GotoXY (1, 24);

End;



Procedure UpcaseStr (Var Str : String);

Var

  Ct : Byte;



Begin

  For Ct := 1 to Length (Str) Do

    Str[Ct] := Upcase(Str[Ct]);

End;



Procedure ChkParam;

Var

  Ct         : Byte;

  MyParamStr : String;



Begin

  ESC        := False;

  DoSub      := False;

  Beep       := False;

  NoClean    := False;

  Debug      := False;

  Prompt     := False;

  MyParamStr := '';

  OldDir     := '';

  NumOfFile  := 0;

  NumOfVirF  := 0;

  NumOfVirR  := 0;



  If ParamCount < 1 Then WriteHelpScr;



  If POS ('/',ParamStr(1)) <> 0 Then WriteHelpScr;

  For Ct := 1 To ParamCount Do

    MyParamStr := MyParamStr + ParamStr(Ct) + ' ';

  UpcaseStr (MyParamStr);



  If Pos ('/B ' , MyParamStr) > 0 Then Beep    := True;

  If Pos ('/NC ', MyParamStr) > 0 Then NoClean := True;

  If Pos ('/S ' , MyParamStr) > 0 Then DoSub   := True;

  If Pos ('/D ' , MyParamStr) > 0 Then Debug   := True; {undoc param HA!} 
  If Pos ('/P ' , MyParamStr) > 0 Then Prompt  := True;



  Ct          := 0;                             {Split path and filename} 
  MyPathStr   := '';

  FileNameStr := '';



  MyParamStr := ParamStr(1);                    {[path]Filename} 
  UpcaseStr(MyParamStr);



  FSplit (MyParamStr, Dir, Name, Ext);



  MyPathStr   := Dir;

  If MyPathStr[Length(MyPathStr)] = ':' Then {Patch for : 'c:'} 
    MyPathStr := MyPathStr + '\'

  Else

    If MyPathStr[Length(MyPathStr)] = '\' Then

      If (MyPathStr[Length(MyPathStr) - 1] <> ':') AND (Length(MyParamStr) <> 1) Then

        Delete (MyPathStr, Length(MyPathStr), 1); {Patch for : 'c:\' and patch for :
'c:\test\tmpdir\'} 


  FileNameStr := Name + Ext;

  If FileNameStr = '' Then

    FileNameStr := '*.*';



  WriteLn ('Path      : ', MyPathStr);

  WriteLn ('Filename  : ', FileNameStr);

  WriteLn
('
');

  GotoXY (1, 23);

  WriteLn
('
');

End;



Begin

  Clrscr;

  WriteLn;

  WriteLn ('-> Nuke ',NameOfVirus,' 649 & 651 virus v 1.1 FREEWARE 1995 by BUGSY of
OBSESSiON <-'); 
  WriteLn;

  ChkParam;

  FindVirus;

End.



==================================================================
============= 


% Bugsy's TaiPan remover %



{ FREEWARE 1994 by BUGSY & SPAWN of OBSESSION                                } 
{ This is the Tai-Pan nuker source-code.                                     } 
{ Do with it as you like, just remember who made it.                         } 
{                                                                            } 
{ Contact us if you like. Coders are :                                       } 
{                                                                            } 
{ Benjamin Petersen                                                          } 
{ Nybrovej 304, F48                                                          } 
{ 2800 Lyngby, Denmark                                                       } 
{ Phone # : +45 45974348                                                     } 
{ Internet mail address : ben@ktas.dk                                        } 
{                                                                            } 
{ Michael Skovslund                                                          } 
{ Stationsvej 2                                                              } 
{ 4681 Herfoelge, Denmark                                                    } 
{ Phone # : +45 56275314                                                     } 
{                                                                            } 
{            Well, sorry about missing comments in source code!              } 
{                                                                            } 
{                          BUGSY & SPAWN of ...                              } 
{                                                     }

{                                                       }

{                                                            } 
{                                                    }



Program NukeTaiPan;

{$A+,B-,D+,E+,F-,G-,I-,L+,N-,O-,P-,Q-,R-,S+,T-,V+,X+,Y+}

{$M 64000,0,655360}  {BP 7.0 compiler options}



Uses

  Crt,

  Dos;



Const

  MyFileSize  = 10950;                  {Remember to change this one} 
  MyFileName  = 'NUKETAIP.EXE';

  VirusSize   = 438;

  VirStartPos = 438;

  NameOfVirus = 'Tai-Pan (Whisper)';

  SomeOfVirus = #$E8#$00#$00#$5E#$83#$EE#$03#$B8#$CE#$7B#$CD#$21; 


Var

  InFile      : File of Byte;



  DirInfo     : SearchRec;



  Ct          : Byte;

  H           ,

  M           ,

  S           ,

  Hund        ,

  SubCt       : Word;



  NumOfFile   ,

  NumOfVirF   ,

  NumOfVirR   : Longint;



  Path        : PathStr;

  Dir         : DirStr;

  Name        : NameStr;

  Ext         : ExtStr;



  OldDir      ,

  FileNameStr ,

  MyPathStr   ,

  MyDir       ,

  TempPath    ,

  Buffer      : String;



  ESC         ,

  DoSub       ,

  Beep        ,

  NoClean     ,

  Debug       ,

  Prompt      : Boolean;



Procedure Error (Err : Byte);

Begin

  Write ('Error (',Err,') : ');

  Case Err Of

    1 : WriteLn ('No files found.');

    2 : WriteLn ('Can''t find directory.');

    3 : Begin

          WriteLn (NameOfVirus,' virus is resident in memory !'); 
          WriteLn ('Don''t worry, ',NameOfVirus,' can''t infect this file.'); 
          WriteLn ('Boot from a clean floppy and try again.'); 
        End;

    4 : WriteLn (MyFileName, ' has been changed !. Virus ?'); 
    5 : WriteLn ('Remember to change ''MZ'' to ''ZM''.'); { Internal         } 
                                                          { Use any hex file } 
                                                          { editor to change } 
                                                          { the 2 first byte } 
                                                          { in the exefile   } 
                                                          { from 'MZ' to 'ZM'} 
                                                          { This is done to  } 
                                                          { prevent tai-pan  } 
                                                          { to infect the    } 
                                                          { tai-pan numer    } 
    6 : WriteLn ('Can''t seek into file.');

    7 : WriteLn ('Can''t read from file.');

    8 : WriteLn ('Can''t close file.');

    9 : WriteLn ('Can''t open file.');

   10 : WriteLn ('Can''t write to file.');

   11 : WriteLn ('Cat''t truncate file.');

   12 : WriteLn ('Can''t get directory.');

  Else

    WriteLn ('Not defined, programmer forgot this one !');   {hmmmmm....} 
  End;

  If OldDir <> '' Then ChDir(OldDir);

  If IOResult <> 0 Then;

  Window (1, 1, 80, 25);

  GotoXY (1, 24);

  Halt (1);

End;



Procedure WriteHelpScr;

Begin

  GotoXY (WhereX, WhereY-1);

  WriteLn
('
Ŀ');

  WriteLn (' USAGE : Nuketaip [path]filename.ext [/nc] [/b] [/s] [/p]                    ');

  WriteLn ('                                                                             '); 
  WriteLn (' You can use ANY valid dos wildcard.                                         '); 
  WriteLn ('                                                                             '); 
  WriteLn (' /NC no clean  /P prompt before cleaning file                                '); 
  WriteLn (' /B  beep      /S search subdirectory                                        '); 
  WriteLn
('
Ĵ');

  WriteLn ('         Coded by BUGSY & SPAWN of..                  
  '); 
  WriteLn (' --                                                         ');

  WriteLn ('                                 
         '); 
  WriteLn ('  |                                  
        '); 
  WriteLn ('                                      
        '); 
  WriteLn ('                                    
        '); 
  WriteLn (' If you want to contact us, our addresses are  :                      ');

  WriteLn
('
Ĵ                ');

  WriteLn (' Benjamin Petersen       Michael Skovslund                   
  '); 
  WriteLn (' Nybrovej 304, F48       Stationsvej 2             P R O F E S S I O N E L ');

  WriteLn (' 2800 Lyngby, Denmark    4681 Herfoelge, Denmark   The serious
PC-magazine '); 
  WriteLn (' Phone # : +45 45974348  Phone # : +45 56275314    with CD-ROM every
month '); 
  WriteLn
('
');

  Halt (1);

End;



Function VirusIsInMem : Boolean; Assembler;

Var

  TempByte : Boolean;

Asm

    mov  TempByte, 0

    mov  ax, 7BCEh                      {Virus id word}

    int  21h

    cmp  ax, 7BCEh

    Jne  @NoVirus

    mov  TempByte, 1

@NoVirus:

    mov  al,TempByte

    xor  ah,ah

End;



Function ChkFile : Boolean;

Var

  Ct       ,

  TempByte : Byte;

  ErrCode  : Integer;



Begin

  Inc (NumOfFile);

  FileMode := 0;   {ReadOnly mode}

  If MyDir[Length(MyDir)] = '\' Then

    Write (MyDir,DirInfo.Name)

  Else

    Write (MyDir,'\',DirInfo.Name);



  Assign (InFile, DirInfo.Name);

  Reset (InFile);

  If IOResult <> 0 Then Begin

    WriteLn (' ERROR : Can''t open file, share violation ?'); 
    ChkFile := False;

    Exit;

  End;



  Seek (InFile, DirInfo.Size - VirStartPos);

  If IOResult <> 0 Then Error (6);



  Buffer := '';

  While Length (Buffer) < Length(SomeOfVirus) do

    Buffer := Buffer + ' ';

  For Ct := 1 to Length (SomeOfVirus) Do Begin

    Read(InFile, TempByte);

    If IOResult <> 0 Then Error (7);

    Buffer[Ct] := Chr (TempByte);

  End;

  Close (InFile);

  If IOResult <> 0 Then Error (8);



  If Buffer = SomeOfVirus Then Begin

    ChkFile := True;

    WriteLn (', INFECTET WITH ',NameOfVirus);

  End Else Begin

    ChkFile := False;

    WriteLn;

  End;

  FileMode := 2;       {Read/Write mode}

End;



Procedure CleanFile;

Var

  Ch       : Char;

  TempByte : Byte;

  Restore  : Array [1..10] of Byte;

  Bolp     ,

  Pif      : Word;

  RealSize : LongInt;

  Ct       : Byte;

  SndCt    : Word;



Begin

  Inc (NumOfVirF);

  If Beep Then

    For Ct := 1 To 2 Do Begin

      For SndCt := 0 To 100 Do Begin

        Sound(1000+(8*SndCt));

        Delay(1);

      End;

      For SndCt := 100 DownTo 0 Do Begin

        Sound(1000+(8*SndCt));

        Delay(1);

      End;

      NoSound;

      NoSound;    {Just in case}

    End;



  If NoClean Then Exit;



  If Prompt Then Begin

    Write('Do you wish to clean this file (y/n) ? ');

    Ch := Upcase (ReadKey);

    If Ch = 'Y' Then

      WriteLn (Ch)

    Else Begin

      WriteLn ('N');

      Exit;

    End;

  End;



  Write ('Cleaning file, ');

  If DirInfo.Attr AND ReadOnly = ReadOnly Then Begin

    WriteLn ('BAD. ------> read only <------');

    Exit;

  End;



  Assign (InFile, DirInfo.Name);

  Reset (InFile);

  If IOResult <> 0 Then Error (9);



  Seek (InFile, DirInfo.Size - 10);             {Read original SS:SP, CS:IP} 
  If IOResult <> 0 Then Error (6);



  For Ct := 1 To 10 Do Begin

    Read (InFile, Restore[Ct]);

    If IOResult <> 0 Then Error (7);

  End;



  Seek (InFile, 14);                            {Restore SS:SP, CS:IP} 
  If IOResult <> 0 Then Error (6);

  For Ct := 1 to 10 Do Begin

    Write(InFile, Restore[Ct]);

    If IOResult <> 0 Then Error (7);

  End;



  Seek (InFile, 2);

  If IOResult <> 0 Then Error (6);

  Read (InFile, TempByte);

  If IOResult <> 0 Then Error (7);

  Bolp := TempByte;

  Read (InFile, TempByte);

  If IOResult <> 0 Then Error (7);

  Bolp := Bolp + (TempByte * $100);             {Read byte on last page (BOLP)} 
  Read (InFile, TempByte);

  If IOResult <> 0 Then Error (7);

  Pif := TempByte;

  Read (InFile, TempByte);

  If IOResult <> 0 Then Error (7);

  Pif := Pif + (TempByte * $100);               {Read pages in file (PIF)} 
  RealSize := Pif * $200 + Bolp;                {Calc. the real filesize} 
  RealSize := RealSize - VirusSize;             {Calc. original filesize} 


  Pif  := RealSize DIV $200;

  Bolp := RealSize MOD $200;

  Seek(InFile, 2);

  If IOResult <> 0 Then Error (6);

  TempByte := Bolp MOD $100;                    {Write original filesize} 
  Write(InFile, TempByte);

  If IOResult <> 0 Then Error (10);

  TempByte := Bolp DIV $100;

  Write(InFile, TempByte);

  If IOResult <> 0 Then Error (10);

  TempByte := Pif MOD $100;

  Write(InFile, TempByte);

  If IOResult <> 0 Then Error (10);

  TempByte := Pif DIV $100;

  Write(InFile, TempByte);

  If IOResult <> 0 Then Error (10);

  Seek (InFile, DirInfo.size - VirusSize);

  If IOResult <> 0 Then Error (6);

  Truncate (InFile);                             {Delete virus from file} 
  If IOResult <> 0 Then Error (11);

  Close (InFile);                               {Finito boyz} 
  If IOResult <> 0 Then Error (8);

  WriteLn ('Done !');

  Inc (NumOfVirR);

End;



Procedure OneDir;

Var

  Ch : Char;



Begin

  GetDir(0, MyDir);

  If IOResult <> 0 Then Error (12);

  FindFirst (FileNameStr, anyfile, DirInfo);

  While (DosError = 0) AND (ESC = False) Do Begin

    If Keypressed Then Begin

      Ch := ReadKey;

      If Ch = #27 Then

        ESC := True;

    End;

    If (DirInfo.Size >= VirusSize) AND (DirInfo.Name <> '.') AND (DirInfo.Name <> '..')
Then 
      If ChkFile Then

        CleanFile;

    FindNext(DirInfo);

  End;

End;



Procedure DoSubDir (SubDirInfo : SearchRec);

Begin

  If ESC Then Exit;

  If SubCt <> 0 Then Begin

    ChDir (SubDirInfo.Name);

    If IOResult <> 0 Then Error (2);

  End;

  Inc (SubCt);



  If DosError = 0 Then Begin

    FindFirst ('*.*', AnyFile, SubDirInfo);

    If (SubDirInfo.Attr AND Directory = Directory) And (SubDirInfo.Name[1] <> '.') Then

      DoSubDir (SubDirInfo);

    While DosError = 0 Do Begin

      FindNext (SubDirInfo);

      If DosError <> 0 Then Break;

      If (SubDirInfo.Attr AND Directory = Directory) And (SubDirInfo.Name[1] <> '.')Then

        DoSubDir (SubDirInfo);

    End;

    Dec (SubCt);



    GetDir (0, TempPath);

    If IOResult <> 0 Then Error (2);

    OneDir;

    DosError := 0;

    If SubCt <> 0 Then Begin

      ChDir ('..');

      If IOResult <> 0 Then Error (2);

    End;

  End;

End;



Procedure FindVirus;

Var

  TempStr   : String[2];

  TempByte  : Byte;

  TimeUsed  : LongInt;



Begin

  GetTime (H,M,S,Hund);

  TimeUsed := ((H * 3600) + (M * 60) + S);

  Window (1, 7, 80, 22);

  If VirusIsInMem Then Error (3);



  If NOT Debug Then Begin

    FindFirst (ParamStr(0), AnyFile, DirInfo);

    If (DirInfo.Size <> MyFileSize) OR (DirInfo.Name <> MyFileName) Then Error (4); 


    TempStr := '--';

    Assign (InFile, ParamStr(0));

    Reset (InFile);

    Read (InFile, Byte(TempStr[1]));

    Read (InFile, Byte(TempStr[2]));

    Close (InFile);

    If TempStr <> 'ZM' Then Error (5);

  End;



  GetDir (0, OldDir);

  If MyPathStr <> '' Then Begin

    ChDir(MyPathStr);

    If IOResult <> 0 Then Error (2);

  End;



  If DoSub Then Begin

    Ct := 0;

    DirInfo.Name := FileNameStr;

    DosError := 0;

    DoSubDir (DirInfo)

  End Else Begin

    OneDir;

  End;



  If MyPathStr <> '' Then Begin

    ChDir (OldDir);

    If IOResult <> 0 Then Error (2);

  End;



  GetTime (H,M,S,Hund);

  TimeUsed := ((H * 3600) + (M * 60) + S) - TimeUsed;



  WriteLn;

  WriteLn ('Files checked  : ', NumOfFile);

  WriteLn ('Infectet files : ', NumOfVirF);

  WriteLn ('Repaired files : ', NumOfVirR);

  If TimeUsed <> 0 Then Begin

    WriteLn ('Files/second   : ', (NumOfFile/TimeUsed):0:2); 
    WriteLn ('Timed used     : ', TimeUsed DIV 60,' Min ', (TimeUsed - (TimeUsed DIV 60 *
60)):0,' Sec.'); 
  End;

  WriteLn;



  If ESC Then

    Write ('Terminated by user !')

  Else

    Write ('All files done !');



  Window (1, 1, 80, 25);

  GotoXY (1, 24);

End;



Procedure UpcaseStr (Var Str : String);

Var

  Ct : Byte;



Begin

  For Ct := 1 to Length (Str) Do

    Str[Ct] := Upcase(Str[Ct]);

End;



Procedure ChkParam;

Var

  Ct         : Byte;

  MyParamStr : String;



Begin

  ESC        := False;

  DoSub      := False;

  Beep       := False;

  NoClean    := False;

  Debug      := False;

  Prompt     := False;

  MyParamStr := '';

  OldDir     := '';

  NumOfFile  := 0;

  NumOfVirF  := 0;

  NumOfVirR  := 0;



  If ParamCount < 1 Then WriteHelpScr;



  If POS ('/',ParamStr(1)) <> 0 Then WriteHelpScr;

  For Ct := 1 To ParamCount Do

    MyParamStr := MyParamStr + ParamStr(Ct) + ' ';

  UpcaseStr (MyParamStr);



  If Pos ('/B ' , MyParamStr) > 0 Then Beep    := True;

  If Pos ('/NC ', MyParamStr) > 0 Then NoClean := True;

  If Pos ('/S ' , MyParamStr) > 0 Then DoSub   := True;

  If Pos ('/D ' , MyParamStr) > 0 Then Debug   := True; {undoc param HA!} 
  If Pos ('/P ' , MyParamStr) > 0 Then Prompt  := True;



  Ct          := 0;                             {Split path and filename} 
  MyPathStr   := '';

  FileNameStr := '';



  MyParamStr := ParamStr(1);                    {[path]Filename} 
  UpcaseStr(MyParamStr);



  FSplit (MyParamStr, Dir, Name, Ext);



  MyPathStr   := Dir;

  If MyPathStr[Length(MyPathStr)] = ':' Then {Patch for : 'c:'} 
    MyPathStr := MyPathStr + '\'

  Else

    If MyPathStr[Length(MyPathStr)] = '\' Then

      If (MyPathStr[Length(MyPathStr) - 1] <> ':') AND (Length(MyParamStr) <> 1) Then

        Delete (MyPathStr, Length(MyPathStr), 1); {Patch for : 'c:\' and patch for :
'c:\test\tmpdir\'} 


  FileNameStr := Name + Ext;

  If FileNameStr = '' Then

    FileNameStr := '*.*';



  WriteLn ('Path      : ', MyPathStr);

  WriteLn ('Filename  : ', FileNameStr);

  WriteLn
('
');

  GotoXY (1, 23);

  WriteLn
('
');

End;



Begin

  Clrscr;

  WriteLn;

  WriteLn ('Nuke ',NameOfVirus,' virus v 2.2 FREEWARE 1994 by BUGSY & SPAWN of
OBSESSION.'); 
  WriteLn;

  ChkParam;

  FindVirus;

End.

==================================================================
============== 


% Rilo's Taipan finder (PAS version) %





Source      : FINDTAI.PAS

Version     : 1.0

Compiler    : Borland Turbo Pascal 7.0

Date        : 26-11-1994

Author      : R. W. Loerakker

Purpose     : Short course on scanning viruses

Description : This program is just made as a demonstration program on how 
              you can make a program to scan for a certain virus. This 
              doesn't mean this is perfect. It's just an example of how 
              a scanner engine might work. This detects the TAI-PAN virus 
              in infected files on the current drive.



PS. I kinda think I've modified this program, but can't remember where 
    :-). Sorry Richard.. Hehe.



-   The Unforgiven.

==================================================================
=======*) 
Uses Crt, DOS;



Const

  Sig : Array[0..9] of Byte = ($e8,$00,$00,$5e,$83,$ee,$03,$b8,$ce,$7b); 


Var F : File;

  Buf1 : Array [0..$1C] Of Byte;

  Buf2 : Array [0..30] Of Byte;

  Nr, Hp, Cs, Ip : Word;

  Ep: LongInt;

  Infected : Integer;

  Scanned  : Integer;

  Attrib : Word;



Function Up (S : String) : String;

Var I : Integer;

Begin

  For I := 1 To Length (S) Do

    S [I] := UpCase (S [I] );

  Up := S;

End;



Function Rep (Times : Integer; What : String) : String;

Var Tmp : String;

  I : Integer;

Begin

  Tmp := '';

  For I := 1 To Times Do

    Tmp := Tmp + What;

  Rep := Tmp;

End;



Function Compare ( B : Array Of Byte) : Boolean;

Var

  C : Byte;

  IsIt : Boolean;

Begin

  IsIt := True;

  C := 0;

  While (C <= 9) And (IsIt) Do

  Begin

    If B[C] <> Sig[C] Then IsIt := False;

    Inc(C);

  End;

  Compare := IsIt;

End;



Procedure FExe (N : String);

Begin

  FileMode := 0;

  If Pos ('.EXE', N) <> 0 Then Begin

  Assign (F, N);

  GetFAttr (F, Attrib);

  SetFAttr (F, 0);

  FileMode := 2;

  Reset (F, 1);

  BlockRead (F, Buf1, SizeOf (Buf1), Nr);

  Ep := 0;

    If Buf1[0]+(Buf1[1] * 256) = $5a4d Then Begin

      Hp := Buf1 [8] + Buf1 [9] * 256;

      Ip := Buf1 [$14] + Buf1 [$15] * 256;

      Cs := Buf1 [$16] + Buf1 [$17] * 256;

      Ep := Cs + Hp;

      Ep := (Ep * 16 + Ip) And $FFFFF;

    End;

    Seek (F, Ep);

    BlockRead (F, Buf2, SizeOf (Buf2), Nr);

    Write (N);

    If Compare ( Buf2) Then Begin

      Write (Rep (60 - Length (N), ' '), 'Infected. ');

      Inc (Infected);

    End

    Else Write (Rep (60 - Length (N), ' '), 'Clean.'#13);

    inc (Scanned);

  Close (F);

  SetFAttr (F, Attrib);

  writeln;

  End;

End;



Procedure SDir ( SPath : String);

Var S : SearchRec;

Begin

  FindFirst (SPath + '*.*', AnyFile Xor VolumeID, S);

  If S. Name = '.' Then

  Begin

    FindNext (S);

    FindNext (S);

  End;

  If (DosError = 0) And (S. Attr And Directory <> Directory) Then 
  Begin

    FExe (SPath + S. Name);

    FindNext (S);

  End;

  While DosError = 0 Do

  Begin

    If (S. Attr And Directory = Directory) Then

    Begin

      SDir (SPath + S. Name + '\');

    End

    Else

      FExe (SPath + S. Name);

    FindNext (S);

  End;

End;



Begin

  WriteLn ('F-TAIPAN V1.0 (C) 1994 by R. Loerakker');

  WriteLn;

  WriteLn ('Searching for TAI-PAN...');

  WriteLn;

  Infected := 0;

  SDir (Copy (Up (ParamStr (0) ) , 0, 2) + '\');

  ClrEol;

  WriteLn (Scanned, ' files scanned.');

  WriteLn (Infected, ' files infected!');

End.

==================================================================
============= 


% Rilo's Taipan Finder (C++ version) %



Source      : FINDTAI.CPP

Version     : 1.0

Compiler    : Borland C++ 3.1

Date        : 26-11-1994

Author      : R. W. Loerakker

Purpose     : Short course on scanning viruses

Description : This program is just made as a demonstration program on how 
              you can make a program to scan for a certain virus. This 
              doesn't mean this is perfect. It's just an example of how 
              a scanner engine might work. This detects the TAI-PAN virus 
              in infected files on the current drive.



#include

#include

#include

#include

#include



#define done 0

#define BB buf.cbuf

#define WB buf.ibuf



unsigned long infections = 0, ep;



void scandir(char *path) {

  union filebuf {

    unsigned char cbuf[40];

    unsigned int ibuf[20];

  } buf;

  char search[80], newd[80], scan[80];

  struct ffblk ffblk;

  unsigned char taisig[10] = {0xe8,0x00,0x00,0x5e,0x83,0xee,0x03,0xb8,0xce,0x7b};

  FILE *f;

  int chk, i;



  strcat(strcpy(search,path), "\\*.*");

  if (done == findfirst(search,&ffblk,0xff)) do {

    if (ffblk.ff_attrib & FA_DIREC && '.' != *ffblk.ff_name) { 
      strcat(strcat(strcpy(newd, path), "\\"), ffblk.ff_name); 
      scandir(newd);

    }

    else {

    if ((strstr(ffblk.ff_name,".EXE")) || (strstr(ffblk.ff_name,".COM")) ||
(strstr(ffblk.ff_name,".OV"))) { 
      strcat(strcat(strcpy(scan,path),"\\"),ffblk.ff_name); 
      printf("%-60s",scan);

      if ((f = fopen(scan,"rb")) == NULL)

        printf("Could not open file\n");

      else {

        fread(BB,sizeof(BB),1,f);

        if (WB[0] == 0x5a4d) {

          fseek(f,ep = ((WB[4]+WB[0xb]) << 4) + WB[0xa] & 0xfffff,0); 
          fread(BB,sizeof(taisig),1,f);

          i = 0; chk = 0;

          for (i = 0; i < 10; i++) {

            if (BB[i] == taisig[i]) chk++;

              else break;

          }

          chk == 10 ? printf("Infected!\n",infections++) : printf("Clean.\r"); 
        }

        else printf("Clean.\r");

        }

        fclose(f);

      }

    }

  } while (done == findnext(&ffblk));

  return;

}



unsigned int main(void) {

  printf(" F-TAIPAN V1.0 (C) 1994 by R. Loerakker \n\n\Finds the TAI-PAN virus on the
current drive...\n\n"); 
  scandir("");

  printf("Found %lu infected files on current drive!\t\t\t\t\n",infections); 
  return infections;

}

==================================================================
============== 


% Rilo's K-Bravo remover %



Source      : K-BRAVO

Version     : 1.0

Compiler    : Borland C++ 3.1

Date        : 05-01-1995

Author      : R. W. Loerakker

Purpose     : Get rid of the "Bravo" virus

Description : This program will kill the Bravo virus. The source code of 
              this killer is put in public domain for educational purposes. 
              Please don't patch my name out of it and claim it as your 
              own.



/* standard header files */

#include

#include

#include

#include

#include

#include

#include



/* amount of retries before reading error occurs */

#define MAXRETRIES 5



/* make a boolean */

enum bool { FALSE, TRUE };



/* some type definitions that we might use */

typedef unsigned char BYTE;

typedef far BYTE *memfar;



int result;

int retries;

/* virus signature */

unsigned char signature[] = { 0xBE, 0x36, 0x7C, 0xA1, 0x00, 0x7C, 0xBF, 
                              0x00, 0x02, 0xAB, 0xB9, 0xC2, 0x01 }; 
/* buffer for disk sector */

unsigned char buffer[512];



/* Hello message */

void init_msg(void) {

  printf("K-BRAVO V1.0 by R. Loerakker (VRCH) (C) 1995\n"); 
}



/* checks amount of retries and terminates if too much */

void chk_err(void) {

  if (retries == MAXRETRIES) {

    printf("\nDisk error - program terminated\n");

    exit(1);

  }

}



/* compares a piece of memory with the virus signature */

bool compare(int seg, int ofs) {

  int count;

  memfar chkmem = (memfar) MK_FP(seg,ofs);



  for (count = 0; count < sizeof(signature); count++) {

    if (*chkmem++ != signature[count]) break;

  }

  return (count == sizeof(signature) ? TRUE : FALSE);

}



/* checks if the virus is memory resident */

bool chk_mem(void) {

  return (compare(0x0000,0x023E)) ? TRUE : FALSE;

}



/* checks the bootsector of "drive" to see if it's infected */ 
bool chk_boot(int drive) {

  result = biosdisk(4,drive,0,0,1,1,buffer);

  for (retries = 0; retries < MAXRETRIES; retries++) {

    result = biosdisk(2,drive,0,0,1,1,buffer);

    if (result == 0) break;

  }

  chk_err();

  return (compare(FP_SEG(buffer),FP_OFF(buffer+0x0072)) && result == 0) ? TRUE :
FALSE; 
}



/* checks if "Bravo" is detected at sector start (destroyed by the virus) */ 
bool chk_destroyed(void) {

  int count;

  unsigned char bravo[] = { 'B', 'r', 'a', 'v', 'o' };

  memfar chkmem = (memfar) MK_FP(FP_SEG(buffer),FP_OFF(buffer)); 


  for (count = 0; count < sizeof(bravo); count++) {

    if (*chkmem++ != bravo[count]) break;

  }

  return (count == sizeof(bravo) ? TRUE : FALSE);

}



/* retrieve original bootsector */

bool restore_boot(int drive) {

  int sector = buffer[0x003E];  /* the virus stored it there */ 
  int head = buffer[0x003F];    /* the virus stored it there */ 


  for (retries = 0; retries < MAXRETRIES; retries++) {

    result = biosdisk(2,drive,head,0,sector,1,buffer);

    if (result == 0) break;

  }

  chk_err();

  for (retries = 0; retries < MAXRETRIES; retries++) {

    result = biosdisk(3,drive,0,0,1,1,buffer);

    if (result == 0) break;

  }

  chk_err();

  return TRUE;

}



void main(void) {

  bool goodkey;

  char ch;

  int drv;

  init_msg();

  if (chk_mem()) {

    printf("BRAVO virus found active in memory!\nDisabling BRAVO virus.\n\n"); 
    /* restore original interrupts and corrupts virus image */ 
    movedata(0x0000,0x0202,0x0000,0x004C, 0x0004);

    movedata(0x0000,0x0206,0x0000,0x0100, 0x0004);

    movedata(0x0000,0x0200,0x0000,0x0201, 0x0100);

  }

  for (;;) {

    printf("\nEnter DRIVE (A, B or C) to be scanner or 'X' to exit : "); 
    do {

    ch = toupper(getch());

    goodkey = TRUE;

    switch (ch) {

      case 'A' : drv = 0; break;

      case 'B' : drv = 1; break;

      case 'C' : drv = 128; break;

      case 'X' : printf("\nThanks for using K-BRAVO!\n");

                 exit(0);

                 break;

      default : goodkey = FALSE;

    }

    } while (!goodkey);

    printf("%c\nScanning drive %c:\n", ch, ch);

    if (chk_boot(drv)) {

      printf("Disk is infected with BRAVO!\n");

      if (restore_boot(drv)) printf("Disk is now disinfected.\n"); 
    }

    if (chk_destroyed()) {

      printf("Disk is destroyed by BRAVO!\n");

      /* the original mbr is at the 2nd sector */

      buffer[0x003E] = 2;

      buffer[0x003F] = 0;

      if (restore_boot(drv)) printf("Disk is now resurrected!\n"); 
    }

  }

}

==================================================================
============== 


% Freaking Dooz Taipan remover %





"Atleast it's ASM"

             - TU



smart

jumps

locals



code            segment

assume          cs:code,ds:code



org             100h



main:

                jmp     start



vir_size        equ     438

vir_id          equ     258            ; bytes from end .. 


credits         db      " tai-pan virus remover .. coded by freaking dooz 1994",13,10,"$"

removed         db      " tai-pan virus succesfully removed",13,10,"$" 
in_mem          db      " the tai-pan virus is already in memory .. reboot!!",13,10,"$" 
not_inf         db      " the file you specified is not infected .. sorry :)",13,10,"$" 
syntax          db      " syntax .. untai [filename.ext]",13,10,"$" 
buffer          db      7 dup (0)

vir_sig         db      "Whisper"



f_size          dw      0

o_fsize         dw      0

f_handle        dw      0

org_stuff       dw      5 dup (0)

exe_header      dw      14 dup (0)

tempseg         dw      0

                jmp     start



start:

                mov     ah,4ah         ; wow !! big program .. 
                mov     bx,1*(1024/16)

                int     21h



                mov     ah,9

                mov     dx,offset credits

                int     21h



                mov     ax,7bceh

                int     21h

                cmp     ax,7bceh

                jz      @@in_mem



                mov     ah,48h

                mov     bx,4096

                int     21h

                jc      @@schluuut

                mov     tempseg,ax



                mov     si,82h

                xor     ax,ax

                cmp     [si-2],al

                jz      @@syntax



                xor     bx,bx

                mov     bl,[si-2]

                mov     [si+bx-1],al



                mov     dx,si

                mov     ax,3d02h

                int     21h

                jc      @@syntax

                mov     f_handle,ax

                mov     bx,ax



                mov     ah,3fh

                mov     dx,offset exe_header

                mov     cx,1ch

                int     21h            ; get the .exe file header .. 


                mov     ax,4202h       ; please excuse this lame coding .. 
                xor     cx,cx

                xor     dx,dx

                int     21h



                mov     f_size,ax



                sub     ax,vir_id

                mov     dx,ax

                xor     cx,cx

                mov     ax,4200h

                int     21h



                mov     ah,3fh

                mov     dx,offset buffer

                mov     cx,7

                int     21h



                mov     cx,7

                xor     si,si

@@1:

                mov     al,buffer[si]

                cmp     vir_sig[si],al

                jnz     @@not_inf

                inc     si

                loop    @@1



                mov     ax,4200h

                xor     cx,cx

                mov     dx,f_size

                sub     dx,10

                int     21h



                mov     dx,offset org_stuff

                mov     cx,10

                mov     ah,3fh

                int     21h            ; get original cs:ip .. 


                mov     ax,4200h

                xor     cx,cx

                xor     dx,dx

                int     21h



                push    cs

                pop     es



                mov     si,offset org_stuff

                mov     di,offset exe_header+14

                mov     cx,5

                rep     movsw          ; restore ss:sp + cs:ip 


                mov     ax,f_size

                sub     ax,vir_size

                mov     o_fsize,ax



                add     ax,511

                shr     ax,9

                mov     exe_header+4,ax



                mov     ax,o_fsize

                and     ax,511

                mov     exe_header+2,ax



                mov     ah,3fh

                xor     dx,dx

                mov     ds,cs:tempseg

                mov     cx,cs:o_fsize

                int     21h



                push    cs

                pop     ds



                mov     es,cs:tempseg

                xor     di,di

                mov     si,offset exe_header

                mov     cx,14

                rep     movsw



                mov     ah,3ch         ; create "clean" file .. 
                xor     cx,cx

                mov     dx,82h

                int     21h

                xchg    ax,bx



                mov     ah,40h         ; write "clean" file .. 
                mov     ds,cs:tempseg

                xor     dx,dx

                mov     cx,cs:o_fsize

                int     21h



                mov     ah,3eh

                mov     bx,cs:f_handle

                int     21h



                mov     ah,9

                mov     dx,offset removed

                int     21h



@@schluuut:

                int     20h



@@in_mem:

                mov     ah,9

                mov     dx,offset in_mem

                int     21h

                jmp     @@schluuut



@@not_inf:

                mov     ah,9

                mov     dx,offset not_inf

                int     21h

                jmp     @@schluuut

@@syntax:

                mov     ah,9

                mov     dx,offset syntax

                int     21h

                jmp     @@schluuut



code            ends

end             main

==================================================================
============== 


% HYBRiS Remover by TU/IR %



According to Qark, it's low to produce removers against your own 
code :-). But ah well..  If someone learn something from this code, 
don't write removers for my next virus to come.. sometime :-). 


Thank you very much.



- The Unforgiven.

==================================================================
============== 


.model  tiny

.code

org     100h



start:



jmp short begin_code



copyright db "HYBRiS.1435 Remover. (c) 1995 The Unforgiven/Immortal Riot",0 


begin_code:

push    dx                              ; Cool self-check.. 
push    ds

mov     ah,9

mov     dx,offset intro_msg

int     21h

pop     bx

pop     dx

cmp     bx,dx

jne     wrong

mov     ah,9

mov     dx,offset ok_msg

int     21h

jmp     short start_msg1



wrong:

mov     ah,9

mov     dx,offset wrong_msg

int     21h

int     20h



intro_msg       db 'Selfcheck $'

ok_msg          db 'OK',13,10,'$'

wrong_msg       db 'Failed',13,10,'$'



start_msg1:



mov     ah,9                    ;print starting msg...

mov     dx, offset begin

int     21h



mov     ah,0                    ;did they agree on the rules? 
int     16h



cmp     ah,15h                  ;y/Y

je      ok_phile                ;yes, they did



mov     ah,9                    ;print blah..

mov     dx, offset not_yes

int     21h

int     20h

not_yes db "User Failure!",13,10,07,36



ok_phile:

mov     ah,4ah                  ;Do a virus installation check. . . 
mov     bx,0ffffh

mov     cx,0d00dh

int     21h



cmp     ax,cx                   ;ax=cx=d00d= the virus is TSR. . . 
jne     not_res



mov     ah,9

mov     dx, offset resident

int     21h

int     20h



not_res:

mov     ah,2fh                  ;Get DTA-area to es:bx

int     21h



mov     ah,4eh                  ;find first file matching ds:dx (com) 
                                ;with any attribute

next:

mov     cx,7

mov     dx, offset f_com

int     21h



jc      no_com                  ;we have no more com-files 


call    main                    ;got a com-file - search it 


mov     ah,4fh                  ;get next com-file

jmp     short next



no_com:



terminate:                      ;no more files!



mov     ah,9

mov     dx, offset stat1

int     21h



; This nice statistics is made by Blonde. Greetings to him. 


mov     dx, word ptr [count]

call    dec16out



mov     ah,9

mov     dx, offset stat2

int     21h



mov     dx, word ptr [inf]

call    dec16out



mov     ax,4cffh

int     21h



main:

inc     byte ptr [count]



push    ax

push    bx

push    cx

push    dx

push    di

push    si



push    es

push    es

pop     ds

push    cs

pop     es



mov     si,bx

add     si,1Eh                  ;bx = pointer to fname (1eh) 
mov     di,offset fname_buf

mov     cx,0Fh                  ;cx=15



push    cx                      ;save cx = 15

push    di                      ;save di (fname)

rep     movsb                   ;rep until cx=0

pop     di                      ;restore di

pop     cx                      ;and set cx=15



xor     al,al                   ;zero out al

cld                             ;Clear direction

repne   scasb                   ;Scan es:[di] for al

push    di                      ;save di

mov     al,20h                  ;

rep     stosb                   ;Store al (fname) to es:[di] 


mov     byte ptr es:[di],36     ;'$'



pop     di

pop     es



push    cs

pop     ds



;mov    ah,9                    ;print fname

;mov    dx,offset fname_buf

;int    21h



mov     cx,15                   ;with BIOS function due to this procedure 
mov     si, offset fname_buf    ;can be used quite frequently. This is 
lup:    lodsb                   ;faster

int     29h                     ;mov ah,0ch, int 10h

loop    lup



mov     ax,3d02h                ;prepare open in read/write access 
mov     dx,bx                   ;bx into dx

add     dx,1eh                  ;bx = pointer to fname

push    es                      ;make es=ds

pop     ds

int     21h                     ;do it!

jnc     read_file



mov     ah,9                    ;uerm? we couldnt open the file 
mov     dx, offset error_open   ;fucking write-protected.. or lame coding 
int     21h                     ;not zoinking f_attribs??

jmp     no_inf



read_file:



mov     bx,ax                   ;place file handle in bx



mov     ah,3fh                  ;read first 4 bytes of the file 
mov     cx,4                    ;to a buffer in memory

mov     dx, offset read_buf

int     21h



cmp     byte ptr ds:[read_buf+3],'@' ;4th byte = @?

jne     No_inf



cmp     byte ptr ds:[read_buf],0e9h  ;1st byte = jmp?

jne     no_inf



inc     byte ptr [inf]



mov     ah,9                         ;say that the file is infected 
mov     dx, offset is_inf

int     21h



mov     ah,0                         ;wait keypress

int     16h



cmp     ah,15h                       ;y/Y ?

je      remove                       ; => they want to remove it.. 
jmp     no_inf



remove:

mov     ax,4202h

mov     cx,-1

mov     dx,-4

int     21h



mov     ah,3fh                          ;read those bytes to a buffer 
mov     cx,4

mov     dx,offset read_buf

int     21h



mov     ax,4200h                         ;seek the beginning of file 
xor     cx,cx

xor     dx,dx

int     21h



mov     ah,40h                          ;write the original bytes to 
mov     dx,offset read_buf              ;the top of file

mov     cx,4

int     21h



mov     ax,4202h                        ;seek (filesize-vir_size) 
mov     cx,-1

mov     dx,-1435

int     21h



mov     ah,40h                          ;truncate vir_size.. 
xor     cx,cx

int     21h



mov     ah,9                     ;Report that the file is clean. . . 
mov     dx, offset _clean

int     21h

mov     byte ptr [clean_f],1



no_inf:



cmp     byte ptr [clean_f],1

je      skip

mov     ah,9                    ;say that the file is infected 
mov     dx, offset is_cle

int     21h



skip:

mov     ah,9                    ;print linefeed instead of 
mov     dx, offset linefeed     ;mov byte ptr es:[di-1],13 
int     21h                     ;mov byte ptr es:[di],10

                                ;mov byte ptr es:[di+1],36 (see above) 
                                ;this is simpler for reporting. . . 


mov     ah,3eh                  ;close file

int     21h



pop     si                      ;restore registers in use

pop     si

pop     dx

pop     cx

pop     bx

pop     ax



ret                             ;and return to caller



dec16out:

push    ds                      ;This convertation is

push    di                      ;Blonde(tm)

push    dx

push    cx

push    ax

xor     cx,cx                   ;initialize the counter

lea     di, buf                 ;point to a buffer



dec16out1:

push    cx                      ;save the count

mov     ax,dx                   ;AX is the numerator

xor     dx,dx                   ;clear upper half

mov     cx,10                   ;divisor of 10

div     cx                      ;divide

xchg    ax,dx                   ;get quotient



add     al,30h                  ;increase to ASCII

mov     [di],al                 ;put in byte in ascii-format 
inc     di                      ;point to next byte



pop     cx                      ;restore count

inc     cx                      ;count the digit

or      dx,dx                   ;done? (dx=0?)

jnz     dec16out1               ;if not zero, loop until dx = 0 


dec16out2:

dec     di                      ;decreasment of di

mov     dl,[di]

mov     ah,2

int     21h                     ;write dl to screen output 
loop    dec16out2



pop     ax                       ;restore registers

pop     cx

pop     dx

pop     di

pop     ds

ret                             ;and return



begin:



db "Remover for the HYBRIS virus: This program is free of charge for all users.",13,10 
db 'DISCLAIMER: This software is provided "AS IS" without warranty of any kind,',13,10 
db "either expressed or implied, including but not limited to the fitness for",13,10 
db "any particular purpose. The entire risc as to its quality of performance",13,10 
db "is assumed by the user. Agree with those rules [Y/N]",13,10,36 


f_com          db       "*.COM",0           ;COM-spec

buf            dw       ?

read_buf       db       ?,?,?,?             ;4 buffers to read into 
is_inf         db       "Is infected! Remove it? [Y/N]$ "

_clean         db       " File is now clean....$"

is_cle         db       "is clean...$"

error_open     db       " Error open file$ ";shouldnt happen. . . 
resident       db       "Virus is already resident, aborting$" 
fname_buf      db       65 dup (?)          ;fname = max 64, but ah well! 
linefeed       db       0ah,0dh,'$'         ;linefeed+ end of print marker. 
count          dw       0

inf            dw       0

clean_f        db       ?

host_clean     db       "Self-checking OK!",13,10,36

host_infected  db       "Program is infected and will not run$",13,10 
stat1          db       13,10

               db       "Number of files scanned: $"

stat2          db       13,10

               db       "Number of files cleaned: $"



end start

==================================================================
============== 


% Aron's SVP v2 monitor program %



In IR#6, I released v1.00 of this program ;-). Kinda crappy disasm, 
I figured.. Here's a better one, which also detects a few other 
viruses.. Such programs always helped me, and might help someone 
as well..  So enjoy :-).



- The Unforgiven.



progsize equ endlab-start

tsrsize equ endlab-tsr



cseg    SEGMENT PUBLIC BYTE 'code'

        assume cs:cseg, ds:cseg

        org     100h



start:



        push    cs

        pop     ds



        mov     ah,9

        mov     dx,offset logo                  ;Print program logo 
        int     21h



        mov     ax,0fefeh

        int     21h



        mov     ah,4ah                          ; Get #of free paras 
        mov     bx,0ffffh                       ; in bx

        int     21h                             ;



        sub     bx,progsize/16+1                ; change allocation 
        mov     ah,4ah

        int     21h



        mov     ah,48h                          ; allocate memory 
        mov     bx,tsrsize/16+1

        int     21h

        jc      nomem



        dec     ax                              ; ax-1 = MCB 
        mov     es,ax

        mov     word ptr es:[1],8               ; Mark DOS as owner 
        inc     ax

        push    ax                              ; Save ax for later use 


        mov     ax,3521h                        ; Get orgiginal vector 
        int     21h                             ; for int21 from es:bx 
        mov     word ptr ds:[OldInt21],bx

        mov     word ptr ds:[OldInt21+2],es



        mov     ax,3516h                        ; and for int16h as well! 
        int     21h

        mov     word ptr ds:[OldInt16],bx

        mov     word ptr ds:[OldInt16+2],es



        pop     es                              ; Segment for memory 
        mov     si,offset tsr

        xor     di,di

        mov     cx,tsrsize

        rep     movsb                           ; Copy program to memory 


        push    es

        pop     ds



        mov     dx,newint16-tsr                 ; Adress for new int16h 
        mov     ax,2516h                        ; in allocated memory 
        int     21h



        mov     dx,newint21-tsr                 ; and for 21h as well 
        mov     ax,2521h

        int     21h



        push    cs

        pop     ds



exit:

        mov     ax,4C00h

        int     21h



nomem:

        mov     ah,9

        mov     dx,offset nomemmsg

        int     21h

        jmp     @exit



logo      db '.....................................',13,10 
          db ': SVP - Small Virus Protection v1.2 :',13,10 
          db ':                                   :',13,10 
          db ':    (c) Markus Aronsson 1994       :',13,10 
          db ':...................................:',13,10,13,10,'$' 


nomemmsg db     'Not enough memory to load TSR!',13,10,'$' 


tsr:

newint21:

        push    bx                              ; save bx

        xor     bx,bx                           ; nill bx



        cmp     ax,0FEFEh                       ; compare resident 
        je      resident                        ; check!



v1:

        mov     ah,30h

        mov     bx,1009

        int     21h

        cmp     bx,9001

        jne     v__

        mov     bx, offset conz-tsr

v__:

        cmp     ax,07bceh                       ; check for taipain 
        jne     v2                              ; not resident! 
        mov     bx,offset taipan-tsr



v2:

v@@:

        cmp     ax,0abc0h                       ; check for scitzo! 
        jne     v@                              ; not resident! 
        mov     bx,offset scitzo-tsr

        mov     ah,0

        int     16h

        cmp     ah,15h

        jne     v@

        ret



v@:     cmp     ax,0dcbah

        jne     v3

        mov     bx, offset scitzo-tsr



v3:     cmp     ax,04bffh                       ; check for desperado! 
        jne     v4                              ; not resident! 
        mov     bx,offset despera-tsr



v4:     cmp     ax,07777h                       ; check for digital pollution 
        jne     v6                              ; not resident! 
        mov     bx,offset digpol-tsr

v5:

        cmp     ax,0fa01h                       ; check for vsafe unloading! 
        jne     v6                              ; nope!

        mov     bx, offset vsafeun-tsr

v6:

        or      bx,bx                           ; bx=0?

        jne     virusfound

        pop     bx                              ; restore bx 


doold21:  db 0EAh                               ; jmp far ptr 
oldint21: dd 0                                  ; saved vector for int21h 


newint16:



        cmp     ax,0fa01h                       ; check for vsafe unloading 
        jne     doold16                         ; nop!



        mov     bx,offset vsafeun-tsr

        je      virusfound                      ; print warning! 


doold16:  db 0EAh                               ; jmp far ptr 
oldint16: dd 0                                  ; saved int16h 


resident:

        push    cs

        pop     ds

        mov     dx, residen-tsr

        mov     ah,09

        jmp     @exit



virusfound:

        push    cs

        pop     ds



        mov     ah,09

        mov     dx,offset svp-tsr

        int     21h

        mov     dx,bx

@exit:  int     21h

        mov     ax,4c00h

        int     21h



residen db 'SVP is already resident!',13,10,'$'

svp     db 13,10,'SVP -> File infected by $'

taipan  db 'TAIPAN!',13,10,'$'

despera db 'DESPERADO!',13,10,'$'

scitzo  db 'SCITZO!',13,10,'$'

digpol  db 'DIGITAL POLUTION!',13,10,'$'

vsafeun db 'a virus using the VSAFE UNINSTALL code, such as Junkie.',13,10,'$' 
conz    db "Conzouler.912 Infected!",13,10,36



endlab:



cseg    ends

        end     start

==================================================================
==============