		  Ŀ
		    SMEG v0.3  A Linkable Polymorph Engine  
		  
		  (Simulated Metamorphic Encryption Generator)

	  Programming and Documentation (C) The Black Baron U.K.  1994
                   Is the the first British Polymorph Engine??!
	  



FILES INCLUDED IN THIS PACKAGE:


		SMEG    .OBJ	The linkable SMEG v0.3 engine
		SMEG    .TXT	This documentation

		GENDEMO .COM	Generation difference demonstration program
		TRIVIA	.COM	A trivial, non polymorphic .COM virus
		TRIVSMEG.COM	Same as TRIVIA.COM but now polymorphic!

		GENDEMO .ASM	TASM/MASM source for GENDEMO .COM
		TRIVIA	.ASM	TASM/MASM source for TRIVIA  .COM
		TRIVSMEG.ASM	TASM/MASM source for TRIVSMEG.COM



ASSUMPTIONS MADE FOR THE USE OF SMEG:


Every effort has been made to make SMEG as easy as possible to link into your
own code, however, due to the complexity of the engine it is assumed that you
have at least a basic knowledge of 8086/88 assembler.  Those of you who don't
will find this package of little use!  It should be noted that linking SMEG
to someone else's code is not a trivial task, however, if you write your own
code then linking should be fairly painless!

Also, it would be wise to print this document.  This will make your life a
lot easier when you start playing with SMEG.  This document contains no
special printer formatting codes (other than TABS) and has not been formatted
in any page like style.  It is just "As It Was Written".  So, printing it on
fan-fold will be OK, but if your printer can only print one page at a time
you should load this into your favourite text editor/word processor and
format it into pages of your own preference.

In this document I have used the term ADDRESS to represent an OFFSET within a
SEGMENT.  ADDRESS, therefore, means JUST the offset and NOT segment:offset! 
I will use the term ADDRESS and/or SEGMENT:OFFSET throughout this document.



SMEG v0.3 WHAT IS IT AND WHY v0.3?


SMEG v0.3 is a polymorph engine that can be linked into your code, it was
designed for computer viruses but could be used for other things, to encrypt
and provide a unique decryptor.  See the enclosed POLYMORF.TXT for a more
detailed description if you really don't know what a polymorph engine is!

v0.3?  Well, this is the first version to be made available to "the public",
there have been two versions prior to this, v0.1 used in my PATHOGEN virus and
v0.2 used in my QUEEG virus.  "STOP!", I hear you cry; "DOESN'T THUNDERBYTES
TBAV v6.20 FIND SMEG ENCRYPTED VIRUSES?", well, yes and no!  It claims to find
all known polymorphs and any future ones by using a clever software tracer
technique and, to give it it's due, it does find approximately 96% of all
QUEEG (SMEG v0.2) infections!  However, it still missed 4%!

SMEG v0.3, however, contains more advanced "junk program generator" technology
than versions 0.1 and 0.2!


AN EXAMPLE:


I took QUEEG and replaced SMEG v0.2 with SMEG v0.3 but with this technology
"turned off".  TBAV 6.20 detected 96% of infections; reporting "A SMEG
ENCRYPTED VIRUS" has been found.  Turning on the technology and running
the test again TBAV 6.20 detected 0%!  In fact, it didn't even try decrypting
the infected files and 'Skipped' or 'Checked' them, just like non-infected
programs!





NOTES ON ASSEMBLING AND LINKING:


Wherever possible you should force your assembler to do multiple passes, to
fix those annoying, redundant, NOPS in your code.  TASM has this ability,
sadly MASM doesn't (at least my version doesn't!).  The source code provided
in this package is TASM/MASM compatible, if you use a different assembler
then you might find assembling the demonstration programs awkward!

One important point is that SMEG is designed to run as a TINY memory modeled
piece of code, therefore, all CALLS to SMEG functions are NEAR and you MUST
make sure the DATA SEGMENT is the same as the CODE SEGMENT where SMEG resides.

