Simple driver runs on XP but fails on Vista

Hi Guys,

I wrote a simple driver to detect process creation, but it is not working on Vista, however it works on XP.

The driver was build through the build environment of XP using the DDK.

Below is the code:

VOID ProcViewProcessCallback(IN HANDLE ParentId, IN HANDLE ProcessId, IN BOOLEAN Create);  
  
void DriverUnload(PDRIVER_OBJECT pDriverObject)  
{  
 DbgPrint("Driver unloading");  
  
if (g_ProcCreateNotificationInstalled == TRUE)  
 {   
 //  
 // Remove the callback  
 //   
 NTSTATUS ntStatus = PsSetCreateProcessNotifyRoutine(ProcViewProcessCallback, TRUE);  
  
if (ntStatus == STATUS_UNSUCCESSFUL)  
 {  
 DbgPrint ("Failed to remove process create notification\n");  
 }  
 else  
 {  
 g_ProcCreateNotificationInstalled = TRUE;  
 }  
 }  
}  
  
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)  
{  
 NTSTATUS ntStatus = STATUS_UNSUCCESSFUL;  
 DbgPrint ("Driver now loading\n");  
  
DriverObject-\>DriverUnload = DriverUnload;  
  
//  
 // Set up the callback  
 //   
 ntStatus = PsSetCreateProcessNotifyRoutine(ProcViewProcessCallback, FALSE);  
  
if (ntStatus == STATUS_UNSUCCESSFUL)  
 {  
 DbgPrint ("Failed to set a process create notification\n");  
 }  
 else  
 {  
 g_ProcCreateNotificationInstalled = TRUE;  
 }  
  
return ntStatus;  
}  
  
VOID ProcViewProcessCallback(IN HANDLE ParentId, IN HANDLE ProcessId, IN BOOLEAN Create)  
{  
 char wzMsg [256];  
  
if (Create == TRUE)  
 {  
 sprintf (wzMsg, "%d - created\n", ProcessId);  
 }  
 else  
 {  
 sprintf (wzMsg, "%d - deleted\n", ProcessId);  
 }  
  
DbgPrint (wzMsg);  
}  

Can someone point out what’s missing over here?

Cheers,
Hitesh

How does it fail?

mm

xxxxx@gmail.com wrote:

Hi Guys,

I wrote a simple driver to detect process creation, but it is not working on Vista, however it works on XP.

The driver was build through the build environment of XP using the DDK.

Below is the code:

VOID ProcViewProcessCallback(IN HANDLE ParentId, IN HANDLE ProcessId, IN BOOLEAN Create);  
  
void DriverUnload(PDRIVER_OBJECT pDriverObject)  
{  
DbgPrint("Driver unloading");  
  
if (g_ProcCreateNotificationInstalled == TRUE)  
{   
//  
// Remove the callback  
//   
NTSTATUS ntStatus = PsSetCreateProcessNotifyRoutine(ProcViewProcessCallback, TRUE);  
  
if (ntStatus == STATUS_UNSUCCESSFUL)  
{  
DbgPrint ("Failed to remove process create notification\n");  
}  
else  
{  
g_ProcCreateNotificationInstalled = TRUE;  
}  
}  
}  
  
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)  
{  
NTSTATUS ntStatus = STATUS_UNSUCCESSFUL;  
DbgPrint ("Driver now loading\n");  
  
DriverObject-\>DriverUnload = DriverUnload;  
  
//  
// Set up the callback  
//   
ntStatus = PsSetCreateProcessNotifyRoutine(ProcViewProcessCallback, FALSE);  
  
if (ntStatus == STATUS_UNSUCCESSFUL)  
{  
DbgPrint ("Failed to set a process create notification\n");  
}  
else  
{  
g_ProcCreateNotificationInstalled = TRUE;  
}  
  
return ntStatus;  
}  
  
VOID ProcViewProcessCallback(IN HANDLE ParentId, IN HANDLE ProcessId, IN BOOLEAN Create)  
{  
char wzMsg [256];  
  
if (Create == TRUE)  
{  
sprintf (wzMsg, "%d - created\n", ProcessId);  
}  
else  
{  
sprintf (wzMsg, "%d - deleted\n", ProcessId);  
}  
  
DbgPrint (wzMsg);  
}  

Can someone point out what’s missing over here?

Cheers,
Hitesh

On a different note, declaring a large array on the stack (in ProcViewProcessCallback ) in kernel mode is not a good idea, esp in this case where it is not needed at all (not to mention HANDLE can be 64 bits wide, so %d does not work either). It should be

char* action = NULL;

if (Create == TRUE)
{
action = “created”;
}
else
{
action = “deleted”;
}

DbgPrint (“%p - %s\n”, ProcessId, action);

d

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
Sent: Monday, June 23, 2008 9:36 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] Simple driver runs on XP but fails on Vista

Hi Guys,

