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 ================================================================== ==============