{"id":454,"date":"2010-05-17T01:46:52","date_gmt":"2010-05-17T01:46:52","guid":{"rendered":"https:\/\/driverentry.com.br\/en\/2010\/05\/17\/preventing-process-execution\/"},"modified":"2026-07-31T04:50:40","modified_gmt":"2026-07-31T04:50:40","slug":"preventing-process-execution","status":"publish","type":"post","link":"https:\/\/driverentry.com.br\/en\/2010\/05\/17\/preventing-process-execution\/","title":{"rendered":"Preventing Process Execution"},"content":{"rendered":"<div style=\"text-align: right;\"><a href=\"https:\/\/driverentry.com.br\/2010\/05\/17\/prevenindo-execucao-de-processos\/\"><img loading=\"lazy\" decoding=\"async\" title=\"Em Portugues\" src=\"https:\/\/driverentry.com.br\/en\/wp-content\/uploads\/2026\/07\/br.gif\" alt=\"\" width=\"21\" height=\"19\" \/><\/a><\/div>\n<p><img loading=\"lazy\" decoding=\"async\" style=\"float: right; padding: 0 0 5px 5px;\" src=\"https:\/\/driverentry.com.br\/en\/wp-content\/uploads\/2026\/07\/StopIcon.png\" alt=\"\" width=\"150\" height=\"151\" \/>During that long period when I was away from new posts on the blog, some things happened that deserved a little place here on my list of posts to write. <a href=\"http:\/\/groups.google.com\/group\/ccppbrasil\/browse_thread\/thread\/ace4f9312b8e5668#\">One of them<\/a> was the long discussion that took place on the <a href=\"http:\/\/groups.google.com\/group\/ccppbrasil\">C\/C++ group<\/a> list. It was about the steps to follow to write a driver that would do a bit of everything regarding security services. One of the items especially discussed was the idea of writing a driver that could prevent a certain process from being executed. Let me say right away that I am not going to get into whether this solves a security problem or not. I am not here to discuss that and, to be quite honest, I do not even want to. In this post I will demonstrate, in a very simple way, how we can prevent the execution of a process.<\/p>\n<h3>Tracking the lifetime of Processes<\/h3>\n<p>Before going around putting both feet on a process&#8217;s chest to make it fall, let&#8217;s first just see how to monitor its lifetime. This is easily done by calling the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ff559951(VS.85).aspx\">PsSetCreateProcessNotifyRoutine()<\/a> routine, which has been available since back when the rainbow was black and white. Although the documentation says it has been available since Windows 2000, I already know this routine from other carnivals and I know it has been around at least since the late Windows NT 3.51. Wow, I am getting old. But back to the subject, this routine registers a callback function that notifies our driver about the start and the end of processes in the system. This is especially useful if a certain driver wants to keep information related to processes; thus, knowing when a process has ended is essential to free the resources used by such information.<\/p>\n<div style=\"font-family: Courier New; font-size: 9pt; color: black; background: #A4F64C; border: 1px outset; padding: 0 0 0 5px;\">\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">NTSTATUS PsSetCreateProcessNotifyRoutine(<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">  __in  PCREATE_PROCESS_NOTIFY_ROUTINE NotifyRoutine,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">  __in  BOOLEAN Remove<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">);<\/pre>\n<\/div>\n<p>The callback function registered by this routine has the signature shown below:<\/p>\n<div style=\"font-family: Courier New; font-size: 9pt; color: black; background: #A4F64C; border: 1px outset; padding: 0 0 0 5px;\">\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">VOID<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">(*PCREATE_PROCESS_NOTIFY_ROUTINE) (<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    IN HANDLE  ParentId,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    IN HANDLE  ProcessId,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    IN BOOLEAN  Create<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    );<\/pre>\n<\/div>\n<p>Pretty simple, isn&#8217;t it? The first parameter is the <em>ProcessId<\/em> of the parent process in this creation. This means that, for example, if you start Notepad from <em>&#8220;Run&#8230;&#8221;<\/em> in the Windows Start menu, we will have <em>Explorer.exe<\/em> as the parent process of the new <em>Notepad.exe<\/em> process. The second parameter is the <em>ProcessId<\/em> of the process being started or ended at the time of the call. Last but not least, we have the flag that will indicate whether this is a start or an end notification for a process.<\/p>\n<p>One important thing to note here is about the parent process&#8217;s <em>ProcessId<\/em>. This parameter is reliable in process-start notifications, but not so much when it comes to termination. This happens because when a process is being started, its parent process is still there, safe and sound, but when a process ends, even though the <em>ParentId<\/em> carries the same value as the process-start notification, that data is no longer valid. Let me give an example to make it easier.<\/p>\n<ol>\n<li>Process1(32) creates Process2(57), we receive the call: CreateProcessNotifyRoutine(32, 57, TRUE);<\/li>\n<li>Process1(32) ends.<\/li>\n<li>Process3(32) is created and gets an Id equal to 32.<\/li>\n<li>Process2(57) ends and we receive the call: CreateProcessNotifyRoutine(32, 57, FALSE);<\/li>\n<\/ol>\n<p>In the termination notification for Process2 that occurred in step 4, the process whose Id is 32 is now Process3, which, by the way, is not really the parent process of Process2. So when you gather information about a process, do it during its initialization, keep this data in a list and then remove it when the process ends.<\/p>\n<p>Registering the callback function is very simple, but what really matters is removing this registration when the driver is unloaded. Can you imagine what would happen if one of these notifications were delivered to a driver that is no longer in memory? Well, I can.<\/p>\n<h3>Getting the path of a process image<\/h3>\n<p>It is likely that you want to obtain more information about the processes involved in these notifications; one such piece of information is the path of the file being executed. You can obtain this information using the Id of the processes we receive in the new-process notification. To do this, we will have to use the almost-documented <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms687420(VS.85).aspx\">ZwQueryInformationProcess()<\/a> routine. This is a native API that has existed forever but was never officially documented. To use it, just declare its signature as shown below.<\/p>\n<div style=\"font-family: Consolas; font-size: 9pt; color: black; background: #A4F64C; border: 1px outset; padding: 0 0 0 5px;\">\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">NTSTATUS<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">ZwQueryInformationProcess(IN HANDLE ProcessHandle,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                          IN PROCESSINFOCLASS ProcessInformationClass,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                          OUT PVOID ProcessInformation,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                          IN ULONG ProcessInformationLength,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                          OUT PULONG ReturnLength OPTIONAL);<\/pre>\n<\/div>\n<p>If you want to know more about undocumented native APIs, <a href=\"http:\/\/www.metasploit.com\/users\/opcode\/syscalls.html\">this link<\/a> is a huge help, but nothing beats <a href=\"http:\/\/www.amazon.com\/gp\/product\/1578701996\/ref=s9_simh_gw_p14_i1?pf_rd_m=ATVPDKIKX0DER&amp;pf_rd_s=center-2&amp;pf_rd_r=0TA5AKHBS2B9MS30G9VR&amp;pf_rd_t=101&amp;pf_rd_p=470938631&amp;pf_rd_i=507846\">this book<\/a>.<\/p>\n<p>The code below uses this API to obtain a process&#8217;s image from its Pid. Notice that <em>ZwQueryInformationProcess()<\/em> asks for a handle to the process you want to obtain information about. To obtain that handle we will first need to obtain the <strong>EPROCESS<\/strong> structure that represents a process in Kernel-Mode. We will do this using the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ff551920(VS.85).aspx\">PsLookupProcessByProcessId()<\/a> function, which will return a pointer to that structure.<\/p>\n<div style=\"font-family: Consolas; font-size: 9pt; color: black; background: #A4F64C; border: 1px outset; padding: 0 0 0 5px;\">\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">NTSTATUS PsLookupProcessByProcessId(<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">  __in   HANDLE ProcessId,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">  __out  PEPROCESS *Process<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">);<\/pre>\n<\/div>\n<p>Although opaque, this structure will allow us to obtain the handle to the process it represents, now using the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ff550985(VS.85).aspx\">ObOpenObjectByPointer()<\/a> function of the <strong>Object Manager<\/strong>.<\/p>\n<div style=\"font-family: Consolas; font-size: 9pt; color: black; background: #A4F64C; border: 1px outset; padding: 0 0 0 5px;\">\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">NTSTATUS ObOpenObjectByPointer(<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">  __in      PVOID Object,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">  __in      ULONG HandleAttributes,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">  __in_opt  PACCESS_STATE PassedAccessState,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">  __in      ACCESS_MASK DesiredAccess,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">  __in_opt  POBJECT_TYPE ObjectType,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">  __in      KPROCESSOR_MODE AccessMode,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">  __out     PHANDLE Handle<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">);<\/pre>\n<\/div>\n<p>I think everything will be easier to understand with the source below. After all, a line of code is worth more than a thousand words. The following function obtains the EPROCESS structure of a process, then obtains the handle to it, and with that handle obtains the information we want from the process. OK, OK, OK&#8230; Here is the source, but don&#8217;t forget to read the comments.<\/p>\n<div style=\"font-family: Consolas; font-size: 9pt; color: black; background: #A4F64C; border: 1px outset; padding: 0 0 0 5px;\">\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"><span style=\"color: green;\">\/****<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\"><span style=\"color: green;\">***     GetProcessImageName<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"><span style=\"color: green;\">**<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\"><span style=\"color: green;\">**      Returns a PUNICODE_STRING containing the path<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"><span style=\"color: green;\">**      of the image used by the process whose Pid was<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\"><span style=\"color: green;\">**      provided as a parameter.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"><span style=\"color: green;\">*\/<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">NTSTATUS<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">GetProcessImageName(HANDLE           hProcessId,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                    PUNICODE_STRING* ppusImageName)<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">{<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    NTSTATUS        nts;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    PUNICODE_STRING pusImageName = NULL;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    ULONG           ulSize;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    HANDLE          hProcess;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    PEPROCESS       pEProcess;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    <span style=\"color: green;\">\/\/-f--&gt; First of all, zero out the output variable.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    *ppusImageName = NULL;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    <span style=\"color: green;\">\/\/-f--&gt; Here we obtain the structure that represents a process<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    <span style=\"color: green;\">\/\/     (EPROCESS) from its Pid;<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    nts = PsLookupProcessByProcessId(hProcessId,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                                     &amp;pEProcess);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    <span style=\"color: blue;\">if<\/span> (!NT_SUCCESS(nts))<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        <span style=\"color: blue;\">return<\/span> nts;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    <span style=\"color: green;\">\/\/-f--&gt; Now we obtain a handle to this object.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    nts = ObOpenObjectByPointer(pEProcess,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                                OBJ_KERNEL_HANDLE,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                                NULL,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                                <span style=\"color: purple;\">0<\/span>,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                                *PsProcessType,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                                KernelMode,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                                &amp;hProcess);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    <span style=\"color: green;\">\/\/-f--&gt; Whether or not the handle was obtained,<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    <span style=\"color: green;\">\/\/      we will have to release the reference we obtained<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    <span style=\"color: green;\">\/\/      to the EPROCESS.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    ObDereferenceObject(pEProcess);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    <span style=\"color: blue;\">if<\/span> (!NT_SUCCESS(nts))<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        <span style=\"color: blue;\">return<\/span> nts;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    <span style=\"color: green;\">\/\/-f--&gt; Now that we have the handle to the process, we can<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    <span style=\"color: green;\">\/\/      obtain information about it; in this case,<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    <span style=\"color: green;\">\/\/      we will obtain the path of the process image.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    nts = ZwQueryInformationProcess(hProcess,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                                    ProcessImageFileName,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                                    NULL,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                                    <span style=\"color: purple;\">0<\/span>,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                                    &amp;ulSize);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    <span style=\"color: green;\">\/\/-f--&gt; To get the right size, we pass zero on the first<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    <span style=\"color: green;\">\/\/      attempt; this will return an error and the number<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    <span style=\"color: green;\">\/\/      of bytes needed to obtain this information.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    <span style=\"color: blue;\">if<\/span> (nts != STATUS_INFO_LENGTH_MISMATCH)<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        <span style=\"color: blue;\">return<\/span> nts;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    <span style=\"color: green;\">\/\/-f--&gt; The returned size includes the size of the UNICODE_STRING structure,<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    <span style=\"color: green;\">\/\/      so everything is allocated at once.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    pusImageName = (PUNICODE_STRING) ExAllocatePoolWithTag(PagedPool,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                                                           ulSize,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                                                           TRACER_TAG);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    <span style=\"color: green;\">\/\/-f--&gt; Oops! Close Photoshop and try again.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    <span style=\"color: blue;\">if<\/span> (!pusImageName)<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        <span style=\"color: blue;\">return<\/span> STATUS_INSUFFICIENT_RESOURCES;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    <span style=\"color: green;\">\/\/-f--&gt; Now we offer the buffer allocated with the right size.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    <span style=\"color: green;\">\/\/      What could go wrong? (EVERYTHING!)<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    nts = ZwQueryInformationProcess(hProcess,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                                    ProcessImageFileName,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                                    pusImageName,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                                    ulSize,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                                    &amp;ulSize);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    <span style=\"color: blue;\">if<\/span> (!NT_SUCCESS(nts))<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    {<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        <span style=\"color: green;\">\/\/-f--&gt; Oops! Something went wrong.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        ExFreePoolWithTag(pusImageName,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                          TRACER_TAG);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    }<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    <span style=\"color: blue;\">else<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    {<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        <span style=\"color: green;\">\/\/-f--&gt; All good so far. The caller is in charge<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        <span style=\"color: green;\">\/\/      of freeing the memory allocated here.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        *ppusImageName = pusImageName;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    }<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    <span style=\"color: blue;\">return<\/span> nts;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">}<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">&nbsp;<\/pre>\n<\/div>\n<p>With this routine it becomes easy to write the following callback function that will show us basic information about the processes started and ended.<\/p>\n<div style=\"font-family: Consolas; font-size: 9pt; color: black; background: #A4F64C; border: 1px outset; padding: 0 0 0 5px;\">\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"><span style=\"color: green;\">\/****<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\"><span style=\"color: green;\">***     OnCreateProcess<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"><span style=\"color: green;\">**<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\"><span style=\"color: green;\">**      Callback function that will be registered if this<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"><span style=\"color: green;\">**      driver is running on Windows Vista or earlier.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\"><span style=\"color: green;\">*\/<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">VOID<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">OnCreateProcess(HANDLE  hParentId,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                HANDLE  hProcessId,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                BOOLEAN bCreate)<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">{<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    <span style=\"color: green;\">\/\/-f--&gt; Here we check whether the event is about a creation<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    <span style=\"color: green;\">\/\/      or termination of a process.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    <span style=\"color: blue;\">if<\/span> (bCreate)<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    {<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        NTSTATUS        nts;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        PUNICODE_STRING pusImageName = NULL;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        <span style=\"color: green;\">\/\/-f--&gt; Gets the path of the image that was used by<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        <span style=\"color: green;\">\/\/      this process.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        nts = GetProcessImageName(hProcessId,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                                  &amp;pusImageName);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        <span style=\"color: blue;\">if<\/span> (NT_SUCCESS(nts))<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        {<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            <span style=\"color: green;\">\/\/-f--&gt; If the path was obtained successfully,<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            <span style=\"color: green;\">\/\/      it registers the process-start notification.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            DbgPrint(<span style=\"color: #a31515;\">\"[Process Tracer] Action = Starting\\n\"<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                     <span style=\"color: #a31515;\">\"                 Process Id = 0x%x\\n\"<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                     <span style=\"color: #a31515;\">\"                 Parent Id = 0x%x\\n\"<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                     <span style=\"color: #a31515;\">\"                 Image name = %wZ\\n\\n\"<\/span>,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                     hProcessId,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                     hParentId,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                     pusImageName);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            <span style=\"color: green;\">\/\/-f--&gt; Releases the allocated resources.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            ExFreePool(pusImageName);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        }<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    }<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    <span style=\"color: blue;\">else<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    {<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        <span style=\"color: green;\">\/\/-f--&gt; Registers the process-termination event.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        DbgPrint(<span style=\"color: #a31515;\">\"[Process Tracer] Action = Finishing\\n\"<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                 <span style=\"color: #a31515;\">\"                 Process Id = 0x%x\\n\"<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                 <span style=\"color: #a31515;\">\"                 Parent Id = 0x%x\\n\\n\"<\/span>,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                 hProcessId,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                 hParentId);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    }<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">}<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">&nbsp;<\/pre>\n<\/div>\n<p>With these functions working on a Windows XP, we will have the following output in the debugger.<\/p>\n<div style=\"font-family: Consolas; font-size: 9pt; color: black; background: #A4F64C; border: 1px outset; padding: 0 0 0 5px;\">\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">[Process Tracer] Action = Starting<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                 Process Id = <span style=\"color: #ff0000;\">0x35c<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                 Parent Id = <span style=\"color: #ff0000;\">0x694<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                 Image name = \\Device\\HarddiskVolume1\\WINDOWS\\system32\\notepad.exe<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">kd&gt; !process <span style=\"color: #ff0000;\">0x35c<\/span> 0<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">Searching for Process with Cid == 35c<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">Cid handle table at e1003000 with 380 entries in use<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">PROCESS 82100020  SessionId: 0  Cid: 035c    Peb: 7ffd7000  ParentCid: 0694<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    DirBase: 08840400  ObjectTable: e10d2400  HandleCount:  41.<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    Image: <span style=\"color: #ff0000;\">notepad.exe<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">kd&gt; !process <span style=\"color: #ff0000;\">0x694<\/span> 0<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">Searching for Process with Cid == 694<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">Cid handle table at e1003000 with 380 entries in use<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">PROCESS 821cc228  SessionId: 0  Cid: 0694    Peb: 7ffd6000  ParentCid: 0640<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    DirBase: 08840200  ObjectTable: e18df2a0  HandleCount: 365.<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    Image: <span style=\"color: #ff0000;\">explorer.exe<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">kd&gt; g<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">[Process Tracer] Action = Finishing<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                 Process Id = <span style=\"color: #ff0000;\">0x35c<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                 Parent Id = <span style=\"color: #ff0000;\">0x694<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">&nbsp;<\/pre>\n<\/div>\n<p>Right at the beginning I start the Notepad process from the <em>&#8220;Run&#8230;&#8221;<\/em> menu as I mentioned at the very beginning. After that I use WinDbg&#8217;s <strong>!process<\/strong> extension to obtain minimal information about the processes involved in this notification. Then I close Notepad, giving rise to the last message shown above.<\/p>\n<h3>A new API in Windows Vista SP1<\/h3>\n<p>All right, this is very cool, but we are here to talk about how to prevent a certain process from being executed. Preventing process execution in Windows Vista became child&#8217;s play with the new <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ff559953(VS.85).aspx\">PsSetCreateProcessNotifyRoutineEx()<\/a> routine, whose signature is listed right below:<\/p>\n<div style=\"font-family: Courier New; font-size: 9pt; color: black; background: #A4F64C; border: 1px outset; padding: 0 0 0 5px;\">\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">NTSTATUS PsSetCreateProcessNotifyRoutineEx(<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">  __in  PCREATE_PROCESS_NOTIFY_ROUTINE_EX NotifyRoutine,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">  __in  BOOLEAN Remove<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">);<\/pre>\n<\/div>\n<p>This routine registers a callback function that also notifies your driver about the start and end of processes in the system. The first parameter indicates the callback routine to be registered, while the second parameter indicates whether the routine should be registered or removed. Very similar to its older sister <em>PsSetCreateProcessNotifyRoutine().<\/em> The callback routine must have the following signature:<\/p>\n<div style=\"font-family: Courier New; font-size: 9pt; color: black; background: #A4F64C; border: 1px outset; padding: 0 0 0 5px;\">\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">VOID CreateProcessNotifyEx(<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">  __inout   PEPROCESS Process,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">  __in      HANDLE ProcessId,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">  __in_opt  PPS_CREATE_NOTIFY_INFO CreateInfo<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">);<\/pre>\n<\/div>\n<p>It is easy to see that the parameters of this callback function have changed quite a bit. To know whether the event is about the creation or the termination of a process, just check the <em>CreateInfo<\/em> parameter. If it is non-null, then it is about a new process being executed; otherwise, about its termination. Let&#8217;s take a look at this structure:<\/p>\n<div style=\"font-family: Courier New; font-size: 9pt; color: black; background: #A4F64C; border: 1px outset; padding: 0 0 0 5px;\">\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"><span style=\"color: blue;\">typedef<\/span> <span style=\"color: blue;\">struct<\/span> _PS_CREATE_NOTIFY_INFO {<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">  SIZE_T              Size;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">  <span style=\"color: blue;\">union<\/span> {<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    ULONG  Flags;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    <span style=\"color: blue;\">struct<\/span> {<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">      ULONG FileOpenNameAvailable  :<span style=\"color: purple;\">1<\/span>;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">      ULONG Reserved  :<span style=\"color: purple;\">31<\/span>;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    } ;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">  } ;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">  HANDLE              ParentProcessId;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">  CLIENT_ID           CreatingThreadId;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">  <span style=\"color: blue;\">struct<\/span> _FILE_OBJECT *FileObject;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">  PCUNICODE_STRING    ImageFileName;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">  PCUNICODE_STRING    CommandLine;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">  NTSTATUS            CreationStatus;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">} PS_CREATE_NOTIFY_INFO, *PPS_CREATE_NOTIFY_INFO;<\/pre>\n<\/div>\n<p>Yeah, it seems that life became much easier for those who want to seek greater detail about the processes involved in the notification. The great appeal of this new version is that we can prevent the creation of a process just by modifying the <em>CreationStatus<\/em> field. Just to exemplify this ease, I wrote the callback function below. Always read the comments.<\/p>\n<div style=\"font-family: Consolas; font-size: 9pt; color: black; background: #A4F64C; border: 1px outset; padding: 0 0 0 5px;\">\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"><span style=\"color: green;\">\/****<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\"><span style=\"color: green;\">***     OnCreateProcessEx<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"><span style=\"color: green;\">**<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\"><span style=\"color: green;\">**      Callback function that will be registered if this<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"><span style=\"color: green;\">**      driver is running on Windows Vista SP1 or later.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\"><span style=\"color: green;\">*\/<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">VOID<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">OnCreateProcessEx(PEPROCESS                 pEProcess,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                  HANDLE                    hProcessId,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                  PPS_CREATE_NOTIFY_INFO    pCreateInfo)<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">{<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    <span style=\"color: green;\">\/\/-f--&gt; Here we check whether the event is about a creation<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    <span style=\"color: green;\">\/\/      or termination of a process.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    <span style=\"color: blue;\">if<\/span> (pCreateInfo)<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    {<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        UNICODE_STRING  usBlockingApp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        <span style=\"color: green;\">\/\/-f--&gt; Since this is just an example, I am putting the file<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        <span style=\"color: green;\">\/\/      path hard coded here, but remember that references to<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        <span style=\"color: green;\">\/\/      file images may use HarddiskVolume1 or other<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        <span style=\"color: green;\">\/\/      variations that change depending on many things.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        RtlInitUnicodeString(&amp;usBlockingApp,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                             L<span style=\"color: #a31515;\">\"\\\\??\\\\C:\\\\Windows\\\\System32\\\\Notepad.exe\"<\/span>);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        <span style=\"color: green;\">\/\/-f--&gt; Comparing the image of the process that was just created<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        <span style=\"color: green;\">\/\/      with the path I used above.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        <span style=\"color: blue;\">if<\/span> (RtlEqualUnicodeString(&amp;usBlockingApp,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                                  pCreateInfo-&gt;ImageFileName,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                                  TRUE))<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        {<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            <span style=\"color: green;\">\/\/-f--&gt; All right, now it is time to grab the guy and show up terrifying:<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            <span style=\"color: green;\">\/\/      \"Hand it over, playboy!\"<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            DbgPrint(<span style=\"color: #a31515;\">\"[Process Tracer] Action = Blocking\\n\"<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                     <span style=\"color: #a31515;\">\"                 Process Id = 0x%x\\n\"<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                     <span style=\"color: #a31515;\">\"                 Parent Id = 0x%x\\n\"<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                     <span style=\"color: #a31515;\">\"                 Image name = %wZ\\n\\n\"<\/span>,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                     hProcessId,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                     pCreateInfo-&gt;ParentProcessId,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                     pCreateInfo-&gt;ImageFileName);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            <span style=\"color: green;\">\/\/-f--&gt; Changes the process-creation status so that<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            <span style=\"color: green;\">\/\/      it does not proceed.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            pCreateInfo-&gt;CreationStatus = STATUS_ACCESS_DENIED;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        }<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        <span style=\"color: blue;\">else<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        {<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            <span style=\"color: green;\">\/\/-f--&gt; It is not our \"man\"; let the process start normally.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">            DbgPrint(<span style=\"color: #a31515;\">\"[Process Tracer] Action = Starting\\n\"<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                     <span style=\"color: #a31515;\">\"                 Process Id = 0x%x\\n\"<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                     <span style=\"color: #a31515;\">\"                 Parent Id = 0x%x\\n\"<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                     <span style=\"color: #a31515;\">\"                 Image name = %wZ\\n\\n\"<\/span>,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                     hProcessId,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                     pCreateInfo-&gt;ParentProcessId,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                     pCreateInfo-&gt;ImageFileName);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        }<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    }<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    <span style=\"color: blue;\">else<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    {<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        <span style=\"color: green;\">\/\/-f--&gt; Here we just register the notification of the termination of<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        <span style=\"color: green;\">\/\/      a process.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        DbgPrint(<span style=\"color: #a31515;\">\"[Process Tracer] Action = Finishing\\n\"<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                 <span style=\"color: #a31515;\">\"                 Process Id = 0x%x\\n\\n\"<\/span>,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                 hProcessId);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    }<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">}<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">&nbsp;<\/pre>\n<\/div>\n<p>Notice that the path to the file whose creation I am blocking is <em>hard-coded<\/em> in the example source. This path may have a different syntax for the same file depending on how the process is created or on which version of Windows we are running. For this reason, if you want to run this test at home, check that the syntax is as I used here; otherwise adjust it and recompile the example.<\/p>\n<h3>One driver, two options<\/h3>\n<p>This new API is available only for Windows Vista SP1 and later, but it is likely that you want a driver that is still able to run on earlier versions of Windows even if the system does not support this routine. As you must already know, simply calling the <em>PsSetCreateProcessNotifyRoutineEx()<\/em> routine in your driver will create a static dependency and your driver will not be able to be loaded on older versions of Windows.<\/p>\n<p style=\"text-align: center;\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" src=\"https:\/\/driverentry.com.br\/en\/wp-content\/uploads\/2026\/07\/PrTracerFail.png\" alt=\"\" width=\"413\" height=\"464\" \/><\/p>\n<p style=\"text-align: left;\">To prevent this static dependency while having a single binary that can be loaded on both older and newer versions, using the newer version of this routine, we will use the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ff554563(VS.85).aspx\">MmGetSystemRoutineAddress()<\/a> function, which is the Kernel-Mode sister of the well-known <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms683212(VS.85).aspx\">GetProcAddress()<\/a> in User-Mode. The example driver available for download at the end of this post has these characteristics precisely to demonstrate how this can be done. Obviously, running the driver on Windows XP we will not have operating-system support to interrupt a process, and we will have to resort to alternative techniques to obtain the same result.<\/p>\n<p style=\"text-align: left;\">The <em>DriverEntry<\/em> function for this driver looks like this:<\/p>\n<div style=\"font-family: Consolas; font-size: 9pt; color: black; background: #A4F64C; border: 1px outset; padding: 0 0 0 5px;\">\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"><span style=\"color: green;\">\/****<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\"><span style=\"color: green;\">***     DriverEntry<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"><span style=\"color: green;\">**<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\"><span style=\"color: green;\">**      Entry point of the driver. If you are still thinking<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\"><span style=\"color: green;\">**      it is easy, do not worry, you will end up changing your mind.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\"><span style=\"color: green;\">*\/<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">NTSTATUS<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">DriverEntry(PDRIVER_OBJECT     pDriverObj,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">            PUNICODE_STRING    pusRegistryPath)<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">{<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    UNICODE_STRING  usSystemRoutine;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    NTSTATUS        nts;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    <span style=\"color: green;\">\/\/-f--&gt; Registers our cleanup function so that<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    <span style=\"color: green;\">\/\/      our driver can be unloaded.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    pDriverObj-&gt;DriverUnload = OnDriverUnload;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    <span style=\"color: green;\">\/\/-f--&gt; Initializes the name of the routine we will try to look up dynamically.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    RtlInitUnicodeString(&amp;usSystemRoutine,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                         L<span style=\"color: #a31515;\">\"PsSetCreateProcessNotifyRoutineEx\"<\/span>);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    <span style=\"color: green;\">\/\/-f--&gt; Here we check whether the system already supports PsSetCreateProcessNotifyRoutineEx<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    <span style=\"color: green;\">\/\/      Exactly as the teacher taught GetProcessAddress() back in kindergarten.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    *(PVOID*)&amp;pfPsSetCreateProcessNotifyRoutineEx = MmGetSystemRoutineAddress(&amp;usSystemRoutine);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    <span style=\"color: blue;\">if<\/span> (pfPsSetCreateProcessNotifyRoutineEx)<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    {<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        <span style=\"color: green;\">\/\/-f--&gt; If we are on Windows Vista SP1 or later, we will have the address<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        <span style=\"color: green;\">\/\/      of this routine, and therefore we will register with it.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        nts = pfPsSetCreateProcessNotifyRoutineEx(OnCreateProcessEx,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                                                  FALSE);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    }<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    <span style=\"color: blue;\">else<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    {<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        <span style=\"color: green;\">\/\/-f--&gt; Whoa! We are running on some 386. Let us register with<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">        <span style=\"color: green;\">\/\/      that routine from the 90s.<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">        nts = PsSetCreateProcessNotifyRoutine(OnCreateProcess,<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                                              FALSE);<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    }<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">    ASSERT(NT_SUCCESS(nts));<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">    <span style=\"color: blue;\">return<\/span> nts;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">}<\/pre>\n<\/div>\n<h3>Testing PsSetCreateProcessNotifyRoutineEx()<\/h3>\n<p>By now you must be jumping for joy imagining that your world-domination driver will finally work with great ease using this new API, but the thing is that this routine is not for just anyone. That is because only digitally signed drivers can call this new routine without receiving the STATUS_ACCESS_DENIED return.<\/p>\n<blockquote>\n<p>But Fernando, how am I going to be able to test your example driver? I don&#8217;t have a certificate or anything!<\/p>\n<\/blockquote>\n<p>This routine initially checks whether the module where your driver is defined has the integrity-check bit set. To set this bit just for fun, add the \/INTEGRITYCHECK option to your project&#8217;s linker options. The sources file of the example project looks like this:<\/p>\n<div style=\"font-family: Consolas; font-size: 9pt; color: black; background: #A4F64C; border: 1px outset; padding: 0 0 0 5px;\">\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">TARGETNAME=ProcessTracer<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">TARGETTYPE=DRIVER<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">SOURCES=ProcessTracer.cpp<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">&nbsp;<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">LINKER_FLAGS=\/INTEGRITYCHECK<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">&nbsp;<\/pre>\n<\/div>\n<p>This will make the system check your driver&#8217;s signature, but since your driver is not signed, you will still receive the same error. To finally see this work without even having a certificate, you will have to disable code-integrity checking for drivers in Windows Vista.<\/p>\n<p>All right, no panic. Start Windows Vista and press F8 as soon as Boot begins, then select the option below in the menu that appears as shown below:<\/p>\n<p style=\"text-align: center;\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" src=\"https:\/\/driverentry.com.br\/en\/wp-content\/uploads\/2026\/07\/DesabilitaAssinaturaDriver.png\" alt=\"\" width=\"640\" height=\"480\" \/><\/p>\n<p>With these two modifications it is possible to test the example driver and get an output in the debugger like the one illustrated below:<\/p>\n<div style=\"font-family: Consolas; font-size: 9pt; color: black; background: #A4F64C; border: 1px outset; padding: 0 0 0 5px;\">\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">[Process Tracer] Action = <span style=\"color: #ff0000;\">Blocking<\/span><\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                 Process Id = 0x3a4<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FAFAFA;\">                 Parent Id = 0xd98<\/pre>\n<pre style=\"margin: 0px; padding: 0 0 0 5px; background: #FFFFFF;\">                 Image name = \\??\\C:\\Windows\\system32\\notepad.exe<\/pre>\n<\/div>\n<p>In this case, once again, I tried to start Notepad through the <em>&#8220;Run&#8230;&#8221;<\/em> menu, but this time the output I got was the one shown below:<\/p>\n<p style=\"text-align: center;\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" src=\"https:\/\/driverentry.com.br\/en\/wp-content\/uploads\/2026\/07\/PrTracerDenied.png\" alt=\"\" width=\"581\" height=\"147\" \/><\/p>\n<p>Phew! Another giant post for the collection. I hope I helped, and see you next time!<\/p>\n<p class=\"download\"><a href=\"http:\/\/www.driverentry.com.br\/samples\/ProcessTracer.zip\">ProcessTracer.zip<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>During that long period when I was away from new posts on the blog, some things happened that deserved a little place here on my list of posts to write. One of them was the long discussion that took place on the C\/C++ group list. It was about the steps to follow to write a [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"pagelayer_contact_templates":[],"_pagelayer_content":"","footnotes":""},"categories":[1],"tags":[],"class_list":["post-454","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/driverentry.com.br\/en\/wp-json\/wp\/v2\/posts\/454","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/driverentry.com.br\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/driverentry.com.br\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/driverentry.com.br\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/driverentry.com.br\/en\/wp-json\/wp\/v2\/comments?post=454"}],"version-history":[{"count":1,"href":"https:\/\/driverentry.com.br\/en\/wp-json\/wp\/v2\/posts\/454\/revisions"}],"predecessor-version":[{"id":455,"href":"https:\/\/driverentry.com.br\/en\/wp-json\/wp\/v2\/posts\/454\/revisions\/455"}],"wp:attachment":[{"href":"https:\/\/driverentry.com.br\/en\/wp-json\/wp\/v2\/media?parent=454"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/driverentry.com.br\/en\/wp-json\/wp\/v2\/categories?post=454"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/driverentry.com.br\/en\/wp-json\/wp\/v2\/tags?post=454"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}