I wrote a simple driver to detect process creation, but it is not working on Vista, however it works on XP.

The driver was build through the build environment of XP using the DDK.

Below is the code:

VOID ProcViewProcessCallback(IN HANDLE ParentId, IN HANDLE ProcessId, IN BOOLEAN Create);  
  
void DriverUnload(PDRIVER_OBJECT pDriverObject)  
{  
 DbgPrint("Driver unloading");  
  
if (g_ProcCreateNotificationInstalled == TRUE)  
 {  
 //  
 // Remove the callback  
 //  
 NTSTATUS ntStatus = PsSetCreateProcessNotifyRoutine(ProcViewProcessCallback, TRUE);  
  
if (ntStatus == STATUS_UNSUCCESSFUL)  
 {  
 DbgPrint ("Failed to remove process create notification\n");  
 }  
 else  
 {  
 g_ProcCreateNotificationInstalled = TRUE;  
 }  
 }  
}  
  
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)  
{  
 NTSTATUS ntStatus = STATUS_UNSUCCESSFUL;  
 DbgPrint ("Driver now loading\n");  
  
DriverObject-\>DriverUnload = DriverUnload;  
  
//  
 // Set up the callback  
 //  
 ntStatus = PsSetCreateProcessNotifyRoutine(ProcViewProcessCallback, FALSE);  
  
if (ntStatus == STATUS_UNSUCCESSFUL)  
 {  
 DbgPrint ("Failed to set a process create notification\n");  
 }  
 else  
 {  
 g_ProcCreateNotificationInstalled = TRUE;  
 }  
  
return ntStatus;  
}  
  
VOID ProcViewProcessCallback(IN HANDLE ParentId, IN HANDLE ProcessId, IN BOOLEAN Create)  
{  
 char wzMsg [256];  
  
if (Create == TRUE)  
 {  
 sprintf (wzMsg, "%d - created\n", ProcessId);  
 }  
 else  
 {  
 sprintf (wzMsg, "%d - deleted\n", ProcessId);  
 }  
  
DbgPrint (wzMsg);  
}  

Can someone point out what’s missing over here?

Cheers,
Hitesh


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

Doron Holan wrote:

On a different note, declaring a large array on the stack (in ProcViewProcessCallback ) in kernel mode is not a good idea, esp in this case where it is not needed at all (not to mention HANDLE can be 64 bits wide, so %d does not work either). It should be

char* action = NULL;

if (Create == TRUE)
{
action = “created”;
}
else
{
action = “deleted”;
}

DbgPrint (“%p - %s\n”, ProcessId, action);

I can’t stop myself from rewriting this in a more keystroke-efficient way:

DbgPrint( “%p - %s\n”, ProcessId, Create ? “created” : “deleted” );


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Sure, that works. Typically though the bodies of code in the if and else are more complicated than just assigning a string value, in which case it would flow better to do the assignment and not reevalute Created twice

d

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Tim Roberts
Sent: Monday, June 23, 2008 10:33 AM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] Simple driver runs on XP but fails on Vista

Doron Holan wrote:

On a different note, declaring a large array on the stack (in ProcViewProcessCallback ) in kernel mode is not a good idea, esp in this case where it is not needed at all (not to mention HANDLE can be 64 bits wide, so %d does not work either). It should be

char* action = NULL;

if (Create == TRUE)
{
action = “created”;
}
else
{
action = “deleted”;
}

DbgPrint (“%p - %s\n”, ProcessId, action);

I can’t stop myself from rewriting this in a more keystroke-efficient way:

DbgPrint( “%p - %s\n”, ProcessId, Create ? “created” : “deleted” );


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

There are some other bug here:


ntStatus = PsSetCreateProcessNotifyRoutine(ProcViewProcessCallback, FALSE);
if (ntStatus == STATUS_UNSUCCESSFUL)
{
DbgPrint ("Failed to set a process create notification\n");
}
else
{
g_ProcCreateNotificationInstalled = TRUE;
}

is not a proper way to check if this succeeded or not. So this ALWAYS assume
success because according to doc PsSet.. returns either STATUS_SUCCESS or
STATUS_INVALID_PARAMETER. Use the NT_SUCCESS macro instead.

//Daniel

