Windows Syscall logging from the kernel
Hi. I'm trying to log specific system calls (win32k) that are called in Windows 7. I've tried a couple of ways already. The first thing i tried was drstrace. It's the exact kind of output that I need ( Function Name, Paramters, and return value ), but not all the system calls are getting logged. I'm not 100% sure why this happens but system calls like NtGdiSet~ types are called at once using NtGdiFlush, so these system calls cannot be captured at the user level.
Next I tried logman and xperf, and these seem log those functions drstrace couldn't but they do not resolve system call names (this is not such a big deal actually), and they don't log parameters. And also it does log the return value of the system call but it does not match from which call the return value came from and this is kind of a big deal.
I've thought of building a driver to hook functions at the kernel level, but I've never developed a driver and it didn't work out very well..
So I want to ask if there already is program that can do this or how can i build a driver that can log what I want?
Related
I read here that the inverse is possible, but how does one achieve such a thing? I'd hope there's a simple way, similar to calling from a loaded DLL, but my google research comes up with nothing. My only other thought is that one could pass some predefined constants through WriteFile or DeviceIoControl that the driver parses like a switch statement to execute the relevant function; does a more direct method exist?
The question is why would you want to do it? Generally if you have to rely on some mechanism like this, you need to revisit the design of the application/driver that you are writing.
The correct way to do something in context of your user mode application is exactly what you described. You can do a DeviceIoControl call to your driver and the driver validates all the parameters that you have passed, then carries out the operation on behalf of the user mode call.
If for some reason, you need to call into kernel directly, you will have to resort to undocumented methods. There are ways to hook into kernel dispatch table and overwrite one of the dispatch handler to redirect the call to your function. But I hope you never ever ship anything like this to your customer. This is good for learning how the dispatch table works, etc but introduces several security nightmares. Ultimately your software should not be responsible for someone's machine getting hacked.
I'm working on a way to hook any API call to perform some verification on the function. (I'm creating a SandBox)
The first way that I think about, is with register key, and implement our own dll into MicrosoftNT to be able to redirect any defined syscall. https://www.apriorit.com/dev-blog/160-apihooks .
Problem? only work on 32 bit, and if the binarie is loading User32.dll, so it's abig issue.
The second way is to inject a dll into a process? Simple but impossible, most program is defended from those injection, so it's not possible.
The last way that I think was to modify the SSDT to change the function address by mine and redirect to the original by creating a driver. Or by InlineHook and just modify the first byte of each address that I want.
The Problem, only working on 32 bit, because windows add a PatchGuard on the Kernel, so we can't do that.
We can delete de PatchGuard but, anticheat will notice the technique.
For the Sandbox I think it won't be a problem to delete a PatchGuard.
The main problem is for real time analysis, I have no more idea how I can do to hook every API call that I want, on any windows OS. I mean on 32 and 62 bit.
I'm a beginner in this domain I started this week so I'm open to any suggestion.
You say you want to hook every API call for a sandbox but then reference the SSDT? Those are two very different things. Do you want to hook VirtualQuery(Ex) or do you want to hook NtQueryVirtualMemory? From kernel or user mode? Or maybe you're referring to all loaded module exports as well as kernel system services?
WinApi
Iterate all loaded modules as well as installing an event to hook all future modules loaded. For each one you will iterate all exports and apply a hook of your preference which all jump to some handler. This handler should be raw assembly that preserves the CPU state, calls some method that does the logging and filtering, restores CPU state, before finally jumping to the original.
Syscalls
Disable Patchguard and apply hooks to every method in the service table similar to the WinApi method described above. This is definitely not suitable for production for obvious reasons.
Use an instrumentation callback which uses ZwSetInformationProcess to redirect most syscalls to an arbitrary assembly block. You can extract the syscall id here as well as parameters. Universal support is an issue though as it wasn't introduced until W7 iirc and you have a lot of limitations prior to W10.
Map a wrapper module that has a hook for every syscall into each newly loaded process from kernel. These hooks will apply to ntdll and simply invoke an NtDeviceIoControlFile call with the syscall id and arguments, forwarding it to your kernel driver for processing. This is commonly employed by antivirus software to monitor user mode system calls without disrupting Patchguard.
The most approved method would probably be callbacks. You can register process and thread callbacks in kernel, stripping handle access at your leisure. This will give you full control over process and thread access from external processes, and you can add a file minfilter to similarly restrict access to the file system.
Is this based on context switching that schedules processes on the cpu? Im a bit lost with understand how this works
system call is not context switch based. context switch is exchange of process running on cpu. which call is going to be used is decided on the system call number which is used as index in system call table. only process context is changed from user to kernel. I always suggest for reading understanding linux kernel an excellent book
I need to know if there is anyway to redirect some data of a system call (like for copy_file() with parameters such as old path, new path, etc.) to a log file for each and every time that function will be invoked.
https://github.com/timdiels/sysintercept
"sysintercept allows you to intercept and modify win32 system calls done by a process. sysintercept provides a CLI. Aim is to allow rewriting paths, translating keyboard input, ... various things for improved compatibility."
If you want to know how to intercept system calls yourself programmatically, you can inspect the source code.
For Windows, there is Process Monitor (ProcMon) tool which logs system calls such as File I/O.
http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx
I'm developing a driver that hooks some functions in windows (hardening driver that will block some actions). The problem is, that I want to log which was the user who attempted to run those actions.
For example, I've put an hook on ZwSetValueKey in order to filter registry writing.
The hook works perfectly, But I don't know how to get the caller SID. I've found out that I can determine whether the mode of the caller(i.e. user mode or kernel mode) using ExGetPreviousMode. But I'm not really sure how to determine the SID if the caller was in user mode.
Thanks.
If this were user mode, you'd start with GetCurrentProcess or GetCurrentThread, and then call GetProcessToken or GetThreadToken. This would get you an access token, from which the SID can be extracted directly. In kernel model, there's PsGetCurrentProcess and ZwOpenProcessTokenEx, and the like for threads.
Here's the equivalent question for user space: How to get Calling-Process Windows User Access Token.
I haven't tested this, but I hope it gets you started.
VOID SeCaptureSubjectContext(Out PSECURITY_SUBJECT_CONTEXT) is probably the kernel-mode API you're looking for, at least if you have ntifs.h available.