Because SMEG uses INDEXED CALLS, Etc,  if you don't make sure the DS is the
same as SMEGS CS, before calling any SMEG functions, unpredictable results can
occur.

Any assembler/linker command line examples in this document will be based on
TASM and TLINK.

SMEG.OBJ was produced with TASM v2.51 with all non-essential items (regards to
linking) removed.

There was only one segment (the code seg) and it's declaration was as follows:

CODESG		SEGMENT BYTE PUBLIC

The assume line was as follows:

		ASSUME	CS:CODESG,DS:CODESG,ES:CODESG,SS:CODESG

All procedures are NEAR and there are NO segment overrides (hence the need for
the DS to be the same as SMEGS CS) or self contained work areas.

There are just three PUBLIC labels, referring to the NEAR procedures:

		POLYMORPH
		ENCRYPT
		JUNK_GEN

Theses are described in full later on in this document.





DEMONSTRATION PROGRAMS


Before I describe how to link SMEG into you own code you might like to try
running one of the demo programs included in this package?  If so, read the
descriptions below before exiting your text viewer/editor:


GENDEMO.COM


GENDEMO is a small program that will generate a chosen amount of executable
and encrypted .COM files.  When any of these generated .COM's is run you will
see a short message.  It's main purpose is to demonstrate how each generation
is VERY different from the last.  Each generated .COM consists of a randomly
generated decryptor followed by a small program to display a message.  In each
case this small message program and the message itself will be encrypted.

Enter GENDEMO from the DOS prompt.

You will be presented with a small menu requesting the number of generations
you require, 10 - 10000.  Only choose 10000 if you have a large hard disk and
lots of time!!  After selecting the number, GENDEMO will proceed to generate,
it will inform you when it's finished and return you to the DOS prompt.  If
you now do a DIR you will see your chosen number of .COM's like this:

		0000.COM
		0001.COM
		0002.COM   .....   Down to your chosen number - 1

You can run any of these by entering it's name at the DOS prompt, I.E:  0002

You might like to use a HEX editor (or DEBUG) to see how different each
generation is.

The source code for GENDEMO is provided as GENDEMO.ASM, it's TASM/MASM
compatible and you can examine it to see how each generation is produced by
using SMEG's functions.  The source is not commented.

You can re-assemble and link to produce GENDEMO.COM as follows:

		TASM  /M2 GENDEMO
		TLINK /T  GENDEMO SMEG;

If using MASM and LINK, you must EXE2BIN the resultant .EXE to produce:
GENDEMO.COM


TRIVIA.COM


TRIVIA is a small non-resident, direct action .COM virus.  It contains no
disk damaging routines and only contains a trivial payload.  To infect a file
with TRIVIA do the following:

Make a temporary sub-directory and copy TRIVIA.COM into this.  Next move to
this sub-directory and use ATTRIB to set the READ ONLY flag on TRIVIA.COM,
this is how TRIVIA marks infected files and doing this will stop TRIVIA from
infecting itself!  Next copy a "victim" .COM file from your system into this
temporary sub-directory.

Now enter TRIVIA at the DOS prompt.

Do a DIR and you should notice that your victim file has grown!  Also, if you
do an ATTRIB you will see the READ ONLY flag has been set.  However, the time
and date should remain unaltered.

TRIVIA will infect ONE and only ONE uninfected file in the CURRENT and only
the CURRENT directory.  If no uninfected files can be found, no infection will
occur. 

Therefore, executing an infected file causes other .COM's in the current
directory to become infected, one by one.  Because TRIVIA is NON-RESIDENT it
can only reproduce when you execute a previously infected file.

The payload contained in TRIVIA is very trivial.  If it's a FRIDAY the 13th
(very original, eh!!?) and you run an infected .COM the .COM will not run,
instead, you are returned to DOS with the message:

"This program requires Microsoft Windows."

