Finding addresses of Windows functions
Executing a Windows function is more complicated than executing a
syscall in
Linux because Linux syscalls are simply numbered.
However, on Windows, in order to execute a Windows function, one must first load the DLL that contains the function and then determine the address of the function wihtin this DLL.
One DLL that is loaded for all processes is kernel32.dll. This DLL exhibits the functions that are needed to determine function addresses: LoadLibrary
and GetProcAddress
.
Thus, the recipe to execute
WinAPI functions is roughly:
- Get the base address of kernel32.dll
- Determine the address of
GetProcAddress
.
- Determine the address of
LoadLibrary
using GetProcAddress
.
- Load one of the WinAPI DLLs (e.g. user32.dll)
- Determine the address of the desired WinAPI function, again using
GetProcAddress
.
- Push and/or load the function parameters
- Call the address that was previously obtained.
kernel32.dll
kernel32.dll starts with MZ\x90. The default kernel32.dll base address is dependent on the OS:
- NT: 0x77f00000
- 2kSP2/2kSP3: 0x77fe80000
- WinXP: 0x77e60000
Thus, the start of kernel32 might be found be starting in 0x77f00000 and searching backward for MZ\x90.
However, an easier way to get the addresses of GetProcAddress
and LoadLibrary
is to look them up in the Process Environment Block (PEB) where they are stored.
In the 32-bit
WinAPI, the PEB is found at
[fs:30h]
, in the 64-bit version at
[gs:60h]
.