update READMME

This commit is contained in:
nganhkhoa 2020-05-19 04:20:04 +07:00
parent 5bddf90501
commit dd16a31984
2 changed files with 583 additions and 547 deletions

571
README.md
View File

@ -1,558 +1,35 @@
> If you came here for `MmNonPagedPoolStart`, `MmNonPagedPoolEnd`, you ended up at the right place.
# LPUS (A live pool-tag scanning solution)
`NonPagedPool` in Windows has two variables that defined the start and end of the section in kernel memory. Online blog posts and tutorials show an outdated version of these two variables.
This is the frontend to the live pool tag scanning solution, the backend is a driver (which is now closed source).
Take a look at [this old post](https://web.archive.org/web/20061110120809/http://www.rootkit.com/newsread.php?newsid=153). `_DBGKD_GET_VERSION64 KdVersionBlock` was a very important structure into the debugger block of Windows. However, if you try to find this structure in Windows 10, you will hit `KdVersionBlock == 0` (Ouch!!!). But this structure provides offset into `MmNonPagedPool{Start,End}`, how can we get those?
## How this works
Luckily, both `MmNonPagedPoolStart` and `MmNonPagedPoolEnd` in Windows XP, can be found by offseting from `ntoskrnl.exe`. Rekall team are very positive that their tools doesn't rely on profiles file like Volatility but use PDB provided by Windows to find these values.
In simple way, we use PDB files to get the global variable offsets and structure definitions.
The backend finds the kernel base and use these values to calculate the nonpaged-pool range.
A more detailed report is in [nonpaged-pool-range.md](nonpaged-pool-range.md)
The frontend calls the backend to scan for a specific tag.
In [Rekall source code](https://github.com/google/rekall/blob/c5d68e31705f4b5bd2581c1d951b7f6983f7089c/rekall-core/rekall/plugins/windows/pool.py#L87), the values of those variables are:
## How to use
- Windows XP: `MmNonPagedPool{Start,End}`
- Windows 7 and maybe 8: `MiNonPagedPoolStartAligned`, `MiNonPagedPoolEnd`, and `MiNonPagedPoolBitMap`
- Windows 10 below
Example is [here](./src/bin/eprocess_scan.rs).
In Windows 7, 8, another field was added to controll the allocation of `NonPagedPool`, which is why there is [this paper about pool tag quick scanning](https://www.sciencedirect.com/science/article/pii/S1742287616000062).
```rust
use lpus::{
driver_state::{DriverState}
};
However, from Windows 10, the whole game changed around when the global offset to those (similar) variables are gone. Instead Windows 10 introduced a new variable `MiState`. `MiState` offset is available and we can get those start/end variables by either:
- Windows 2015: `*((ntoskrnl.exe+MiState)->SystemNodeInformation->NonPagedPool{First,Last}Va)`
- Windows 2016: `*((ntoskrnl.exe+MiState)->Hardware.SystemNodeInformation->NonPagedPool{First,Last}Va)`
The `NonPagedBitMap` was still visible untill the May 2019 Update, here, take a look at these 2 consecutive update [`1809 Redstone 5 (October Update)`](https://www.vergiliusproject.com/kernels/x64/Windows%2010%20%7C%202016/1809%20Redstone%205%20(October%20Update)/\_MI\_SYSTEM\_NODE\_INFORMATION) and [`1903 19H1 (May 2019 Update)`](https://www.vergiliusproject.com/kernels/x64/Windows%2010%20%7C%202016/1903%2019H1%20(May%202019%20Update)/\_MI\_SYSTEM\_NODE\_INFORMATION).
Yeah, now `pool tag quick scanning` is useless (gah). Windows OS changes quite frequently right? Tell you more, I am using the Insider version of Windows in 2020, and guess what, I found out that they put another struct to point to those value. So now we need to go like this:
- Windows 2020 Insider preview: `*((ntoskrnl.exe+MiState)->SystemNodeNonPagedPool->NonPagedPool{First,Last}Va)`
> If you go with low-level, then you only care about the offset and formula to get those variables but knowing the structure is well benefit.
Anyway, I create this project to help me with my thesis, following outdated structs online yields no result. Oh, yeah, a guy seems to be asking on [how to get `MmNonPagedPoolStart`](https://reverseengineering.stackexchange.com/q/6483) on `stackexchange`, too bad [the answer](https://reverseengineering.stackexchange.com/a/6487) is not so much helpful.
Take a look at my ntoskrnl.exe pdb file parsed.
```
PDB for Amd64, guid: 3c6978d6-66d9-c05a-53b6-a1e1561282c8, age: 1,
Void(UNNOWN) PsActiveProcessHead 0xc1f970 23:129392
Void(UNNOWN) MiState 0xc4f200 23:324096
Void(UNNOWN) KeNumberNodes 0xcfc000 24:0
Void(UNNOWN) PsLoadedModuleList 0xc2ba30 23:178736
Void(UNNOWN) KdDebuggerDataBlock 0xc00a30 23:2608
beginstruct _LIST_ENTRY
0x0 _LIST_ENTRY* Flink
0x8 _LIST_ENTRY* Blink
endstruct
beginstruct _RTL_BITMAP
0x0 U32 SizeOfBitMap
0x8 U32 Buffer
endstruct
beginstruct _EPROCESS
0x0 _KPROCESS Pcb
0x438 _EX_PUSH_LOCK ProcessLock
0x440 Void UniqueProcessId
0x448 _LIST_ENTRY ActiveProcessLinks
0x458 _EX_RUNDOWN_REF RundownProtect
0x460 U32 Flags2
0x460 UNNOWN JobNotReallyActive
0x460 UNNOWN AccountingFolded
0x460 UNNOWN NewProcessReported
0x460 UNNOWN ExitProcessReported
0x460 UNNOWN ReportCommitChanges
0x460 UNNOWN LastReportMemory
0x460 UNNOWN ForceWakeCharge
0x460 UNNOWN CrossSessionCreate
0x460 UNNOWN NeedsHandleRundown
0x460 UNNOWN RefTraceEnabled
0x460 UNNOWN PicoCreated
0x460 UNNOWN EmptyJobEvaluated
0x460 UNNOWN DefaultPagePriority
0x460 UNNOWN PrimaryTokenFrozen
0x460 UNNOWN ProcessVerifierTarget
0x460 UNNOWN RestrictSetThreadContext
0x460 UNNOWN AffinityPermanent
0x460 UNNOWN AffinityUpdateEnable
0x460 UNNOWN PropagateNode
0x460 UNNOWN ExplicitAffinity
0x460 UNNOWN ProcessExecutionState
0x460 UNNOWN EnableReadVmLogging
0x460 UNNOWN EnableWriteVmLogging
0x460 UNNOWN FatalAccessTerminationRequested
0x460 UNNOWN DisableSystemAllowedCpuSet
0x460 UNNOWN ProcessStateChangeRequest
0x460 UNNOWN ProcessStateChangeInProgress
0x460 UNNOWN InPrivate
0x464 U32 Flags
0x464 UNNOWN CreateReported
0x464 UNNOWN NoDebugInherit
0x464 UNNOWN ProcessExiting
0x464 UNNOWN ProcessDelete
0x464 UNNOWN ManageExecutableMemoryWrites
0x464 UNNOWN VmDeleted
0x464 UNNOWN OutswapEnabled
0x464 UNNOWN Outswapped
0x464 UNNOWN FailFastOnCommitFail
0x464 UNNOWN Wow64VaSpace4Gb
0x464 UNNOWN AddressSpaceInitialized
0x464 UNNOWN SetTimerResolution
0x464 UNNOWN BreakOnTermination
0x464 UNNOWN DeprioritizeViews
0x464 UNNOWN WriteWatch
0x464 UNNOWN ProcessInSession
0x464 UNNOWN OverrideAddressSpace
0x464 UNNOWN HasAddressSpace
0x464 UNNOWN LaunchPrefetched
0x464 UNNOWN Background
0x464 UNNOWN VmTopDown
0x464 UNNOWN ImageNotifyDone
0x464 UNNOWN PdeUpdateNeeded
0x464 UNNOWN VdmAllowed
0x464 UNNOWN ProcessRundown
0x464 UNNOWN ProcessInserted
0x464 UNNOWN DefaultIoPriority
0x464 UNNOWN ProcessSelfDelete
0x464 UNNOWN SetTimerResolutionLink
0x468 _LARGE_INTEGER CreateTime
0x470 U64[16] ProcessQuotaUsage
0x480 U64[16] ProcessQuotaPeak
0x490 U64 PeakVirtualSize
0x498 U64 VirtualSize
0x4a0 _LIST_ENTRY SessionProcessLinks
0x4b0 Void ExceptionPortData
0x4b0 U64 ExceptionPortValue
0x4b0 UNNOWN ExceptionPortState
0x4b8 _EX_FAST_REF Token
0x4c0 U64 MmReserved
0x4c8 _EX_PUSH_LOCK AddressCreationLock
0x4d0 _EX_PUSH_LOCK PageTableCommitmentLock
0x4d8 _ETHREAD* RotateInProgress
0x4e0 _ETHREAD* ForkInProgress
0x4e8 _EJOB* CommitChargeJob
0x4f0 _RTL_AVL_TREE CloneRoot
0x4f8 volatile U64 NumberOfPrivatePages
0x500 volatile U64 NumberOfLockedPages
0x508 Void Win32Process
0x510 _EJOB* Job
0x518 Void SectionObject
0x520 Void SectionBaseAddress
0x528 U32 Cookie
0x530 _PAGEFAULT_HISTORY* WorkingSetWatch
0x538 Void Win32WindowStation
0x540 Void InheritedFromUniqueProcessId
0x548 volatile U64 OwnerProcessId
0x550 _PEB* Peb
0x558 _MM_SESSION_SPACE* Session
0x560 Void Spare1
0x568 _EPROCESS_QUOTA_BLOCK* QuotaBlock
0x570 _HANDLE_TABLE* ObjectTable
0x578 Void DebugPort
0x580 _EWOW64PROCESS* WoW64Process
0x588 Void DeviceMap
0x590 Void EtwDataSource
0x598 U64 PageDirectoryPte
0x5a0 _FILE_OBJECT* ImageFilePointer
0x5a8 UChar[15] ImageFileName
0x5b7 UChar PriorityClass
0x5b8 Void SecurityPort
0x5c0 _SE_AUDIT_PROCESS_CREATION_INFO SeAuditProcessCreationInfo
0x5c8 _LIST_ENTRY JobLinks
0x5d8 Void HighestUserAddress
0x5e0 _LIST_ENTRY ThreadListHead
0x5f0 volatile U32 ActiveThreads
0x5f4 U32 ImagePathHash
0x5f8 U32 DefaultHardErrorProcessing
0x5fc I32 LastThreadExitStatus
0x600 _EX_FAST_REF PrefetchTrace
0x608 Void LockedPagesList
0x610 _LARGE_INTEGER ReadOperationCount
0x618 _LARGE_INTEGER WriteOperationCount
0x620 _LARGE_INTEGER OtherOperationCount
0x628 _LARGE_INTEGER ReadTransferCount
0x630 _LARGE_INTEGER WriteTransferCount
0x638 _LARGE_INTEGER OtherTransferCount
0x640 U64 CommitChargeLimit
0x648 volatile U64 CommitCharge
0x650 volatile U64 CommitChargePeak
0x680 _MMSUPPORT_FULL Vm
0x7c0 _LIST_ENTRY MmProcessLinks
0x7d0 U32 ModifiedPageCount
0x7d4 I32 ExitStatus
0x7d8 _RTL_AVL_TREE VadRoot
0x7e0 Void VadHint
0x7e8 U64 VadCount
0x7f0 volatile U64 VadPhysicalPages
0x7f8 U64 VadPhysicalPagesLimit
0x800 _ALPC_PROCESS_CONTEXT AlpcContext
0x820 _LIST_ENTRY TimerResolutionLink
0x830 _PO_DIAG_STACK_RECORD* TimerResolutionStackRecord
0x838 U32 RequestedTimerResolution
0x83c U32 SmallestTimerResolution
0x840 _LARGE_INTEGER ExitTime
0x848 _INVERTED_FUNCTION_TABLE* InvertedFunctionTable
0x850 _EX_PUSH_LOCK InvertedFunctionTableLock
0x858 U32 ActiveThreadsHighWatermark
0x85c U32 LargePrivateVadCount
0x860 _EX_PUSH_LOCK ThreadListLock
0x868 Void WnfContext
0x870 _EJOB* ServerSilo
0x878 UChar SignatureLevel
0x879 UChar SectionSignatureLevel
0x87a _PS_PROTECTION Protection
0x87b UNNOWN HangCount
0x87b UNNOWN GhostCount
0x87b UNNOWN PrefilterException
0x87c U32 Flags3
0x87c UNNOWN Minimal
0x87c UNNOWN ReplacingPageRoot
0x87c UNNOWN Crashed
0x87c UNNOWN JobVadsAreTracked
0x87c UNNOWN VadTrackingDisabled
0x87c UNNOWN AuxiliaryProcess
0x87c UNNOWN SubsystemProcess
0x87c UNNOWN IndirectCpuSets
0x87c UNNOWN RelinquishedCommit
0x87c UNNOWN HighGraphicsPriority
0x87c UNNOWN CommitFailLogged
0x87c UNNOWN ReserveFailLogged
0x87c UNNOWN SystemProcess
0x87c UNNOWN HideImageBaseAddresses
0x87c UNNOWN AddressPolicyFrozen
0x87c UNNOWN ProcessFirstResume
0x87c UNNOWN ForegroundExternal
0x87c UNNOWN ForegroundSystem
0x87c UNNOWN HighMemoryPriority
0x87c UNNOWN EnableProcessSuspendResumeLogging
0x87c UNNOWN EnableThreadSuspendResumeLogging
0x87c UNNOWN SecurityDomainChanged
0x87c UNNOWN SecurityFreezeComplete
0x87c UNNOWN VmProcessorHost
0x87c UNNOWN VmProcessorHostTransition
0x87c UNNOWN AltSyscall
0x87c UNNOWN TimerResolutionIgnore
0x880 I32 DeviceAsid
0x888 Void SvmData
0x890 _EX_PUSH_LOCK SvmProcessLock
0x898 U64 SvmLock
0x8a0 _LIST_ENTRY SvmProcessDeviceListHead
0x8b0 U64 LastFreezeInterruptTime
0x8b8 _PROCESS_DISK_COUNTERS* DiskCounters
0x8c0 Void PicoContext
0x8c8 Void EnclaveTable
0x8d0 U64 EnclaveNumber
0x8d8 _EX_PUSH_LOCK EnclaveLock
0x8e0 U32 HighPriorityFaultsAllowed
0x8e8 _PO_PROCESS_ENERGY_CONTEXT* EnergyContext
0x8f0 Void VmContext
0x8f8 U64 SequenceNumber
0x900 U64 CreateInterruptTime
0x908 U64 CreateUnbiasedInterruptTime
0x910 U64 TotalUnbiasedFrozenTime
0x918 U64 LastAppStateUpdateTime
0x920 UNNOWN LastAppStateUptime
0x920 UNNOWN LastAppState
0x928 volatile U64 SharedCommitCharge
0x930 _EX_PUSH_LOCK SharedCommitLock
0x938 _LIST_ENTRY SharedCommitLinks
0x948 U64 AllowedCpuSets
0x950 U64 DefaultCpuSets
0x948 U64 AllowedCpuSetsIndirect
0x950 U64 DefaultCpuSetsIndirect
0x958 Void DiskIoAttribution
0x960 Void DxgProcess
0x968 U32 Win32KFilterSet
0x970 volatile _PS_INTERLOCKED_TIMER_DELAY_VALUES ProcessTimerDelay
0x978 volatile U32 KTimerSets
0x97c volatile U32 KTimer2Sets
0x980 volatile U32 ThreadTimerSets
0x988 U64 VirtualTimerListLock
0x990 _LIST_ENTRY VirtualTimerListHead
0x9a0 _WNF_STATE_NAME WakeChannel
0x9a0 _PS_PROCESS_WAKE_INFORMATION WakeInfo
0x9d0 U32 MitigationFlags
0x9d0 <anonymous-tag> MitigationFlagsValues
0x9d4 U32 MitigationFlags2
0x9d4 <anonymous-tag> MitigationFlags2Values
0x9d8 Void PartitionObject
0x9e0 U64 SecurityDomain
0x9e8 U64 ParentSecurityDomain
0x9f0 Void CoverageSamplerContext
0x9f8 Void MmHotPatchContext
0xa00 _KE_IDEAL_PROCESSOR_ASSIGNMENT_BLOCK IdealProcessorAssignmentBlock
0xab8 _RTL_AVL_TREE DynamicEHContinuationTargetsTree
0xac0 _EX_PUSH_LOCK DynamicEHContinuationTargetsLock
endstruct
beginstruct _RTL_BITMAP_EX
0x0 U64 SizeOfBitMap
0x8 U64 Buffer
endstruct
beginstruct _MI_SYSTEM_INFORMATION
0x0 _MI_POOL_STATE Pools
0xc0 _MI_SECTION_STATE Sections
0x400 _MI_SYSTEM_IMAGE_STATE SystemImages
0x4a8 _MI_SESSION_STATE Sessions
0x1530 _MI_PROCESS_STATE Processes
0x1580 _MI_HARDWARE_STATE Hardware
0x1740 _MI_SYSTEM_VA_STATE SystemVa
0x1c00 _MI_COMBINE_STATE PageCombines
0x1c20 _MI_PAGELIST_STATE PageLists
0x1cc0 _MI_PARTITION_STATE Partitions
0x1d80 _MI_SHUTDOWN_STATE Shutdowns
0x1df8 _MI_ERROR_STATE Errors
0x1f00 _MI_ACCESS_LOG_STATE AccessLog
0x1f80 _MI_DEBUGGER_STATE Debugger
0x20a0 _MI_STANDBY_STATE Standby
0x2140 _MI_SYSTEM_PTE_STATE SystemPtes
0x2340 _MI_IO_PAGE_STATE IoPages
0x2400 _MI_PAGING_IO_STATE PagingIo
0x24b0 _MI_COMMON_PAGE_STATE CommonPages
0x2580 _MI_SYSTEM_TRIM_STATE Trims
0x25c0 _MI_SYSTEM_ZEROING Zeroing
0x25e0 _MI_ENCLAVE_STATE Enclaves
0x2628 U64 Cookie
0x2630 Void** BootRegistryRuns
0x2638 volatile I32 ZeroingDisabled
0x263c UChar FullyInitialized
0x263d UChar SafeBooted
0x2640 const _tlgProvider_t* TraceLogging
0x2680 _MI_VISIBLE_STATE Vs
endstruct
beginstruct _PEB
0x0 UChar InheritedAddressSpace
0x1 UChar ReadImageFileExecOptions
0x2 UChar BeingDebugged
0x3 UChar BitField
0x3 UNNOWN ImageUsesLargePages
0x3 UNNOWN IsProtectedProcess
0x3 UNNOWN IsImageDynamicallyRelocated
0x3 UNNOWN SkipPatchingUser32Forwarders
0x3 UNNOWN IsPackagedProcess
0x3 UNNOWN IsAppContainer
0x3 UNNOWN IsProtectedProcessLight
0x3 UNNOWN IsLongPathAwareProcess
0x4 UChar[4] Padding0
0x8 Void Mutant
0x10 Void ImageBaseAddress
0x18 _PEB_LDR_DATA* Ldr
0x20 _RTL_USER_PROCESS_PARAMETERS* ProcessParameters
0x28 Void SubSystemData
0x30 Void ProcessHeap
0x38 _RTL_CRITICAL_SECTION* FastPebLock
0x40 _SLIST_HEADER* AtlThunkSListPtr
0x48 Void IFEOKey
0x50 U32 CrossProcessFlags
0x50 UNNOWN ProcessInJob
0x50 UNNOWN ProcessInitializing
0x50 UNNOWN ProcessUsingVEH
0x50 UNNOWN ProcessUsingVCH
0x50 UNNOWN ProcessUsingFTH
0x50 UNNOWN ProcessPreviouslyThrottled
0x50 UNNOWN ProcessCurrentlyThrottled
0x50 UNNOWN ProcessImagesHotPatched
0x50 UNNOWN ReservedBits0
0x54 UChar[4] Padding1
0x58 Void KernelCallbackTable
0x58 Void UserSharedInfoPtr
0x60 U32 SystemReserved
0x64 U32 AtlThunkSListPtr32
0x68 Void ApiSetMap
0x70 U32 TlsExpansionCounter
0x74 UChar[4] Padding2
0x78 Void TlsBitmap
0x80 U32[8] TlsBitmapBits
0x88 Void ReadOnlySharedMemoryBase
0x90 Void SharedData
0x98 Void* ReadOnlyStaticServerData
0xa0 Void AnsiCodePageData
0xa8 Void OemCodePageData
0xb0 Void UnicodeCaseTableData
0xb8 U32 NumberOfProcessors
0xbc U32 NtGlobalFlag
0xc0 _LARGE_INTEGER CriticalSectionTimeout
0xc8 U64 HeapSegmentReserve
0xd0 U64 HeapSegmentCommit
0xd8 U64 HeapDeCommitTotalFreeThreshold
0xe0 U64 HeapDeCommitFreeBlockThreshold
0xe8 U32 NumberOfHeaps
0xec U32 MaximumNumberOfHeaps
0xf0 Void* ProcessHeaps
0xf8 Void GdiSharedHandleTable
0x100 Void ProcessStarterHelper
0x108 U32 GdiDCAttributeList
0x10c UChar[4] Padding3
0x110 _RTL_CRITICAL_SECTION* LoaderLock
0x118 U32 OSMajorVersion
0x11c U32 OSMinorVersion
0x120 U16 OSBuildNumber
0x122 U16 OSCSDVersion
0x124 U32 OSPlatformId
0x128 U32 ImageSubsystem
0x12c U32 ImageSubsystemMajorVersion
0x130 U32 ImageSubsystemMinorVersion
0x134 UChar[4] Padding4
0x138 U64 ActiveProcessAffinityMask
0x140 U32[240] GdiHandleBuffer
0x230 Void(UNNOWN)* PostProcessInitRoutine
0x238 Void TlsExpansionBitmap
0x240 U32[128] TlsExpansionBitmapBits
0x2c0 U32 SessionId
0x2c4 UChar[4] Padding5
0x2c8 _ULARGE_INTEGER AppCompatFlags
0x2d0 _ULARGE_INTEGER AppCompatFlagsUser
0x2d8 Void pShimData
0x2e0 Void AppCompatInfo
0x2e8 _UNICODE_STRING CSDVersion
0x2f8 const _ACTIVATION_CONTEXT_DATA* ActivationContextData
0x300 _ASSEMBLY_STORAGE_MAP* ProcessAssemblyStorageMap
0x308 const _ACTIVATION_CONTEXT_DATA* SystemDefaultActivationContextData
0x310 _ASSEMBLY_STORAGE_MAP* SystemAssemblyStorageMap
0x318 U64 MinimumStackCommit
0x320 Void[32] SparePointers
0x340 U32[20] SpareUlongs
0x358 Void WerRegistrationData
0x360 Void WerShipAssertPtr
0x368 Void pUnused
0x370 Void pImageHeaderHash
0x378 U32 TracingFlags
0x378 UNNOWN HeapTracingEnabled
0x378 UNNOWN CritSecTracingEnabled
0x378 UNNOWN LibLoaderTracingEnabled
0x378 UNNOWN SpareTracingBits
0x37c UChar[4] Padding6
0x380 U64 CsrServerReadOnlySharedMemoryBase
0x388 U64 TppWorkerpListLock
0x390 _LIST_ENTRY TppWorkerpList
0x3a0 Void[1024] WaitOnAddressHashTable
0x7a0 Void TelemetryCoverageHeader
0x7a8 U32 CloudFileFlags
0x7ac U32 CloudFileDiagFlags
0x7b0 RChar PlaceholderCompatibilityMode
0x7b1 RChar[7] PlaceholderCompatibilityModeReserved
0x7b8 _LEAP_SECOND_DATA* LeapSecondData
0x7c0 U32 LeapSecondFlags
0x7c0 UNNOWN SixtySecondEnabled
0x7c0 UNNOWN Reserved
0x7c4 U32 NtGlobalFlag2
endstruct
beginstruct _MI_DYNAMIC_BITMAP
0x0 _RTL_BITMAP_EX Bitmap
0x10 U64 MaximumSize
0x18 U64 Hint
0x20 Void BaseVa
0x28 U64 SizeTopDown
0x30 U64 HintTopDown
0x38 Void BaseVaTopDown
0x40 U64 SpinLock
endstruct
beginstruct _MI_HARDWARE_STATE
0x0 U32 NodeMask
0x4 U32 NumaHintIndex
0x8 U32 NumaLastRangeIndexInclusive
0xc UChar NodeShift
0xd UChar ChannelShift
0x10 U32 ChannelHintIndex
0x14 U32 ChannelLastRangeIndexInclusive
0x18 _MI_NODE_NUMBER_ZERO_BASED* NodeGraph
0x20 _MI_SYSTEM_NODE_NONPAGED_POOL* SystemNodeNonPagedPool
0x28 _HAL_NODE_RANGE[32] TemporaryNumaRanges
0x48 _HAL_NODE_RANGE* NumaMemoryRanges
0x50 _HAL_CHANNEL_MEMORY_RANGES* ChannelMemoryRanges
0x58 U32 SecondLevelCacheSize
0x5c U32 FirstLevelCacheSize
0x60 U32 PhysicalAddressBits
0x64 U32 PfnDatabasePageBits
0x68 U32 LogicalProcessorsPerCore
0x6c UChar ProcessorCachesFlushedOnPowerLoss
0x70 U64 TotalPagesAllowed
0x78 U32 SecondaryColorMask
0x7c U32 SecondaryColors
0x80 U32 FlushTbForAttributeChange
0x84 U32 FlushCacheForAttributeChange
0x88 U32 FlushCacheForPageAttributeChange
0x8c U32 CacheFlushPromoteThreshold
0x90 _LARGE_INTEGER PerformanceCounterFrequency
0xc0 U64 InvalidPteMask
0x100 U32[12] LargePageColors
0x110 U64 FlushTbThreshold
0x118 _MI_PFN_CACHE_ATTRIBUTE[16][64] OptimalZeroingAttribute
0x158 UChar AttributeChangeRequiresReZero
0x160 _MI_ZERO_COST_COUNTS[32] ZeroCostCounts
0x180 U64 HighestPossiblePhysicalPage
0x188 U64 VsmKernelPageCount
endstruct
beginstruct _MI_SYSTEM_NODE_NONPAGED_POOL
0x0 _MI_DYNAMIC_BITMAP DynamicBitMapNonPagedPool
0x48 U64 CachedNonPagedPoolCount
0x50 U64 NonPagedPoolSpinLock
0x58 _MMPFN* CachedNonPagedPool
0x60 Void NonPagedPoolFirstVa
0x68 Void NonPagedPoolLastVa
0x70 _MI_SYSTEM_NODE_INFORMATION* SystemNodeInformation
endstruct
beginstruct _MI_SYSTEM_NODE_INFORMATION
0x0 _CACHED_KSTACK_LIST[64] CachedKernelStacks
0x40 _GROUP_AFFINITY GroupAffinity
0x50 U16 ProcessorCount
0x58 Void BootZeroPageTimesPerProcessor
0x60 U64 CyclesToZeroOneLargePage
0x68 U64 ScaledCyclesToZeroOneLargePage
0x70 _MI_WRITE_CALIBRATION WriteCalibration
0xc0 volatile I32 IoPfnLock
endstruct
```
----
Global variables offset are parsed and can be queried by `nt!` in Windbg. In a kernel driver, we need to get the kernel base address (which is `nt!`). Kernel base address is the loaded address of `ntoskrnl.exe`. There is a shellcode to get the address [here](https://gist.github.com/Barakat/34e9924217ed81fd78c9c92d746ec9c6), using IDT table. But when I use the shellcode with the Windows Insider preview 2020, the address is wrong (it still a loaded PE though). Other ways to get the address are listed [here](https://m0uk4.gitbook.io/notebooks/mouka/windowsinternal/find-kernel-module-address-todo). And hereby I present another way to get the kernel base address.
A device driver can get a pointer to a `EPROCESS` through the use of `PEPROCESS IoGetCurrentProcess`. And as we know, `EPROCESS` has pointer to other `EPROCESS` as a doubly linked list. If we dump them all out, we can notice a few things:
- The image name returned by calling `IoGetCurrentProcess` is `System`
- The `EPROCESS` before `System` is somehow empty
```cpp
PVOID eprocess = (PVOID)IoGetCurrentProcess();
DbgPrint("eprocess : 0x%p, [%15s]\n", eprocess, (char*)((ULONG64)eprocess + ImageBaseNameOffset));
for (int i = 0; i < 100; i++) {
eprocess = (PVOID)(*(ULONG64*)((ULONG64)eprocess + ActiveProcessLinksOffset) - ActiveProcessLinksOffset);
DbgPrint("eprocess : 0x%p, [%15s]\n", eprocess, (char*)((ULONG64)eprocess + ImageBaseOffset));
fn main() -> Result<(), Box<dyn Error>> {
let mut driver = DriverState::new();
println!("NtLoadDriver() -> 0x{:x}", driver.startup());
driver.scan_pool(b"Tag ", |pool_addr, header, data_addr| {
})?;
println!("NtUnloadDriver() -> 0x{:x}", driver.shutdown());
}
// sample output
eprocess : 0xFFFFF8037401F528, [ ]
eprocess : 0xFFFF840F5A0D9080, [ System]
eprocess : 0xFFFF840F5A28C040, [ Secure System]
eprocess : 0xFFFF840F5A2EF040, [ Registry]
eprocess : 0xFFFF840F622BF040, [ smss.exe]
eprocess : 0xFFFF840F6187D080, [ smss.exe]
eprocess : 0xFFFF840F6263D140, [ csrss.exe]
eprocess : 0xFFFF840F6277F0C0, [ smss.exe]
eprocess : 0xFFFF840F627C2080, [ wininit.exe]
eprocess : 0xFFFF840F64187140, [ csrss.exe]
eprocess : 0xFFFF840F641CD080, [ services.exe]
```
And if we debug and compare the address of that `Empty EPROCESS+ActiveProcessLinksOffset` with `nt!PsActiveProcessHead`, it is just the same. And with the given offset parsed from the PDB file, we can get kernel base address.
The closure is a mutable closure, so you can just put a vector and saves the result.
The function signature for the closure is: `FnMut(u64, &[u8], u64) -> Result<bool, std::error::Error>`
Parsing the struct data is up to you.
You can use `driver.deref_addr(addr, &value)` to dereference an address in kernel space
and `driver.pdb_store.get_offset_r("offset")?` to get an offset from PDB file.
```cpp
PVOID eprocess = (PVOID)IoGetCurrentProcess();
DbgPrint("eprocess : 0x%p, [%15s]\n", eprocess, (char*)((ULONG64)eprocess + ImageBaseNameOffset));
PVOID processHead = (PVOID)(*(ULONG64*)((ULONG64)eprocess + ActiveProcessLinksOffset + BLinkOffset));
DbgPrint("PsActiveProcessHead : 0x%p\n", processHead);
PVOID ntosbase = (PVOID)((ULONG64)processHead - ActiveHeadOffset);
DbgPrint("ntoskrnl.exe : 0x%p\n", ntosbase);
```
From now we have successfully get the kernel base address to index into other global variables.
(In this way we use `PsActiveProcessHead`, but a better way maybe traversing `PsLoadedModuleList` which could get the correct address of `ntoskrnl.exe` but I do not know)

559
nonpaged-pool-range.md Normal file
View File

@ -0,0 +1,559 @@
> If you came here for `MmNonPagedPoolStart`, `MmNonPagedPoolEnd`, you ended up at the right place.
`NonPagedPool` in Windows has two variables that defined the start and end of the section in kernel memory. Online blog posts and tutorials show an outdated version of these two variables.
Take a look at [this old post](https://web.archive.org/web/20061110120809/http://www.rootkit.com/newsread.php?newsid=153). `_DBGKD_GET_VERSION64 KdVersionBlock` was a very important structure into the debugger block of Windows. However, if you try to find this structure in Windows 10, you will hit `KdVersionBlock == 0` (Ouch!!!). But this structure provides offset into `MmNonPagedPool{Start,End}`, how can we get those?
Luckily, both `MmNonPagedPoolStart` and `MmNonPagedPoolEnd` in Windows XP, can be found by offseting from `ntoskrnl.exe`. Rekall team are very positive that their tools doesn't rely on profiles file like Volatility but use PDB provided by Windows to find these values.
In [Rekall source code](https://github.com/google/rekall/blob/c5d68e31705f4b5bd2581c1d951b7f6983f7089c/rekall-core/rekall/plugins/windows/pool.py#L87), the values of those variables are:
- Windows XP: `MmNonPagedPool{Start,End}`
- Windows 7 and maybe 8: `MiNonPagedPoolStartAligned`, `MiNonPagedPoolEnd`, and `MiNonPagedPoolBitMap`
- Windows 10 below
In Windows 7, 8, another field was added to controll the allocation of `NonPagedPool`, which is why there is [this paper about pool tag quick scanning](https://www.sciencedirect.com/science/article/pii/S1742287616000062).
However, from Windows 10, the whole game changed around when the global offset to those (similar) variables are gone. Instead Windows 10 introduced a new variable `MiState`. `MiState` offset is available and we can get those start/end variables by either:
- Windows 2015: `*((ntoskrnl.exe+MiState)->SystemNodeInformation->NonPagedPool{First,Last}Va)`
- Windows 2016: `*((ntoskrnl.exe+MiState)->Hardware.SystemNodeInformation->NonPagedPool{First,Last}Va)`
The `NonPagedBitMap` was still visible untill the May 2019 Update, here, take a look at these 2 consecutive update [`1809 Redstone 5 (October Update)`](https://www.vergiliusproject.com/kernels/x64/Windows%2010%20%7C%202016/1809%20Redstone%205%20(October%20Update)/\_MI\_SYSTEM\_NODE\_INFORMATION) and [`1903 19H1 (May 2019 Update)`](https://www.vergiliusproject.com/kernels/x64/Windows%2010%20%7C%202016/1903%2019H1%20(May%202019%20Update)/\_MI\_SYSTEM\_NODE\_INFORMATION).
Yeah, now `pool tag quick scanning` is useless (gah). Windows OS changes quite frequently right? Tell you more, I am using the Insider version of Windows in 2020, and guess what, I found out that they put another struct to point to those value. So now we need to go like this:
- Windows 2020 Insider preview: `*((ntoskrnl.exe+MiState)->SystemNodeNonPagedPool->NonPagedPool{First,Last}Va)`
> If you go with low-level, then you only care about the offset and formula to get those variables but knowing the structure is well benefit.
Anyway, I create this project to help me with my thesis, following outdated structs online yields no result. Oh, yeah, a guy seems to be asking on [how to get `MmNonPagedPoolStart`](https://reverseengineering.stackexchange.com/q/6483) on `stackexchange`, too bad [the answer](https://reverseengineering.stackexchange.com/a/6487) is not so much helpful.
Take a look at my ntoskrnl.exe pdb file parsed.
```
PDB for Amd64, guid: 3c6978d6-66d9-c05a-53b6-a1e1561282c8, age: 1,
Void(UNNOWN) PsActiveProcessHead 0xc1f970 23:129392
Void(UNNOWN) MiState 0xc4f200 23:324096
Void(UNNOWN) KeNumberNodes 0xcfc000 24:0
Void(UNNOWN) PsLoadedModuleList 0xc2ba30 23:178736
Void(UNNOWN) KdDebuggerDataBlock 0xc00a30 23:2608
beginstruct _LIST_ENTRY
0x0 _LIST_ENTRY* Flink
0x8 _LIST_ENTRY* Blink
endstruct
beginstruct _RTL_BITMAP
0x0 U32 SizeOfBitMap
0x8 U32 Buffer
endstruct
beginstruct _EPROCESS
0x0 _KPROCESS Pcb
0x438 _EX_PUSH_LOCK ProcessLock
0x440 Void UniqueProcessId
0x448 _LIST_ENTRY ActiveProcessLinks
0x458 _EX_RUNDOWN_REF RundownProtect
0x460 U32 Flags2
0x460 UNNOWN JobNotReallyActive
0x460 UNNOWN AccountingFolded
0x460 UNNOWN NewProcessReported
0x460 UNNOWN ExitProcessReported
0x460 UNNOWN ReportCommitChanges
0x460 UNNOWN LastReportMemory
0x460 UNNOWN ForceWakeCharge
0x460 UNNOWN CrossSessionCreate
0x460 UNNOWN NeedsHandleRundown
0x460 UNNOWN RefTraceEnabled
0x460 UNNOWN PicoCreated
0x460 UNNOWN EmptyJobEvaluated
0x460 UNNOWN DefaultPagePriority
0x460 UNNOWN PrimaryTokenFrozen
0x460 UNNOWN ProcessVerifierTarget
0x460 UNNOWN RestrictSetThreadContext
0x460 UNNOWN AffinityPermanent
0x460 UNNOWN AffinityUpdateEnable
0x460 UNNOWN PropagateNode
0x460 UNNOWN ExplicitAffinity
0x460 UNNOWN ProcessExecutionState
0x460 UNNOWN EnableReadVmLogging
0x460 UNNOWN EnableWriteVmLogging
0x460 UNNOWN FatalAccessTerminationRequested
0x460 UNNOWN DisableSystemAllowedCpuSet
0x460 UNNOWN ProcessStateChangeRequest
0x460 UNNOWN ProcessStateChangeInProgress
0x460 UNNOWN InPrivate
0x464 U32 Flags
0x464 UNNOWN CreateReported
0x464 UNNOWN NoDebugInherit
0x464 UNNOWN ProcessExiting
0x464 UNNOWN ProcessDelete
0x464 UNNOWN ManageExecutableMemoryWrites
0x464 UNNOWN VmDeleted
0x464 UNNOWN OutswapEnabled
0x464 UNNOWN Outswapped
0x464 UNNOWN FailFastOnCommitFail
0x464 UNNOWN Wow64VaSpace4Gb
0x464 UNNOWN AddressSpaceInitialized
0x464 UNNOWN SetTimerResolution
0x464 UNNOWN BreakOnTermination
0x464 UNNOWN DeprioritizeViews
0x464 UNNOWN WriteWatch
0x464 UNNOWN ProcessInSession
0x464 UNNOWN OverrideAddressSpace
0x464 UNNOWN HasAddressSpace
0x464 UNNOWN LaunchPrefetched
0x464 UNNOWN Background
0x464 UNNOWN VmTopDown
0x464 UNNOWN ImageNotifyDone
0x464 UNNOWN PdeUpdateNeeded
0x464 UNNOWN VdmAllowed
0x464 UNNOWN ProcessRundown
0x464 UNNOWN ProcessInserted
0x464 UNNOWN DefaultIoPriority
0x464 UNNOWN ProcessSelfDelete
0x464 UNNOWN SetTimerResolutionLink
0x468 _LARGE_INTEGER CreateTime
0x470 U64[16] ProcessQuotaUsage
0x480 U64[16] ProcessQuotaPeak
0x490 U64 PeakVirtualSize
0x498 U64 VirtualSize
0x4a0 _LIST_ENTRY SessionProcessLinks
0x4b0 Void ExceptionPortData
0x4b0 U64 ExceptionPortValue
0x4b0 UNNOWN ExceptionPortState
0x4b8 _EX_FAST_REF Token
0x4c0 U64 MmReserved
0x4c8 _EX_PUSH_LOCK AddressCreationLock
0x4d0 _EX_PUSH_LOCK PageTableCommitmentLock
0x4d8 _ETHREAD* RotateInProgress
0x4e0 _ETHREAD* ForkInProgress
0x4e8 _EJOB* CommitChargeJob
0x4f0 _RTL_AVL_TREE CloneRoot
0x4f8 volatile U64 NumberOfPrivatePages
0x500 volatile U64 NumberOfLockedPages
0x508 Void Win32Process
0x510 _EJOB* Job
0x518 Void SectionObject
0x520 Void SectionBaseAddress
0x528 U32 Cookie
0x530 _PAGEFAULT_HISTORY* WorkingSetWatch
0x538 Void Win32WindowStation
0x540 Void InheritedFromUniqueProcessId
0x548 volatile U64 OwnerProcessId
0x550 _PEB* Peb
0x558 _MM_SESSION_SPACE* Session
0x560 Void Spare1
0x568 _EPROCESS_QUOTA_BLOCK* QuotaBlock
0x570 _HANDLE_TABLE* ObjectTable
0x578 Void DebugPort
0x580 _EWOW64PROCESS* WoW64Process
0x588 Void DeviceMap
0x590 Void EtwDataSource
0x598 U64 PageDirectoryPte
0x5a0 _FILE_OBJECT* ImageFilePointer
0x5a8 UChar[15] ImageFileName
0x5b7 UChar PriorityClass
0x5b8 Void SecurityPort
0x5c0 _SE_AUDIT_PROCESS_CREATION_INFO SeAuditProcessCreationInfo
0x5c8 _LIST_ENTRY JobLinks
0x5d8 Void HighestUserAddress
0x5e0 _LIST_ENTRY ThreadListHead
0x5f0 volatile U32 ActiveThreads
0x5f4 U32 ImagePathHash
0x5f8 U32 DefaultHardErrorProcessing
0x5fc I32 LastThreadExitStatus
0x600 _EX_FAST_REF PrefetchTrace
0x608 Void LockedPagesList
0x610 _LARGE_INTEGER ReadOperationCount
0x618 _LARGE_INTEGER WriteOperationCount
0x620 _LARGE_INTEGER OtherOperationCount
0x628 _LARGE_INTEGER ReadTransferCount
0x630 _LARGE_INTEGER WriteTransferCount
0x638 _LARGE_INTEGER OtherTransferCount
0x640 U64 CommitChargeLimit
0x648 volatile U64 CommitCharge
0x650 volatile U64 CommitChargePeak
0x680 _MMSUPPORT_FULL Vm
0x7c0 _LIST_ENTRY MmProcessLinks
0x7d0 U32 ModifiedPageCount
0x7d4 I32 ExitStatus
0x7d8 _RTL_AVL_TREE VadRoot
0x7e0 Void VadHint
0x7e8 U64 VadCount
0x7f0 volatile U64 VadPhysicalPages
0x7f8 U64 VadPhysicalPagesLimit
0x800 _ALPC_PROCESS_CONTEXT AlpcContext
0x820 _LIST_ENTRY TimerResolutionLink
0x830 _PO_DIAG_STACK_RECORD* TimerResolutionStackRecord
0x838 U32 RequestedTimerResolution
0x83c U32 SmallestTimerResolution
0x840 _LARGE_INTEGER ExitTime
0x848 _INVERTED_FUNCTION_TABLE* InvertedFunctionTable
0x850 _EX_PUSH_LOCK InvertedFunctionTableLock
0x858 U32 ActiveThreadsHighWatermark
0x85c U32 LargePrivateVadCount
0x860 _EX_PUSH_LOCK ThreadListLock
0x868 Void WnfContext
0x870 _EJOB* ServerSilo
0x878 UChar SignatureLevel
0x879 UChar SectionSignatureLevel
0x87a _PS_PROTECTION Protection
0x87b UNNOWN HangCount
0x87b UNNOWN GhostCount
0x87b UNNOWN PrefilterException
0x87c U32 Flags3
0x87c UNNOWN Minimal
0x87c UNNOWN ReplacingPageRoot
0x87c UNNOWN Crashed
0x87c UNNOWN JobVadsAreTracked
0x87c UNNOWN VadTrackingDisabled
0x87c UNNOWN AuxiliaryProcess
0x87c UNNOWN SubsystemProcess
0x87c UNNOWN IndirectCpuSets
0x87c UNNOWN RelinquishedCommit
0x87c UNNOWN HighGraphicsPriority
0x87c UNNOWN CommitFailLogged
0x87c UNNOWN ReserveFailLogged
0x87c UNNOWN SystemProcess
0x87c UNNOWN HideImageBaseAddresses
0x87c UNNOWN AddressPolicyFrozen
0x87c UNNOWN ProcessFirstResume
0x87c UNNOWN ForegroundExternal
0x87c UNNOWN ForegroundSystem
0x87c UNNOWN HighMemoryPriority
0x87c UNNOWN EnableProcessSuspendResumeLogging
0x87c UNNOWN EnableThreadSuspendResumeLogging
0x87c UNNOWN SecurityDomainChanged
0x87c UNNOWN SecurityFreezeComplete
0x87c UNNOWN VmProcessorHost
0x87c UNNOWN VmProcessorHostTransition
0x87c UNNOWN AltSyscall
0x87c UNNOWN TimerResolutionIgnore
0x880 I32 DeviceAsid
0x888 Void SvmData
0x890 _EX_PUSH_LOCK SvmProcessLock
0x898 U64 SvmLock
0x8a0 _LIST_ENTRY SvmProcessDeviceListHead
0x8b0 U64 LastFreezeInterruptTime
0x8b8 _PROCESS_DISK_COUNTERS* DiskCounters
0x8c0 Void PicoContext
0x8c8 Void EnclaveTable
0x8d0 U64 EnclaveNumber
0x8d8 _EX_PUSH_LOCK EnclaveLock
0x8e0 U32 HighPriorityFaultsAllowed
0x8e8 _PO_PROCESS_ENERGY_CONTEXT* EnergyContext
0x8f0 Void VmContext
0x8f8 U64 SequenceNumber
0x900 U64 CreateInterruptTime
0x908 U64 CreateUnbiasedInterruptTime
0x910 U64 TotalUnbiasedFrozenTime
0x918 U64 LastAppStateUpdateTime
0x920 UNNOWN LastAppStateUptime
0x920 UNNOWN LastAppState
0x928 volatile U64 SharedCommitCharge
0x930 _EX_PUSH_LOCK SharedCommitLock
0x938 _LIST_ENTRY SharedCommitLinks
0x948 U64 AllowedCpuSets
0x950 U64 DefaultCpuSets
0x948 U64 AllowedCpuSetsIndirect
0x950 U64 DefaultCpuSetsIndirect
0x958 Void DiskIoAttribution
0x960 Void DxgProcess
0x968 U32 Win32KFilterSet
0x970 volatile _PS_INTERLOCKED_TIMER_DELAY_VALUES ProcessTimerDelay
0x978 volatile U32 KTimerSets
0x97c volatile U32 KTimer2Sets
0x980 volatile U32 ThreadTimerSets
0x988 U64 VirtualTimerListLock
0x990 _LIST_ENTRY VirtualTimerListHead
0x9a0 _WNF_STATE_NAME WakeChannel
0x9a0 _PS_PROCESS_WAKE_INFORMATION WakeInfo
0x9d0 U32 MitigationFlags
0x9d0 <anonymous-tag> MitigationFlagsValues
0x9d4 U32 MitigationFlags2
0x9d4 <anonymous-tag> MitigationFlags2Values
0x9d8 Void PartitionObject
0x9e0 U64 SecurityDomain
0x9e8 U64 ParentSecurityDomain
0x9f0 Void CoverageSamplerContext
0x9f8 Void MmHotPatchContext
0xa00 _KE_IDEAL_PROCESSOR_ASSIGNMENT_BLOCK IdealProcessorAssignmentBlock
0xab8 _RTL_AVL_TREE DynamicEHContinuationTargetsTree
0xac0 _EX_PUSH_LOCK DynamicEHContinuationTargetsLock
endstruct
beginstruct _RTL_BITMAP_EX
0x0 U64 SizeOfBitMap
0x8 U64 Buffer
endstruct
beginstruct _MI_SYSTEM_INFORMATION
0x0 _MI_POOL_STATE Pools
0xc0 _MI_SECTION_STATE Sections
0x400 _MI_SYSTEM_IMAGE_STATE SystemImages
0x4a8 _MI_SESSION_STATE Sessions
0x1530 _MI_PROCESS_STATE Processes
0x1580 _MI_HARDWARE_STATE Hardware
0x1740 _MI_SYSTEM_VA_STATE SystemVa
0x1c00 _MI_COMBINE_STATE PageCombines
0x1c20 _MI_PAGELIST_STATE PageLists
0x1cc0 _MI_PARTITION_STATE Partitions
0x1d80 _MI_SHUTDOWN_STATE Shutdowns
0x1df8 _MI_ERROR_STATE Errors
0x1f00 _MI_ACCESS_LOG_STATE AccessLog
0x1f80 _MI_DEBUGGER_STATE Debugger
0x20a0 _MI_STANDBY_STATE Standby
0x2140 _MI_SYSTEM_PTE_STATE SystemPtes
0x2340 _MI_IO_PAGE_STATE IoPages
0x2400 _MI_PAGING_IO_STATE PagingIo
0x24b0 _MI_COMMON_PAGE_STATE CommonPages
0x2580 _MI_SYSTEM_TRIM_STATE Trims
0x25c0 _MI_SYSTEM_ZEROING Zeroing
0x25e0 _MI_ENCLAVE_STATE Enclaves
0x2628 U64 Cookie
0x2630 Void** BootRegistryRuns
0x2638 volatile I32 ZeroingDisabled
0x263c UChar FullyInitialized
0x263d UChar SafeBooted
0x2640 const _tlgProvider_t* TraceLogging
0x2680 _MI_VISIBLE_STATE Vs
endstruct
beginstruct _PEB
0x0 UChar InheritedAddressSpace
0x1 UChar ReadImageFileExecOptions
0x2 UChar BeingDebugged
0x3 UChar BitField
0x3 UNNOWN ImageUsesLargePages
0x3 UNNOWN IsProtectedProcess
0x3 UNNOWN IsImageDynamicallyRelocated
0x3 UNNOWN SkipPatchingUser32Forwarders
0x3 UNNOWN IsPackagedProcess
0x3 UNNOWN IsAppContainer
0x3 UNNOWN IsProtectedProcessLight
0x3 UNNOWN IsLongPathAwareProcess
0x4 UChar[4] Padding0
0x8 Void Mutant
0x10 Void ImageBaseAddress
0x18 _PEB_LDR_DATA* Ldr
0x20 _RTL_USER_PROCESS_PARAMETERS* ProcessParameters
0x28 Void SubSystemData
0x30 Void ProcessHeap
0x38 _RTL_CRITICAL_SECTION* FastPebLock
0x40 _SLIST_HEADER* AtlThunkSListPtr
0x48 Void IFEOKey
0x50 U32 CrossProcessFlags
0x50 UNNOWN ProcessInJob
0x50 UNNOWN ProcessInitializing
0x50 UNNOWN ProcessUsingVEH
0x50 UNNOWN ProcessUsingVCH
0x50 UNNOWN ProcessUsingFTH
0x50 UNNOWN ProcessPreviouslyThrottled
0x50 UNNOWN ProcessCurrentlyThrottled
0x50 UNNOWN ProcessImagesHotPatched
0x50 UNNOWN ReservedBits0
0x54 UChar[4] Padding1
0x58 Void KernelCallbackTable
0x58 Void UserSharedInfoPtr
0x60 U32 SystemReserved
0x64 U32 AtlThunkSListPtr32
0x68 Void ApiSetMap
0x70 U32 TlsExpansionCounter
0x74 UChar[4] Padding2
0x78 Void TlsBitmap
0x80 U32[8] TlsBitmapBits
0x88 Void ReadOnlySharedMemoryBase
0x90 Void SharedData
0x98 Void* ReadOnlyStaticServerData
0xa0 Void AnsiCodePageData
0xa8 Void OemCodePageData
0xb0 Void UnicodeCaseTableData
0xb8 U32 NumberOfProcessors
0xbc U32 NtGlobalFlag
0xc0 _LARGE_INTEGER CriticalSectionTimeout
0xc8 U64 HeapSegmentReserve
0xd0 U64 HeapSegmentCommit
0xd8 U64 HeapDeCommitTotalFreeThreshold
0xe0 U64 HeapDeCommitFreeBlockThreshold
0xe8 U32 NumberOfHeaps
0xec U32 MaximumNumberOfHeaps
0xf0 Void* ProcessHeaps
0xf8 Void GdiSharedHandleTable
0x100 Void ProcessStarterHelper
0x108 U32 GdiDCAttributeList
0x10c UChar[4] Padding3
0x110 _RTL_CRITICAL_SECTION* LoaderLock
0x118 U32 OSMajorVersion
0x11c U32 OSMinorVersion
0x120 U16 OSBuildNumber
0x122 U16 OSCSDVersion
0x124 U32 OSPlatformId
0x128 U32 ImageSubsystem
0x12c U32 ImageSubsystemMajorVersion
0x130 U32 ImageSubsystemMinorVersion
0x134 UChar[4] Padding4
0x138 U64 ActiveProcessAffinityMask
0x140 U32[240] GdiHandleBuffer
0x230 Void(UNNOWN)* PostProcessInitRoutine
0x238 Void TlsExpansionBitmap
0x240 U32[128] TlsExpansionBitmapBits
0x2c0 U32 SessionId
0x2c4 UChar[4] Padding5
0x2c8 _ULARGE_INTEGER AppCompatFlags
0x2d0 _ULARGE_INTEGER AppCompatFlagsUser
0x2d8 Void pShimData
0x2e0 Void AppCompatInfo
0x2e8 _UNICODE_STRING CSDVersion
0x2f8 const _ACTIVATION_CONTEXT_DATA* ActivationContextData
0x300 _ASSEMBLY_STORAGE_MAP* ProcessAssemblyStorageMap
0x308 const _ACTIVATION_CONTEXT_DATA* SystemDefaultActivationContextData
0x310 _ASSEMBLY_STORAGE_MAP* SystemAssemblyStorageMap
0x318 U64 MinimumStackCommit
0x320 Void[32] SparePointers
0x340 U32[20] SpareUlongs
0x358 Void WerRegistrationData
0x360 Void WerShipAssertPtr
0x368 Void pUnused
0x370 Void pImageHeaderHash
0x378 U32 TracingFlags
0x378 UNNOWN HeapTracingEnabled
0x378 UNNOWN CritSecTracingEnabled
0x378 UNNOWN LibLoaderTracingEnabled
0x378 UNNOWN SpareTracingBits
0x37c UChar[4] Padding6
0x380 U64 CsrServerReadOnlySharedMemoryBase
0x388 U64 TppWorkerpListLock
0x390 _LIST_ENTRY TppWorkerpList
0x3a0 Void[1024] WaitOnAddressHashTable
0x7a0 Void TelemetryCoverageHeader
0x7a8 U32 CloudFileFlags
0x7ac U32 CloudFileDiagFlags
0x7b0 RChar PlaceholderCompatibilityMode
0x7b1 RChar[7] PlaceholderCompatibilityModeReserved
0x7b8 _LEAP_SECOND_DATA* LeapSecondData
0x7c0 U32 LeapSecondFlags
0x7c0 UNNOWN SixtySecondEnabled
0x7c0 UNNOWN Reserved
0x7c4 U32 NtGlobalFlag2
endstruct
beginstruct _MI_DYNAMIC_BITMAP
0x0 _RTL_BITMAP_EX Bitmap
0x10 U64 MaximumSize
0x18 U64 Hint
0x20 Void BaseVa
0x28 U64 SizeTopDown
0x30 U64 HintTopDown
0x38 Void BaseVaTopDown
0x40 U64 SpinLock
endstruct
beginstruct _MI_HARDWARE_STATE
0x0 U32 NodeMask
0x4 U32 NumaHintIndex
0x8 U32 NumaLastRangeIndexInclusive
0xc UChar NodeShift
0xd UChar ChannelShift
0x10 U32 ChannelHintIndex
0x14 U32 ChannelLastRangeIndexInclusive
0x18 _MI_NODE_NUMBER_ZERO_BASED* NodeGraph
0x20 _MI_SYSTEM_NODE_NONPAGED_POOL* SystemNodeNonPagedPool
0x28 _HAL_NODE_RANGE[32] TemporaryNumaRanges
0x48 _HAL_NODE_RANGE* NumaMemoryRanges
0x50 _HAL_CHANNEL_MEMORY_RANGES* ChannelMemoryRanges
0x58 U32 SecondLevelCacheSize
0x5c U32 FirstLevelCacheSize
0x60 U32 PhysicalAddressBits
0x64 U32 PfnDatabasePageBits
0x68 U32 LogicalProcessorsPerCore
0x6c UChar ProcessorCachesFlushedOnPowerLoss
0x70 U64 TotalPagesAllowed
0x78 U32 SecondaryColorMask
0x7c U32 SecondaryColors
0x80 U32 FlushTbForAttributeChange
0x84 U32 FlushCacheForAttributeChange
0x88 U32 FlushCacheForPageAttributeChange
0x8c U32 CacheFlushPromoteThreshold
0x90 _LARGE_INTEGER PerformanceCounterFrequency
0xc0 U64 InvalidPteMask
0x100 U32[12] LargePageColors
0x110 U64 FlushTbThreshold
0x118 _MI_PFN_CACHE_ATTRIBUTE[16][64] OptimalZeroingAttribute
0x158 UChar AttributeChangeRequiresReZero
0x160 _MI_ZERO_COST_COUNTS[32] ZeroCostCounts
0x180 U64 HighestPossiblePhysicalPage
0x188 U64 VsmKernelPageCount
endstruct
beginstruct _MI_SYSTEM_NODE_NONPAGED_POOL
0x0 _MI_DYNAMIC_BITMAP DynamicBitMapNonPagedPool
0x48 U64 CachedNonPagedPoolCount
0x50 U64 NonPagedPoolSpinLock
0x58 _MMPFN* CachedNonPagedPool
0x60 Void NonPagedPoolFirstVa
0x68 Void NonPagedPoolLastVa
0x70 _MI_SYSTEM_NODE_INFORMATION* SystemNodeInformation
endstruct
beginstruct _MI_SYSTEM_NODE_INFORMATION
0x0 _CACHED_KSTACK_LIST[64] CachedKernelStacks
0x40 _GROUP_AFFINITY GroupAffinity
0x50 U16 ProcessorCount
0x58 Void BootZeroPageTimesPerProcessor
0x60 U64 CyclesToZeroOneLargePage
0x68 U64 ScaledCyclesToZeroOneLargePage
0x70 _MI_WRITE_CALIBRATION WriteCalibration
0xc0 volatile I32 IoPfnLock
endstruct
```
----
Global variables offset are parsed and can be queried by `nt!` in Windbg. In a kernel driver, we need to get the kernel base address (which is `nt!`). Kernel base address is the loaded address of `ntoskrnl.exe`. There is a shellcode to get the address [here](https://gist.github.com/Barakat/34e9924217ed81fd78c9c92d746ec9c6), using IDT table. But when I use the shellcode with the Windows Insider preview 2020, the address is wrong (it still a loaded PE though). Other ways to get the address are listed [here](https://m0uk4.gitbook.io/notebooks/mouka/windowsinternal/find-kernel-module-address-todo). And hereby I present another way to get the kernel base address.
A device driver can get a pointer to a `EPROCESS` through the use of `PEPROCESS IoGetCurrentProcess`. And as we know, `EPROCESS` has pointer to other `EPROCESS` as a doubly linked list. If we dump them all out, we can notice a few things:
- The image name returned by calling `IoGetCurrentProcess` is `System`
- The `EPROCESS` before `System` is somehow empty
```cpp
PVOID eprocess = (PVOID)IoGetCurrentProcess();
DbgPrint("eprocess : 0x%p, [%15s]\n", eprocess, (char*)((ULONG64)eprocess + ImageBaseNameOffset));
for (int i = 0; i < 100; i++) {
eprocess = (PVOID)(*(ULONG64*)((ULONG64)eprocess + ActiveProcessLinksOffset) - ActiveProcessLinksOffset);
DbgPrint("eprocess : 0x%p, [%15s]\n", eprocess, (char*)((ULONG64)eprocess + ImageBaseOffset));
}
// sample output
eprocess : 0xFFFFF8037401F528, [ ]
eprocess : 0xFFFF840F5A0D9080, [ System]
eprocess : 0xFFFF840F5A28C040, [ Secure System]
eprocess : 0xFFFF840F5A2EF040, [ Registry]
eprocess : 0xFFFF840F622BF040, [ smss.exe]
eprocess : 0xFFFF840F6187D080, [ smss.exe]
eprocess : 0xFFFF840F6263D140, [ csrss.exe]
eprocess : 0xFFFF840F6277F0C0, [ smss.exe]
eprocess : 0xFFFF840F627C2080, [ wininit.exe]
eprocess : 0xFFFF840F64187140, [ csrss.exe]
eprocess : 0xFFFF840F641CD080, [ services.exe]
```
And if we debug and compare the address of that `Empty EPROCESS+ActiveProcessLinksOffset` with `nt!PsActiveProcessHead`, it is just the same. And with the given offset parsed from the PDB file, we can get kernel base address.
```cpp
PVOID eprocess = (PVOID)IoGetCurrentProcess();
DbgPrint("eprocess : 0x%p, [%15s]\n", eprocess, (char*)((ULONG64)eprocess + ImageBaseNameOffset));
PVOID processHead = (PVOID)(*(ULONG64*)((ULONG64)eprocess + ActiveProcessLinksOffset + BLinkOffset));
DbgPrint("PsActiveProcessHead : 0x%p\n", processHead);
PVOID ntosbase = (PVOID)((ULONG64)processHead - ActiveHeadOffset);
DbgPrint("ntoskrnl.exe : 0x%p\n", ntosbase);
```
From now we have successfully get the kernel base address to index into other global variables.
(In this way we use `PsActiveProcessHead`, but a better way maybe traversing `PsLoadedModuleList` which could get the correct address of `ntoskrnl.exe` but I do not know)