The source code for TRIVIA is provided as TRIVIA.ASM, it's TASM/MASM
compatible.  It doesn't use any special tricks and could be re-coded much
tighter!!  Apologies to code purists for this!  The source is commented.

You can re-assemble and link to produce TRIVIA.COM as follows:

		TASM  /M2 TRIVIA
		TLINK /T  TRIVIA;

If using MASM and LINK, you must EXE2BIN the resultant .EXE to produce:
TRIVIA.COM

TRIVIA.COM is provided as a demo virus, try infecting a few .COM's and then
scan them with TBAV and you will see that they are spotted as:

"POSSIBLY INFECTED BY AN UNKNOWN VIRUS", or something like that!


TRIVSMEG.COM


TRIVSMEG is identical to TRIVIA.COM with the exception that the virus is now
polymorphic.  Prepare a few "sacrificial goats" and infect them as described
in the description of TRIVIA.COM.  Replacing, of course, all references to
TRIVIA with TRIVSMEG!

Now try scanning them with TBAV.  Spot the difference?!!!

Examine each infected file and note how different each infected portion is.

The source code for TRIVSMEG is provided as TRIVSMEG.ASM, it's TASM/MASM
compatible.  It doesn't use any special tricks, apart from SMEG functions, and
could be re-coded much tighter!!  The source is commented.

You can re-assemble and link to produce TRIVSMEG.COM as follows:

		TASM  /M2 TRIVSMEG
		TLINK /T  TRIVSMEG SMEG;     {Note the linking in of SMEG}

If using MASM and LINK, you must EXE2BIN the resultant .EXE to produce:
TRIVSMEG.COM

Examine the .ASM for TRIVSMEG to get a feel for linking with the SMEG engine,
but first read on and familiarise yourself with SMEG and it's idiosyncrasies!





USING SMEG.OBJ IN YOUR OWN CODE


The remainder of this document is dedicated to describing how to use the SMEG
polymorph engine in your own code.  Please note; the text has been written
from a "Virus Writers" point of view, but SMEG can be used in non-viral code
should you wish.  It is at this point that I must stress again; you will need
at least a basic understanding of 8086/88 assembly language to make sense of
the text that follows!

POINTS TO NOTE:


SMEG uses NO instructions above standard 8086/88 and it's junk code generator
and decryptors also use only the basic 8086/88 instruction set, thus insuring
that SMEG and it's generated code will run on ALL PC's and compatibles, from
humble XT's to Pentium "Dream Machines"!

SMEG contains NO disk I/O routines.  It's purpose is to generate decryptors
and encrypt code/data.  Therefore, all reading/writing to disk must be done
by your own code!

LINKING SMEG INTO YOUR OWN CODE:


Actually linking the engine with your own code is a painless task.

An example:  LINK MYVIRUS SOMEDATA MORECODE SMEG;

To CALL any of the SMEG functions (there are only three!) from your code you
must include the following EXTRN declarations, EXACTLY as shown:

		EXTRN	POLYMORPH : NEAR
		EXTRN	ENCRYPT   : NEAR
		EXTRN	JUNK_GEN  : NEAR  {This is optional, see later}

(You can put these declarations on a single line, if you wish)

IMPORTANT NOTE:


You MUST NOT call ENCRYPT or JUNK_GEN without having first called POLYMORPH,
as the POLYMORPH function sets up various data items for use by the other two
routines.  THIS IS VERY IMPORTANT!
           

ANOTHER IMPORTANT NOTE (Reminder!)


Because SMEG contains calls via indexed tables etc, you MUST ensure that the
DATA SEGMENT is the same as the CODE SEGMENT where SMEG resides.  Failure to
ensure this will result in unpredictable results, possibly a system crash or
worse!

All three routines require the BP register to point to a free area of memory
containing AT LEAST 45 bytes.  This 45 byte space is all that is used by SMEG
as work area.  There is more information on register usage in the function
descriptions.

