Virus Labs & Distribution
VLAD #5 - Win API tutorial


           Calling the Windows API in Assembly Language
                            by
                        Qark [VLAD]


        If you didn't read the windows document in VLAD#4 or don't
        know anything about lowlevel windows structures, then turn
        back now!

                ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ

        Although I designed this document with a view to virus writing,
        I've never seen any information like this anywhere, so it
        could just as easily be used as a general low-level windows text.
        Feel free to use it as such.

        I worked out the 'procedure ordinal number listing' by using
        a diskeditor to increase the 'procedure ordinal number' in the
        disk file, and seeing which API was produced by viewing the file
        with a disassembler.  This took many hours.  I only did it for
        the KERNEL functions because they are the only ones that are useful
        for viruses.  If you require pretty windows and scroll bars then
        change the 'index into the module reference table' to refer to GDI
        or USER and work out the 'procedure ordinal numbers' for yourself.

                
                ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
        

        To work out the parameters to enter into the API, you will need
        an API listing.  These are normally of phone book proportions
        and I'm not about to type one out, so grab one from your local
        library.  If you can, check to make sure that the book you are
        thinking of choosing lists the selector functions such as
        'AllocCStoDSAlias'.  These functions are considered obselete
        by Windows 3.1, but they are still there, and should be listed!

        All parameters passed into an API are done using the stack.
        The values shown in the API listing need to be PUSH'ed in order.
        Any return data will be passed back in AX if it is a word, and 
        DX:AX if a dword.  (I might be wrong about this, but it has worked
        so far!)

        For example, my 'Windows API Bible' (which doesnt list the selector
        API functions) says to call "_lopen", which opens a file the same
        as int 21 AH=3dh, do this:
        Syntax: int _lopen (LPSTR lppathname, int ireadwrite);
        Returns: int, file handle, or -1 if error.

        Let's analyse the syntax.
        The 'int' at the start means the return value will be an integer,
        which is a word, and thus passed in AX.  If it had said 'LONG' then
        we'd know it was passing back in DX:AX.
        LPSTR is a pointer to an asciiz string (the book tells us this) so
        push the segment, and then offset of the filename to be opened.
        'ireadwrite' is the openmode, so based on experience, 2 will be the
        word pushed to open in read/write mode.

        Now here is the full fileopen API all written up, including
        relocation entry and call:
                ...
                push    ds              ;ds:dx=filename
                push    dx
                mov     ax,2            ;open in read/write mode
                push    ax
        apicall:
                db      9ah             ;Call Far Ptr
                dw      0ffffh          ;Windows needs these.
                dw      0
                mov     bx,ax           ;file handle into BX
                ...

        The relocation item is setout like so:

                db      3               ;32 bit pointer
                db      1               ;Import Ordinal
                dw      offset apicall + 1      ;Offset of api entry
                dw      1               ;Index into module reference table
                                        ;of KERNAL.
                dw      55h             ;Indicate '_lopen' API call.
                                        ;This is the 'procedure ordinal
                                        ;number'

        In the relocation I have assumed that the kernal is the first
        thing in the module reference table.  Don't assume this.  In a virus
        you will have to search for it.

        I got the '55h' by checking the table below.  The 'procedure ordinal
        number' indicates which API the relocation is talking about.
        If you changed the '55h' to a '56h' it would be a '_lwrite' API
        call instead.  Check below to see why.

        When in doubt, ask me about it.

                ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
        

        Procedure Ordinal Number Listing for KERNAL functions.


        '*' indicates a handy function.
        If the procedure 'doesnt exist' theres a chance it may be an
        undocumented API.

        01h     -       FatalExit
        02h     -       ExitKernal
        03h     -       GetVersion
        04h     -       LocalInit
        05h     -       LocalAlloc
        06h     -       LocalRealloc
        07h     -       LocalFree
        08h     -       LocalLock
        09h     -       LocalUnlock
        0ah     -       LocalSize
        0bh     -       LocalHandle
        0ch     -       LocalFlags
        0dh     -       LocalCompact
        0eh     -       LocalNotify
        0fh     -       GlobalAlloc

        10h     -       GlobalRealloc
        11h     -       GlobalFree
        12h     -       GlobalLock
        13h     -       GlobalUnlock
        14h     -       GlobalSize
        15h     -       GlobalHandle
        16h     -       GlobalFlags
        17h     -       LockSegment                     *
        18h     -       UnlockSegment
        19h     -       GlobalCompact
        1ah     -       GlobalFreeAll
        1bh     -       ??? Doesnt exist ???
        1ch     -       GlobalMasterHandle
        1dh     -       Yield
        1eh     -       WaitEvent
        1fh     -       PostEvent

        20h     -       SetPriority
        21h     -       LockCurrentTask
        22h     -       SetTaskQueue
        23h     -       GetTaskQueue
        24h     -       GetCurrentTask
        25h     -       GetCurrentPDB
        26h     -       SetTaskSignalProc
        27h     -       ??? Doesnt exist ???
        28h     -       ??? Doesnt exist ???
        29h     -       EnableDos
        2ah     -       DisableDos
        2bh     -       ??? Doesnt exist ???
        2ch     -       ??? Doesnt exist ???
        2dh     -       LoadModule
        2eh     -       FreeModule
        2fh     -       GetModuleHandle

        30h     -       GetModuleUsage
        31h     -       GetModuleFileName
        32h     -       GetProcAddress
        33h     -       MakeProcInstance
        34h     -       FreeProcInstance
        35h     -       CallProcInstance
        36h     -       GetInstaceData
        37h     -       Catch
        38h     -       Throw
        39h     -       GetProfileInt
        3ah     -       GetProfileString
        3bh     -       WriteProfileString
        3ch     -       FindResource
        3dh     -       LoadResource
        3eh     -       LockResource
        3fh     -       FreeResource

        40h     -       AccessResource
        41h     -       SizeofResource
        42h     -       AllocResource
        43h     -       SetResourceHandler
        44h     -       InitAtomTable
        45h     -       FindAtom
        46h     -       AddAtom
        47h     -       DeleteAtom
        48h     -       GetAtomName
        49h     -       GetAtomHandle
        4ah     -       OpenFile
        4bh     -       OpenPathName
        4ch     -       DeletePathName
        4dh     -       Reserved1
        4eh     -       Reserved2
        4fh     -       Reserved3

        50h     -       Reserved4
        51h     -       _lclose                         *
        52h     -       _lread                          *
        53h     -       _lcreat                         *
        54h     -       _llseek                         *
        55h     -       _lopen                          *
        56h     -       _lwrite                         *
        57h     -       Reserved5
        58h     -       lstrcpy
        59h     -       lstrcat
        5ah     -       lstrlen
        5bh     -       InitTask
        5ch     -       GetTempDrive
        5dh     -       GetCodeHandle
        5eh     -       DefineHandleTable
        5fh     -       LoadLibrary

        60h     -       FreeLibrary
        61h     -       GetTempFileName
        62h     -       GetLastDiskChange
        63h     -       GetLPErrMode
        64h     -       ValidateCodeSegments
        65h     -       NoHookDosCall
        66h     -       Dos3Call                        *
        67h     -       NetBIOSCall
        68h     -       GetCodeInfo
        69h     -       GetExeVersion
        6ah     -       SetSwapAreaSize
        6bh     -       SetErrorMode
        6ch     -       SwitchStackTo
        6dh     -       SwitchStackBack
        6eh     -       PatchCodeHandle
        6fh     -       GlobalWire

        70h     -       GlobalUnwire
        71h     -       __AHShift
        72h     -       __AHinCR
        73h     -       OutputDebugString
        74h     -       InitLib
        75h     -       OldYield
        76h     -       GetTaskQueueDS
        77h     -       GetTaskQueueES
        78h     -       UndefDynLink
        79h     -       LocalShrink
        7ah     -       IsTaskLocked
        7bh     -       KbDrSt
        7ch     -       EnableKernal
        7dh     -       DisableKernal
        7eh     -       MemoryFreed
        7fh     -       GetPrivateProfileInt

        80h     -       GetPrivateProfileString
        81h     -       WritePrivateProfileString
        82h     -       FileCDR
        83h     -       GetDosEnvironment
        84h     -       GetWinFlags
        85h     -       GetExePtr
        86h     -       GetWindowsDirectory
        87h     -       GetSystemDirectory
        88h     -       GetDriveType
        89h     -       FatalAppExit
        8ah     -       GetHeapSpaces
        8bh     -       Dosignal
        8ch     -       SetSigHandler
        8dh     -       InitTask1
        8eh     -       ??? Doesnt exist ???
        8fh     -       ??? Doesnt exist ???

        90h     -       ??? Doesnt exist ???
        91h     -       ??? Doesnt exist ???
        92h     -       ??? Doesnt exist ???
        93h     -       ??? Doesnt exist ???       
        94h     -       ??? Doesnt exist ???
        95h     -       ??? Doesnt exist ???
        96h     -       Directed Yield
        97h     -       WinOldApCall
        98h     -       GetNumTasks
        99h     -       ??? Doesnt exist ???
        9ah     -       ??? Doesnt exist ???
        9bh     -       GetTaskDS
        9ch     -       LimitEMSPages
        9dh     -       GetCurPID
        9fh     -       GlobalHandleNoRip

        0a0h    -       EMSCopy
        0a1h    -       LocalCountFree
        0a2h    -       LocalHeapSize
        0a3h    -       GlobalLRUOldest
        0a4h    -       GlobalLRUNewest
        0a5h    -       A20Proc
        0a6h    -       WinExec
        0a7h    -       GetExpWinVer
        0a8h    -       DirectResAlloc
        0a9h    -       GetFreeSpace
        0aah    -       AllocCStoDSAlias                *
        0abh    -       AllocDStoCSAlias                *
        0ach    -       AllocAlias                      *
        0adh    -       __ROMBIOS
        0aeh    -       __a000h
        0afh    -       AllocSelector                   *

        0b0h    -       FreeSelector                    *
        0b1h    -       PrestoChangoSelector            *
        0b2h    -       __winflags
        0b3h    -       __d000h
        0b4h    -       LongPtrAdd
        0b5h    -       __b000h
        0b6h    -       __b800h
        0b7h    -       __0000h
        0b8h    -       GlobalDosAlloc                  *
        0b9h    -       GlobalDosFree                   *
        0bah    -       GetSelectorBase                 *
        0bbh    -       SetSelectorBase                 *
        0bch    -       GetSelectorLimit                *
        0bdh    -       SetSelectorLimit                *
        0beh    -       __e000h
        0bfh    -       GlobalPageLock

        0c0h    -       GlobalPageUnlock
        0c1h    -       __0040h
        0c2h    -       __f000h
        0c3h    -       __c000h
        0c4h    -       SelectorAccessRights            *
        0c5h    -       GlobalFix
        0c6h    -       GlobalUnfix
        0c7h    -       SetHandleCount
        0c8h    -       ValidateFreeSpaces
        0c9h    -       ReplaceInst
        0cah    -       RegisterPtrAce
        0cbh    -       DebugBreak
        0cch    -       SwapRecording
        0cdh    -       CvwBreak
        0ceh    -       AllocSelectorArray
        0cfh    -       IsDBCSLeadByte

        0d0h    -       ??? Doesnt exist ???
        0d1h    -       ??? Doesnt exist ???

        0e0h    -       ??? Doesnt exist ???

        0f0h    -       ??? Doesnt exist ???

                
                ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ


- VLAD #5 INDEX -

ARTICLE.1_1      

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

ARTICLE.2_1      

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

ARTICLE.3_1      

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

ARTICLE.4_1      

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

ARTICLE.5_1      

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

About VLAD - Links - Contact Us - Main