From 116d1ede0cc0d5d57f593264251668531252c74b Mon Sep 17 00:00:00 2001 From: Egor Tensin Date: Wed, 6 May 2015 22:22:41 +0300 Subject: initial commit --- src/sysenter/main.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 src/sysenter/main.c (limited to 'src/sysenter/main.c') diff --git a/src/sysenter/main.c b/src/sysenter/main.c new file mode 100644 index 0000000..24d3ac4 --- /dev/null +++ b/src/sysenter/main.c @@ -0,0 +1,98 @@ +/** + * \file + * \author Egor Tensin + * \copyright This file is licensed under the terms of the MIT License. + * See LICENSE.txt for details. + */ + +#include + +static __int64 old_msr_value = 0; +static void *old_ki_fast_call_entry = NULL; + +static void __stdcall log_system_call() +{ + static LONG count = 0; + static const LONG throttle = 10000; + + LONG n = InterlockedIncrement(&count); + + if (n % throttle == 0) + DbgPrint("Another %ld of `sysenter`s (eax=)!\n", throttle); +} + +static void __declspec(naked) new_ki_fast_call_entry() +{ + __asm + { + pushad + pushfd + mov ecx, 0x23 + push 0x30 + pop fs + mov ds, cx + mov es, cx + call log_system_call + popfd + popad + jmp [old_ki_fast_call_entry] + } +} + +#define IA32_SYSENTER_EIP 0x176 + +static void hook_sysenter() +{ + /* + __asm + { + mov ecx, IA32_SYSENTER_EIP + rdmsr + mov old_ki_fast_call_entry, eax + mov eax, new_ki_fast_call_entry + xor edx, edx + wrmsr + } + */ + + old_msr_value = __readmsr(IA32_SYSENTER_EIP); + old_ki_fast_call_entry = (void *) old_msr_value; + __writemsr(IA32_SYSENTER_EIP, new_ki_fast_call_entry); +} + +static void unhook_sysenter() +{ + /* + __asm + { + mov ecx, IA32_SYSENTER_EIP + mov eax, old_ki_fast_call_entry + xor edx, edx + wrmsr + } + */ + + __writemsr(IA32_SYSENTER_EIP, old_msr_value); +} + +static void on_driver_unload(DRIVER_OBJECT *driver_object) +{ + KTIMER timer; + LARGE_INTEGER time_out; + + unhook_sysenter(); + + KeInitializeTimer(&timer); + time_out.QuadPart = -30000000; // 3 sec + KeSetTimer(&timer, time_out, NULL); + + KeWaitForSingleObject(&timer, Executive, KernelMode, FALSE, NULL); +} + +NTSTATUS DriverEntry(DRIVER_OBJECT *driver_object, + UNICODE_STRING *registry_path) +{ + driver_object->DriverUnload = on_driver_unload; + hook_sysenter(); + return STATUS_SUCCESS; +} -- cgit v1.2.3