监控系统调用、上下文切换、页错误等。
Hook system calls, context switches, page faults, DPCs and more. InfinityHook works along side Patchguard and VBS/Hyperguard to subtly hook various kernel events. InfinityHook is incredibly portable and stealthy, it works in all versions of Windows 7 to the latest versions of Windows 10.
InfinityHook stands to be one of the best tools in the rootkit arsenal over the last decade.
The sample in this repository is a kernel driver that will hook system calls for you. It is extremely easy to use and requires you to call a single API. Please read below for usage instructions. We leave it upon the reader to decipher the implementation details and create hooks for other events like context switches, page faults, and DPCs. The comments embedded in the source files can help you toward this task.
To use InfinityHook, simply reference the libinfinityhook library in your kernel driver and include infinityhook.h:
Call IfhInitialize. You will need to pass a function pointer to a user-defined routine:
NTSTATUS IfhInitialize(_In_ INFINITYHOOKCALLBACK InfinityHookCallback)
Your callback should be of this type:
typedef void (__fastcall* INFINITYHOOKCALLBACK)(_In_ unsigned int SystemCallIndex, _Inout_ void** SystemCallFunction);
Your InfinityHookCallback is invoked before the system executes the actual system call. The first argument passed to your callback handler is the system call index, and the second is a function pointer to the system call that is about to be invoked. You may choose to overwrite this function pointer, and the system will branch to the routine of your choosing instead. This allows you to receive all of its arguments. Ideally, you would save off the original routine pointed to by SystemCallFunction, so your hook can invoke the original at some point allowing you to monitor/filter the data.
To understand InfinityHook, a little background in ETW (Event Tracing for Windows) is helpful. ETW is a construct within the Windows kernel for logging and consuming a rather enormous amount of possible events. The three main components of this are controllers, providers, and consumers. A controller typically creates and defines a trace session. A trace session consists of a name, an identifier GUID, flags about how the kernel should serialize and prepare the data for consumers, and information about what providers are enabled for that session. A controller can also manage and modify existing built-in trace sessions. The main interface for a controller to do all of the aforementioned work is through the NtTraceControl API.
A provider gives event data to logger sessions. It's typically through the NtTraceEvent API or the kernel equivalent, EtwWrite. Based on how the session is setup by the controller, a consumer, which is previously aware of the event data, either consumes the data in real time, a file, or perhaps occasionally from a circular buffer.
To understand more on ETW internals, please read: https://docs.microsoft.com/en-us/windows/win32/etw/about-event-tracing
When a session is created, it has the opportunity to collect events from SystemTraceProvider, instead of collecting events from registered providers. A list of these events fired by SystemTraceProvider can be found here: https://docs.microsoft.com/en-us/windows/win32/etw/event-trace-properties
It should be of note that this is not the complete list. There are plenty of undocumented ones ;).
You'll probably notice that the list of items in EnableFlags is the same that InfinityHook allows you to hook. This is because each active logger session is put into an array of WMI_LOGGER_CONTEXT structures. They look like this:
…
Although not exported, this array is easily resolvable because a pointer to it exists right after EtwpDebuggerData, which interestingly enough can be signature scanned for Windows 7, 8, 8.1, and all the existing versions of Windows 10, using just a 5 byte signature: 0x2c, 0x08, 0x04, 0x38, 0x0c.
At +0x28 in the _WMI_LOGGER_CONTEXT structure, you can see a member called GetCpuClock. This is a function pointer that can be one of three values based on how the session was configured: EtwGetCycleCount, EtwpGetSystemTime, or PpmQueryTime. We simply overwrite this function pointer with a custom routine, but this is only half the battle.
First, we choose to hijack the circular kernel context logger session because it's always running by default. If not, we turn it on, and we configure it to log syscalls only, in a circular memory buffer.
After this, we walk up the stack to locate magic values, in order to filter out the fact that this is not a syscall exit being logged. We grab SystemCallNumber saved into the current _KTHREAD from logic in KiSystemCall64. The real magic here occurs because prior to KiSystemCall64 invoking PerfInfoLogSyscallEntry, it saves the resolved system call target pointer on the stack. We locate this pointer for you and, if you so choose, you are able to overwrite it in your handler.
The sample code provided is for system calls only, and as mentioned above, it's up to the reader to implement it for other events. This sample was also only quickly whipped up and tested for 1903 and 1803. The stack walk function may need to be tweaked for earlier Windows 10 builds and 7.
暂无开放 Issues,或尚未同步最近议题。