2.1 Windows API Call Flow

The Windows operating system provides services by exposing APIs implemented in DLLs. An application uses the service by calling the API implemented in the DLL. Most API functions end up calling the system service routine in the ntoskrnl.exe (kernel executive). In this section, we will examine what happens when an application calls an API, and how the API ends up calling the system service routines in ntoskrnl.exe (executive). Specifically, we will look at what happens when an application invokes the WriteFile() API. The following diagram gives a high-level overview of the API call flow:

  1. When a process is invoked by double-clicking a program, the process executable image and all its associated DLLs are loaded into the process memory by the Windows loader. When a process starts, the main thread gets created, which reads the executable code from the memory and starts executing it. An important point to remember is that it is not the process that executes the code, it is the thread that executes the code (a process is merely a container for the threads). The thread that is created starts executing in the user-mode (with restricted access). A process may explicitly create additional threads, as required.
  2. Let's suppose that an application needs to call the WriteFile() API, which is exported by kernel32.dll. To transfer the execution control to WriteFile(), the thread has to know the address of WriteFile() in the memory. If the application imports WriteFile(), then it can determine its address by looking in a table of function pointers called the Import Address Table (IAT)as shown in the preceding diagram. This table is located in an application's executable image in the memory, and it is populated by the windows loader with the function addresses when the DLLs are loaded.

An application can also load a DLL during runtime by calling the LoadLibrary() API, and it can determine the address of a function within the loaded DLL by using the GetProcessAddress() API. If an application loads a DLL during runtime, then the IAT does not get populated.

  1. Once the thread determines the address of WriteFile() from the IAT or during runtime, it calls WriteFile(), implemented in kernel32.dll. The code in the WriteFile() function ends up calling a function, NtWriteFile(), exported by the gateway DLL, ntdll.dll. The NtWriteFile() function in ntdll.dll is not a real implementation of NtWriteFile(). The actual function, with the same name, NtWriteFile() (system service routine), resides in ntoskrnl.exe (executive), which contains the real implementation. The NtWriteFile() in ntdll.dll is just a stub routine that executes either SYSENTER (x86) or SYSCALL (x64) instructions. These instructions transition the code to the kernel mode.
  2. Now, the thread running in kernel mode (with unrestricted access) needs to find the address of the actual function, NtWriteFile()implemented in ntoskrnl.exe. To do that, it consults a table in the kernel space called the System Service Descriptor Table (SSDT) and determines the address of NtWriteFile(). It then calls the actual NtWriteFile() (system service routine) in the Windows executive (in ntoskrnl.exe), which directs the request to the I/O functions in the I/O manager. The I/O manager then directs the request to the appropriate kernel-mode device driver. The kernel-mode device driver uses the routines exported by HAL to interface with the hardware.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
13.58.39.23