Calling the Native API directly is attractive for malware writers because it allows them to do things that might not otherwise be possible. There is a lot of functionality that is not exposed in the regular Windows API, but can be accomplished by calling the Native API directly.
Additionally, calling the Native API directly is sometimes stealthier. Many antivirus and host-protection products monitor the system calls made by a process. If the process calls the Native API function directly, it may be able to evade a poorly designed security product.
shows a diagram of a system call with a poorly designed security program monitoring calls to kernel32.dll. In order to bypass the security program, some hypothetical malware uses the Native API. Instead of calling the Windows functions ReadFile
and WriteFile
, this malware calls the functions NtReadFile
and NtWriteFile
. These functions are in ntdll.dll and are not monitored by the security program. A well-designed security program will monitor calls at all levels, including the kernel, to ensure that this tactic doesn’t work.
There are a series of Native API calls that can be used to get information about the system, processes, threads, handles, and other items. These include NtQuerySystemInformation
, NtQueryInformationProcess
, NtQueryInformationThread
, NtQueryInformationFile
, and NtQueryInformationKey
. These calls provide much more detailed information than any available Win32 calls, and some of these functions allow you to set fine-grained attributes for files, processes, threads, and so on.
Another Native API function that is popular with malware authors is NtContinue
. This function is used to return from an exception, and it is meant to transfer execution back to the main thread of a program after an exception has been handled. However, the location to return to is specified in the exception context, and it can be changed. Malware often uses this function to transfer execution in complicated ways, in order to confuse an analyst and make a program more difficult to debug.
We covered several functions that start with the prefix Nt
. In some instances, such as in the export tables of ntdll.dll, the same function can have either the Nt
prefix or the Zw
prefix. For example, there is an NtReadFile
function and a ZwReadFile
function. In the user space, these functions behave in exactly the same way, and usually call the exact same code. There are sometimes minor differences when called from kernel mode, but those differences can be safely ignored by the malware analyst.
Native applications are applications that do not use the Win32 subsystem and issue calls to the Native API only. Such applications are rare for malware, but are almost nonexistent for nonmalicious software, and so a native application is likely malicious. The subsystem in the PE header indicates if a program is a native application.