ZF

          Обращение к Windows API на Языке Ассемблера
                       от Quark [VLAD]

             (Вольный перевод - (c) DrMad, 1998 )

    Если вы  еще  не читали документ про Windows в VLAD#4 или не знаете
ничего про низкоуровневые структуры Windows,  то тут Вам нефига делать.

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

    Хотя я  разрабатывал этот документ с прицелом на написание вирусов,
я нигде раньше не встречал  подобной  информации,  так  что  это  может
спокойно  рассматриваться  как  текст  про  Windows  общего назначения.
Чувсвуйте себя свободно и не стесняйтесь.

    Я разработал свой "упорядоченный список процедур"  с использованием
дискового  редактора  для  упорядочивания "номеров процедур" в дисковом
файле, и с использованием дизассемблера для определения того, какой API
был создан.  Это заняло много часов. Я сделал это только для функций из
KERNEL,  потому что только они полезны  для  вирусов.  Если  вам  нужны
красивые  окошки  и  линейки  прокрутки,  то измените "индекс в таблице
ссылок на модули" так, чтобы он ссылался на GDI или USER и разработайте
свой собственный "упорядоченный список процедур".

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

    Чтобы составить параметры для доступа к API,  вам необходим листинг
API.  Эта  книжка  была  бы размером с телефонный справочник,  и я и не
собирался набирать ее,  так что  выдирайте  информацию  сами  из  своей
библиотеки.  Если вы можете, то имейте в виду, что книжка, о которой вы
думаете,  содержит перечисления функций  типа  "AllocCStoDSAlias".  Эти
функции  появились еще в Windows 3.1,  но раз они все еще остались,  то
должны быть перечислены.

    Все параметры,  передаваемые в API,  размещаются в стеке. Значения,
описанные  в  листинге API,  должны быть помещены в стек в определенном
порядке.  Любые возвращаемые данные передаются назад  в  AX,  если  это
слово,  и в DX:AX, если это двойное слово. (Я могу и ошибаться, но пока
это работает!)

    Например, моя  "Библия  Windows  API"   (которая   не   перечисляет
селекторы  функций  API) говорится про вызов функции "_lopen",  которая
открывает файл точно также, как int 21 AH=3dh:
    Синтаксис: int _lopen (LPSTR lppathname, int ireadwrite);
    Возвращаемое значение:  целый хэндл файла или -1 при ошиб-
ке.

    Давайте проанализируем синтаксис.

    Слово "int"  означает,  что  возвращаемое значение имеет целый тип,
который занимает слово,  и оно передается  в  AX.  Если  бы  тапм  было
написано   "long",   то   мы  должны  предполагать,  что  это  значение
возвращается в DX:AX.

    LPSTR - это указатель на строку,  кончающуюся  нулем  (так  говорит
книжка),  так что втолкните в стек сегмент, потом смещение имени файла,
который должен быть  открыт.  "IREADWRITE"  -  это  режим  открытия,  и
опытным путем установлено, что для режима чтения/записи нужно втолкнуть
в стек 2.


    Теперь перед  вами  полный  вызов  API-функции  fileopen ,  включая
подготовку параметров и обращение.

                ...
                push    ds      ;ds:dx=имя файла
                push    dx
                mov     ax,2    ;открыть в режиме чт/зап
                push    ax
        apicall:
                db      9ah     ;CALL FAr PTR
                dw      0ffffh  ;Это надо для Windows
                dw      0
                mov     bx,ax   ;Хэндл файла - в BX
                ...

    Блок параметров выглядит так:

                db      3    ;32-битный указатель
                db      1    ;Номер в Импорте
                dw      offset apicall + 1 ;Смещение до
                                           ;API-функции
                dw      1    ;Индекс в таблице ссылок на
                             ;модули в KERNAL.
                dw      55h  ;Означает вызов '_lopen'.
                             ;Это "порядковый номер процедуры"

    В блоке  параметров  я  предположил,  что KERNEL - первый элемент в
таблице ссылок на модули.  Это не всегда так. В вирусе вы должны искать
его.

    Я получил  '55h'  проверкой  нижеприведенной  таблицы.  "Порядковый
номер процедуры" показывает,  о какой функции API идет  речь.  Если  вы
заментие   '55h'   на  '56h',  то  получите  вызов  функции  '_lwrite'.
Посмотрите ниже - почему так.

    Если сомневаетесь - спросите меня.

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

    Список порядковых номеров функций KERNEL.

    '*' означает handy function.
    Если про процедуру сказано,  что "не существует", то, возможно, что
это просто недокументированная процедура.

        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     -       ??? Не существует ???
        1ch     -       GlobalMasterHandle
        1dh     -       Yield
        1eh     -       WaitEvent
        1fh     -       PostEvent

        20h     -       SetPriority
        21h     -       LockCurrentTask
        22h     -       SetTaskQueue
        23h     -       GetTaskQueue
        24h     -       GetCurrentTask
        25h     -       GetCurrentPDB
        26h     -       SetTaskSignalProc
        27h     -       ??? Не существует ???
        28h     -       ??? Не существует ???
        29h     -       EnableDos
        2ah     -       DisableDos
        2bh     -       ??? Не существует ???
        2ch     -       ??? Не существует ???
        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     -       ??? Не существует ???
        8fh     -       ??? Не существует ???

        90h     -       ??? Не существует ???
        91h     -       ??? Не существует ???
        92h     -       ??? Не существует ???
        93h     -       ??? Не существует ???
        94h     -       ??? Не существует ???
        95h     -       ??? Не существует ???
        96h     -       Directed Yield
        97h     -       WinOldApCall
        98h     -       GetNumTasks
        99h     -       ??? Не существует ???
        9ah     -       ??? Не существует ???
        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    -       ??? Не существует ???
        0d1h    -       ??? Не существует ???

        0e0h    -       ??? Не существует ???

        0f0h    -       ??? Не существует ???

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


(C) NF, 1998-2004