Обращение к 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 - ??? Не существует ???
-----------------------------------
|