tklengyel / drakvuf

DRAKVUF Black-box Binary Analysis
https://drakvuf.com
Other
1.07k stars 255 forks source link

apimon for WoW64 turbo thunk #912

Open skvl opened 4 years ago

skvl commented 4 years ago

With dll-hooks-list.txt like this:

SysWOW64\ntdll.dll,NtGetContextThread,log,handle,pcontext
SysWOW64\ntdll.dll,NtSetContextThread,log,handle,pcontext
SysWOW64\kernel32.dll,GetThreadContext,log,handle,pcontext
SysWOW64\kernel32.dll,SetThreadContext,log,handle,pcontext

, I get the trace like this:

apimon Time=1591272472.445971,PID=196,PPID=1252,TID=2652,ProcessName="\Device\HarddiskVolume2\Users\John\Desktop\share\myapp.exe",Method=GetThreadContext,CalledFrom=0x1391FF8,ReturnValue=0x1,Arg0=0x40,Arg1=0x2bf8a0
...
apimon Time=1591272472.447604,PID=196,PPID=1252,TID=2652,ProcessName="\Device\HarddiskVolume2\Users\John\Desktop\share\myapp.exe",Method=SetThreadContext,CalledFrom=0x139213B,ReturnValue=0x1,Arg0=0x40,Arg1=0x2bf8a0

In the article WoW64 Internals one could read:

Turbo thunks are an optimalization of WoW64 subsystem - specifically on Windows x64 -
that enables for particular system calls to never leave the wow64cpu.dll - the conversion
of parameters and return value, and the syscall instruction itself is fully performed there.
The set of functions that use these turbo thunks reveals, that they are usually very simple
in terms of parameter conversion - they receive numerical values or handles.

Late in examples:

* NtMapViewOfSection uses turbo thunk with index 0 (TurboDispatchJumpAddressEnd)
* NtWaitForSingleObject uses turbo thunk with index 13 (Thunk3ArgSpNSpNSpReloadState)
* NtDeviceIoControlFile uses turbo thunk with index 27 (DeviceIoctlFile)

So apimon fails to catch such functions.

@tklengyel @icedevml what you think?

skvl commented 4 years ago

Theoretically it is possible to disable turbo thunks.

E.g. one could catch SysWOW64\ntdll.dll!NtWow64CallFunction64 and zero bits with turbo thunk index. Or it is possible to inject something like this:

#define WOW64_TURBO_THUNK_DISABLE 0
#define WOW64_TURBO_THUNK_ENABLE  1   // STATUS_NOT_SUPPORTED :(

    ThunkInput = WOW64_TURBO_THUNK_DISABLE;
    Status = NtWow64CallFunction64(Wow64FunctionTurboThunkControl,
                                   0,
                                   sizeof(ThunkInput),
                                   &ThunkInput,
                                   0,
                                   NULL,
                                   NULL);
icedevml commented 4 years ago

tbh I was completely not aware of that, I will try to investigate within next few days

skvl commented 4 years ago

@icedevml thank you very much!