IoQueryFileDosDeviceName Causing BSOD

Hello all. I am new to the boards and to the Windows DDK. I had to pick it up for my new job. We are developing a Malware Development system and we have a portion that hooks all of the zw functions and passes the information to userland via IRP communications so we can create an infection tree.

So anyways I have been making improvements to the system as it wasn’t getting full path names for the targets of zwCreateFile, zwReadFile, and zwWriteFile, so I figured out how to do so with ObReferenceObjectByHandle. The only problem is I wasn’t getting a drive letter or a symbolic link in front of the path. So I learned about a function called IoQueryFileDosDeviceName…and it works…but after about 2 minutes of running it BSODs. It doesn’t give me anything like BAD_POOL_CALLER or anything, it just lists ws2ifsl.sys as the offending party. That is the winsock2 ifs layer if I’m not mistaken.

So armed with this knowledge, I realized that the part of our system that tracks TCP and DNS traffic uses Winsock. So I disabled it, and sure enough…no more BSOD. I am confused as to why this is happening…especially since I didn’t write the TCP, DNS portion.

But what I wanted to know is if there was a way I could make my call to IoQueryFileDosDeviceName and somehow ignore any FILE_OBJECTs that have to do with winsock2. Because I imagine if it worked for several minutes before crashing, then it must be BSODing when it finds FILE_OBJECT that both the TCP, DNS portion and my zw hooking portion are trying to use. Here is the code I use to find the path via the handle, including the call to IoQueryFileDosDeviceName:

int GetPathByHandle(PHANDLE handle, char *path, int pathLen) {
ANSI_STRING ansiFileName;
ANSI_STRING ansiDriveLetter;
PFILE_OBJECT fObject;
NTSTATUS myNtStatus;
POBJECT_NAME_INFORMATION pObjectInfo = ExAllocatePool(NonPagedPool, sizeof(OBJECT_NAME_INFORMATION)+1024);

if(path==NULL)
return -1;

RtlInitAnsiString(&ansiFileName, “NULL”);

myNtStatus = ObReferenceObjectByHandle((HANDLE)*handle, GENERIC_READ, *IoFileObjectType, KernelMode, &fObject, NULL);

if(myNtStatus >= STATUS_SUCCESS && fObject!=NULL && fObject->FileName.Buffer!=NULL){
IoQueryFileDosDeviceName(fObject, &pObjectInfo);
//DbgPrint(“VolumeLabel(%d): %wZ\n”, fObject->DeviceObject->Vpb->VolumeLabelLength, fObject->DeviceObject->Vpb->VolumeLabel);
RtlUnicodeStringToAnsiString(&ansiFileName, &(fObject->FileName), TRUE);
RtlUnicodeStringToAnsiString(&ansiDriveLetter, &(pObjectInfo->Name), TRUE);
RtlStringCbPrintfA(path, pathLen, “%s%s”,ansiDriveLetter.Buffer, ansiFileName.Buffer);
ObDereferenceObject(fObject);
ExFreePool(pObjectInfo);
//strncpy(path, ansiFileName.Buffer, pathLen);
}
else
return -1;

return 1;
}

Any assistance would be appreciated. This has me pulling my hair out…and getting the guy who made the TCP, DNS section to fix his code is out of the question.

I wanted to update that I just changed the code to ensure that the NT_STATUS of IoQueryFileDosDeviceName is coming back as NT_SUCCESS. And that pObjectInfo comes back non-null.

>

We are developing a Malware Development system

I’m really hoping that’s a typo and you mean Malware Detection System…

James

O_O;

Oh crap. Yeah. It’s a typo. I am tired. I have been at this all night.

So let it be known…Malware DETECTION System.

wrote in message news:xxxxx@ntdev…
> Hello all. …

> and my zw hooking portion are trying to use. …

You should not mention this on this newsgroup. Malware detection inside the
os is a lost battle anyway. Check previous numerous posts why.
They are alternatives & more promising techniques.

J.

Yeah…tell my boss that. lol

He just tells me what to code and I do it. He is a complete idiot. He used a global variable in his kernel code to hold path names, and he wondered why it often contained parts of other paths. And this man has a doctorate in CS.

Careful what you say… most people on the list have pretty thick skins but your boss may not, and this list is publicly archived and very searchable via google.

Sent from my iPhone

On 14/10/2010, at 22:26, “xxxxx@gmail.com” wrote:

> Yeah…tell my boss that. lol
>
> He just tells me what to code and I do it. He is a complete idiot. He used a global variable in his kernel code to hold path names, and he wondered why it often contained parts of other paths. And this man has a doctorate in CS.
>
> —
> 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

Yeah…I wish I could edit my post now…I am just a little perturbed at him right now.

IoQueryFileDosDeviceName:

ObjectNameInformation - you provide the address of a pointer, the
function allocates the object, you free it.

Your code is allocating the object, providing the address of the
pointer, the function is overwriting your allocated objects address,
you are freeing the functions allocated object and leaking the one you
allocated. After two minutes of this: BSOD.

Try prefast and driver verifier. Try reading the manual very freaking carefully.

Mark Roddy

