=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Hey Guyz, Another fine release from iLLEGALITY, this time its how to write your own virus, and get your name in all the computer magazines. I didn't actually write this thing, the Black Baron did, so don't come running to me when your test virus wipes your hd, i just distributed the thing. Well anyway enjoy d00ds, cya at my next release. Dr d00m. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ SMEG v0.3 A Linkable Polymorph Engine ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ (Simulated Metamorphic Encryption Generator) Programming and Documentation (C) The Black Baron 1994 ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ 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 POLYMORF.TXT General description of a polymorph engine 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! So, with the above in mind, no explanation of how to program in 8086/88 will be given in this documentation. It is assumed that you understand what I am babbling on about! 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! 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! On the subject of linking. When linking SMEG to your code it's easier if it is linked last, I.E: LINK MYVIRUS SOMEDATA MORECODE SMEG; One VERY important point is that SMEG is designed to run as a TINY memory modeled piece of code, therefore, before calling ANY of the SMEG functions you MUST make sure all your segment registers are the same and SMEG is reachable in the current CODE SEGMENT, just like a .COM file. To this end, after linking you must use EXE2BIN to convert to a .COM or use the /T option on TLINK and the later versions of Microsofts LINK. Because SMEG uses INDEXED CALLS and so-on if you don't make sure all the segments are the same 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 is 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 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, one point to remember is that SMEG should be the LAST thing linked on the linker command line. This makes life a lot easier! An example: LINK MYVIRUS SOMEDATA MORECODE SMEG; Note how SMEG was linked last? If your linker contains fancy segment sorting options these should be turned OFF to ensure that the SMEG object code is, indeed, the last thing in your final program. Linking SMEG last isn't strictly essential, however, this document has been written with the "linking SMEG last" method in mind! 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 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! ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Because SMEG contains calls via indexed tables etc, you MUST ensure that ALL segment registers are the same value (as in a .COM file), this value MUST be the same as the current 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! When you relocate you MUST remember to relocate ALL of the segment registers. 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 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 if no padding is required. Look in TRIVSMEG.ASM to see this in action: CALC_PAD: AND AX,15 ;Mask low nibble JNZ NEED_TO_PAD ;If it isn't zero, must pad! RET NEED_TO_PAD: NEG AX ;NEG AX ADD AX,16 ;Same as 16 - original AX RET 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 ALL segments 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 all the other segment registers equal the new, relocated, CODE SEGMENT before you make any SMEG function calls. As per SMEG's segment rules. 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 relocation 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. 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: 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. DX : Must point to the start address of the code/data you wish to encrypt. 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 BP! After calling polymorph the RAM pointed to by 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 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 DI. You can find out the original address (DI when you called POLYMORPH) by: MOV wordreg,[BP+4] ;It's address {DI originally} 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: 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 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 address by: MOV wordreg,[BP] ;It's size {CX originally} MOV wordreg,[BP+4] ;It's address {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: 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 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 DI address by: MOV wordreg,[BP+4] ;It's address 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 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 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. 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. Thanks. Oh, and maybe a little credit in your creation for me?! (C) The Black Baron 1994.