Monday, January 14, 2013

Call64, Bypassing Wow64 Emulation Layer

In this post i will discuss a piece of code that i wrote to ease the process of issuing 64-bit system calls without passing through the Wow64 emulation layer implemented in Wow64cpu.dll, Wow64.dll, and Wow64win.dll.


I implemented it in a function called "Call64()". Since some arguments in 64-bit system calls are 64 bits long, the "Call64()" function expects its arguments in the form of pointers to LARGE_INTEGER structures. Also, the return value is in the form of a pointer to a LARGE_INTEGER structure.


Let's take the implementation of this function step by step.

The first argument Call64 takes is a pointer to a LARGE_INTEGER structure which will receive the return value (RAX) of this system call. It is the caller's responsibility to allocate this structure. Also, it is the caller's responsibility to type-cast the value returned in it.

The second argument the function takes is the system call number or ordinal e.g. The "ZwWaitForSingleObject" function in Windows 7 has a system call number of 0x1.

This argument is later used to formulate the shellcode used to issue the 64-bit system call.


Since this function is supposed to make 64-bit system calls with different number of arguments, the function is implemented as variadic (A function with an indefinite number of arguments) with the third argument being the number of arguments the system call expects. The next arguments are all in the form of pointers to LARGE_INTEGER structures.

The function prototype is like below:

After we have looked at how the arguments look like, let's see how the function works.

First, given the number of arguments, it calculated the stack space needed and commits it using the "_alloca" function. The newly-allocated stack space is initialized to zero.

The function takes the first four arguments and stores them in RCX, RDX, R8, and R9 respectively. Extra arguments are stored on stack. Also, shadow space is taken care of.

Using the value of the 64-bit mode Code Segment selector, the function makes a Far Call to a 64-bit shellcode responsible for issuing the system call.


Suppose that we want to make a call to the "ZwClose" function using the "Call64" function, what you should do is allocate two LARGE_INTEGER structure, one to hold the value of the "Handle" parameter and the other to receive the return value (RAX). It looks like below.

Other example is the "ProcessConsoleHostProcess" class of the "ZwSetInformationProcess" function. If we trace into this call, we will find that the Wow64 emulation layer implemented in Wow64.dll prevents Wow64 processes from making such call and thus preventing them from changing their console host processes. See implementation of the "wow64!whNtSetInformationProcess" function.

The sole solution to this is to directly make the system call without passing through the Wow64 emulation layer. The call using the "Call64" function is like below.


N.B. You should bear in mind that some system calls expect pointer arguments to be aligned by 8 and this is why we should align them by using e.g. the "_aligned_malloc" function.


Source code and examples can be found here. The function has also been implemented in a Dynamic Link Library, you can find it and its header and .lib files here.

GitHub project from here.

Any comments, ideas, or bug reports are more than welcome.

You can follow me on Twitter @waleedassar

Friday, December 7, 2012

Windows Internals: SkipThreadAttach

In this post i will not present any new tricks but i will instead discuss a new issue introduced in later versions of Windows regarding thread creation.
In a previous post, i quickly explained the ntdll "NtCreateThreadEx" function and its flag HideFromDebugger 0x4 that when passed to the function causes the new thread to be created hidden from debuggers.

In this post we will see another interesting flag that i prefer to call it SuppressDllMains 0x2. Let's see this in disassembly.

As we can see in the image above, the "PspAllocateThread" function inspects the "Flags" parameter. If the SuppressDllMains 0x2 flag is set, then the function sets the "SkipThreadAttach 0x8" bit flag in the new thread's TEB.

Similarly for the 64-bit version of the function. If the "SuppressDllMains" flag is passed, then the "SkipThreadAttach 0x8" bit flag is set in both the 32-bit TEB and 64-bit TEB of the new thread.

N.B. The bit flags are at offset 0xFCA in 32-bit TEB's and at offset 0x17EE in 64-bit TEB's.

Now let's see what the "SkipThreadAttach" bit flag does. To track this, we will have to shift to user-mode.

In OllyDbg, search for the "\xCA\x0F" (0xFCA) in ntdll.dll and see which functions make use of the "SkipThreadAttach 0x8" bit flag.

The ntdll "RtlIsCurrentThreadAttachExempt" function was among the results i found.
This function returns false if the "SkipThreadAttach" bit flag is not set.
If the "SkipThreadAttach" bit flag is set, another bit flag "RanProcessInit 0x20" is tested. If not set, the function returns true. Otherwise, the function returns false. In C code it looks something like below.

Searching for all references to the "RtlIsCurrentThreadAttachExempt" function, i found one interesting place in ntdll.dll where this function is called, that is LdrpInitializeThread. 

The "LdrpInitializeThread" function is for calling the DllMain's of loaded dlls ( and TLS callbacks as well) each time a thread is initializing (with the "fdwReason" parameter set to DLL_THREAD_ATTACH) or is exiting (with the "fdwReason" parameter set to DLL_THREAD_DETACH).

Taking the "LdrpInitializeThread" function in disassembly, we can see that if  the ntdll "RtlIsCurrentThreadAttachExempt" function returns true e.g. due to the "NtCreateThreadEx" function being called with the "Flags" parameter set to SuppressDllMains 0x2, the DllMains and TLS callbacks of loaded modules will not be called in the context of the new thread. See image below.


A good example for this is the "DbgUiIssueRemoteBreakin" function in ntdll.dll of Windows 7. This function is called by the "DebugActiveProcess" function to create the attaching thread in the context of the process to be debugged.
In Windows XP, the thread created by the "DbgUiIssueRemoteBreakin" function caused the DllMains and TLS callbacks of loaded modules to be called, presenting another layer of protection against attaching.
In Windows 7, since the "DbgUiIssueRemoteBreakin" function ends up calling the "NtCreateThreadEx" function with the "Flags" parameter set to 0x2 (SuppressDllMains), no DllMain's or TLS callbacks are called for the debugger thread.

You can download the demo of this post from here and source code from here.

You can follow me on Twitter @waleedassar

Any comments or ideas are very welcome.