Add a readme
This commit is contained in:
parent
e0b5cd21a7
commit
4ce58a1307
@ -120,9 +120,9 @@ DriverControl(PDEVICE_OBJECT /* DriverObject */, PIRP Irp) {
|
|||||||
inputData = (PINPUT_DATA)(Irp->AssociatedIrp.SystemBuffer);
|
inputData = (PINPUT_DATA)(Irp->AssociatedIrp.SystemBuffer);
|
||||||
outputData = (POUTPUT_DATA)MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority | MdlMappingNoExecute);
|
outputData = (POUTPUT_DATA)MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority | MdlMappingNoExecute);
|
||||||
scanRange = &(inputData->scanRange);
|
scanRange = &(inputData->scanRange);
|
||||||
DbgPrint("[NAK] :: Range: %llx - %llx", scanRange->start, scanRange->end);
|
DbgPrint("[NAK] :: Range: %llx - %llx\n", scanRange->start, scanRange->end);
|
||||||
(outputData->poolChunk).addr = (ULONG64)scanRemote(scanRange->start, scanRange->end, scanRange->tag);
|
(outputData->poolChunk).addr = (ULONG64)scanRemote(scanRange->start, scanRange->end, scanRange->tag);
|
||||||
DbgPrint("[NAK] :: Found: %llx", (outputData->poolChunk).addr);
|
DbgPrint("[NAK] :: Found: %llx\n", (outputData->poolChunk).addr);
|
||||||
break;
|
break;
|
||||||
case DEREFERENCE_ADDRESS:
|
case DEREFERENCE_ADDRESS:
|
||||||
// DbgPrint("[NAK] :: [ ] Deref address\n");
|
// DbgPrint("[NAK] :: [ ] Deref address\n");
|
||||||
@ -319,7 +319,7 @@ printChunkInfo(PPOOL_HEADER p) {
|
|||||||
|
|
||||||
VOID
|
VOID
|
||||||
scanLargePool(PVOID /* largePageTableArray */, ULONG64 /* largePageTableSize */) {
|
scanLargePool(PVOID /* largePageTableArray */, ULONG64 /* largePageTableSize */) {
|
||||||
DbgPrint("[NAK] :: [-] Scan large pool not supported yet");
|
DbgPrint("[NAK] :: [-] Scan large pool not supported yet\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
PVOID
|
PVOID
|
||||||
@ -331,6 +331,7 @@ scanRemote(ULONG64 startAddress, ULONG64 endAddress, ULONG tag) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
if (!MmIsAddressValid(currentAddr)) {
|
if (!MmIsAddressValid(currentAddr)) {
|
||||||
|
// DbgPrint("[NAK] Skip page at %p\n", currentAddr);
|
||||||
currentAddr = (PVOID)((ULONG64)currentAddr + PAGE_SIZE);
|
currentAddr = (PVOID)((ULONG64)currentAddr + PAGE_SIZE);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
59
note.md
Normal file
59
note.md
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
|
||||||
|
Try to find `MmNonPagedPoolStart` and `MmNonPagedPoolEnd`
|
||||||
|
|
||||||
|
https://web.archive.org/web/20061110120809/http://www.rootkit.com/newsread.php?newsid=153
|
||||||
|
|
||||||
|
`KPCR->KdVersionBlock->Debugger Data List Entry->Flink`
|
||||||
|
|
||||||
|
This technique is old and cannot be used in Windows 10, Windows 7/8 may fail
|
||||||
|
too, After research, the result is summary into this
|
||||||
|
(file)[https://github.com/nganhkhoa/lpus/blob/master/nonpaged-pool-range.md]
|
||||||
|
|
||||||
|
Basically, find ntoskrnl.exe module address (kernel base) in memory and use
|
||||||
|
offsets parsed from PDB file. Finding the kernel base by shellcode is not
|
||||||
|
usable in Windows 2020 Insider Preview, I use IoGetCurrentProcess and traverse
|
||||||
|
the ActiveProcessLinks linked list, Luckily, the process returned by
|
||||||
|
IoGetCurrentProcess (if called in DriverEntry) is System (the first process),
|
||||||
|
so the BLink is `nt!PsActiveProcessHead`. With the offset of
|
||||||
|
`nt!PsActiveProcessHead` parsed from PDB file, we can get the kernel base by
|
||||||
|
subtracting.
|
||||||
|
|
||||||
|
Then traverse the `(_MI_SYSTEM_INFORMATION*)nt!MiState` to find
|
||||||
|
NonPagedPool{First,Last}Va.
|
||||||
|
|
||||||
|
Try the following steps:
|
||||||
|
|
||||||
|
1. `x nt!MiState` to get address of MiState
|
||||||
|
|
||||||
|
2. `dt _MI_SYSTEM_INFORMATION` to get offset to Hardware
|
||||||
|
|
||||||
|
3. `dt _MI_HARDWARE_STATE` to get offset to SystemNodeNonPagedPool with those
|
||||||
|
offset, use the following command to list the NonPagedPool{First,Last}Va
|
||||||
|
|
||||||
|
4. `dt (_MI_SYSTEM_NODE_NONPAGED_POOL*) (<nt!MiState> + <HARDWARE_OFFSET> +
|
||||||
|
<NODE_INFO_OFFSET>)` Sample output
|
||||||
|
|
||||||
|
Sample results:
|
||||||
|
```
|
||||||
|
+0x000 DynamicBitMapNonPagedPool : _MI_DYNAMIC_BITMAP
|
||||||
|
+0x048 CachedNonPagedPoolCount : 0
|
||||||
|
+0x050 NonPagedPoolSpinLock : 0
|
||||||
|
+0x058 CachedNonPagedPool : (null)
|
||||||
|
+0x060 NonPagedPoolFirstVa : 0xffffe580`00000000 Void
|
||||||
|
+0x068 NonPagedPoolLastVa : 0xfffff580`00000000 Void
|
||||||
|
+0x070 SystemNodeInformation : 0xffffe58f`9283b050 _MI_SYSTEM_NODE_INFORMATION
|
||||||
|
```
|
||||||
|
|
||||||
|
The big page pool is denoted by two variables `PoolBigPageTable.Va` and
|
||||||
|
`PoolBigPageTableSize` It seems that this big page is inside NonPagedPool range
|
||||||
|
|
||||||
|
PoolBigPageTable is an array with PoolBigPageTableSize elements, where each
|
||||||
|
elements has:
|
||||||
|
|
||||||
|
- Va -> Address of the allocation
|
||||||
|
- Key -> Pool tag
|
||||||
|
- NumberOfBytes -> Size
|
||||||
|
|
||||||
|
By scanning the non-paged pool, we noticed that the scan hit on a few pages,
|
||||||
|
then no more results is found. The big table seems to be pointing to the
|
||||||
|
location of these allocation. So scanning through big table is faster?
|
Loading…
Reference in New Issue
Block a user