wcsstr in kernel ?

Hi everybody !

I’m writing a driver and for some reasons, I need to search a string into another one.
The two strings are UNICODE_STRING but weirdly wcsstr doesn’t seem to work…

Do you know what could be wrong ?

here is a piece of code :

PUNICODE_STRING procName;
PUNICODE_STRING usProc = “”;
ANSI_STRING asProc;

procName = getCurrentProcName();

RtlInitAnsiString(&asProc, pWriteDataBuffer);
RtlAnsiStringToUnicodeString(usProc, &asProc, TRUE);

if(wcsstr(procName, usProc))
DbgPrint(“yeah”);

Thanks in advance !

There is no guarantee that a UNICODE_STRING will be NULL terminated.
This is one you will have to roll your own.

Don Burn
Windows Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr

xxxxx@gmail.com” wrote in message
news:xxxxx@ntdev:

> Hi everybody !
>
> I’m writing a driver and for some reasons, I need to search a string into another one.
> The two strings are UNICODE_STRING but weirdly wcsstr doesn’t seem to work…
>
> Do you know what could be wrong ?
>
> here is a piece of code :
>
> PUNICODE_STRING procName;
> PUNICODE_STRING usProc = “”;
> ANSI_STRING asProc;
>
> procName = getCurrentProcName();
>
> RtlInitAnsiString(&asProc, pWriteDataBuffer);
> RtlAnsiStringToUnicodeString(usProc, &asProc, TRUE);
>
> if(wcsstr(procName, usProc))
> DbgPrint(“yeah”);
>
>
> Thanks in advance !

> Hi everybody !

I’m writing a driver and for some reasons, I need to search a string into
another one.
The two strings are UNICODE_STRING but weirdly wcsstr doesn’t seem to
work…

Do you know what could be wrong ?

here is a piece of code :

PUNICODE_STRING procName;
PUNICODE_STRING usProc = “”;
ANSI_STRING asProc;

procName = getCurrentProcName();

RtlInitAnsiString(&asProc, pWriteDataBuffer);
RtlAnsiStringToUnicodeString(usProc, &asProc, TRUE);

if(wcsstr(procName, usProc))
DbgPrint(“yeah”);

What surprises me is tbat this code even compiles. Do you even have a
clue as to what a UNICODE_STRING is? RTFM! What, exactly, do you think
assigning “” to a PUNICODE_STRING is going to accomplish? What is
pWriteDataBuffer and where did it come from? If it came from user space,
what leads you to believe it holds an ANSI string (most application
programmers who have a clue think that ‘char’ is a quaint data type left
over from the PDP-11 version of C, but which has little relevance to
modern programming; furthrrmore, by default, all VS projects are created
assuming Unicode). The conversion works because the last parameter is
TRUE, so the erroneous initialization causes no harm. The documentation,
however, is strangely silent on the need to free this buffer, or the
proper means of doing it. But wcsstr wants a pair of PCWSTRs, and that is
not what you gave it. The compiler should have complained bitterly about
this. So any action taken by wcsstr on improper inputs is undefined.
Furthermore, there is really no guarantee that UNICODE_STRINGs are
NUL-terminated, so even if you used
wcsstr(procName->Buffer, usProc->Buffer)
there is no guarantee it would work correctly; it might bluescreen, which
would be a perfectly reasonable response to incorrect arguments.

I suggest that reading documentation, learning to use /W4, and learning to
use a debugger would all be valuable skills to acquire.

There are, as far as I can tell, only two correct lines in the above
sample: the declarations of “procName” and “asProc”. Since you do not
show the code for getCurrentProcName, based on what I’ve seen here it is
very probably wrong.
joe

Thanks in advance !


NTDEV is sponsored by OSR

OSR is HIRING!! See http://www.osr.com/careers

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

In reading my answer, I just saw that the initialixation of usProc is
initializing a PUNICODE_STRING. This initialization is fatal nonsense.

