I’m observing inconsistent behavior with memory write access and I’m not quite sure why.
I’m modifying images as they load from a work item after the process has been suspended. I recognize many on here may have issues with the approach but put that aside for now. For the primary executable and for libraries that are loaded by an APC via LdrLoadDll, this works fine. It’s only when libraries load normally that that modifications fail.
All the images are marked EXECUTE_WRITECOPY which is expected. The DLLs have the MMVAD.u.VadFlags.NoChange bit set to 1. Trying to modify the protection of the memory with ZwProtectVirtualMemory returns 0xC0000045 (STATUS_INVALID_PAGE_PROTECTION) which according to the ReactOS code, is what happens when that bit is set.
Below are three stack traces at PsImageLoadCallback along with the VAD printouts of the image base addresses. Is there another flag somewhere that I’m missing that says even EXECUTE_WRITECOPY are actually not-writable?
I’m testing this on Windows 10 x64 (10240) VM.
-- EXE (CAN MODIFY) --
01 ffffd000`23fba6b0 fffff803`8432c00f nt!PsCallImageNotifyRoutines+0x13c
02 ffffd000`23fba710 fffff803`8432bcfb nt!DbgkCreateThread+0x15b
03 ffffd000`23fba950 fffff803`83fc6e46 nt!PspUserThreadStartup+0x9f
04 ffffd000`23fba9c0 fffff803`83fc6dc0 nt!KiStartUserThread+0x16
05 ffffd000`23fbab00 00007ff9`f9939f30 nt!KiStartUserThreadReturn
0: kd> !vad 0x00007ff7`bac30000 1
VAD @ ffffe0000a7b5a40
Start VPN 7ff7bac30 End VPN 7ff7bac3d Control Area ffffe00009a38b50
FirstProtoPte ffffc001b3bbde70 LastPte ffffc001b3bbded8 Commit Charge f (0n15)
Secured.Flink 0 Blink 0 Banked/Extend 0
File Offset 0
ImageMap ViewShare EXECUTE_WRITECOPY
ControlArea @ ffffe00009a38b50
Segment ffffc001b4f5ac70 Flink ffffe0000a7b5aa0 Blink ffffe0000a7b5aa0
Section Ref 1 Pfn Ref e Mapped Views 1
User Ref 2 WaitForDel 0 Flush Count 8d50
File Object ffffe000091f7f20 ModWriteCount 0 System Views ffff
WritableRefs c0000001 PartitionId 0
Flags (a0) Image File
Segment @ ffffc001b4f5ac70
ControlArea ffffe00009a38b50 BasedAddress 00007ff7bac30000
Total Ptes e
Segment Size e000 Committed 0
Image Commit 1 Image Info ffffc001b4f5acb8
ProtoPtes ffffc001b3bbde70
Flags (820000) ProtectionMask
-- DLL (CAN MODIFY) --
01 ffffd000`285b4680 fffff803`8432e7fa nt!PsCallImageNotifyRoutines+0x13c
02 ffffd000`285b46e0 fffff803`8427bc2d nt!MiMapViewOfImageSection+0x68a
03 ffffd000`285b4830 fffff803`842817e1 nt!MiMapViewOfSection+0x33d
04 ffffd000`285b49a0 fffff803`83fcc263 nt!NtMapViewOfSection+0x2e1
05 ffffd000`285b4a90 00007ff9`f99c37ca nt!KiSystemServiceCopyEnd+0x13
06 000000bd`354be8e8 00007ff9`f997070e ntdll!NtMapViewOfSection+0xa
07 000000bd`354be8f0 00007ff9`f9970255 ntdll!LdrpMapViewOfSection+0xbe
08 000000bd`354be990 00007ff9`f9970125 ntdll!LdrpMapImage+0x75
09 000000bd`354bea30 00007ff9`f996efd8 ntdll!LdrpMapDllWithSectionHandle+0x2d
0a 000000bd`354bea70 00007ff9`f9972d37 ntdll!LdrpMapDllNtFileName+0x130
0b 000000bd`354beb40 00007ff9`f9968e4c ntdll!LdrpMapDllFullPath+0xcb
0c 000000bd`354becc0 00007ff9`f9950911 ntdll!LdrpProcessWork+0x60
0d 000000bd`354bed10 00007ff9`f99505ca ntdll!LdrpLoadDllInternal+0x14d
0e 000000bd`354bed90 00007ff9`f994af86 ntdll!LdrpLoadDll+0xf2
0f 000000bd`354bef30 000000bd`354f002a ntdll!LdrLoadDll+0x96
0: kd> !vad 0x00007ffa`6085c000 1
VAD @ ffffe001fd9fcf70
Start VPN 7ffa60850 End VPN 7ffa60861 Control Area ffffe001ffbc7ba0
FirstProtoPte ffffc00200594820 LastPte ffffc002005948a8 Commit Charge 3 (0n3)
Secured.Flink 0 Blink 0 Banked/Extend 0
File Offset 0
ImageMap ViewShare NoChange EXECUTE_WRITECOPY
ControlArea @ ffffe001ffbc7ba0
Segment ffffc00202af86d0 Flink ffffe001fd9fcfd0 Blink ffffe002007bdd40
Section Ref 1 Pfn Ref 10 Mapped Views 9
User Ref a WaitForDel 0 Flush Count 7da0
File Object ffffe001fce3bc40 ModWriteCount 0 System Views 9f77
WritableRefs c0000002 PartitionId 0
Flags (a0) Image File
Segment @ ffffc00202af86d0
ControlArea ffffe001ffbc7ba0 BasedAddress 00007ffa60850000
Total Ptes 12
Segment Size 12000 Committed 0
Image Commit 3 Image Info ffffc00202af8718
ProtoPtes ffffc00200594820
Flags (820000) ProtectionMask
-- DLL (CANNOT MODIFY) --
01 ffffd000`299b7680 fffff803`8432e7fa nt!PsCallImageNotifyRoutines+0x13c
02 ffffd000`299b76e0 fffff803`8427bc2d nt!MiMapViewOfImageSection+0x68a
03 ffffd000`299b7830 fffff803`842817e1 nt!MiMapViewOfSection+0x33d
04 ffffd000`299b79a0 fffff803`83fcc263 nt!NtMapViewOfSection+0x2e1
05 ffffd000`299b7a90 00000000`4a54001a nt!KiSystemServiceCopyEnd+0x13
06 000000bd`f49ce918 00007ff6`7d5d2af1 0x4a54001a
07 000000bd`f49ce920 00007ff9`f6e70aeb +0x581
08 000000bd`f49cf040 00007ff9`f6e70a0e KERNELBASE!MapViewOfFileExNuma+0xcb
09 000000bd`f49cf0c0 00007ff6`7d5c1fbf KERNELBASE!MapViewOfFile+0x1e
1: kd> !vad 0x00007ffa`28200000 1
VAD @ ffffe002003fa250
Start VPN 7ffa28200 End VPN 7ffa28429 Control Area ffffe0020036c010
FirstProtoPte ffffc001ff24d000 LastPte ffffc001ff24e148 Commit Charge 7 (0n7)
Secured.Flink 0 Blink 0 Banked/Extend 0
File Offset 0
ImageMap ViewShare NoChange EXECUTE_WRITECOPY
ControlArea @ ffffe0020036c010
Segment ffffc001ffeeef70 Flink ffffe002003fa2b0 Blink ffffe002002e7fd0
Section Ref 1 Pfn Ref 227 Mapped Views 2
User Ref 3 WaitForDel 0 Flush Count c248
File Object ffffe001fd3a7290 ModWriteCount 0 System Views d7bb
WritableRefs c0000023 PartitionId 0
Flags (a0) Image File
Segment @ ffffc001ffeeef70
ControlArea ffffe0020036c010 BasedAddress 00007ffa28200000
Total Ptes 22a
Segment Size 22a000 Committed 0
Image Commit 7 Image Info ffffc001ffeeefb8
ProtoPtes ffffc001ff24d000
Flags (820000) ProtectionMask