wrong path reported in LoadImageNotifyRoutine handler

Hello gurus,

Recently I’ve met an interesting problem in XP SP2 and Vista (all with latest updates). In my driver I register an image load callback using the following code:

[…] some code before …

ntStatus = PsSetLoadImageNotifyRoutine(ProcessImageLoad);

[…] some code after …

Which is working fine and it reports a valid path of an image being loaded until I rename the directory where executable file resides.

For example, if I run an executable “C:\AAA\file.exe” I got the following path in handler function: “\Device\HarddiskVolume1\AAA\file.exe” which is correct. If I close application file.exe and rename the folder AAA into BBB and run the application, my handler routine obtains me with the same path, i.e. “\Device\HarddiskVolume1\AAA\file.exe” instead of “\Device\HarddiskVolume1\BBB\file.exe” which is a critical issue for me, because I try to calculate SHA1 for the file, and since the path is invalid I got error.

Can someone please shed a light on this issue, and tell me what am I missing?

Thanks, Petr Kizima

Hi,

I can confirm this, however I can’t remember the exact Windows versions
and service packs up to which this is the scenario (something like: up
to XP SP3 this is broken, from Vista up it is working). Very likely it
is a bug in the OS.

have a nice day,

Sandor

xxxxx@gmail.com wrote:

Hello gurus,

Recently I’ve met an interesting problem in XP SP2 and Vista (all with latest updates). In my driver I register an image load callback using the following code:

[…] some code before …

ntStatus = PsSetLoadImageNotifyRoutine(ProcessImageLoad);

[…] some code after …

Which is working fine and it reports a valid path of an image being loaded until I rename the directory where executable file resides.

For example, if I run an executable “C:\AAA\file.exe” I got the following path in handler function: “\Device\HarddiskVolume1\AAA\file.exe” which is correct. If I close application file.exe and rename the folder AAA into BBB and run the application, my handler routine obtains me with the same path, i.e. “\Device\HarddiskVolume1\AAA\file.exe” instead of “\Device\HarddiskVolume1\BBB\file.exe” which is a critical issue for me, because I try to calculate SHA1 for the file, and since the path is invalid I got error.

Can someone please shed a light on this issue, and tell me what am I missing?

Thanks, Petr Kizima


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, this problem is known.

30 minute fix, build a minifilter that catches and hashes.

I don’t think you’ll find a real solution otherwise, just capture
IRP_MJ_CREATE in your post
callback, hash, and you’ll be ok.

Matt

Thank you all for reply. I wonder, is there any official Microsoft statement which explains the roots of this problem and any possible workarounds? Or can I open a ticket (I am MSDN subscriber) for Microsoft to fix it?

The problem is that I need to calculate the file hashes only when its being loaded (executed), and I do not need to touch it when it gets renamed. So the solution with writing minifilter does not suits me in a best way, because I will need to maintain a table of pathes, sync them, etc which sounds overhead for me.

Thanks,

It might be the tunneling thing (wich BTW was made on purpose for MSDOS compatibility!).

To be sure it is, try the following temporary patch, and test it again.

Locate the following Registry branch:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem

Add a DWORD value with the name MaximumTunnelEntries an set it to a value of zero.

Restart your system.

Does it keep telling you the wrong name after renaming ?

Anyway, for XP and VISTA you can get the actual current name using QueryVirtualMemory.

Inaki.

-----Mensaje original-----
De: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] En nombre de xxxxx@gmail.com
Enviado el: jueves, 07 de agosto de 2008 15:01
Para: Windows System Software Devs Interest List
Asunto: RE:[ntdev] wrong path reported in LoadImageNotifyRoutine handler

Thank you all for reply. I wonder, is there any official Microsoft statement which explains the roots of this problem and any possible workarounds? Or can I open a ticket (I am MSDN subscriber) for Microsoft to fix it?

The problem is that I need to calculate the file hashes only when its being loaded (executed), and I do not need to touch it when it gets renamed. So the solution with writing minifilter does not suits me in a best way, because I will need to maintain a table of pathes, sync them, etc which sounds overhead for me.

Thanks,


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

Don’t do this.

On top of this problem, image sections (including the main process image) are opened on top of files created with FILE_SHARE_DELETE, so they may a any point be renamed away and have a substitute file replaced as the same name. You must not use the image path for security decisions or indeed any sensitive decisions.

  • S

