Issue while attempting to retrieve the file object's path name associated with process section

Hi All,

We encountered a issue while attempting to retrieve the file object’s
path name associated with process section object after renaming the
folder that contains the executable image.

File System: NTFS
OS: seems like all x32 NT based (2000, XP, 2003 & their SP)

Steps to reproduce:

  1. Create a new folder named “1” on disk (for example, C:)
  2. Copy any executable file (e.g., “test.exe”) to the created folder.
  3. Execute this application.
  4. Exit from this application (e.g., “test.exe”).
  5. Rename folder “1” to another name (for example, “2”).
  6. Execute the application located in this folder (“2\test.exe”) that
    was executed at step 3.

What did we get?
The new process is successfully running, however we can’t get the
correct path name for the section object associated with this process,
and also we got the incorrect path name in the
PsSetLoadImageNotifyRoutine callback routine (see below example #4).

As a result of querying the path name of process section we got:
\Device\HardDiskXXX\1\test.exe

Instead of expected:
\Device\HardDiskXXX\2\test.exe

We tried the different methods of getting the path name for the
section object associated with the process. All methods, except the
reading PEB give the incorrect path name:(

Example #1.

PSECTION pSection;

get section for process executable image

PFILE_OBJECT pSectionFile =
pSection->Segment->ControlArea->FilePointer;
ObQueryNameString(pSectionFile, …);

Example #2.

Use IoQueryFileInformation for file object associated with process
section object
or
use ObOpenObjectByName AND ZwQueryInformationFile for this file object

Example #3.
Direct scan file object fields and get file path name.

Example #4.

VOID
NTAPI
_PsSetLoadImageNotifyRoutine(
IN PUNICODE_STRING FullImageName,
IN HANDLE ProcessId,
IN PIMAGE_INFO ImageInfo)
{
KdPrint((“Load image: %ws\n”, FullImageName->Buffer));
}

EXTERN_C
NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT pDriverObject,
IN PUNICODE_STRING pRegistryPath)
{
return PsSetLoadImageNotifyRoutine(&_PsSetLoadImageNotifyRoutine);
}

Basing on PDB information (ntoskrnl.exe) the unexported function
MmGetFileNameForSection that is called
before executing load-image callback routine got the invalid path name
also.

What can anybody say on this matter?

Best regards,
Andrey Alekseev

Development Team
ISV System Safety Ltd.
http://www.syssafety.com

xxxxx@syssafety.com wrote:

Hi All,

We encountered a issue while attempting to retrieve the file object’s
path name associated with process section object after renaming the
folder that contains the executable image.

File System: NTFS
OS: seems like all x32 NT based (2000, XP, 2003 & their SP)

Steps to reproduce:

  1. Create a new folder named “1” on disk (for example, C:)
  2. Copy any executable file (e.g., “test.exe”) to the created folder.
  3. Execute this application.
  4. Exit from this application (e.g., “test.exe”).
  5. Rename folder “1” to another name (for example, “2”).
  6. Execute the application located in this folder (“2\test.exe”) that
    was executed at step 3.

What did we get?
The new process is successfully running, however we can’t get the
correct path name for the section object associated with this process,
and also we got the incorrect path name in the
PsSetLoadImageNotifyRoutine callback routine (see below example #4).

As a result of querying the path name of process section we got:
\Device\HardDiskXXX\1\test.exe

Instead of expected:
\Device\HardDiskXXX\2\test.exe

We tried the different methods of getting the path name for the
section object associated with the process. All methods, except the
reading PEB give the incorrect path name:(

Example #1.

PSECTION pSection;

get section for process executable image

PFILE_OBJECT pSectionFile =
pSection->Segment->ControlArea->FilePointer;
ObQueryNameString(pSectionFile, …);

Example #2.

Use IoQueryFileInformation for file object associated with process
section object
or
use ObOpenObjectByName AND ZwQueryInformationFile for this file object

Example #3.
Direct scan file object fields and get file path name.

Example #4.

VOID
NTAPI
_PsSetLoadImageNotifyRoutine(
IN PUNICODE_STRING FullImageName,
IN HANDLE ProcessId,
IN PIMAGE_INFO ImageInfo)
{
KdPrint((“Load image: %ws\n”, FullImageName->Buffer));
}

EXTERN_C
NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT pDriverObject,
IN PUNICODE_STRING pRegistryPath)
{
return PsSetLoadImageNotifyRoutine(&_PsSetLoadImageNotifyRoutine);
}

Basing on PDB information (ntoskrnl.exe) the unexported function
MmGetFileNameForSection that is called
before executing load-image callback routine got the invalid path name
also.

What can anybody say on this matter?

Best regards,
Andrey Alekseev

Development Team
ISV System Safety Ltd.
http://www.syssafety.com

Hi,

I can repro this…

lkd> dt 0x8177b658 _FILE_OBJECT
+0x000 Type : 5
+0x002 Size : 112
+0x004 DeviceObject : 0x824f5570 _DEVICE_OBJECT
+0x008 Vpb : 0x8251a288 _VPB
+0x00c FsContext : 0xe24370d0
+0x010 FsContext2 : 0xe25cca58
+0x014 SectionObjectPointer : 0xff2e4c14 _SECTION_OBJECT_POINTERS
+0x018 PrivateCacheMap : (null)
+0x01c FinalStatus : 0
+0x020 RelatedFileObject : (null)
+0x024 LockOperation : 0 ‘’
+0x025 DeletePending : 0 ‘’
+0x026 ReadAccess : 0x1 ‘’
+0x027 WriteAccess : 0 ‘’
+0x028 DeleteAccess : 0 ‘’
+0x029 SharedRead : 0x1 ‘’
+0x02a SharedWrite : 0 ‘’
+0x02b SharedDelete : 0x1 ‘’
+0x02c Flags : 0x44042
+0x030 FileName : _UNICODE_STRING “\1\NOTEPAD.EXE”

This is some pretty interesting behaviour… likely caused by caching…

If this issue only happened while reading these structures I wouldn’t
care much…after all, these are private structures and your driver
shouldn’t go munching into them…they can change from one OS revision
to the next, and you might find yourself reading a NULL pointer or even
a totally different structure. However, PsSetLoadImageNotifyRoutine is
fair game and it should be returning you the right image name.

Now I’m sure there could be some ways of doing this yourself
(KeStackAttachProcess to it, read the PEB, KeStackUnattach), but this is
again dealing with undocumented structures that change (well OK, the PEB
was specially designed to remain pretty constant, but you should still
shouldn’t read it)…

The actual bug about renaming the file has been in the kernel since
Windows 2000 and has already been discussed here (way back in 2001 or
2002), but nobody from MS stepped up with any acknowledgement (And the
topic had gotten way offtopic).

Best regards,
Alex Ionescu

Hi,

may be it was caused by the cache manager.
yes, there are no problem with getting the required information with other
methods (e.g. PEB)

but all NT based OS’es have this problem and this question is still open:
when this issue will be fixed?
especially since you said this problem was discussed in 2001-2002. There
were enough time to fix this bug.

some antiviruses & HIPS can use load-image callback routines
(PsSetLoadImageNotifyRoutine) to determine
the status of the loaded image.
what do they receive in this case?:frowning:

or MS will return to this problem only when there would be found a way to
use this issue
to force some antiviruses to bypass the scanning of the running process? - I
think it will be found.

Best regards,
Andrey Alekseev
Development Team
ISV System Safety Ltd.
http://www.syssafety.com

“Alex Ionescu [397670]” wrote in message
news:xxxxx@ntdev…
> xxxxx@syssafety.com wrote:
>> Hi All,
>>
>> We encountered a issue while attempting to retrieve the file object’s
>> path name associated with process section object after renaming the
>> folder that contains the executable image.
>>
>> File System: NTFS
>> OS: seems like all x32 NT based (2000, XP, 2003 & their SP)
>>
>> Steps to reproduce:
>> 1. Create a new folder named “1” on disk (for example, C:)
>> 2. Copy any executable file (e.g., “test.exe”) to the created folder.
>> 3. Execute this application.
>> 4. Exit from this application (e.g., “test.exe”).
>> 5. Rename folder “1” to another name (for example, “2”).
>> 6. Execute the application located in this folder (“2\test.exe”) that
>> was executed at step 3.
>>
>> What did we get?
>> The new process is successfully running, however we can’t get the
>> correct path name for the section object associated with this process,
>> and also we got the incorrect path name in the
>> PsSetLoadImageNotifyRoutine callback routine (see below example #4).
>>
>> As a result of querying the path name of process section we got:
>> \Device\HardDiskXXX\1\test.exe
>>
>> Instead of expected:
>> \Device\HardDiskXXX\2\test.exe
>>
>> We tried the different methods of getting the path name for the
>> section object associated with the process. All methods, except the
>> reading PEB give the incorrect path name:(
>>
>> Example #1.
>>
>> PSECTION pSection;
>> …
>> get section for process executable image
>> …
>> PFILE_OBJECT pSectionFile =
>> pSection->Segment->ControlArea->FilePointer;
>> ObQueryNameString(pSectionFile, …);
>>
>> Example #2.
>>
>> Use IoQueryFileInformation for file object associated with process
>> section object
>> or
>> use ObOpenObjectByName AND ZwQueryInformationFile for this file object
>>
>> Example #3.
>> Direct scan file object fields and get file path name.
>>
>> Example #4.
>>
>> VOID
>> NTAPI
>> _PsSetLoadImageNotifyRoutine(
>> IN PUNICODE_STRING FullImageName,
>> IN HANDLE ProcessId,
>> IN PIMAGE_INFO ImageInfo)
>> {
>> KdPrint((“Load image: %ws\n”, FullImageName->Buffer));
>> }
>>
>> EXTERN_C
>> NTSTATUS
>> DriverEntry(
>> IN PDRIVER_OBJECT pDriverObject,
>> IN PUNICODE_STRING pRegistryPath)
>> {
>> return PsSetLoadImageNotifyRoutine(&_PsSetLoadImageNotifyRoutine);
>> }
>>
>> Basing on PDB information (ntoskrnl.exe) the unexported function
>> MmGetFileNameForSection that is called
>> before executing load-image callback routine got the invalid path name
>> also.
>>
>> What can anybody say on this matter?
>>
>> Best regards,
>> Andrey Alekseev
>>
>> Development Team
>> ISV System Safety Ltd.
>> http://www.syssafety.com
>>
>>
>>
>
> Hi,
>
> I can repro this…
>
> lkd> dt 0x8177b658 _FILE_OBJECT
> +0x000 Type : 5
> +0x002 Size : 112
> +0x004 DeviceObject : 0x824f5570 _DEVICE_OBJECT
> +0x008 Vpb : 0x8251a288 _VPB
> +0x00c FsContext : 0xe24370d0
> +0x010 FsContext2 : 0xe25cca58
> +0x014 SectionObjectPointer : 0xff2e4c14 _SECTION_OBJECT_POINTERS
> +0x018 PrivateCacheMap : (null)
> +0x01c FinalStatus : 0
> +0x020 RelatedFileObject : (null)
> +0x024 LockOperation : 0 ‘’
> +0x025 DeletePending : 0 ‘’
> +0x026 ReadAccess : 0x1 ‘’
> +0x027 WriteAccess : 0 ‘’
> +0x028 DeleteAccess : 0 ‘’
> +0x029 SharedRead : 0x1 ‘’
> +0x02a SharedWrite : 0 ‘’
> +0x02b SharedDelete : 0x1 ‘’
> +0x02c Flags : 0x44042
> +0x030 FileName : _UNICODE_STRING “\1\NOTEPAD.EXE”
>
> This is some pretty interesting behaviour… likely caused by caching…
>
> If this issue only happened while reading these structures I wouldn’t care
> much…after all, these are private structures and your driver shouldn’t
> go munching into them…they can change from one OS revision to the next,
> and you might find yourself reading a NULL pointer or even a totally
> different structure. However, PsSetLoadImageNotifyRoutine is fair game and
> it should be returning you the right image name.
>
> Now I’m sure there could be some ways of doing this yourself
> (KeStackAttachProcess to it, read the PEB, KeStackUnattach), but this is
> again dealing with undocumented structures that change (well OK, the PEB
> was specially designed to remain pretty constant, but you should still
> shouldn’t read it)…
>
> The actual bug about renaming the file has been in the kernel since
> Windows 2000 and has already been discussed here (way back in 2001 or
> 2002), but nobody from MS stepped up with any acknowledgement (And the
> topic had gotten way offtopic).
>
> Best regards,
> Alex Ionescu
>

Andrey Alekseev wrote:

Hi,

may be it was caused by the cache manager.
yes, there are no problem with getting the required information with other
methods (e.g. PEB)

but all NT based OS’es have this problem and this question is still open:
when this issue will be fixed?
especially since you said this problem was discussed in 2001-2002. There
were enough time to fix this bug.

Perhaps nobody filed an actual bug report on it yet? I am in the
Vista/Server program so I will check this out for you.

some antiviruses & HIPS can use load-image callback routines
(PsSetLoadImageNotifyRoutine) to determine
the status of the loaded image.
what do they receive in this case?:frowning:

I would hope most anti-viruses use an IFS mini-filter/legacy filter and
intercept the IRPs directly, instead of relying on
PsSetLoadImageNotifyRoutine… although if the File Object itself still
has the old name, I don’t know if even that would help.

or MS will return to this problem only when there would be found a way to
use this issue
to force some antiviruses to bypass the scanning of the running process? - I
think it will be found.

It does seem like an interesting way to bypass anti-viruses which use
this API… but again, it’s possible MS never bothered with this because
not a lot of people found this bug. I’ll submit a formal report and see
what they have to say.

Best regards,
Alex Ionescu

Best regards,
Andrey Alekseev
Development Team
ISV System Safety Ltd.
http://www.syssafety.com

Hi Alex,

yes, certainly - anti-viruses must use FS filter driver - let’s hope for the
best;) - but how the other software? :frowning:
may be we’ll contact with MS about this issue directly also.
may be and this bug will be fixed sometime;)

thanks,

Best regards,
Andrey Alekseev

“Alex Ionescu [397670]” wrote in message
news:xxxxx@ntdev…
> Andrey Alekseev wrote:
>> Hi,
>>
>> may be it was caused by the cache manager.
>> yes, there are no problem with getting the required information with
>> other methods (e.g. PEB)
>>
>> but all NT based OS’es have this problem and this question is still open:
>> when this issue will be fixed?
>> especially since you said this problem was discussed in 2001-2002. There
>> were enough time to fix this bug.
>
> Perhaps nobody filed an actual bug report on it yet? I am in the
> Vista/Server program so I will check this out for you.
>
>>
>> some antiviruses & HIPS can use load-image callback routines
>> (PsSetLoadImageNotifyRoutine) to determine
>> the status of the loaded image.
>> what do they receive in this case?:frowning:
>
> I would hope most anti-viruses use an IFS mini-filter/legacy filter and
> intercept the IRPs directly, instead of relying on
> PsSetLoadImageNotifyRoutine… although if the File Object itself still
> has the old name, I don’t know if even that would help.
>
>>
>> or MS will return to this problem only when there would be found a way to
>> use this issue
>> to force some antiviruses to bypass the scanning of the running
>> process? - I think it will be found.
>
> It does seem like an interesting way to bypass anti-viruses which use this
> API… but again, it’s possible MS never bothered with this because not a
> lot of people found this bug. I’ll submit a formal report and see what
> they have to say.
>
> Best regards,
> Alex Ionescu
>
>
>>
>> Best regards,
>> Andrey Alekseev
>> Development Team
>> ISV System Safety Ltd.
>> http://www.syssafety.com
>>
>

The issue you see is called file system tunelling…
a windows file system feature
in a filter driver you can use
FltGetTunneledName to get the real name
Take a look at KB172190

You know you just answered a question for 2006, right?

Adds a new meaning to “bring out your dead!”

Peter