Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Midi12/12823859abc4b18c45587949c65fb38f to your computer and use it in GitHub Desktop.
Save Midi12/12823859abc4b18c45587949c65fb38f to your computer and use it in GitHub Desktop.
NtQuerySystemInformation SystemSuperfetchInformation Version 2 (since windows 10.0.18362.1 at least)
// see more @ https://www.unknowncheats.me/forum/general-programming-and-reversing/397104-ntquerysysteminformation-systemsuperfetchinformation.html
#pragma once
#include <cstdint>
#include <vector>
#include "lazy_loader_light.hpp"
#include "ntstatus.hpp"
// Credits: waryas (https://github.com/waryas/UMPMLib)
#pragma warning( push )
#pragma warning( disable: 4200 )
namespace superfetch {
namespace native {
typedef enum class _SUPERFETCH_INFORMATION_CLASS {
SuperfetchRetrieveTrace = 1, // Query
SuperfetchSystemParameters = 2, // Query
SuperfetchLogEvent = 3, // Set
SuperfetchGenerateTrace = 4, // Set
SuperfetchPrefetch = 5, // Set
SuperfetchPfnQuery = 6, // Query
SuperfetchPfnSetPriority = 7, // Set
SuperfetchPrivSourceQuery = 8, // Query
SuperfetchSequenceNumberQuery = 9, // Query
SuperfetchScenarioPhase = 10, // Set
SuperfetchWorkerPriority = 11, // Set
SuperfetchScenarioQuery = 12, // Query
SuperfetchScenarioPrefetch = 13, // Set
SuperfetchRobustnessControl = 14, // Set
SuperfetchTimeControl = 15, // Set
SuperfetchMemoryListQuery = 16, // Query
SuperfetchMemoryRangesQuery = 17, // Query
SuperfetchTracingControl = 18, // Set
SuperfetchTrimWhileAgingControl = 19,
SuperfetchInformationMax = 20
} SUPERFETCH_INFORMATION_CLASS;
//
// Buffer for NtQuery/SetInformationSystem for the Superfetch Class
//
typedef struct _SUPERFETCH_INFORMATION {
ULONG Version;
ULONG Magic;
SUPERFETCH_INFORMATION_CLASS InfoClass;
PVOID Data;
ULONG Length;
} SUPERFETCH_INFORMATION, * PSUPERFETCH_INFORMATION;
typedef struct _RTL_BITMAP {
ULONG SizeOfBitMap;
PULONG Buffer;
} RTL_BITMAP, * PRTL_BITMAP;
typedef struct _PF_PHYSICAL_MEMORY_RANGE {
ULONG_PTR BasePfn;
ULONG_PTR PageCount;
} PF_PHYSICAL_MEMORY_RANGE, * PPF_PHYSICAL_MEMORY_RANGE;
typedef struct _PF_MEMORY_RANGE_INFO {
ULONG Version;
ULONG RangeCount;
PF_PHYSICAL_MEMORY_RANGE Ranges[ANYSIZE_ARRAY];
} PF_MEMORY_RANGE_INFO, * PPF_MEMORY_RANGE_INFO;
typedef struct __declspec(align(8)) _PF_MEMORY_RANGE_INFO_V2 {
ULONG version;
ULONG flags;
ULONG ranges_count;
_PF_PHYSICAL_MEMORY_RANGE ranges[ANYSIZE_ARRAY];
} PF_MEMORY_RANGE_INFO_V2, * PPF_MEMORY_RANGE_INFO_V2;
typedef struct _PHYSICAL_MEMORY_RUN {
SIZE_T BasePage;
SIZE_T PageCount;
} PHYSICAL_MEMORY_RUN, * PPHYSICAL_MEMORY_RUN;
typedef enum class _SYSTEM_INFORMATION_CLASS
{
SystemBasicInformation,
SystemProcessorInformation,
SystemPerformanceInformation,
SystemTimeOfDayInformation,
SystemPathInformation, /// Obsolete: Use KUSER_SHARED_DATA
SystemProcessInformation,
SystemCallCountInformation,
SystemDeviceInformation,
SystemProcessorPerformanceInformation,
SystemFlagsInformation,
SystemCallTimeInformation,
SystemModuleInformation,
SystemLocksInformation,
SystemStackTraceInformation,
SystemPagedPoolInformation,
SystemNonPagedPoolInformation,
SystemHandleInformation,
SystemObjectInformation,
SystemPageFileInformation,
SystemVdmInstemulInformation,
SystemVdmBopInformation,
SystemFileCacheInformation,
SystemPoolTagInformation,
SystemInterruptInformation,
SystemDpcBehaviorInformation,
SystemFullMemoryInformation,
SystemLoadGdiDriverInformation,
SystemUnloadGdiDriverInformation,
SystemTimeAdjustmentInformation,
SystemSummaryMemoryInformation,
SystemMirrorMemoryInformation,
SystemPerformanceTraceInformation,
SystemObsolete0,
SystemExceptionInformation,
SystemCrashDumpStateInformation,
SystemKernelDebuggerInformation,
SystemContextSwitchInformation,
SystemRegistryQuotaInformation,
SystemExtendServiceTableInformation, // used to be SystemLoadAndCallImage
SystemPrioritySeperation,
SystemPlugPlayBusInformation,
SystemDockInformation,
SystemPowerInformationNative,
SystemProcessorSpeedInformation,
SystemCurrentTimeZoneInformation,
SystemLookasideInformation,
SystemTimeSlipNotification,
SystemSessionCreate,
SystemSessionDetach,
SystemSessionInformation,
SystemRangeStartInformation,
SystemVerifierInformation,
SystemAddVerifier,
SystemSessionProcessesInformation,
SystemLoadGdiDriverInSystemSpaceInformation,
SystemNumaProcessorMap,
SystemPrefetcherInformation,
SystemExtendedProcessInformation,
SystemRecommendedSharedDataAlignment,
SystemComPlusPackage,
SystemNumaAvailableMemory,
SystemProcessorPowerInformation,
SystemEmulationBasicInformation,
SystemEmulationProcessorInformation,
SystemExtendedHanfleInformation,
SystemLostDelayedWriteInformation,
SystemBigPoolInformation,
SystemSessionPoolTagInformation,
SystemSessionMappedViewInformation,
SystemHotpatchInformation,
SystemObjectSecurityMode,
SystemWatchDogTimerHandler,
SystemWatchDogTimerInformation,
SystemLogicalProcessorInformation,
SystemWo64SharedInformationObosolete,
SystemRegisterFirmwareTableInformationHandler,
SystemFirmwareTableInformation,
SystemModuleInformationEx,
SystemVerifierTriageInformation,
SystemSuperfetchInformation,
SystemMemoryListInformation,
SystemFileCacheInformationEx,
SystemThreadPriorityClientIdInformation,
SystemProcessorIdleCycleTimeInformation,
SystemVerifierCancellationInformation,
SystemProcessorPowerInformationEx,
SystemRefTraceInformation,
SystemSpecialPoolInformation,
SystemProcessIdInformation,
SystemErrorPortInformation,
SystemBootEnvironmentInformation,
SystemHypervisorInformation,
SystemVerifierInformationEx,
SystemTimeZoneInformation,
SystemImageFileExecutionOptionsInformation,
SystemCoverageInformation,
SystemPrefetchPathInformation,
SystemVerifierFaultsInformation,
MaxSystemInfoClass,
} SYSTEM_INFORMATION_CLASS;
typedef struct _SYSTEM_BASIC_INFORMATION {
ULONG Reserved;
ULONG TimerResolution;
ULONG PageSize;
ULONG NumberOfPhysicalPages;
ULONG LowestPhysicalPageNumber;
ULONG HighestPhysicalPageNumber;
ULONG AllocationGranularity;
ULONG_PTR MinimumUserModeAddress;
ULONG_PTR MaximumUserModeAddress;
ULONG_PTR ActiveProcessorsAffinityMask;
CCHAR NumberOfProcessors;
} SYSTEM_BASIC_INFORMATION, * PSYSTEM_BASIC_INFORMATION;
struct RTL_PROCESS_MODULE_INFORMATION
{
unsigned int Section;
void* MappedBase;
void* ImageBase;
unsigned int ImageSize;
unsigned int Flags;
unsigned short LoadOrderIndex;
unsigned short InitOrderIndex;
unsigned short LoadCount;
unsigned short OffsetToFileName;
char FullPathName[256];
};
struct RTL_PROCESS_MODULES
{
unsigned int NumberOfModules;
RTL_PROCESS_MODULE_INFORMATION Modules[0];
};
struct SYSTEM_HANDLE
{
ULONG ProcessId;
BYTE ObjectTypeNumber;
BYTE Flags;
USHORT Handle;
PVOID Object;
ACCESS_MASK GrantedAccess;
};
struct SYSTEM_HANDLE_INFORMATION
{
ULONG HandleCount;
SYSTEM_HANDLE Handles[0];
};
#define PAGE_SHIFT 12
#define PAGE_SIZE (1 << 12)
#define SE_DEBUG_PRIVILEGE (20L)
#define SE_PROF_SINGLE_PROCESS_PRIVILEGE (13L)
#define SPAGE_SIZE 0x1000
#define SUPERFETCH_VERSION 0x2D
#define SUPERFETCH_MAGIC 0x6B756843
}
struct physical_memory_range_t {
std::uintptr_t start;
std::uintptr_t end;
std::size_t page_count;
std::uintptr_t size;
};
struct superfect_config_t {
bool initialized = false;
std::vector<physical_memory_range_t> physical_memory_ranges;
};
__declspec(selectany) superfect_config_t g_superfetch_config;
static bool initialize_privileges(void) {
BOOLEAN old;
auto status = LAZYCALL(NTSTATUS, "ntdll.dll!RtlAdjustPrivilege", SE_PROF_SINGLE_PROCESS_PRIVILEGE, TRUE, FALSE, &old);
status |= LAZYCALL(NTSTATUS, "ntdll.dll!RtlAdjustPrivilege", SE_DEBUG_PRIVILEGE, TRUE, FALSE, &old);
if (status != ERROR_SUCCESS) {
return false;
}
native::SYSTEM_BASIC_INFORMATION basicInfo;
status = LAZYCALL(NTSTATUS, "ntdll.dll!NtQuerySystemInformation", native::SYSTEM_INFORMATION_CLASS::SystemBasicInformation, &basicInfo, sizeof(basicInfo), nullptr);
if (status != STATUS_SUCCESS) {
return false;
}
return true;
}
static superfect_config_t& initialize(void) {
if (!initialize_privileges()) {
return g_superfetch_config;
}
// assign superfecth version dynamically, some system are v1 some are v2 due to windows update
// (on my system nt!PfpMemoryRangesQuery checks for memory_range_info.Version == 2)
native::PPF_MEMORY_RANGE_INFO_V2 memory_ranges = nullptr;
native::SUPERFETCH_INFORMATION sf_info = {};
std::size_t result_length = 0;
native::PF_MEMORY_RANGE_INFO_V2 memory_range_info = {};
memory_range_info.version = 2;
auto build_info = [=](native::PSUPERFETCH_INFORMATION SuperfetchInfo, PVOID Buffer, ULONG Length, native::SUPERFETCH_INFORMATION_CLASS InfoClass) -> void {
SuperfetchInfo->Version = SUPERFETCH_VERSION;
SuperfetchInfo->Magic = SUPERFETCH_MAGIC;
SuperfetchInfo->Data = Buffer;
SuperfetchInfo->Length = Length;
SuperfetchInfo->InfoClass = InfoClass;
};
build_info(&sf_info, &memory_range_info, sizeof(memory_range_info), native::SUPERFETCH_INFORMATION_CLASS::SuperfetchMemoryRangesQuery);
NTSTATUS status = LAZYCALL(NTSTATUS, "ntdll.dll!NtQuerySystemInformation", native::SYSTEM_INFORMATION_CLASS::SystemSuperfetchInformation, &sf_info, sizeof(sf_info), &result_length);
if (status == STATUS_BUFFER_TOO_SMALL) {
memory_ranges = static_cast<native::PPF_MEMORY_RANGE_INFO_V2>(HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, result_length));
memory_ranges->version = 2;
build_info(&sf_info, memory_ranges, static_cast<ULONG>(result_length), native::SUPERFETCH_INFORMATION_CLASS::SuperfetchMemoryRangesQuery);
status = LAZYCALL(NTSTATUS, "ntdll!NtQuerySystemInformation", native::SYSTEM_INFORMATION_CLASS::SystemSuperfetchInformation, &sf_info, sizeof(sf_info), &result_length);
if (status != STATUS_SUCCESS) {
return g_superfetch_config;
}
} else if (status == STATUS_SUCCESS) {
memory_ranges = &memory_range_info;
} else {
return g_superfetch_config;
}
if (memory_ranges->ranges_count == 0x0) {
return g_superfetch_config;
}
native::PPHYSICAL_MEMORY_RUN Node;
for (ULONG i = 0; i < memory_ranges->ranges_count; i++) {
Node = reinterpret_cast<native::PPHYSICAL_MEMORY_RUN>(&memory_ranges->ranges[i]);
g_superfetch_config.physical_memory_ranges.push_back({
Node->BasePage << PAGE_SHIFT,
(Node->BasePage + Node->PageCount) << PAGE_SHIFT,
Node->PageCount,
((Node->PageCount << PAGE_SHIFT) >> 10) * 1024 // kb to byte
});
}
g_superfetch_config.initialized = true;
return g_superfetch_config;
}
}
#pragma warning( pop )
@iwgregn
Copy link