Weirdly, you claim “wcsstr doesn’t seem to work”. It’s not weird at all.
And “doesn’t work” is a meaningless nonsense phrase.

First: if anything is weird, it is that this compiles without errors or
warnings
Second: assuming you have disabled or ignored all the warnings, it should
bluscreen; if it does not, that is amazingly weird.

joe

> Hi everybody !
>
> I’m writing a driver and for some reasons, I need to search a string
> into
> another one.
> The two strings are UNICODE_STRING but weirdly wcsstr doesn’t seem to
> work…
>
> Do you know what could be wrong ?
>
> here is a piece of code :
>
> PUNICODE_STRING procName;
> PUNICODE_STRING usProc = “”;
> ANSI_STRING asProc;
>
> procName = getCurrentProcName();
>
> RtlInitAnsiString(&asProc, pWriteDataBuffer);
> RtlAnsiStringToUnicodeString(usProc, &asProc, TRUE);
>
> if(wcsstr(procName, usProc))
> DbgPrint(“yeah”);
>
>
What surprises me is tbat this code even compiles. Do you even have a
clue as to what a UNICODE_STRING is? RTFM! What, exactly, do you think
assigning “” to a PUNICODE_STRING is going to accomplish? What is
pWriteDataBuffer and where did it come from? If it came from user space,
what leads you to believe it holds an ANSI string (most application
programmers who have a clue think that ‘char’ is a quaint data type left
over from the PDP-11 version of C, but which has little relevance to
modern programming; furthrrmore, by default, all VS projects are created
assuming Unicode). The conversion works because the last parameter is
TRUE, so the erroneous initialization causes no harm. The documentation,
however, is strangely silent on the need to free this buffer, or the
proper means of doing it. But wcsstr wants a pair of PCWSTRs, and that is
not what you gave it. The compiler should have complained bitterly about
this. So any action taken by wcsstr on improper inputs is undefined.
Furthermore, there is really no guarantee that UNICODE_STRINGs are
NUL-terminated, so even if you used
wcsstr(procName->Buffer, usProc->Buffer)
there is no guarantee it would work correctly; it might bluescreen, which
would be a perfectly reasonable response to incorrect arguments.

I suggest that reading documentation, learning to use /W4, and learning to
use a debugger would all be valuable skills to acquire.

There are, as far as I can tell, only two correct lines in the above
sample: the declarations of “procName” and “asProc”. Since you do not
show the code for getCurrentProcName, based on what I’ve seen here it is
very probably wrong.
joe
> Thanks in advance !
>
> —
> NTDEV is sponsored by OSR
>
> OSR is HIRING!! See http://www.osr.com/careers
>
> 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
>


NTDEV is sponsored by OSR

OSR is HIRING!! See http://www.osr.com/careers

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

So the compiler is assigning the address of the static string “” to a
pointer to a UNICODE_STRING - that alone won’t cause a crash. Nor will
reading the memory pointed at by PUNICODE_STRING now that it is initialized
to something that happens to be valid memory.

I was a bit surprised that this doesn’t crash:
RtlAnsiStringToUnicodeString(usProc, &asProc, TRUE);

But by specifying TRUE the function allocates the UNICODE_STRING buffer,
and clobbers the allocated space for the static string “” (and probably the
string adjacent to it) with the updated UNICODE_STRING values.

The code might win the coveted “Worst Code Sample Posted to NTDEV Evah”
prize.

Mark Roddy

On Tue, May 28, 2013 at 2:11 PM, wrote:

