MuTation Engine Version 1.00á (22-04-92) (C) 1992 CrazySoft, Inc. written by Mad Maniac. ****** This is a beta release ment only to be distributed to the ****** ****** members of Destroyers, Inc. Do not, repeat, DO NOT spread! ****** 1. License You are free to include this Engine in viruses. Using it in another ways is prohibited. You are free to give it to people that will only use it in this way. MuTaion engine is free. 2. How it works Please read the whole document before trying to do something with the Engine. If you have never written a virus in Assembler, DON'T start with the Engine. First do this, then return back to the Engine. MuTation Engine is an object module that could be linked to any virus. It has been written in Assembler and assembled under Turbo Assembler 2.5. We recommend that you use this assembler to compile the viruses that will carry the Engine. Linking it to an object file produced by other assemblers, or high-level languages compilers is theoretically possible, but we never tried and do not recommend it. We decided NOT to give up the Engine's source code at this time. The Engine will encrypt your code each time with a different encryption key. It will also generate a routine to decrypt it, which will also differ each time. Both the decryption routine and the encrypted code will have variable lengths. Thus your virus will be hardly detectable. The Engine's code is about 2KB; we believe this is not too big. 3. How to use it We assume that you will use Turbo Assembler 2.5 to compile your virus. Put the following at the beginning of your source code: .model tiny .code extrn mut_engine: near Then you write your virus as usual. When you need to encrypt the code, you just call the Engine. Put the following instruction in your code: call mut_engine You also need to supply the parameters for the Engine. They are passed in registers. Results are also passed in registers. Of course, you must link the MTE.OBJ module to your virus! You can rely on the fact that the Engine will not modify itself while running, and will not need any data to be preserved between calls (except for RND_BUF, see below). 4. Input parameters All parameters are mandatory. Description follows: ES = Work segment The Engine needs work space. On entry, ES must point to a free segment. It will use the first 2048 (MAX_LEN) bytes of it PLUS length of the code that will be encrypted. If, for example, your virus will be 3KB in length (including the Engine!), the work segment must have at least 5120 bytes free. The segment needs not to be initialized; it contents will be lost after calling the Engine. DS:DX => Code to encrypt On entry, just set DS:DX to point to the code you want to be encrypted. CX = Length of code to encrypt On entry, just set CX to the length of the code you want to be encrypted. BP = Offset where the decryption routine will be executed The Engine needs to know what will be the value of IP when the decryption routine will take control. For example, if your virus infects a COM file, and adds itself BEFORE it, you must set this value to 100h. DI = Offset of the code entry point This is the offset where to pass control after the decryption routine has decrypted the encrypted code. This is also the start offset for decrypting. The code before this offset will NOT be decrypted. Usually, set this value to 0. SI = Offset from start address where the encrypted code will be This is the offset where the encrypted code will be taken from (The decrypted code will be put immediately after the decryption routine). If you set this value to 0, the encrypted code is assumed to be immediately after the decryption routine (this is the normal case). BL = Decryption routine size (1 = Tiny, 3 = Small, 7 = Medium, 15 = Big) This affects the size and the speed of execution of the decryption routine. Only the above listed 4 values are allowed (other values will crash the Engine). Usually, set this to 0fh. AX = Bit field Bit 0 = Preserve AX \ Bit 1 = Preserve CX \ Set each bit to 1 if you want the value of the Bit 2 = Preserve DX \ corresponding register to be preserved when the Bit 3 = Preserve BX \ decryption routine receives control. Set it to Bit 4 = Preserve SP / 0 if you don't want it preserved. Other Bit 5 = Preserve BP / registers will be preserved in any case. Bit 6 = Preserve SI / Bit 7 = Preserve DI / Bit 8 = Would probably run at different CPU Set this bit to 1 if the decryption routine could run on another computer (this is the normal case). Bit 9 = Don't assume CS = DS on execution Set this bit to 1 if you're not sure that DS will point to CS on entry to the decryption routine (this is the normal case for EXE files). Otherwise, set it to 0. Bit 10 = Don't assume CS = SS on execution Set this bit to 1 if you're not sure that SS will point to CS on entry to the decryption routine (This is the normal case for EXE files). Otherwise, set it to 0. Bit 11 = Don't align encrypted code onto paragraph boundary Set this bit to 1 if you don't care if the decrypted code is aligned on a paragraph boundary. Otherwise, set it to 0. Note that the value of IP will be unknown at the time when the decrypted code receives control. 5. Results The Engine returns the following values in registers (all others except for the listed below will be trashed): ES = Work segment The ES value is preserved. DS:DX => Decryption routine + encrypted code DS:DX now points to the decryption routine immediately followed by the encrypted code. If SI was set to 0 on entry, the code is ready to be put in a file. If not, you must treat separately the first DI and next CX-DI bytes (see below). CX = Length of the decryption routine + encrypted code CX now has the summary length of both the decryption routine and encrypted code. AX = Length of the code that was encrypted AX now has the length of the code that will be decrypted at the time when the decryption routine receives control. This value may differ from the value that you passed in CX on entry; but it is not less than it in any case. It might be greater with no more than 32 (MAX_ADD_LEN) bytes. This is because of how the Engine works. DI = Offset of decryption routine end This is the length of the decryption routine, and an offset where the encrypted code starts. You might need this if SI was not set to 0 on entry. This value is not greater than 512 (MAX_ADD) bytes. SI = Offset of loop start This is an offset in the newly generated decryption routine where the decryption loop starts. You might need it if SI was not set to 0 on entry. If you don't, just ignore it. 6. Stack usage Before you call the Engine, make sure there is PLENTY of stack space free (256 bytes appear to be enough). For resident viruses, it is strongly recommended that you maintain your own stack. Otherwise the chance is that you will blow the DOS stack. This will change in the final release of MtE 1.0. 7. Random numbers Unfortunately, what was said above was NOT sufficient to include the Engine in your virus. The reason is, that in order to generate random encryption keys, the Engine uses a pseudo-random number generator. To achieve greater flexibility, we decided to include it in another object module. You have two options: 1) To use the sample pseudo-random numbers generator, included with the Engine 2) To design your own random numbers generator 7.1. Using the sample generator It is easier to choose this option. In this case you need to link the RND.OBJ module to the virus. Also put the following instruction at the beginning of your source code: extrn rnd_buf: word Where the virus FIRST receives control, put the following instruction: mov cs:[rnd_buf],0 You also MUST ensure that the contents of RND_BUF (which is in _DATA segment) will be preserved between two calls of the Engine. If you need pseudo-random numbers in your virus, you can use the RND_GET and RND_INIT procedures, if you declared them as externals (see below). However, either RND_INIT or MUT_ENGINE should be called prior to calling RND_GET! 7.2. Designing your own generator To do this, you need to write two procedures, RND_INIT and RND_GET. They must be declared as publics either in your virus, or in a separate module. RND_INIT must return a RANDOM number in AX. RND_GET must return a PSEUDO-RANDOM number in AX. These procedures MUST preserve all registers except for AX. If you don't understand it, don't do it. The Engine works great with the sample generator. 8. Final Notes Well, that's for now. No time for more. Look at the demo virus and other sample files included here to get an idea how can you use it. After you include it in your virus, please check carefully if the Engine does what you expect it to do. Feel free to experiment with it. If you have problems using it, or have any comments or suggestions about it, write a message to Dark Avenger at the: Virus eXchange BBS in Sofia Phone number: (+359)-2-20-4198 Working hours: 20:00 - 06:00 GMT (in the winter) 19:00 - 05:00 GMT (in the summer) The final release of the Engine should also be available at that BBS. Remember do not pass the Engine to any others than the members of Destroyers, Inc.! Greetings, CrazySoft, Inc. Bulgaria