wrote in message news:xxxxx@ntdev...
> Hi Guys,
>
> I wrote a simple driver to detect process creation, but it is not working
> on Vista, however it works on XP.
>
> The driver was build through the build environment of XP using the DDK.
>
> Below is the code:
>
> <br>&gt; VOID ProcViewProcessCallback(IN HANDLE ParentId, IN HANDLE ProcessId, IN <br>&gt; BOOLEAN Create);<br>&gt;<br>&gt; void DriverUnload(PDRIVER_OBJECT pDriverObject)<br>&gt; {<br>&gt; DbgPrint("Driver unloading");<br>&gt;<br>&gt; if (g_ProcCreateNotificationInstalled == TRUE)<br>&gt; {<br>&gt; //<br>&gt; // Remove the callback<br>&gt; //<br>&gt; NTSTATUS ntStatus = <br>&gt; PsSetCreateProcessNotifyRoutine(ProcViewProcessCallback, TRUE);<br>&gt;<br>&gt; if (ntStatus == STATUS_UNSUCCESSFUL)<br>&gt; {<br>&gt; DbgPrint ("Failed to remove process create notification\n");<br>&gt; }<br>&gt; else<br>&gt; {<br>&gt; g_ProcCreateNotificationInstalled = TRUE;<br>&gt; }<br>&gt; }<br>&gt; }<br>&gt;<br>&gt; NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING <br>&gt; RegistryPath)<br>&gt; {<br>&gt; NTSTATUS ntStatus = STATUS_UNSUCCESSFUL;<br>&gt; DbgPrint ("Driver now loading\n");<br>&gt;<br>&gt; DriverObject-&gt;DriverUnload = DriverUnload;<br>&gt;<br>&gt; //<br>&gt; // Set up the callback<br>&gt; //<br>&gt; ntStatus = PsSetCreateProcessNotifyRoutine(ProcViewProcessCallback, <br>&gt; FALSE);<br>&gt;<br>&gt; if (ntStatus == STATUS_UNSUCCESSFUL)<br>&gt; {<br>&gt; DbgPrint ("Failed to set a process create notification\n");<br>&gt; }<br>&gt; else<br>&gt; {<br>&gt; g_ProcCreateNotificationInstalled = TRUE;<br>&gt; }<br>&gt;<br>&gt; return ntStatus;<br>&gt; }<br>&gt;<br>&gt; VOID ProcViewProcessCallback(IN HANDLE ParentId, IN HANDLE ProcessId, IN <br>&gt; BOOLEAN Create)<br>&gt; {<br>&gt; char wzMsg [256];<br>&gt;<br>&gt; if (Create == TRUE)<br>&gt; {<br>&gt; sprintf (wzMsg, "%d - created\n", ProcessId);<br>&gt; }<br>&gt; else<br>&gt; {<br>&gt; sprintf (wzMsg, "%d - deleted\n", ProcessId);<br>&gt; }<br>&gt;<br>&gt; DbgPrint (wzMsg);<br>&gt; }<br>&gt;
>
> Can someone point out what's missing over here?
>
> Cheers,
> Hitesh
>
>

“Tim Roberts” wrote in message news:xxxxx@ntdev…

> I can’t stop myself from rewriting this in a more keystroke-efficient way:
>
> DbgPrint( “%p - %s\n”, ProcessId, Create ? “created” : “deleted” );
>
> –

Not only keystroke-efficient. Using the ternary operator often results in
optimizations by using conditional instructions which will otherwise be
missed by the MS compilers.

//Daniel

Hi All,

Thanks for the replies. The problem was that in Vista DbgPrint is
disabled by default, you need to add “DEFAULT” : REG_DWORD :
0xFFFFFFFF to the key
“HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session
Manager\Debug Print Filter”. And on next boot it starts printing the
messages.

Thanks for pointing out the mistakes in my code as well.

Secondly, I wanted to know if I can use Windows API inside a driver. I
tired to include windows.h and I get all kinds of errors.

Actually, I’m trying to hook certain API’s and felt that it will be
easier if I could put my code for hooking over in the driver than to
notify the user mode app, which will then do the hooking. Also, since
at startup time process’s will be created and there will be no user
mode app to do the patching, so I don’t want to miss any calls to the
API’s.

I’m not trying to write a virus or something, just a monitoring app :).

Thanks.

Best Regards,
Hitesh

On Mon, Jun 23, 2008 at 12:35 PM, wrote:
> “Tim Roberts” wrote in message news:xxxxx@ntdev…
>
>> I can’t stop myself from rewriting this in a more keystroke-efficient way:
>>
>> DbgPrint( “%p - %s\n”, ProcessId, Create ? “created” : “deleted” );
>>
>> –
>
>
> Not only keystroke-efficient. Using the ternary operator often results in
> optimizations by using conditional instructions which will otherwise be
> missed by the MS compilers.
>
> //Daniel
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>

logan wrote:

Secondly, I wanted to know if I can use Windows API inside a driver. I
tired to include windows.h and I get all kinds of errors.

Absolutely not. The Windows subsystem (and hence the Win32 API) is
strictly a user-mode concept. The calls simply do not exist in kernel mode.

Actually, I’m trying to hook certain API’s and felt that it will be
easier if I could put my code for hooking over in the driver than to
notify the user mode app, which will then do the hooking. Also, since
at startup time process’s will be created and there will be no user
mode app to do the patching, so I don’t want to miss any calls to the
API’s.

I’m not trying to write a virus or something, just a monitoring app :).

To hook calls in another process, you must inject user-mode code into
that process. That can only be done from user mode.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.