> In reading my answer, I just saw that the initialixation of usProc is
> initializing a PUNICODE_STRING. This initialization is fatal nonsense.
>
> Weirdly, you claim “wcsstr doesn’t seem to work”. It’s not weird at all.
> And “doesn’t work” is a meaningless nonsense phrase.
>
> First: if anything is weird, it is that this compiles without errors or
> warnings
> Second: assuming you have disabled or ignored all the warnings, it should
> bluscreen; if it does not, that is amazingly weird.
>
> joe
>
> >> Hi everybody !
> >>
> >> I’m writing a driver and for some reasons, I need to search a string
> >> into
> >> another one.
> >> The two strings are UNICODE_STRING but weirdly wcsstr doesn’t seem to
> >> work…
> >>
> >> Do you know what could be wrong ?
> >>
> >> here is a piece of code :
> >>
> >> PUNICODE_STRING procName;
> >> PUNICODE_STRING usProc = “”;
> >> ANSI_STRING asProc;
> >>
> >> procName = getCurrentProcName();
> >>
> >> RtlInitAnsiString(&asProc, pWriteDataBuffer);
> >> RtlAnsiStringToUnicodeString(usProc, &asProc, TRUE);
> >>
> >> if(wcsstr(procName, usProc))
> >> DbgPrint(“yeah”);
> >>
> >>
> > What surprises me is tbat this code even compiles. Do you even have a
> > clue as to what a UNICODE_STRING is? RTFM! What, exactly, do you think
> > assigning “” to a PUNICODE_STRING is going to accomplish? What is
> > pWriteDataBuffer and where did it come from? If it came from user space,
> > what leads you to believe it holds an ANSI string (most application
> > programmers who have a clue think that ‘char’ is a quaint data type left
> > over from the PDP-11 version of C, but which has little relevance to
> > modern programming; furthrrmore, by default, all VS projects are created
> > assuming Unicode). The conversion works because the last parameter is
> > TRUE, so the erroneous initialization causes no harm. The documentation,
> > however, is strangely silent on the need to free this buffer, or the
> > proper means of doing it. But wcsstr wants a pair of PCWSTRs, and that
> is
> > not what you gave it. The compiler should have complained bitterly about
> > this. So any action taken by wcsstr on improper inputs is undefined.
> > Furthermore, there is really no guarantee that UNICODE_STRINGs are
> > NUL-terminated, so even if you used
> > wcsstr(procName->Buffer, usProc->Buffer)
> > there is no guarantee it would work correctly; it might bluescreen, which
> > would be a perfectly reasonable response to incorrect arguments.
> >
> > I suggest that reading documentation, learning to use /W4, and learning
> to
> > use a debugger would all be valuable skills to acquire.
> >
> > There are, as far as I can tell, only two correct lines in the above
> > sample: the declarations of “procName” and “asProc”. Since you do not
> > show the code for getCurrentProcName, based on what I’ve seen here it is
> > very probably wrong.
> > joe
> >> Thanks in advance !
> >>
> >> —
> >> NTDEV is sponsored by OSR
> >>
> >> OSR is HIRING!! See http://www.osr.com/careers
> >>
> >> 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
> >>
> >
> >
> >
> > —
> > NTDEV is sponsored by OSR
> >
> > OSR is HIRING!! See http://www.osr.com/careers
> >
> > 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
> >
>
>
>
> —
> NTDEV is sponsored by OSR
>
> OSR is HIRING!! See http://www.osr.com/careers
>
> 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
>

xxxxx@gmail.com wrote:

Hi everybody !

I’m writing a driver and for some reasons, I need to search a string into another one.
The two strings are UNICODE_STRING but weirdly wcsstr doesn’t seem to work…

Do you know what could be wrong ?

Yes. You are assuming that UNICODE_STRING is the same as wchar_t. It’s
not. UNICODE_STRING is a structure. Please Google it for more information.


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

> The two strings are UNICODE_STRING but weirdly wcsstr doesn’t seem to work…

Surely it won’t, since UNICODE_STRING is not zero-terminated, and wcsstr requires zero termination.

Try to find some RtlXxx string function which replaces wcsstr for UNICODE_STRING, or write your own.


Maxim S. Shatskih
Microsoft MVP on File System And Storage
xxxxx@storagecraft.com
http://www.storagecraft.com

> So the compiler is assigning the address of the static string “” to a