-----Original Message-----
From: xxxxx@gmail.com
Sent: Thursday, August 07, 2008 05:21
To: Windows System Software Devs Interest List
Subject: [ntdev] wrong path reported in LoadImageNotifyRoutine handler

Hello gurus,

Recently I’ve met an interesting problem in XP SP2 and Vista (all with latest updates). In my driver I register an image load callback using the following code:

[…] some code before …

ntStatus = PsSetLoadImageNotifyRoutine(ProcessImageLoad);

[…] some code after …

Which is working fine and it reports a valid path of an image being loaded until I rename the directory where executable file resides.

For example, if I run an executable “C:\AAA\file.exe” I got the following path in handler function: “\Device\HarddiskVolume1\AAA\file.exe” which is correct. If I close application file.exe and rename the folder AAA into BBB and run the application, my handler routine obtains me with the same path, i.e. “\Device\HarddiskVolume1\AAA\file.exe” instead of “\Device\HarddiskVolume1\BBB\file.exe” which is a critical issue for me, because I try to calculate SHA1 for the file, and since the path is invalid I got error.

Can someone please shed a light on this issue, and tell me what am I missing?

Thanks, Petr Kizima


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

Once again, querying the “current” name is not reliable as it can be renamed away at any time due to the sharing protection ldr/CreateProcess apply when creating the file objects used for the image section mapping.

This is easy to see as you can rename away (but not immediately delete) a loaded exe or dll in explorer, provided the filesystem ACLs give you such rights.

Depending on the filename can very easily lead to security holes, esp. Once the OP mentions hashing the image. An attacker can create a process using evil.exe and then rename it and rename good.exe to the old filename, and this approach (PsSetImageLoadNotifyRoutine) would be none the wiser.

This may be perhaps mitigated if you enforce a rul that the exe must load from a “secure” location, but that is its own can of very big worms.

  • S

-----Original Message-----
From: I?aki Castillo
Sent: Thursday, August 07, 2008 09:08
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] wrong path reported in LoadImageNotifyRoutine handler

It might be the tunneling thing (wich BTW was made on purpose for MSDOS compatibility!).

To be sure it is, try the following temporary patch, and test it again.

Locate the following Registry branch:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem

Add a DWORD value with the name MaximumTunnelEntries an set it to a value of zero.

Restart your system.

Does it keep telling you the wrong name after renaming ?

Anyway, for XP and VISTA you can get the actual current name using QueryVirtualMemory.

Inaki.

-----Mensaje original-----
De: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] En nombre de xxxxx@gmail.com
Enviado el: jueves, 07 de agosto de 2008 15:01
Para: Windows System Software Devs Interest List
Asunto: RE:[ntdev] wrong path reported in LoadImageNotifyRoutine handler

Thank you all for reply. I wonder, is there any official Microsoft statement which explains the roots of this problem and any possible workarounds? Or can I open a ticket (I am MSDN subscriber) for Microsoft to fix it?

The problem is that I need to calculate the file hashes only when its being loaded (executed), and I do not need to touch it when it gets renamed. So the solution with writing minifilter does not suits me in a best way, because I will need to maintain a table of pathes, sync them, etc which sounds overhead for me.

Thanks,


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


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

Inaski,

Thanks for a hint. I tried it and it did NOT help. The same problem persist.

Have you tried QueryVritualmemory to get the current name?
BTW don’t do this within the notify routine.

-----Mensaje original-----
De: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] En nombre de xxxxx@gmail.com
Enviado el: jueves, 07 de agosto de 2008 17:10
Para: Windows System Software Devs Interest List
Asunto: RE:[ntdev] wrong path reported in LoadImageNotifyRoutine handler

Inaski,

Thanks for a hint. I tried it and it did NOT help. The same problem persist.


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

Ken,

No paranoics, please. I am not doing a security software such as filter for av or fw. I am just trying to investigate the sequence of processes being started and closed. My main question is not about the design of my software, my question is more technical and detailed: why do I get improper image for a loaded process if I change its folder name.

Thanks,

Inaski,

Sorry, have no references to QueryVritualmemory in documentation and in google.

Probably you do mean that I should attach to stack of process, and read virtual memory to get the process path from PEB? Well, this sounds like a solution, but I suspect that I might get problems of syncronization while reading memory of PEB + this solution seems too hackery for me. I also can consider using ZwQueryInformationProcess and ProcessBasicInformation but I am out of luck in Windows 2k

> Sorry, have no references to QueryVritualmemory in documentation and in

