This entry was updated on March 14, 2015
A week or so ago I posted an article on CodeProject related to InstrumentationCallback and how this feature facilitates code instrumentation for important transitions, as well as works as an interesting anti-debug and analysis mechanism.
You can find the article here.
What I failed to mention in the article, is that while 32 bit processes running in the WOW64 layer can also make use of this functionality, they are left void of the KiRaiseUserExceptionDispatcher and system call transitions. This is not a major problem because under WOW64, system calls can still be instrumented in a number of interesting ways without kernel code. One of them being usage of the wow64log library. You can read more about that here.
Under WOW64, you can still instrument:
LdrInitializeThunk
KiUserExceptionDispatcher
KiUserApcDispatcher
KiUserCallbackDispatcher
Hi ! I do have several questions :
ReplyDelete- does the callback set into IntrumentationCallback is in ring0 or in the process (ring3) space ? I believe it is in ring3, am I correct ?
- once the callback is reached, does it have to go back to the kernel (if is in ring3 ?) ? Can it perform manipulation on a SYSCALL output or just be used in a code-coverage purpose ?
Thanks :)
hi,
ReplyDeleteyes you are correct, the linear address of the callback is meant to be in user-space.
for a system call, once the callback is reached it means the system service has finished it's execution, just as if you were reaching the return address following a syscall. So from there you would do whatever it is your tool does before branching to the actual return address. Like log it, manipulate return buffers, etc :)
WAW, this is quite powerfull !!! It works just like a SYSRET hook, really fun !
ReplyDeleteI did not find any information about this technique on the Internet, I don't understand why (well, okay, this is not undocumented).
Is this used by legitimate Microsoft processes in the wild ?
It could be, but not that I have seen.
ReplyDeleteNice find, everdox. I played with the "InstrumentationCallback" once before, but this was only for being an anti-Debug trick since it requires a privilege held by almost all debuggers which is automatically passed to child processes i.e. debuggees.
ReplyDeleteI reversed the "NtSetInformationProcess" and found out the following which might help:
1) The "ProcessInformationLength" must be 0x8
2) The calling Process must be holding the "SeDebugPrivilege" privilege for the call to succeed. #Anti-Debug Trick here.
3) The supplied "Instrumentation Callback" address must be canonical. Wouldn't it be for this check, executing SYSRET later would cause a #GP.
4) In case you are calling the "NtSetInformationProcess" function to set the "Instrumentation Callback" of another process, the process handle must have the "PROCESS_SET_INFORMATION" access right.
5) The Calling process and the target process must be both Wow64 or both Native64. Otherwise, an error STATUS_NOT_SUPPORTED will be returned.
6) In case of Wow64 Processes, the call ends up filling the "InstrumentationCallback" field of the 32Bit PEB (at offset 0x254), while in case of Native64 processes, the call ends up filling the "InstrumentationCallback" field of the target process's _KPROCESS object and setting the "instrumented" bit of each thread's _DISPATCHER_HEADER.
I am now using that as both ANTI-DEBUG + REDIRECTION trick, here it is.
http://pastebin.com/9TqRGsM5
POC:
http://goo.gl/iyvSl
Nice Blog by the way.