On Thu, Oct 14, 2010 at 5:57 AM, wrote:
> Hello all. ?I am new to the boards and to the Windows DDK. ?I had to pick it up for my new job. ?We are developing a Malware Development system and we have a portion that hooks all of the zw functions and passes the information to userland via IRP communications so we can create an infection tree.
>
> So anyways I have been making improvements to the system as it wasn’t getting full path names for the targets of zwCreateFile, zwReadFile, and zwWriteFile, so I figured out how to do so with ObReferenceObjectByHandle. ?The only problem is I wasn’t getting a drive letter or a symbolic link in front of the path. ?So I learned about a function called IoQueryFileDosDeviceName…and it works…but after about 2 minutes of running it BSODs. ?It doesn’t give me anything like BAD_POOL_CALLER or anything, it just lists ws2ifsl.sys as the offending party. ?That is the winsock2 ifs layer if I’m not mistaken.
>
> So armed with this knowledge, I realized that the part of our system that tracks TCP and DNS traffic uses Winsock. ?So I disabled it, and sure enough…no more BSOD. ?I am confused as to why this is happening…especially since I didn’t write the TCP, DNS portion.
>
> But what I wanted to know is if there was a way I could make my call to IoQueryFileDosDeviceName and somehow ignore any FILE_OBJECTs that have to do with winsock2. ?Because I imagine if it worked for several minutes before crashing, then it must be BSODing when it finds FILE_OBJECT that both the TCP, DNS portion and my zw hooking portion are trying to use. ?Here is the code I use to find the path via the handle, including the call to IoQueryFileDosDeviceName:
>
> int GetPathByHandle(PHANDLE handle, char *path, int pathLen) {
> ? ? ? ?ANSI_STRING ansiFileName;
> ? ? ? ?ANSI_STRING ansiDriveLetter;
> ? ? ? ?PFILE_OBJECT fObject;
> ? ? ? ?NTSTATUS myNtStatus;
> ? ? ? ?POBJECT_NAME_INFORMATION pObjectInfo = ExAllocatePool(NonPagedPool, sizeof(OBJECT_NAME_INFORMATION)+1024);
>
> ? ? ? ?if(path==NULL)
> ? ? ? ? ? ? ? ?return -1;
>
> ? ? ? ?RtlInitAnsiString(&ansiFileName, “NULL”);
>
> ? ? ? ?myNtStatus = ObReferenceObjectByHandle((HANDLE)*handle, GENERIC_READ, *IoFileObjectType, KernelMode, &fObject, NULL);
>
> ? ? ? ?if(myNtStatus >= STATUS_SUCCESS && fObject!=NULL && fObject->FileName.Buffer!=NULL){
> ? ? ? ? ? ? ? ?IoQueryFileDosDeviceName(fObject, &pObjectInfo);
> ? ? ? ? ? ? ? ?//DbgPrint(“VolumeLabel(%d): %wZ\n”, fObject->DeviceObject->Vpb->VolumeLabelLength, fObject->DeviceObject->Vpb->VolumeLabel);
> ? ? ? ? ? ? ? ?RtlUnicodeStringToAnsiString(&ansiFileName, &(fObject->FileName), TRUE);
> ? ? ? ? ? ? ? ?RtlUnicodeStringToAnsiString(&ansiDriveLetter, &(pObjectInfo->Name), TRUE);
> ? ? ? ? ? ? ? ?RtlStringCbPrintfA(path, pathLen, “%s%s”,ansiDriveLetter.Buffer, ansiFileName.Buffer);
> ? ? ? ? ? ? ? ?ObDereferenceObject(fObject);
> ? ? ? ? ? ? ? ?ExFreePool(pObjectInfo);
> ? ? ? ? ? ? ? ?//strncpy(path, ansiFileName.Buffer, pathLen);
> ? ? ? ?}
> ? ? ? ?else
> ? ? ? ? ? ? ? ?return -1;
>
> ? ? ? ?return 1;
> }
>
> Any assistance would be appreciated. ?This has me pulling my hair out…and getting the guy who made the TCP, DNS section to fix his code is out of the question.
>
> —
> 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
>

If I don’t allocate the space for the device object, when I build it tells me that it’s uninitialized (as an error). So am I not supposed to allocate space for it?

And also it’s odd that the blue screen cites ws2ifsl.sys as the source of the problem. I disable the LSP portion of the detection system and poof…problem is gone.

Your code is just wrong and I pointed out its wrongness with respect
to the docs. I have no idea what you mean by " If I don’t allocate the
space for the device object, when I build it tells me that it’s
uninitialized (as an error). So am I not supposed to allocate space
for it?" but the answer is ‘yes do not allocate any memory’.

#include “ntifs.h”
void
test(PFILE_OBJECT FileObject)
{
POBJECT_NAME_INFORMATION ObjectNameInformation = NULL;

NTSTATUS Status = IoQueryFileDosDeviceName(FileObject,
&ObjectNameInformation);
if (NT_SUCCESS(Status))
{
ASSERT(ObjectNameInformation != NULL);
ExFreePool(ObjectNameInformation);
}
}

That should compile and work correctly.

Mark Roddy

