Acquire for create section with PAGE_READWRITE when executing

I am seeing something i did not expect. I am intercepting Acquire for Nt create section (in a mini-filter) and looking for SyncTypeCreateSection with PAGE_READWRITE access. I did not expect to see it when executing a file (.exe) and the first time I execute it I do not see it. I see the acquire for PAGE_READ and for PAGE_EXECUTE but not for PAGE_READWRITE. If I execute it again I see it called once with PAGE_READWRITE (see stack below). Can anybody explain why? (this is on XP SP3)

ChildEBP RetAddr Args to Child
b0ff075c ba665033 865809ec b0ff07a8 b0ff07d8 Mydriver!SsPreAcquireCallback+0x9d [c:\sys\mydriver\mydriver.c @ 1303]
b0ff0788 ba5fe6e6 00000004 000000ff b0ff07d8 fltMgr!FltvPreOperation+0x3f
b0ff07f4 ba633511 b0ff080c b0ff08a8 b0ff0874 fltMgr!FltpPerformPreCallbacks+0x6a0
b0ff0828 804ec379 866f9278 b0ff08b0 865d0020 fltMgr!FltpPreFsFilterOperation+0x151
b0ff0850 805613d7 01ff0874 00000001 00000001 nt!FsFilterPerformCallbacks+0xa5
b0ff09a8 805622bc 86992dd0 00000001 00000004 nt!FsRtlAcquireFileExclusiveCommon+0x173
b0ff09bc 8050a005 86992dd0 00000004 00000000 nt!FsRtlAcquireToCreateMappedSection+0x12
b0ff0a58 805a089b b0ff0aa4 0000000d b0ff0b8c nt!MmCreateSection+0x265
b0ff0ac8 8053d648 b0ff0bbc 0000000d b0ff0b8c nt!NtCreateSection+0x12f
b0ff0ac8 804fe1a1 b0ff0bbc 0000000d b0ff0b8c nt!KiFastCallEntry+0xf8
b0ff0b5c 80614dca b0ff0bbc 0000000d b0ff0b8c nt!ZwCreateSection+0x11
b0ff0bb4 80616535 b0ff0bdc 00000081 b0ff0c14 nt!CcPfGetSectionObject+0xca
b0ff0c48 80617147 b0ff0c70 01000000 00000000 nt!CcPfPrefetchSections+0x2b7
b0ff0c88 80617570 e26c7000 00080000 86715da0 nt!CcPfPrefetchScenario+0x7b
b0ff0d04 805c6139 86715da0 e18502c0 00000000 nt!CcPfBeginAppLaunch+0x158
b0ff0d50 80541de2 00000000 7c810705 00000001 nt!PspUserThreadStartup+0xeb
00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x16
kd>

It’s not an answer but the prefetcher is involved so things will get
interesting.

I’m no expert on image activation in NT, but on other OS’s I’d expect to see
this behavior if your image had writeable (no share writable?) sections.
So, first time through the executable bit is mapped into memory and it stays
there. Second time around the executable bits are there already (so no
section set up), but it still needs to get the data sections in (so that
section is set up). So it maps the data in.

I suspect that if you looked hard enough you’d be able to find the offset
into the file and thus what was being mapped. If they are still there it
might also be interesting to look at the parameters to ZwCreateSection?

I’ll ask the usual - “What re you trying to achieve and why does this
matter?”.

wrote in message news:xxxxx@ntfsd…
>I am seeing something i did not expect. I am intercepting Acquire for Nt
>create section (in a mini-filter) and looking for SyncTypeCreateSection
>with PAGE_READWRITE access. I did not expect to see it when executing a
>file (.exe) and the first time I execute it I do not see it. I see the
>acquire for PAGE_READ and for PAGE_EXECUTE but not for PAGE_READWRITE. If
>I execute it again I see it called once with PAGE_READWRITE (see stack
>below). Can anybody explain why? (this is on XP SP3)
>
> ChildEBP RetAddr Args to Child
> b0ff075c ba665033 865809ec b0ff07a8 b0ff07d8
> Mydriver!SsPreAcquireCallback+0x9d [c:\sys\mydriver\mydriver.c @ 1303]
> b0ff0788 ba5fe6e6 00000004 000000ff b0ff07d8 fltMgr!FltvPreOperation+0x3f
> b0ff07f4 ba633511 b0ff080c b0ff08a8 b0ff0874
> fltMgr!FltpPerformPreCallbacks+0x6a0
> b0ff0828 804ec379 866f9278 b0ff08b0 865d0020
> fltMgr!FltpPreFsFilterOperation+0x151
> b0ff0850 805613d7 01ff0874 00000001 00000001
> nt!FsFilterPerformCallbacks+0xa5
> b0ff09a8 805622bc 86992dd0 00000001 00000004
> nt!FsRtlAcquireFileExclusiveCommon+0x173
> b0ff09bc 8050a005 86992dd0 00000004 00000000
> nt!FsRtlAcquireToCreateMappedSection+0x12
> b0ff0a58 805a089b b0ff0aa4 0000000d b0ff0b8c nt!MmCreateSection+0x265
> b0ff0ac8 8053d648 b0ff0bbc 0000000d b0ff0b8c nt!NtCreateSection+0x12f
> b0ff0ac8 804fe1a1 b0ff0bbc 0000000d b0ff0b8c nt!KiFastCallEntry+0xf8
> b0ff0b5c 80614dca b0ff0bbc 0000000d b0ff0b8c nt!ZwCreateSection+0x11
> b0ff0bb4 80616535 b0ff0bdc 00000081 b0ff0c14 nt!CcPfGetSectionObject+0xca
> b0ff0c48 80617147 b0ff0c70 01000000 00000000 nt!CcPfPrefetchSections+0x2b7
> b0ff0c88 80617570 e26c7000 00080000 86715da0 nt!CcPfPrefetchScenario+0x7b
> b0ff0d04 805c6139 86715da0 e18502c0 00000000 nt!CcPfBeginAppLaunch+0x158
> b0ff0d50 80541de2 00000000 7c810705 00000001 nt!PspUserThreadStartup+0xeb
> 00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x16
> kd>
>
>

> b0ff0c48 80617147 b0ff0c70 01000000 00000000 nt!CcPfPrefetchSections+0x2b7

Is it for the .exe or for the .pf file for it?


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

It is the .exe that is being mapped for write. It matters in this case because I am working on a single instance storage driver and mapping it for write breaks the single instancing. Waiting for the write to arrive (I do not actually see any writes to the .exe in this case - just the mapping for write access) before breaking the single instancing would be great but if you allow it to be mapped first you run into deadlock issues trying to restore the data while the file is mapped and some other thread is holding the paging IO resource.