Windows Internals: APIs, Rings and System Calls
2022-06-13 Dawid Farbaniec

The application programming interface (API for short) in Windows is simply a set of functions contained in libraries, which are usually part of the system. They are exposed to developers so that they can use them in their programs. The old Windows API (also called Win32 API) consists of layers (similar to onion) and often some functions are "wrappers" on the lower (level of abstraction) calls. Basic functions are available in the libraries
It is worth noting that for some time the old Win32 API, programmed mainly in C language, is slowly replaced by the new interface called Windows Runtime (WinRT for short).
The most privileged level is the zero level in which the components critical for the operating system, such as drivers, work. The next two levels (ring 1 and ring 2) are of moderate privileges. On the other hand, the user level (ring 3) is a mode in which standard programs run that do not have direct access to critical system or hardware resources. In the documentation for AMD64 and Intel 64 processors, the current privilege level is abbreviated as
The hardware abstraction layer library is named
The functions provided by this library have the prefix
It is worth taking an interest in this library if one want to program drivers and create or analyze code running in the kernel mode.
This is done with the
With command
The
For comparison, one can display the internals of another function, for example:
The previous figures show what the system call looks like.
Please note that the system call numbers (the value passed via the
Hope you like this small tutorial.
kernel32.dll
and user32.dll
. For example: Someone creates a program that uses the Win32 API and needs to create a file. One can use the CreateFile
function for this purpose. But what happens inside the function? One will find there, among others different processor instructions, the call NtCreateFile
. The NtCreateFile
function is in the ntdll.dll
library and is abstractly lower than the Win32 API, and the set of functions prefixed with Nt
contained therein are named Native API. This interface is the bridge between the user's applications and the guts of Windows. The Native API also contains kernel mode (ring 0) elements such as the Zw
prefix function versions (for example: ZwCreateFile
). They are used when developing kernel mode programs.

It is worth noting that for some time the old Win32 API, programmed mainly in C language, is slowly replaced by the new interface called Windows Runtime (WinRT for short).
Privilege Levels (Rings)
The architecture of the Windows system isolates user programs from those running in the kernel mode. This is possible thanks to the security features implemented in the processor, which provide four levels of privilege (rings) for the executed code.
The most privileged level is the zero level in which the components critical for the operating system, such as drivers, work. The next two levels (ring 1 and ring 2) are of moderate privileges. On the other hand, the user level (ring 3) is a mode in which standard programs run that do not have direct access to critical system or hardware resources. In the documentation for AMD64 and Intel 64 processors, the current privilege level is abbreviated as
CPL
(Current Privilege Level). It can be read from the code segment (CS
) register.

Hardware Abstraction Layer (HAL)
HAL's task is, inter alia, hiding details of the implementation of hardware and device support, which increases code portability and provides an interface for communication with the hardware and services of the Windows kernel.
The hardware abstraction layer library is named
HAL.DLL
and is located in the directory:
%WINDOWS%\System32\hal.dll
The functions provided by this library have the prefix
Hal
, for example: HalExamineMBR
.
It is worth taking an interest in this library if one want to program drivers and create or analyze code running in the kernel mode.
System Calls (SYSCALL)
As the Native API is a bridge between user mode (ring 3) and kernel mode (ring 0), it should include some mechanism for forwarding calls to the kernel.This is done with the
SYSCALL
processor instruction. And the best explanation is to look to the inside of the selected Native API function. The sample program may be the system calculator.

With command
u ntdll!NtCreateFile
it is possible to display the internals of the NtCreateFile
function in the Assembly language. The disassembly is shown below.

The
u
command in the WinDbg tool allows one to disassemble, receive a listing in the Assembly language of the selected code fragment (for example: a function or an address in memory). Inside the function NtCreateFile
one can notice, among others:
- passing the argument from the
RCX
register toR10
(theSYSCALL
instruction destroys the contents of theRCX
register), - passing the call number to the
EAX
register (here55h
), - checking instructions (
TEST
,JNE
), - system call via
SYSCALL
instruction, - (...)
For comparison, one can display the internals of another function, for example:
NtQuerySystemInformation
. Here, the SYSCALL
call number in the EAX
register is 36h
.

The previous figures show what the system call looks like.
Please note that the system call numbers (the value passed via the
EAX
register) may change with Windows versions, as they are internal mechanisms and compatibility is not required here. For application developers, there is a Win32 API, while the Native API and SYSCALL
mechanism are used by specialized programs that require it or computer viruses.
Hope you like this small tutorial.
Bibliography
Chris Anley, John Heasman, Felix FX Linder, Gerardo Richarte, 2007 – The Shellcoder’s Handbook, ISBN: 9780470080238https://docs.microsoft.com/en-us/windows/uwp/get-started/universal-application-platform-guide#how-the-universal-windows-platform-relates-to-windows-runtime-apis [access: 2020-08-23]
https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/u--unassemble- [access: 2020-08-31]