pointer to a UNICODE_STRING - that alone won’t cause a crash. Nor will
reading the memory pointed at by PUNICODE_STRING now that it is
initialized
to something that happens to be valid memory.

It shouldn’t even compile, because a const wchar_t is incompatible with
PUNICODE_STRING. Now, assume that by some magic, the assignment takes
place. Then it is pointing to some random place in memory, into which
there will be an attempt to write the two USHORTs and the Buffer value.
But string literals are normally placed in a write-protected segment, so
the attempt to write into that space should take an access fault. Assume
it has not been placed in write-protected memory, then it is pointing to a
one-byte location in memory (the NUL character of a zero-length char
literal). In Win32, it will write 8 bytes into that one-byte space; in
Win64 it would write 12 byes into that one-byte space. Oops. The error,
of course, is declaring it asa PUNICODE_STRING; it should be an
uninitialized UNICODE_STRING.

I was a bit surprised that this doesn’t crash:
RtlAnsiStringToUnicodeString(usProc, &asProc, TRUE);

But by specifying TRUE the function allocates the UNICODE_STRING buffer,
and clobbers the allocated space for the static string “” (and probably
the
string adjacent to it) with the updated UNICODE_STRING values.

Note that the UNICODE_STRING Buffer field must exist inside a valid
UNICODE_STRING object, which is not what the PUNICODE_STRING pointer is
pointing to. In user space, steing literals are linked into the code
segment, and the number of times I’ve had to explain why modifying a
pooled string constant was a Really Bad Idea was not quite weekly,
probably more like three times a month.

The code might win the coveted “Worst Code Sample Posted to NTDEV Evah”
prize.

I think I remember a similar-sized example in which EVERY line was wrong;
this one had two correct lines. Maybe you can claim the DbgPrint is
correct, but since it doesn’t include the driver name and doesn’t end with
a newline, I don’t consider it a good example of usage.

But I have a strong suspicion that getProcName function would win the
prize. What do you want to bet that function returns a pointer to a
stack-allocated local?

Mark Roddy

