MCPcopy Create free account
hub / github.com/HoShiMin/Kernel-Bridge / TriggerCopyOnWrite

Function TriggerCopyOnWrite

Kernel-Bridge/API/PteUtils.cpp:142–224  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

140
141 _IRQL_requires_max_(APC_LEVEL)
142 BOOLEAN TriggerCopyOnWrite(OPTIONAL PEPROCESS Process, PVOID Address, OPTIONAL OUT PULONG PageSize)
143 {
144 BOOLEAN NeedToAttach = Process && Process != PsGetCurrentProcess();
145 KAPC_STATE ApcState;
146 if (NeedToAttach)
147 KeStackAttachProcess(Process, &ApcState);
148
149 BOOLEAN Status = FALSE;
150 PAGE_TABLES_INFO Info = {};
151 Status = GetPageTables(Address, &Info);
152 if (Status) __try
153 {
154 // AVL is a 3-bit field:
155 // AVL:CopyOnWrite : 1
156 // AVL:Unused : 1
157 // AVL:Write : 1;
158 // We're setting the CoW bit (0b001):
159 constexpr unsigned int COW_MASK = 0b001;
160 constexpr unsigned int WRITE_MASK = 0b100;
161
162 if (PageSize) *PageSize = 0;
163
164 switch (Info.Type)
165 {
166 case PAGE_TABLES_INFO::pt32NonPaePage4Kb:
167 // PDE -> PTE -> PA:
168 if (PageSize) *PageSize = 4096;
169 if (!Info.Pte->x32.NonPae.Page4Kb.P || Info.Pte->x32.NonPae.Page4Kb.D || (Info.Pte->x32.NonPae.Page4Kb.AVL & WRITE_MASK)) break;
170 Info.Pte->x32.NonPae.Page4Kb.AVL = COW_MASK;
171 break;
172 case PAGE_TABLES_INFO::pt32NonPaePage4Mb:
173 // PDE -> PA:
174 if (PageSize) *PageSize = 4096 * 1024;
175 if (!Info.Pde->x32.NonPae.Page4Mb.P || Info.Pde->x32.NonPae.Page4Mb.D || (Info.Pde->x32.NonPae.Page4Mb.AVL & WRITE_MASK)) break;
176 Info.Pde->x32.NonPae.Page4Mb.AVL = COW_MASK;
177 break;
178 case PAGE_TABLES_INFO::pt32PaePage4Kb:
179 // PDPE -> PDE -> PTE -> PA:
180 if (PageSize) *PageSize = 4096;
181 if (!Info.Pte->x32.Pae.Page4Kb.P || Info.Pte->x32.Pae.Page4Kb.D || (Info.Pte->x32.Pae.Page4Kb.AVL & WRITE_MASK)) break;
182 Info.Pte->x32.Pae.Page4Kb.AVL = COW_MASK;
183 break;
184 case PAGE_TABLES_INFO::pt32PaePage2Mb:
185 // PDPE -> PDE -> PA:
186 if (PageSize) *PageSize = 2048 * 1024;
187 if (!Info.Pde->x32.Pae.Page2Mb.P || Info.Pde->x32.Pae.Page2Mb.D || (Info.Pde->x32.Pae.Page2Mb.AVL & WRITE_MASK)) break;
188 Info.Pde->x32.Pae.Page2Mb.AVL = COW_MASK;
189 break;
190 case PAGE_TABLES_INFO::pt64Page4Kb:
191 // PML4E -> PDPE -> PDE -> PTE -> PA:
192 if (PageSize) *PageSize = 4096;
193 if (!Info.Pte->x64.Page4Kb.P || Info.Pte->x64.Page4Kb.D || (Info.Pte->x64.Page4Kb.AVL & WRITE_MASK)) break;
194 Info.Pte->x64.Page4Kb.AVL = COW_MASK;
195 break;
196 case PAGE_TABLES_INFO::pt64Page2Mb:
197 // PML4E -> PDPE -> PDE -> PA:
198 if (PageSize) *PageSize = 2048 * 1024;
199 if (!Info.Pde->x64.Page2Mb.P || Info.Pde->x64.Page2Mb.D || (Info.Pde->x64.Page2Mb.AVL & WRITE_MASK)) break;

Callers 2

KbWriteProcessMemoryFunction · 0.85
KbTriggerCopyOnWriteFunction · 0.85

Calls 1

GetPageTablesFunction · 0.85

Tested by

no test coverage detected