336 lines
13 KiB
Plaintext
336 lines
13 KiB
Plaintext
|
|
|||
|
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!
|
|||
|
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
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.
|
|||
|
|
|||
|
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
|
|||
|
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.
|
|||
|
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
|
|||
|
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 ???
|
|||
|
|
|||
|
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
|