On Tue, May 28, 2013 at 2:11 PM, wrote:
>
>> In reading my answer, I just saw that the initialixation of usProc is
>> initializing a PUNICODE_STRING. This initialization is fatal nonsense.
>>
>> Weirdly, you claim “wcsstr doesn’t seem to work”. It’s not weird at
>> all.
>> And “doesn’t work” is a meaningless nonsense phrase.
>>
>> First: if anything is weird, it is that this compiles without errors or
>> warnings
>> Second: assuming you have disabled or ignored all the warnings, it
>> should
>> bluscreen; if it does not, that is amazingly weird.
>>
>> joe
>>
>> >> Hi everybody !
>> >>
>> >> I’m writing a driver and for some reasons, I need to search a string
>> >> into
>> >> another one.
>> >> The two strings are UNICODE_STRING but weirdly wcsstr doesn’t seem to
>> >> work…
>> >>
>> >> Do you know what could be wrong ?
>> >>
>> >> here is a piece of code :
>> >>
>> >> PUNICODE_STRING procName;
>> >> PUNICODE_STRING usProc = “”;
>> >> ANSI_STRING asProc;
>> >>
>> >> procName = getCurrentProcName();
>> >>
>> >> RtlInitAnsiString(&asProc, pWriteDataBuffer);
>> >> RtlAnsiStringToUnicodeString(usProc, &asProc, TRUE);
>> >>
>> >> if(wcsstr(procName, usProc))
>> >> DbgPrint(“yeah”);
>> >>
>> >>
>> > What surprises me is tbat this code even compiles. Do you even have a
>> > clue as to what a UNICODE_STRING is? RTFM! What, exactly, do you
>> think
>> > assigning “” to a PUNICODE_STRING is going to accomplish? What is
>> > pWriteDataBuffer and where did it come from? If it came from user
>> space,
>> > what leads you to believe it holds an ANSI string (most application
>> > programmers who have a clue think that ‘char’ is a quaint data type
>> left
>> > over from the PDP-11 version of C, but which has little relevance to
>> > modern programming; furthrrmore, by default, all VS projects are
>> created
>> > assuming Unicode). The conversion works because the last parameter is
>> > TRUE, so the erroneous initialization causes no harm. The
>> documentation,
>> > however, is strangely silent on the need to free this buffer, or the
>> > proper means of doing it. But wcsstr wants a pair of PCWSTRs, and
>> that
>> is
>> > not what you gave it. The compiler should have complained bitterly
>> about
>> > this. So any action taken by wcsstr on improper inputs is undefined.
>> > Furthermore, there is really no guarantee that UNICODE_STRINGs are
>> > NUL-terminated, so even if you used
>> > wcsstr(procName->Buffer, usProc->Buffer)
>> > there is no guarantee it would work correctly; it might bluescreen,
>> which
>> > would be a perfectly reasonable response to incorrect arguments.
>> >
>> > I suggest that reading documentation, learning to use /W4, and
>> learning
>> to
>> > use a debugger would all be valuable skills to acquire.
>> >
>> > There are, as far as I can tell, only two correct lines in the above
>> > sample: the declarations of “procName” and “asProc”. Since you do not
>> > show the code for getCurrentProcName, based on what I’ve seen here it
>> is
>> > very probably wrong.
>> > joe
>> >> Thanks in advance !
>> >>
>> >> —
>> >> NTDEV is sponsored by OSR
>> >>
>> >> OSR is HIRING!! See http://www.osr.com/careers
>> >>
>> >> 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
>> >>
>> >
>> >
>> >
>> > —
>> > NTDEV is sponsored by OSR
>> >
>> > OSR is HIRING!! See http://www.osr.com/careers
>> >
>> > 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
>> >
>>
>>
>>
>> —
>> NTDEV is sponsored by OSR
>>
>> OSR is HIRING!! See http://www.osr.com/careers
>>
>> 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
>>
>
> —
> NTDEV is sponsored by OSR
>
> OSR is HIRING!! See http://www.osr.com/careers
>
> 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

Thanks for all the nice comments !
It’s my first try writing a kernel driver, i’m just learning…

Well, i’ll explain a bit more what i’m trying to do.

I’m trying to write a tool like Process Monitor, which I’ll put some hooks into the SSDT to monitor some functions.

The hooks work well, but it monitors every processes, and I want to monitor functions calls only in a process name given by a ring3 application.

In order to do that, I use a function getCurrentProcName() which will return the current process name (using a call to ZwQueryInformationProcess()).

I received the process name which we want to monitor from userland in dealing with IRP Write :

NTSTATUS IO_Write(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
PIO_STACK_LOCATION pIoStackIrp = NULL;

pIoStackIrp = IoGetCurrentIrpStackLocation(Irp);
if(pIoStackIrp)
{
pWriteDataBuffer = (PCHAR)Irp->AssociatedIrp.SystemBuffer;
if(pWriteDataBuffer)
{
// we check that the received string terminate with a null byte
if(pWriteDataBuffer[pIoStackIrp->Parameters.Write.Length] != 0)
pWriteDataBuffer[pIoStackIrp->Parameters.Write.Length] = 0;
DbgPrint(“Buffer received from userland : %s”, pWriteDataBuffer);
}
}
}

It works just fine, I received the correct string given from my app in userland.
pWriteDataBuffer is a global PCHAR variable.

My problem is that I want to print out the parameters of the functions I’ve hooked only when they are called from the process given from userland.

So I need to compare the process name given from my function GetCurrentProcName() which returns an UNICODE_STRING with the process name given from userland (which is a PCHAR)

the GetCurrentProcName returns an unicode_string like : “\Device\HarddiskVolume1\WINDOWS\system32\winlogon.exe”

and the process name from userland : “winlogon.exe”

So I need something like strstr(), I mean a function that will be able to search a string into another one. Both strings are from different types, so my idea was to convert the unicode_string to a PCHAR or the PCHAR to a unicode_string and use strstr() or a similar function.