ONE MORE IMPORTANT NOTE BEFORE I DESCRIBE EACH FUNCTION!


If you are planning to CALL any of the SMEG functions from your code and your
code DOES NOT reside at the address it originally started life at, then you
MUST relocate your segments and IP offset as if it did!  Again, this is
because SMEG uses indexed calls that are calculated at LINK TIME and remain
static. A common example here would be a virus.  A diagram explains this:

       YOUR ORIGINAL			         YOUR APPENDED
       			         
your virus	 : 0100h - 02FFh	victim program	    : 0100h - 2FFFh
SMEG		 : 0300h - xxxxh	your appended virus : 3000h - 32FFh
					SMEG		    : 3300h - xxxxh
					 
Note that after appending your virus to the victim program all the static
addresses contained within SMEG's call tables will be incorrect because at
LINK TIME these tables were calculated relative to address 0300h, now they
are all at 3300h but still relative to 0300h!!  Thus, calling any SMEG
functions without first relocating would be disastrous!

If you are not planning on calling any SMEG functions, or indeed, if your
encrypted code doesn't contain the SMEG engine then relocation is optional.
Unless, of course, YOUR code requires it!

It should be noted that the decryptors generated by SMEG are "stand alone"
and do not require a copy of SMEG to run.  An example here are the .COM files
generated by the GENDEMO.COM demonstration program, each of the generated
COM's doesn't contain SMEG, just the decryptor followed by the encrypted code.

Relocation, using the method I am about to describe (which is the same as the
method used in TRIVSMEG and my other two viruses PATHOGEN and QUEEG), is a
two stage affair.

RELOCATION, STAGE ONE:


You must first make sure that the length of the file you are appending your
virus onto is divisible by 16 (10h) exactly in other words it's length MOD 16
equals zero or, to put it yet another way, rounded up to the nearest paragraph
boundary!

The following snippet of code calculates this, call it with AX equal to the
low word of the filesize, it returns (in AX) the number of bytes you have to
add to the file (between 1 and 15) to make it's length MOD 16 = 0. It returns
AX as zero (and the zero flag set) if no padding is required.
Look in TRIVSMEG.ASM to see this in action:

	CALC_PAD:	NEG	AX		;Neg AX!
			AND	AX,15		;Mask low nibble
			RET			;AX = pad count (or ZERO)

I should mention here the size of ALL decryptors generated by SMEG MOD 16 = 0
Therefore, after padding the file and appending a SMEG generated decryptor you
still find yourself on a paragraph boundary, which is handy (and essential!)
for the second stage of this type of relocation process!

RELOCATION, STAGE TWO:


As mentioned earlier, you must ensure that the CS and DS and your IP offset
are the same as they were in your original, non-appended, code.  The following
snippet of code will achieve this.  Again, look in TRIVSMEG.ASM to see it in
action.  It should be noted, this code MUST be the VERY FIRST thing in your
code, AFTER the decryptor, to ensure correct relocation:

	RELOCATE:	CALL	FETCH_IP	;Call the next instruction
	FETCH_IP:	POP	AX		;Fetch address of here into AX
			DEC	AH		;SUB 256
			MOV	CL,4		;A Shift of 4
			SHR	AX,CL		;Divide AX by 16
			MOV	BX,CS		;Fetch current CODE SEGMENT
			ADD	AX,BX		;ADD adjustment to it
			PUSH	AX		;Stack relocated CODE SEGMENT
			MOV	AX,RELOCATED	;Fetch continuation address
			PUSH	AX		;Stack it
			RETF			;FAR RETurn to the next line!
	RELOCATED:				;Rest of your code here

After the RETF, continuation occurs at the address RELOCATED and the CS:IP
is the same as if you had run your original code.  However, at this point all
of the other segment registers remain as they were prior to the relocation. 
If you are a virus you should make a note of one of these registers so you
can restore all the original segment registers prior to running your host!