iwgregn commented Oct 27, 2020

This is great! Kudos on finding the V2. Do you mind adding a license, at least for the V2 code?

@Midi12
Copy link
Author

Midi12 commented Oct 27, 2020

Hi @iwgregn thanks ! Which license would fit it the best tho ? I already gave credits to Waryas for the initial work.

@iwgregn
Copy link

iwgregn commented Oct 28, 2020

Hi Midi12, again, very cool work! Technically, without specifying a license (your permission), the code can't be used. If you make it MIT, then anyone could use your code (the V2 code at least) for other projects (within the MIT license of course). You could probably just stick it as a note at the top, like the ref to see more or credits. Thanks!

@Midi12
Copy link
Author

Midi12 commented Oct 28, 2020

Hi @iwgregn, the underlying problem is a 2 parts problem. First of all, @waryas did not set up a license for his project. Second, the PPF_MEMORY_RANGE_INFO_V2 has not been reversed using clean room reverse engineering and is Microsoft intellectual property. Therefore I won't add a license which would put me at risk of sublicensing proprietary program and breaking their license. Yes technically you can only look at it, however, it is just a POC/snippet and is not meant to be production-ready code.

@iwgregn
Copy link

iwgregn commented Oct 28, 2020

I completely understand, thanks for your time in looking into it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment