PsSetLoadImageNotifyRoutine ImageSize

Hi,

According to the documentation, ImageSize field of IMAGE_INFO is “virtual size, in bytes, of the image”. Lately, when I’ve analyzed a BSOD I’ve noticed that ImageSize was exactly one page size (0x1000) while the “on-disk” image (\Windows\SysWOW64\kernel32.dll) is much larger.
Is that possible? e.g. only partial of the image to load? If yes - what can be a trigger for that?

Thanks,
Shahar.

Documentation is correct, ImageSize is the virtual size of a driver image or
a DLL/EXE image. It should be set correctly (however I got calls on older OS
where it was zero – when I disassembled PsSetLoad- routine, I found out OS
could set ImageSize to zero if there was a problem with image mapping).

Since you got a dump from 64-bit machine, I assume variables/registers have
been already reused and you think it’s 0x1000, is it possible? You can also
check “lmvm kernel32” to see where this module is mapped. If you got a BSOD,
is it really caused by that possible small unexpected ImageSize=0x1000
value?

Petr

Hi Petr,

Thanks for the reply. The 0x1000 size is correct. To get that value I’ve analyzed the address of the IMAGE_INFO structure which its ExtendedInfoPresent flag was set so I’ve dumped the contents of the IMAGE_INFO_EX structure and all its fields seems to be valid.
The ImageBase is pointing to 0a4e0000 which is a valid virtual address while 0a4e0000+1000 is invalid (see below).
This lead me to a conclusion that the notification callback routine might be called with only partial of the image. The BSOD happened since the code assumed that the whole image was loaded, it calculated an offset to the export table which was beyond the first 0x1000 bytes and when it tried to access that memory the system crashed.
This is a part of the callstack which might hint why a partial of the image was loaded:

03 fffff8800b1e3700 fffff800035fa662 nt!PsCallImageNotifyRoutines+0xdc
04 fffff8800b1e3760 fffff800035f66d7 nt!MiMapViewOfImageSection+0x9b2
05 fffff8800b1e38b0 fffff800035f69de nt!MiMapViewOfSection+0x367
06 fffff8800b1e39a0 fffff800032d8e13 nt!NtMapViewOfSection+0x2bd
07 fffff8800b1e3a70 0000000077c8153a nt!KiSystemServiceCopyEnd+0x13
08 000000001dc3e2c8 0000000074e55cbd ntdll!ZwMapViewOfSection+0xa

0: kd> !pte 0a4e0000
VA 000000000a4e0000
PXE at FFFFF6FB7DBED000 PPE at FFFFF6FB7DA00000 PDE at FFFFF6FB40000290 PTE at FFFFF68000052700
contains 007000000B842867 contains 0350000073F46867 contains 26F0000020058867 contains 8F90000001DA4025
pfn b842 —DA–UWEV pfn 73f46 —DA–UWEV pfn 20058 —DA–UWEV pfn 1da4 ----A–UR-V

0: kd> !pte 0a4e0000+1000
VA 000000000a4e1000
PXE at FFFFF6FB7DBED000 PPE at FFFFF6FB7DA00000 PDE at FFFFF6FB40000290 PTE at FFFFF68000052708
contains 007000000B842867 contains 0350000073F46867 contains 26F0000020058867 contains 0000000000000000
pfn b842 —DA–UWEV pfn 73f46 —DA–UWEV pfn 20058 —DA–UWEV not valid

Shahar

Your driver must be extremely careful not to trust the contents of the image being mapped, so as to avoid introducing security vulnerabilities where a malicious user could attack your driver and gain control over the system. The export table information in the image header might not fit typical validity requirements, for example. Furthermore, the possibility exists that if you read data from the image multiple times, you might not get the same answer back twice (e.g. for a writeable part of the image that another thread in the process is concurrently modifying).

Partial mappings of an image are also legal, although less frequently used. (You can use CreateFileMapping with SEC_IMAGE and MapViewOfFile specifying a particular file offset and length to map a partial view of an image yourself, for example.)

Properly examining the image headers of an image located in the user mode portion of the address space from kernel mode is complicated and difficult to get right. I’d highly recommend against such an approach in the general sense, as it is very easy to introduce a vulnerability along the way.

  • S (Msft)

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@checkpoint.com
Sent: Sunday, October 13, 2013 12:53 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] PsSetLoadImageNotifyRoutine ImageSize

Hi Petr,

Thanks for the reply. The 0x1000 size is correct. To get that value I’ve analyzed the address of the IMAGE_INFO structure which its ExtendedInfoPresent flag was set so I’ve dumped the contents of the IMAGE_INFO_EX structure and all its fields seems to be valid.
The ImageBase is pointing to 0a4e0000 which is a valid virtual address while 0a4e0000+1000 is invalid (see below).
This lead me to a conclusion that the notification callback routine might be called with only partial of the image. The BSOD happened since the code assumed that the whole image was loaded, it calculated an offset to the export table which was beyond the first 0x1000 bytes and when it tried to access that memory the system crashed.
This is a part of the callstack which might hint why a partial of the image was loaded:

03 fffff8800b1e3700 fffff800035fa662 nt!PsCallImageNotifyRoutines+0xdc
04 fffff8800b1e3760 fffff800035f66d7 nt!MiMapViewOfImageSection+0x9b2
05 fffff8800b1e38b0 fffff800035f69de nt!MiMapViewOfSection+0x367
06 fffff8800b1e39a0 fffff800032d8e13 nt!NtMapViewOfSection+0x2bd
07 fffff8800b1e3a70 0000000077c8153a nt!KiSystemServiceCopyEnd+0x13
08 000000001dc3e2c8 0000000074e55cbd ntdll!ZwMapViewOfSection+0xa

0: kd> !pte 0a4e0000
VA 000000000a4e0000
PXE at FFFFF6FB7DBED000 PPE at FFFFF6FB7DA00000 PDE at FFFFF6FB40000290 PTE at FFFFF68000052700
contains 007000000B842867 contains 0350000073F46867 contains 26F0000020058867 contains 8F90000001DA4025
pfn b842 —DA–UWEV pfn 73f46 —DA–UWEV pfn 20058 —DA–UWEV pfn 1da4 ----A–UR-V

0: kd> !pte 0a4e0000+1000
VA 000000000a4e1000
PXE at FFFFF6FB7DBED000 PPE at FFFFF6FB7DA00000 PDE at FFFFF6FB40000290 PTE at FFFFF68000052708
contains 007000000B842867 contains 0350000073F46867 contains 26F0000020058867 contains 0000000000000000
pfn b842 —DA–UWEV pfn 73f46 —DA–UWEV pfn 20058 —DA–UWEV not valid

Shahar


NTDEV is sponsored by OSR

Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev

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 your reply. I now understand the whole picture. Thanks again, Shahar.