The first thing your code should do, after relocation, is to make sure the
DATA SEGMENT equals the new, relocated, CODE SEGMENT before you make any SMEG
function calls.  As per SMEG's segment rule.

Note, in the case of a virus, the above relocation technique can be used for
appending to .EXE's as well as .COM's

You may know a better way of relocation, if so then you can use that. 
Providing, of course, SMEG's rules regarding segments are adhered to.


SMEG FUNCTION CALLS AND REQUIREMENTS:


SMEG's functions will be described in order of relevance, which just so
happens to be the CALL order too!

It should be noted here that SMEG is 2016 (07E0h) bytes in size.

The 45 byte work area used by the SMEG functions is disposable and doesn't
have to travel with the engine.  SMEG uses approximately 60 bytes of stack
space, please ensure the SS:SP doesn't clash with the SS:BP work area!


Function Name:  POLYMORPH


This function is the main function contained within SMEG.  It's purpose is to
construct a random size decryptor containing a random decryptor with random
register use peppered throughout random junk code.  This function also sets
up the required values, in a workspace, for the other two SMEG functions and,
therefore, MUST be called prior to calling the other functions.

To call this function you must set up the following registers and observe any
RAM requirements:

     SS:BP : Must point to an area of memory with 45 bytes free.
	     This is the above mentioned WORKSPACE.

      	AX : Must hold the actual start address of the decryptor.  E.G.  If
	     you were generating a decryptor that is at the very start of a
	     .COM file you would load AX with 100h.  See GENDEMO.ASM for
	     this type of generation in action.  Likewise, for a decryptor
             designed to be appended to some other piece of code you would
	     load AX with the append address.  Example:  You are appending a
	     decryptor onto a .COM file that is 300h bytes long, in this case
	     you would load AX with 400h (100h+size of file = append address)
	     See TRIVSMEG.ASM for this type of generation in action.

	CX : Must hold the length, in bytes, of the code/data you wish to
	     encrypt.

     DS:DX : Must point to the start address of the code/data you wish to
	     encrypt.

     ES:DI : Must point to an area of memory with at least CX (see above)
	     bytes of space free.  If CX is less than 1792 (700h) bytes then
	     there MUST be 1792 (700h) bytes free.  This space MUST NOT clash
	     with the 45 byte space pointed to by SS:BP!

