Intercepting process execution in a NT driver - windows

I have developed a driver for Windows XP which is able to monitor the execution of processes.
A callback function receives the notifications using standard WDK API (PsSetCreateProcessNotifyRoutine).
The driver then decides if the process should be authorized or not; if not, it must block its execution/kill it.
What is the cleanest way to intercept execution that way? I do not mind if it is not documented, but I would rather not resort to hooking, if possible.

Ok, according to this document:
http://download.microsoft.com/download/4/4/b/44bb7147-f058-4002-9ab2-ed22870e3fe9/Kernal%20Data%20and%20Filtering%20Support%20for%20Windows%20Server%202008.doc
I need to install a minifilter for IRP_MJ_ACQUIRE_FOR_SECTION_SYNCHRONIZATION and check for PageProtection == PAGE_EXECUTE.

PsSetCreateProcessNotifyRoutineEx (Vista+) will allow you to cause the process-creation operation to fail by changing the CreateInfo->CreationStatus member to an NTSTATUS error code.

Related

How to prevent my process from CreateToolhelp32Snapshot?

Is there a way to prevent another process from detecting my process by using CreateToolhelp32Snapshot?
If you are in a environment where you need to protect users from themselves then these users need to be non-admin users and you can simply create a service or task that runs as a different user so it cannot be killed.
If you absolutely need to hide the process and your chosen method is injection & hooking then there are at least 6 things you need to hook in user-mode:
The toolhelp API
The NT4 process API in psapi.dll
The undocumented native NT API
The terminal server API
Performance counters
WMI
A "better" solution is to remove your process from the PsActiveProcessHead list but you need to be in kernel-mode to do that and that means writing a custom driver. If you go down this route your program will be labeled as malware/rootkit by some security tools (and rightly so).

Receiving DMLERR_POSTMSG_FAILED when calling DdeClientTransaction() with XTYP_POKE

Put on your wayback hats...
I have to use DDE (sorry, absolutely no choice in this) to communicate with an industrial control system. The control system is the DDE server and runs on the same Windows 7 PC as my DDE client. The client uses MfcDDE as it's interface which in turn makes calls to the DdeClientTransaction() functions.
The DDE advise operations work as expected after calling MfcDDE to establish them with DdeClientTransaction(XTYP_ADVSTART). All data points of interest are successfully read through the advice mechanism.
Unfortunately, attempts to write data through the DdeClientTransaction(XTYP_POKE) function fails. Within my client, DdeGetLastError() returns DMLERR_INVALIDPARAMETER (16390 0x4006). Interestingly, DDESpy (yes, I am that desparate) is reporting DMLERR_POSTMSG_FAILED (16396 0x400C).
The client worked in its initial NT implementation, but rebuilt and running under Win7, the XTYPE_POKE is failing. I've contemplated both security and threading as possibilities.
I've been unsuccessful finding a pointing gun for DDE security changes between NT and Win7.
If it matters, the DdeClientTransaction() call is being made in a thread started with WinMain() calling through to AfxWinMain() and CDialog::DoModal() to get to client's functional code.
Thanks for any help you can provide...
Confirmed that DdeClientTransaction(XTYP_POKE) can only be called on the same thread upon which DdeInitialize() was called. The restriction may actually be the same thread upon which DdeConnect() was called, but my money is on the DdeInitialize() since the returned DDEIdInst is passed to DdeConnect(). I could be wrong.
Thanks for letting me work through this with you guys... :)

Start and monitor multiple instances of one process in Windows

I have a Windows application of which I need multiple instances running, with different command line parameters. The application is quite unstable and tends to crash every 48 hours or so.
Since manual checking for failure and restarting in case of one isn't what I love to do I want to write a "manager program" for this. It would launch the program (all its instances) and then watch them. In case a process crashes it would be restarted.
In Linux I could achieve this with fork()s and pids, but this obviously is not available in Windows. So, should I try to implement a CreateProcess version or is there a better way?
When you call CreateProcess, you are returned a handle to the new process in the hProcess member of the process information struct that you pass to CreateProcess. You can use this handle to detect when the process terminates.
For instance, you can create another thread and call WaitForSingleObject(hProcess) and block until the process terminates. Then you can decide whether or not to restart it.
Or your could call GetExitCodeProcess(hProcess, &exitcode) and test exitcode. If it has the value STILL_ACTIVE then your process has not terminated. This approach based on GetExitCodeProcess necessitates polling.
If it can be run as a daemon, the simplest way to ensure it keep running is Non-Sucking Service Manager.
It will allow to run as win32 service applications not designed as services. It will monitor and restart if necessary. And the source code is included, if any customization is needed.
All you need to do is define each of your instances as a service, with the required parameters, at it will do the rest.
If you have some kind of security police limitation and can't use third party tools, then coding will be necessary. The answer from David Heffernan gives you the appropiate direction.
Or it can be done in batch, vbs or js without need of anything out of the system. WMI Win32_Process class should allow you to handle it.

How do I get the caller SID in kernel mode hook? (windows)

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.

GetThreadId on pre-vista systems?

Apperantly, GetThreadId is a Vista API. How can I get a thread's id on pre vista systems?
There are a few options:
When you call CreateThread, you get the handle back.
You can call GetCurrentThreadId to get the current thread's ID.
You can use Thread32First/Thread32Next to enumerate threads.
If you can somehow make the thread in question call GetCurrentThreadId and store it somewhere, you could read the result.
If the thread in question enters an alertable wait state frequently, you could send it an APC with QueueUserAPC; the APC handler can then call GetCurrentThreadId and communicate the result back to the caller using whatever method you like.
You can also do this with undocumented NT functions. Using NtQueryInformationThread() on the ThreadBasicInformation class will give you the thread ID in the returned structure. An example can be found in the wine source. However, I'm not sure what versions of windows this is available on - keep in mind these undocumented functions can change at any time, so it's best to test them on the older versions of windows you're interested in, and simply use GetThreadId() where it's available.
Note that these undocumented functions can only be accessed by LoadLibrary() and GetProcAddress() on NTDLL; they have no import library. According to MSDN, declarations for the data structures can be found in Winternl.h, but if not, just define them yourselves based on the ntinternals links above.

Resources