Click here to Skip to main content
15,867,756 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I have a driver written in pure C and a application in .NET framework which is capable of sending and receiving IOCTL commands. Currently the driver is able to send Process Creation, Image Load Notify and Thread Notify callbacks to the .NET application without issue but now I would like to be able to suspend or wait for the process creation until the application/user allows the process to start or if the user wishes to block the process then it simply does not run. I would imagine there must be some event that needs to be written within the driver or check within the process creation callback to handle this kind of functionality. I have seen kewaitforsingleobject and other methods but its still foggy to me how to send this notification to usermode and then reply back to the driver what should or should not happen. Any insight or advise would be one step closer to learning how this is achieved as I am getting more and more confused with the MSDN examples and partial code snippets and how it fits my issue.

What I have tried:

Not sure what to try :(

Maybe IOCTL block and IOCTL allow to receive a value from User Mode application and set a Boolean value within the driver to check for within the processcreation callback? still I don't know how to have the process creation wait until a response is gained from the users decision so the process does not start or vise versa. Is it possible to start the process suspended from the processcreation callback and have the user mode application resume the main thread of that process to allow the process to run or terminate the process if block is selected?
Posted
Updated 30-May-22 5:40am
v7

1 solution

Hello,

You could block the process creation by setting the CreationStatus member in the PS_CREATE_NOTIFY_INFO structure[^] to access denied in your callback.

I want to tell you that everything you are describing goes against Best Practices[^]. I would suggest that you look at other solutions.

There are better ways to prevent malware or unwanted processes from executing. You should consider blocking the process earlier. One of the first things that occurs during process creation is that the operating system maps the executable into memory. You should intercept it here.

You would want to filter IRP_MJ_ACQUIRE_FOR_SECTION_SYNCHRONIZATION[^] and look for PAGE_EXECUTE page protection. Block it at the file layer before it gets mapped into memory.

You should abandon your idea to kill the process after it's already running. Consider blocking it at the file layer.
 
Share this answer
 
v2
Comments
Dale Seeley 10-May-22 22:40pm    
Thank you Randor for bringing this to my attention I am not sure how I overlooked this with all the hours of research I've been doing but reading the PS_CREATE_NOTIFY_INFO link you have supplied is a structure and not a callback? how is this implemented into the driver if ProcessCreationNotifyEx is not the way and by that time the process is already loaded into memory? Will replacing my major function DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = IoControl; to IRP_MJ_ACQUIRE_FOR_SECTION_SYNCHRONIZATION make it possible to receive the callbacks at the file layer level? and to my original question how would I go about setting an event within all this and wait for response from my user mode application. I have heard inverted calls might be the answer but if there is a better way I am all ears.
Dale Seeley 10-May-22 23:38pm    
Actually I can see now that within my PsSetCreateProcessNotifyRoutineEx I do have PS_CREATE_NOTIFY_INFO and going to that definition shows the exact structure that you have posted here. Is this the file layer that you are speaking of? here is the code I have in that area:

void OnProcessNotify(PEPROCESS Process, HANDLE ProcessId, PPS_CREATE_NOTIFY_INFO CreateInfo)
{
UNREFERENCED_PARAMETER(Process);

if (CreateInfo) {
ProcId = HandleToUlong(ProcessId);
RtlCopyUnicodeString(&ImageP, CreateInfo->ImageFileName);
//DbgPrint("%d %wZ", ProcId, ImageP);
if (!CreateInfo->IsSubsystemProcess) {
CreateInfo->CreationStatus = STATUS_ACCESS_DISABLED_NO_SAFER_UI_BY_POLICY;
}
}
}

I was first wondering how this structure was called, a bit embarrassing seeing this now sorry Its painfully obvious I am not strong yet in C coding. So that brings me back to the MajorFunction IRP_MJ_ACQUIRE_FOR_SECTION_SYNCHRONIZATION as I understand this is the callback that is called when file operations occur:

NTSTATUS FsRtlRegisterFileSystemFilterCallbacks(
[in] _DRIVER_OBJECT *FilterDriverObject,
[in] PFS_FILTER_CALLBACKS Callbacks
);

So I pass in The DriverObject and PFS_FILTER_CALLBACKS which I found to be:

typedef struct _FS_FILTER_CALLBACKS {
ULONG SizeOfFsFilterCallbacks;
ULONG Reserved;
PFS_FILTER_CALLBACK PreAcquireForSectionSynchronization;
PFS_FILTER_COMPLETION_CALLBACK PostAcquireForSectionSynchronization;
PFS_FILTER_CALLBACK PreReleaseForSectionSynchronization;
PFS_FILTER_COMPLETION_CALLBACK PostReleaseForSectionSynchronization;
PFS_FILTER_CALLBACK PreAcquireForCcFlush;
PFS_FILTER_COMPLETION_CALLBACK PostAcquireForCcFlush;
PFS_FILTER_CALLBACK PreReleaseForCcFlush;
PFS_FILTER_COMPLETION_CALLBACK PostReleaseForCcFlush;
PFS_FILTER_CALLBACK PreAcquireForModifiedPageWriter;
PFS_FILTER_COMPLETION_CALLBACK PostAcquireForModifiedPageWriter;
PFS_FILTER_CALLBACK PreReleaseForModifiedPageWriter;
PFS_FILTER_COMPLETION_CALLBACK PostReleaseForModifiedPageWriter;
PFS_FILTER_CALLBACK PreQueryOpen;
PFS_FILTER_COMPLETION_CALLBACK PostQueryOpen;
} FS_FILTER_CALLBACKS, *PFS_FILTER_CALLBACKS;

How is this used to get notified at the file layer which you describe is better because it happens before the process or file is loaded into memory.
Dale Seeley 10-May-22 23:41pm    
Should I be using a minifilter driver or Kernel driver or will it make much difference?
[no name] 11-May-22 0:23am    
[My recommendations]
If your goal is to block process creation I would recommend a minifilter driver. You should want to catch it *before* it executes from the file level.

Code samples are here: https://docs.microsoft.com/en-us/windows-hardware/drivers/samples/file-system-driver-samples

You would want to filter IRP_MJ_ACQUIRE_FOR_SECTION_SYNCHRONIZATION and look for anything being mapped into memory with PAGE_EXECUTE.

[Your current code]
With your current kernel driver you can set the CreationStatus in the PS_CREATE_NOTIFY_INFO structure to block the process creation.

[Your question about event objects]
Your question about events... I would recommend creating an event in the 'Global Namespace' to signal between your malware driver/service.

https://docs.microsoft.com/en-us/windows/win32/termserv/kernel-object-namespaces

[Events between driver/usermode]
https://github.com/Microsoft/Windows-driver-samples/tree/master/general/event

There is a code sample for just about every scenario. Just keep experimenting/exploring and asking questions.
Dale Seeley 11-May-22 0:38am    
Thank you again for the quick response and time taken to help me out in my driver adventure. I agree with you that a minifilter driver would be best also now that I research it and take your advise but will my current code be sufficient or does my current code allow the process to load into memory?

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900