After calling polymorph the RAM pointed to by ES:DI contains a random sized,
random decryptor.  This can be written out to disk at this point as it is no
longer needed by SMEG!  The size of this decryptor varies, from between 320
(140h) and approximately (but no more than) 1792 (700h) bytes and is always
rounded to the nearest paragraph.  To find out the true size of the decryptor
(providing SS:BP points to the 45 byte work area, and it still will if you
haven't altered it!) just do a:

		MOV	wordreg,[BP+39]  (39 is decimal)

So, you would write this many bytes from the memory originally pointed to by
ES:DI.  You can find out the original value of DI (when you called POLYMORPH)
by:

		MOV	wordreg,[BP+4]	;DI original value

On return from POLYMORPH all registers are destroyed, with the exception of:
BP, BX, SI and the segment registers.


Function Name:  ENCRYPT


This function is called after calling POLYMORPH to encrypt your code/data
ready for appending after the decryptor.  Note:  You should write out your
decryptor to the file before calling ENCRYPT else your decryptor in RAM will
be overwritten, as the same RAM area is used.

To call this function you must set up the following registers and observe any
RAM requirements:

     SS:BP : Must point to the same 45 byte work area it did prior to calling
	     POLYMORPH, as BP is preserved by POLYMORPH it's a good idea not
	     to alter it between POLYMORPHS return and calling ENCRYPT.

After calling ENCRYPT the RAM pointed to by ES:DI (when you called POLYMORPH)
will contain your encrypted code/data, it's size is the same as the value in
then CX register when you called POLYMORPH.  This encrypted code/data can now
be written to disk immediately after the decryptor.  Alternatively, you can
recover the size of your encrypted code and it's offset (in the ES) by:

		MOV	wordreg,[BP]	;It's size	{CX originally}
		MOV	wordreg,[BP+4]	;It's offset    {DI originally}

Again, this assumes BP still points to the 45 byte SMEG work area.

The preserved and destroyed registers are the same as those for POLYMORPH.

IMPORTANT:  The encrypted code/data MUST be written to the file IMMEDIATELY
            after the decryptor, NO code/data is to be written in between.


Function Name:  JUNK_GEN


This function is a optional one.  It's purpose is to generate a random amount
of junk that you can append after your encrypted code/data.  This makes
finding the true end of your encrypted code/data impossible.

To call this function you must set up the following registers and observe any
RAM requirements:

     SS:BP : Must point to the same 45 byte work area it did prior to calling
	     POLYMORPH and ENCRYPT, as BP is preserved by both POLYMORPH and
	     ENCRYPT it's a good idea not to alter it between ENCRYPTS return
	     and calling JUNK_GEN.
		
After calling JUNK_GEN the RAM pointed to by ES:DI (when you called POLYMORPH)
will contain a random amount of random junk.  This junk can now be written to
disk immediately after the decryptor, encrypted code/data.  The size of this
junk will vary but is always at least 128 (80h) and no more than 1151 (47Fh)
bytes.  You can, again, recover the original value of DI by:

		MOV	wordreg,[BP+4]	;DI's original value.

The preserved and destroyed registers are the same as those for POLYMORPH and
ENCRYPT with the exception of the following:

		DX	returns pointing to the start of the junk (in the ES)
			the same as the original DI or the word [BP+4]
		CX	returns holding the size of the junk

These just happen to be the registers required for a DOS write, and providing
your file handle is in BX and your DS equals your ES you can write out the
junk to the file by simply:

		MOV	AH,40h
		INT	21h

The size of this junk is pre-calculated during the call to POLYMORPH. 
Therefore, after calling POLYMORPH you can find out how big this junk is
going to be before it is actually generated by doing:

		MOV	wordreg,[BP+37]  (37 is decimal)

This is useful to know, for adjusting .EXE headers etc.  Remember, generating
this junk and writing it to the file is optional and doesn't affect the
decryptor in any way.  Please note, the "junk" created by JUNK_GEN is just
that and is NOT executable code!!

Well, that's the functions described.  A simple (pseudo code) example of an
appending SMEG encryption session might look something like this:

		OPEN	FILE
		GET	FILESIZE
		PAD	SO FILESIZE MOD 16 = 0
		SET	POLYMORPH REGISTERS
		CALL	POLYMORPH
		WRITE	DECRYPTOR TO THE FILE
		CALL	ENCRYPT
		WRITE	ENCRYPTED CODE TO THE FILE
		CALL	JUNK_GEN	 (optional)
		WRITE	JUNK TO THE FILE (optional)
		CLOSE	FILE

That's all there is to it!!!  I've tried to describe SMEG in a brief, but I
hope, complete way.  If you are still unsure how to use it have a look at the
source code for TRIVSMEG.ASM and GENDEMO.ASM (which are both supplied) as
these two programs both use the SMEG engine.

Have fun with SMEG and all I ask is that should you give copies away to your
friends please ONLY give them the archive that you received, I.E.  With NO
amendments or alterations.  Thanks!

Oh, and maybe a small credit in your latest creation for me???!!!

ON A FINAL NOTE:


Please accept my apologies if you have used other Polymorph engines before
and find SMEG a little difficult to use.  SMEG is my first attempt at a
Polymorph engine and it was written without having seen any other Polymorph
engine in action.  Therefore, I didn't know what "format" the others followed
with regards to CALLing and linking.  I hope SMEG meets all the requirements
you might expect from a Polymorph engine.

Have fun.......

(C) The Black Baron U.K. 1994.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