On Thu, Oct 14, 2010 at 8:54 AM, wrote:
> If I don’t allocate the space for the device object, when I build it tells me that it’s uninitialized (as an error). ?So am I not supposed to allocate space for it?
>
> And also it’s odd that the blue screen cites ws2ifsl.sys as the source of the problem. ?I disable the LSP portion of the detection system and poof…problem is gone.
>
> —
> 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
>

Sheesh…no need for hostility pal. I appreciate the help none the less. I will test it. Apparently it was throwing that compile error because I wasn’t initializing it to NULL.

It still BSOD’ed when I made that change -_-;

  1. You post an ill formed question.

  2. NTDEV Sage (Mark) in earnest explains it.

  3. You post a twitty reply.

  4. NTDEV Sage (now likely justifiable thinking you rather impertinent) posts
    *CODE* which fixes the problem found in the first round.

  5. You post another twitty reply.

  6. You then post that “It still BSOD’ed …” without so much as any hint of
    additional information other than to make it sound like you just caught the
    NTDEV Sage in a trap as if his code was ‘wrong’.

Wow. An you think that the NTDEV Sage is going to put down what he is doing
to go out of his way to help you?

Your right. Your boss is a dingbat. Just not for the reasons you think.

Good Luck,
Dave Cattley

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@gmail.com
Sent: Thursday, October 14, 2010 9:45 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] IoQueryFileDosDeviceName Causing BSOD

It still BSOD’ed when I made that change -_-;


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

To clarify. In my code, I made the changes he mentioned. Essentially I set the pObjectInformation variable to NULL so that I wasn’t allocating memory whose address would eventually be overwritten by the call to the IoQueryFileDosDeviceName. I am certain it is the portion of our system that captures TCP and DNS traffic, as the BSOD says ws2ifsl.sys is what caused the BSOD. So I disabled it and it doesn’t BSOD anymore. So the problem seems to lie in when it tries to call IoQueryFileDosDeviceName on something related to Winsock. Perhaps a socket? What I was originally asking was if there was a way to filter out sockets based on the information thats in the FILE_OBJECT returned by ObReferenceObjectByHandle. And then Mark Roddy kindly pointed out some errors in my code. I honestly didn’t intend any disrespect or “twitty”-ness as you put it in my response…I am sorry you took it that way. I was simply posting what had happened when I had tried to implement the change he stated the last time…and then everyone ganged up on me like I had just eaten a baby. Also…I got that last bit of sarcasm there…that was very clever…but uncalled for.

A couple of things:

Can you post the actual or sanitized output of !analyze -v for your crash?
That is generally where the list ‘starts’ with a bugcheck.

The code sequence:

IoQueryFileDosDeviceName(fObject, &pObjectInfo);
//DbgPrint(“VolumeLabel(%d): %wZ\n”,
fObject->DeviceObject->Vpb->VolumeLabelLength,
fObject->DeviceObject->Vpb->VolumeLabel);
RtlUnicodeStringToAnsiString(&ansiFileName,
&(fObject->FileName), TRUE);
RtlUnicodeStringToAnsiString(&ansiDriveLetter,
&(pObjectInfo->Name), TRUE);
RtlStringCbPrintfA(path, pathLen,
“%s%s”,ansiDriveLetter.Buffer, ansiFileName.Buffer);

Can be accomplished with far less verbosity and worry regarding the
management of UNICODE to ANSI conversion by doing the following:

IoQueryFileDosDeviceName(fObject, &pObjectInfo);
//DbgPrint(“VolumeLabel(%d): %wZ\n”,
fObject->DeviceObject->Vpb->VolumeLabelLength,
fObject->DeviceObject->Vpb->VolumeLabel);
RtlStringCbPrintfA(path, pathLen, “%wZ%wZ”,
&(pObjectInfo->Name), &(fObject->FileName));

(or something like that)

Since RtlString…Printf.() can handle the conversion for you and without
any intermediate conversions.

Regarding the question about how in the context of ZwXxx() you might discern
that the FILE_OBJECT is related to Winsock:

The sockets layer in NT creates file objects against the AFD device.

That said, why do you want to exclude socket related FILE_OBJECTs from your
processing? Just to avoid tripping up something? I suggest you identify
the ‘something’ first and fix it because I can imagine it might be just as
problematic for other I/O stacks as well.

Good Luck,
Dave Cattley

I feel sheepish for asking…but where do I locate the crash dump file? I have the Windows Debugging Tools installed already.

I figured it out. I didn’t have XP set up to do a dump. I do now. Let me wait for it to crash.

You will be better served to setup a target machine to which you have a
‘live’ debugger attached. When the bugcheck occurs, the debugger will
break in before writing the crash-dump. !analyze works just fine (better
even sometimes) in that case.

I would say this is the preferred mode of operation when developing a
driver. Relying on crash dumps is a fine thing after development has
reached a stable point and you are collecting data from ‘the field’ about an
issue. When running the build/debug cycle, live debugging is a must.

Good Luck,
Dave Cattley

I’m doing my development inside a VMWare environment. Is it possible to set up the live debugger on the host of the VMWare environment?