I hope you’ll understand it’s my first time dealing with kernel code, i’m just trying to learn.

Thanks

SSDT hooking is not entertained here. As you said, you are learning, use PsSetCreateProcessNotifyRoutine function, or have a look at Capturebat sources. IIRC, it is available on NewZealand version of honeynet.

Goodluck,
Siva

Date: Wed, 29 May 2013 04:54:52 -0400
From: xxxxx@gmail.com
To: xxxxx@lists.osr.com
Subject: RE:[ntdev] wcsstr in kernel ?

Thanks for all the nice comments !
It’s my first try writing a kernel driver, i’m just learning…

Well, i’ll explain a bit more what i’m trying to do.

I’m trying to write a tool like Process Monitor, which I’ll put some hooks into the SSDT to monitor some functions.

The hooks work well, but it monitors every processes, and I want to monitor functions calls only in a process name given by a ring3 application.

In order to do that, I use a function getCurrentProcName() which will return the current process name (using a call to ZwQueryInformationProcess()).

I received the process name which we want to monitor from userland in dealing with IRP Write :

NTSTATUS IO_Write(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
PIO_STACK_LOCATION pIoStackIrp = NULL;

pIoStackIrp = IoGetCurrentIrpStackLocation(Irp);
if(pIoStackIrp)
{
pWriteDataBuffer = (PCHAR)Irp->AssociatedIrp.SystemBuffer;
if(pWriteDataBuffer)
{
// we check that the received string terminate with a null byte
if(pWriteDataBuffer[pIoStackIrp->Parameters.Write.Length] != 0)
pWriteDataBuffer[pIoStackIrp->Parameters.Write.Length] = 0;
DbgPrint(“Buffer received from userland : %s”, pWriteDataBuffer);
}
}
}

It works just fine, I received the correct string given from my app in userland.
pWriteDataBuffer is a global PCHAR variable.

My problem is that I want to print out the parameters of the functions I’ve hooked only when they are called from the process given from userland.

So I need to compare the process name given from my function GetCurrentProcName() which returns an UNICODE_STRING with the process name given from userland (which is a PCHAR)

the GetCurrentProcName returns an unicode_string like : “\Device\HarddiskVolume1\WINDOWS\system32\winlogon.exe”

and the process name from userland : “winlogon.exe”

So I need something like strstr(), I mean a function that will be able to search a string into another one. Both strings are from different types, so my idea was to convert the unicode_string to a PCHAR or the PCHAR to a unicode_string and use strstr() or a similar function.

I hope you’ll understand it’s my first time dealing with kernel code, i’m just trying to learn.

Thanks


NTDEV is sponsored by OSR

OSR is HIRING!! See http://www.osr.com/careers

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

Yeah i know SSDT hooking isn’t the topic here, and I don’t have problem with that, that’s why my question is just about comparing strings not about the hooking stuf

Anyway, thanks for the informations, i’ll take a look at Capturebat sources

The solution was really easy actually, instead of comparing the Buffer member (which is PWSTR type), i was comparing the pointer directly so that works

if(wcsstr(procName->Buffer, proc.Buffer))
DbgPrint(“YOUPI !!”);

procName is a PUNICODE_STRING which is the current process, and proc is a UNICODE_STRING ( a proc name given from userland)

And as we have pointed out that may crash the system since there is no
guarantee that the buffers are NULL terminated! Your code is still
broken.

Don Burn
Windows Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr

xxxxx@gmail.com” wrote in message
news:xxxxx@ntdev:

> The solution was really easy actually, instead of comparing the Buffer member (which is PWSTR type), i was comparing the pointer directly so that works
>
> if(wcsstr(procName->Buffer, proc.Buffer))
> DbgPrint(“YOUPI !!”);
>
> procName is a PUNICODE_STRING which is the current process, and proc is a UNICODE_STRING ( a proc name given from userland)