google.
He meant

SIZE_T WINAPI VirtualQuery(
__in LPCVOID lpAddress,
__out PMEMORY_BASIC_INFORMATION lpBuffer,
__in SIZE_T dwLength
);

and friends.

It’s UM.

----- Original Message -----
From:
To: “Windows System Software Devs Interest List”
Sent: Thursday, August 07, 2008 11:22 AM
Subject: RE:[ntdev] wrong path reported in LoadImageNotifyRoutine handler

> Inaski,
>
> Sorry, have no references to QueryVritualmemory in documentation and in
> google.
>
> Probably you do mean that I should attach to stack of process, and read
> virtual memory to get the process path from PEB? Well, this sounds like a
> solution, but I suspect that I might get problems of syncronization while
> reading memory of PEB + this solution seems too hackery for me. I also can
> consider using ZwQueryInformationProcess and ProcessBasicInformation but I
> am out of luck in Windows 2k
>
> —
> 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

Well, main problem of using UM functions in this case is perfomance issues. Also, I am out of luck to load UM helper application at early stage of driver loading (i.e., before smss.exe starts).

I am still trying to find some official Microsoft KB on this issue.

> I am just trying to investigate the sequence of processes being started

and closed.My main question is not about the design of my software,
my question is more technical and detailed: why do I get improper
image for a loaded process if I change its folder name.

I think this happens because the control area for the process
image remains cached in memory when the parent directory is renamed.
The next time this image is loaded the cached control area is used,
and the file object inside it still contains the original name.

I believe this behavior is by design. A similar situation can occur with the
new process create notifications in Vista SP1
(PsSetCreateProcessNotifyRoutineEx).
For processes created through the regular process creation path
(CreateProcess/NtCreateUserProcess) the exact file name should be
available (FileOpenNameAvailable will be TRUE), but if someone
calls the legacy (and undocumented) NtCreateProcess interface, which
takes a section handle as a parameter, the notification might contain an
out-of-date file object because of control area caching.


This posting is provided “AS IS” with no warranties, and confers no
rights.

I meant ZwQueryVirtualMemory.
This does not work as you describe, no PEB involved. If it would you always would get the wrong name!
Instead it relies on reading the name associated to the mapped image file, which incidentally is always right, even if you rename the file.

However, as you would need a handle to the process to call this function, you cannot use it within the same function you are receiving the callback.
The reason is that Microsoft holds a lock on the process while calling your notification function, so if you intend to open the process within the notification function, you will deadlock. Note that this applies only to Image-Load-Notification routines, not to Create-Process notification.

This behavior is fixed on Vista+SP1 but it is not on earlier versions of Windows.
If you need to get the right name you can use that function above but outside the notification function.

Inaki.

-----Mensaje original-----
De: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] En nombre de xxxxx@gmail.com
Enviado el: jueves, 07 de agosto de 2008 17:22
Para: Windows System Software Devs Interest List
Asunto: RE:[ntdev] wrong path reported in LoadImageNotifyRoutine handler

Inaski,

Sorry, have no references to QueryVritualmemory in documentation and in google.

Probably you do mean that I should attach to stack of process, and read virtual memory to get the process path from PEB? Well, this sounds like a solution, but I suspect that I might get problems of syncronization while reading memory of PEB + this solution seems too hackery for me. I also can consider using ZwQueryInformationProcess and ProcessBasicInformation but I am out of luck in Windows 2k


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

> I meant ZwQueryVirtualMemory. This does not work as you describe,

no PEB involved. If it would you always would get the wrong name!
Instead it relies on reading the name associated to the mapped image
file, which incidentally is always right, even if you rename the file.

If you rename the containing directory though, you should get the old
name.

C:\temp>md x
C:\temp>copy %windir%\System32\notepad.exe x
C:\temp>x\notepad.exe

C:\temp>ren x y
C:\temp>y\notepad.exe

Now examine the running instance of notepad in debugger. The PEB contains
the new name:

0:000> lmf
00000000ffeb0000 00000000ffedf000 notepad C:\temp\y\notepad.exe

The section object however contains the old name:

0:000> !mapped_file 00000000`ffeb0000
Mapped file name for 00000000ffeb0000:
‘\Device\HarddiskVolume1\temp\x\notepad.exe’

!mapped_file calls GetMappedFileName, which calls NtQueryVirtualMemory.


This posting is provided “AS IS” with no warranties, and confers no
rights.