Don Burn, on the GetCurrentProcName, and when i retrieve the buffer from userland, i check for both strings if there are null terminated, if they are not, i add the null byte

Several items here:

  1. How do you add the NULL, by the way that should be 2 bytes? There
    is nothing that guarantees that the space is present in the string for
    the NULL.

  2. You do realize you are leaving a land mine in your code? You may
    know that you need to do the magic of adding the NULL byte, but next
    programmer will know that UNICODE_STRINGS don’t require a NULL and it
    will come and bite them.

This is really poor design for code that has to live in the kernel.

Don Burn
Windows Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr

xxxxx@gmail.com” wrote in message
news:xxxxx@ntdev:

> Don Burn, on the GetCurrentProcName, and when i retrieve the buffer from userland, i check for both strings if there are null terminated, if they are not, i add the null byte

> I’m trying to write a tool like Process Monitor, which I’ll put some hooks into the SSDT

You cannot do this on x64, which is, for instance, all modern Windows Server machines.


Maxim S. Shatskih
Microsoft MVP on File System And Storage
xxxxx@storagecraft.com
http://www.storagecraft.com

>strings if there are null terminated, if they are not, i add the null byte

It is very good that MS have disabled SSDT hooking. Providing such a powerful tool for the developers which this experience and this amount of professional common sense is just plain irresponsible :slight_smile:

Proper way of solving your task:

  • maintain a map of ProcessName->PID in your module. To do this, use Ps notify callbacks and/or ZwQueryXxx functions (depends on Windows version, I’m not sure Ps notify callbacks are available in XP).
  • all security and/or access rights related decisions are made on entry creation for this map. i.e. process creation. Only there should you check the process name. The results of the decisions should be put to some structure of your own layout.
  • then you can easily find this structure given the PID, and the PID is trivially extractable in the IO dispatch routines.
  • if some function does not work with the data format you have - then do not try to coerce the live data to the format expected by it. Sometimes just writing your own function, especially this simple, is better, easier, cheaper and more reliable.
  • C runtime is one world, and UNICODE_STRING is another. It is always better to use the functions from the proper “world”. Look at RtlXxx functions working with UNICODE_STRING.


Maxim S. Shatskih
Microsoft MVP on File System And Storage
xxxxx@storagecraft.com
http://www.storagecraft.com

Mr. Lennon… what you’re doing is REALLY no way at all to learn how to write kernel-mode code for Windows. Seriously. It’s a dumb project, even for an experiment, even for a student.

Learn to do things the right way. Don’t waste your time learning to do stupid, hack things that won’t work in the real world under real conditions. It’s silly and the things you think you’re learning you’ll either have to unlearn later or you’ll try to use them in the “real world” and your dev lead will beat senseless.

Peter
OSR

xxxxx@gmail.com wrote:

The solution was really easy actually, instead of comparing the Buffer member (which is PWSTR type), i was comparing the pointer directly so that works

if(wcsstr(procName->Buffer, proc.Buffer))
DbgPrint(“YOUPI !!”);

procName is a PUNICODE_STRING which is the current process, and proc is a UNICODE_STRING ( a proc name given from userland)

RtlCompareUnicodeString was designed for exactly this purpose, and it
knows how to handle non-zero-terminated strings.


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

*sigh*

Us: “You shouldn’t point a gun at your feet!”
You: “I know but it’s ok now, because I’m wearing flip-flops!”
Us: “Uhm… okie dokie.”

On Wed, May 29, 2013 at 5:06 AM, wrote:
> The solution was really easy actually, instead of comparing the Buffer member (which is PWSTR type), i was comparing the pointer directly so that works
>
> if(wcsstr(procName->Buffer, proc.Buffer))
> DbgPrint(“YOUPI !!”);
>
> procName is a PUNICODE_STRING which is the current process, and proc is a UNICODE_STRING ( a proc name given from userland)
>
> —
> NTDEV is sponsored by OSR
>
> OSR is HIRING!! See http://www.osr.com/careers
>
> 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