Skip to content

Instantly share code, notes, and snippets.

@olliencc
Created January 7, 2022 13:55
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save olliencc/e166a64ca211c51eb69111f26ce57bc1 to your computer and use it in GitHub Desktop.
Save olliencc/e166a64ca211c51eb69111f26ce57bc1 to your computer and use it in GitHub Desktop.
Enumerates which DLL loaded when and why for each process via PEB enumeration
/*
DLL Load Reason Enumerator for Microsoft Windows
Released as open source by NCC Group Plc - http://www.nccgroup.com/
Developed by Ollie Whitehouse, ollie dot whitehouse at nccgroup dot com
Released under AGPL see LICENSE for more information
*/
// Includes
#include "stdafx.h"
#include <time.h>
// Globals
HANDLE hProcess;
TCHAR strErrMsg[1024];
DWORD dwModuleRelocs = 0;
DWORD dwCountError = 0;
DWORD dwCountOK = 0;
DWORD dwVEH = 0;
DWORD dwVCH = 0;
DWORD dwOpen = 0;
// Structures to hold process information
#pragma pack(push, 1)
struct procNfoStuct {
DWORD PID;
TCHAR Name[MAX_PATH];
unsigned long long TotalExecMem = 0;
};
#pragma pack(pop)
procNfoStuct Procs[4098];
DWORD NumOfProcs = 0;
// Manual imports
_NtQueryInformationProcess __NtQueryInformationProcess = (_NtQueryInformationProcess)GetProcAddress(GetModuleHandle(_T("ntdll.dll")), "NtQueryInformationProcess");
_MyNtQueryInformationProcess __MyNtQueryInformationProcess = (_MyNtQueryInformationProcess)GetProcAddress(GetModuleHandle(_T("ntdll.dll")), "NtQueryInformationProcess");
typedef BOOL(WINAPI* LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
LPFN_ISWOW64PROCESS fnIsWow64Process = fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandle(TEXT("kernel32")), "IsWow64Process");
typedef void(__stdcall* pRtlTimeToSecondsSince1970)(PLARGE_INTEGER, PULONG);
pRtlTimeToSecondsSince1970 myRtlTimeToSecondsSince1970 = (pRtlTimeToSecondsSince1970)GetProcAddress(GetModuleHandle(_T("ntdll.dll")), "RtlTimeToSecondsSince1970");
//
// Function : SetDebugPrivilege
// Role : Gets privs for our process
// Notes :
//
BOOL SetPrivilege(HANDLE hProcess, LPCTSTR lPriv)
{
LUID luid;
TOKEN_PRIVILEGES privs;
HANDLE hToken = NULL;
DWORD dwBufLen = 0;
char buf[1024];
ZeroMemory(&luid, sizeof(luid));
if (!LookupPrivilegeValue(NULL, lPriv, &luid)) return false;
privs.PrivilegeCount = 1;
privs.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
memcpy(&privs.Privileges[0].Luid, &luid, sizeof(privs.Privileges[0].Luid));
if (!OpenProcessToken(hProcess, TOKEN_ALL_ACCESS, &hToken))
return false;
if (!AdjustTokenPrivileges(hToken, FALSE, &privs,
sizeof(buf), (PTOKEN_PRIVILEGES)buf, &dwBufLen))
return false;
CloseHandle(hProcess);
CloseHandle(hToken);
return true;
}
//
// GetModuleNameFromAddress
BOOL GetModuleNameFromAddress(HANDLE hProcess, PVOID pvPoint, TCHAR* modName) {
DWORD dwRet, dwMods;
HMODULE hModule[4096];
// Enumerate the process modules
if (EnumProcessModules(hProcess, hModule, 4096 * sizeof(HMODULE), &dwRet) == FALSE)
{
fprintf(stderr, "Couldn't enum modules\n");
return FALSE;
}
dwMods = dwRet / sizeof(HMODULE);
// fwprintf(stdout, _TEXT("[d] VEH handler #1 hunt 0x%p %d\n"), pvPoint,dwMods);
DWORD dwCnt = 0;
for (dwCnt = 0; dwCnt < dwMods; dwCnt++) {
TCHAR cModule[MAX_PATH]; // Process name
GetModuleBaseName(hProcess, hModule[dwCnt], cModule, MAX_PATH);
MODULEINFO modNFO;
if (GetModuleInformation(hProcess, hModule[dwCnt], &modNFO, sizeof(modNFO)) == TRUE) {
//fwprintf(stdout, _TEXT("[i] -//-> %p - %d\n"), modNFO.lpBaseOfDll,modNFO.SizeOfImage);
DWORD64 dwAddress = (DWORD64)pvPoint;
// Make sure the function is the expected range
if (dwAddress > (DWORD64)modNFO.lpBaseOfDll && dwAddress < ((DWORD64)modNFO.lpBaseOfDll + modNFO.SizeOfImage)) {
//fwprintf(stdout, _TEXT("\n........................\n"));
_tcscpy_s(modName, MAX_PATH * sizeof(TCHAR), cModule);
return TRUE;
}
}
}
return FALSE;
}
//
// Get the PEB for the process we are interested in and then return just the CrossProcessFlags
//
//
DWORD GetPEB(HANDLE hProcess, PEB* outPEB, DWORD64* CrossProcessFlags) {
NTSTATUS Status;
PROCESS_BASIC_INFORMATION ProcessInformation;
Status = __NtQueryInformationProcess(hProcess, ProcessBasicInformation, (DWORD_PTR*)&ProcessInformation, sizeof(ProcessInformation), NULL);
if (Status != 0)
{
return 0;
}
SIZE_T dwRead = 0;
if (ReadProcessMemory(hProcess, ProcessInformation.PebBaseAddress, outPEB, sizeof(PEB), &dwRead) == FALSE) {
return 0;
}
PPEB pPEB = (PPEB)ProcessInformation.PebBaseAddress;
if (ReadProcessMemory(hProcess, (PBYTE)pPEB + 0x50, (LPVOID)CrossProcessFlags, sizeof(DWORD64), &dwRead) == FALSE) {
return 0;
}
return (DWORD)dwRead;
}
/// <summary>
/// Analyze the process and its memory regions
/// </summary>
/// <param name="dwPID">Process ID</param>
void AnalyzeProc(DWORD dwPID)
{
DWORD dwRet, dwMods;
HANDLE hProcess;
HMODULE hModule[4096];
TCHAR cProcess[MAX_PATH]; // Process name
BOOL bIsWow64 = FALSE;
BOOL bIsWow64Other = FALSE;
DWORD dwRES = 0;
// Get process handle by hook or by crook
hProcess = OpenProcess(PROCESS_ALL_ACCESS | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, dwPID);
if (hProcess == NULL)
{
if (GetLastError() == 5) {
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, dwPID);
if (hProcess == NULL) {
hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, dwPID);
if (hProcess == NULL) {
fwprintf(stderr, _TEXT("[!] [%d][UNKNOWN] Failed to OpenProcess - %d\n"), dwPID, GetLastError());
dwCountError++;
return;
}
}
}
else {
fwprintf(stderr, _TEXT("[!] [%d][UNKNOWN] Failed to OpenProcess - %d\n"), dwPID, GetLastError());
dwCountError++;
return;
}
}
// Enumerate the process modules
if (EnumProcessModules(hProcess, hModule, 4096 * sizeof(HMODULE), &dwRet) == FALSE)
{
DWORD dwSz = MAX_PATH;
if (QueryFullProcessImageName(hProcess, 0, cProcess, &dwSz) == TRUE) {
fwprintf(stdout, _TEXT("[i] [%d][%s] not analysed %d\n"), dwPID, cProcess, GetLastError());
dwOpen++;
}
else {
fwprintf(stdout, _TEXT("[i] [%d][%s] not analysed %d\n"), dwPID, _TEXT("UNKNOWN"), GetLastError());
dwOpen++;
}
if (GetLastError() == 299) {
//fprintf(stderr, "64bit process and we're 32bit - sad panda! skipping PID %d\n", dwPID);
}
else {
//fprintf(stderr, "Error in EnumProcessModules(%d),%d\n", dwPID, GetLastError());
}
dwCountError++;
return;
}
dwMods = dwRet / sizeof(HMODULE);
// Get the processes name from the first module returned by the above
GetModuleBaseName(hProcess, hModule[0], cProcess, MAX_PATH);
Procs[NumOfProcs].PID = dwPID;
_tcscpy_s(Procs[NumOfProcs].Name, MAX_PATH, cProcess);
//fwprintf(stdout, _TEXT("[i] [%d][%s] analyzing\n"), dwPID, cProcess);
NumOfProcs++;
PEB myPEB;
DWORD64 CrossProcessFlags = -1;
if (GetPEB(hProcess, &myPEB, &CrossProcessFlags) > 0) {
// https://docs.microsoft.com/en-us/windows/win32/api/winternl/ns-winternl-peb_ldr_data
// https://www.geoffchappell.com/studies/windows/km/ntoskrnl/inc/api/ntldr/ldr_data_table_entry.htm?ta=11&tx=205,206,208
//
PEB_LDR_DATA pebLDRData = { 0 };
LDR_DATA_TABLE_ENTRY pebLDREntry = { 0 };
// https://www.ired.team/miscellaneous-reversing-forensics/windows-kernel-internals/exploring-process-environment-block
// https://www.sysnative.com/forums/threads/finding-dlls-for-a-process-with-windbg.14458/
//
SIZE_T dwRead = 0;
// myPEB.Ldr
if (ReadProcessMemory(hProcess, myPEB.Ldr, &pebLDRData, sizeof(myLDR_DATA_TABLE_ENTRY), &dwRead) == TRUE) {
LIST_ENTRY InMemoryOrderModuleList = (pebLDRData.InMemoryOrderModuleList);
LIST_ENTRY* headOfList = InMemoryOrderModuleList.Flink;
myLDR_DATA_TABLE_ENTRY* addressLDREntry = CONTAINING_RECORD(headOfList, myLDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);
//fwprintf(stdout, _TEXT("[i] [%d][%s] addressLDREntry %p\n"), dwPID, cProcess, addressLDREntry);
myLDR_DATA_TABLE_ENTRY remoteLDREntry = { 0 };
BYTE* remoteLDREntryByte = (BYTE *)malloc(sizeof(myLDR_DATA_TABLE_ENTRY));
if (ReadProcessMemory(hProcess, addressLDREntry, &remoteLDREntry, sizeof(myLDR_DATA_TABLE_ENTRY), &dwRead) == TRUE) {
while (TRUE) {
if (remoteLDREntry.DllBase == NULL) break;
PWSTR strDLL = (PWSTR)malloc(remoteLDREntry.BaseDllName.MaximumLength);
// get the string's buffer
if (ReadProcessMemory(hProcess, remoteLDREntry.BaseDllName.Buffer, strDLL, remoteLDREntry.BaseDllName.MaximumLength, &dwRead) == TRUE)
{
TCHAR strReason[MAX_PATH];
// Nasty hack due to https://www.geoffchappell.com/studies/windows/km/ntoskrnl/inc/api/ntldr/ldr_data_table_entry.htm?ta=11&tx=205,206,208
// being accurate and Process Hacker not it would seem
memcpy(remoteLDREntryByte, &remoteLDREntry, sizeof(myLDR_DATA_TABLE_ENTRY));
DWORD wReason;
memcpy(&wReason, remoteLDREntryByte + 0x010C, 4);
LARGE_INTEGER loadTime;
memcpy(&loadTime, remoteLDREntryByte + 0x0100, sizeof(LARGE_INTEGER));
ULONG dwSeconds = 0;
myRtlTimeToSecondsSince1970(&loadTime, &dwSeconds);
time_t timep = (time_t)dwSeconds;
struct tm tmDest;
localtime_s(&tmDest ,&timep);
if (wReason == LoadReasonStaticDependency) {
_tcscpy_s(strReason, MAX_PATH * sizeof(TCHAR), _T("Static Dependency"));
}
else if (wReason == LoadReasonStaticForwarderDependency) {
_tcscpy_s(strReason, MAX_PATH * sizeof(TCHAR), _T("Static Forwarder Dependency"));
}
else if (wReason == LoadReasonDynamicForwarderDependency) {
_tcscpy_s(strReason, MAX_PATH * sizeof(TCHAR), _T("Dynamic Forwarder Dependency"));
}
else if (wReason == LoadReasonDelayloadDependency) {
_tcscpy_s(strReason, MAX_PATH * sizeof(TCHAR), _T("Delayload Dependency"));
}
else if (wReason == LoadReasonDynamicLoad) {
_tcscpy_s(strReason, MAX_PATH * sizeof(TCHAR), _T("Dynamic Load"));
}
else if (wReason == LoadReasonAsImageLoad) {
_tcscpy_s(strReason, MAX_PATH * sizeof(TCHAR), _T("As Image Load"));
}
else if (wReason == LoadReasonAsDataLoad) {
_tcscpy_s(strReason, MAX_PATH * sizeof(TCHAR), _T("As Data Load"));
}
else {
_tcscpy_s(strReason, MAX_PATH * sizeof(TCHAR), _T("Unknown"));
}
TCHAR strWhen[26];
wcsftime(strWhen, 26, _TEXT("%Y-%m-%d %H:%M:%S"), &tmDest);
fwprintf(stdout, _TEXT("[i] [%d][%s] Load Reason for %s is %s - loaded @ %s\n"), dwPID, cProcess, strDLL, strReason, strWhen);
//fwprintf(stdout, _TEXT("[i] [%d][%s] Load Reason for %s is %s - %d\n"), dwPID, cProcess, strDLL, strReason, wReason);
LIST_ENTRY* nextInList = remoteLDREntry.InMemoryOrderLinks.Flink;
myLDR_DATA_TABLE_ENTRY* addressNextLDREntry = CONTAINING_RECORD(nextInList, myLDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);
// free(remoteLDREntry.FullDllName.Buffer);
free(strDLL);
//get the actual remote Table Entry
if (ReadProcessMemory(hProcess, addressNextLDREntry, &remoteLDREntry, sizeof(myLDR_DATA_TABLE_ENTRY), &dwRead) == FALSE) {
// Error
fwprintf(stdout, _TEXT("[i] [%d][%s] Error in ReadProcessMemory - %d\n"), dwPID, cProcess, GetLastError());
return;
}
}
}
/*
while (TRUE) {
}
*/
}
}
//
}
else {
fwprintf(stderr, _TEXT("[!] [%d][UNKNOWN] Failed to get PEB\n"), dwPID);
}
dwCountOK++;
CloseHandle(hProcess);
}
/// <summary>
/// Enumerate all the processes on the system and
/// pass off to the analysis function
/// </summary>
void EnumerateProcesses()
{
DWORD dwPIDArray[4096], dwRet, dwPIDS, intCount;
NumOfProcs = 0;
// Privs
SetPrivilege(GetCurrentProcess(), SE_DEBUG_NAME);
// Be clean
memset(Procs, 0x00, sizeof(Procs));
//
// Enumerate
//
if (EnumProcesses(dwPIDArray, 4096 * sizeof(DWORD), &dwRet) == 0)
{
DWORD dwRet = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0, GetLastError(), 0, strErrMsg, 1023, NULL);
if (dwRet != 0) {
_ftprintf(stderr, TEXT("[!] EnumProcesses() failed - %s"), strErrMsg);
}
else
{
_ftprintf(stderr, TEXT("[!] EnumProcesses() - Error: %d\n"), GetLastError());
}
return;
}
// Total nuber of process IDs
dwPIDS = dwRet / sizeof(DWORD);
//
// Analyze
//
for (intCount = 0; intCount < dwPIDS; intCount++)
{
//fwprintf(stdout, _TEXT("[i] Analyzing PID %d\n"), dwPIDArray[intCount]);
AnalyzeProc(dwPIDArray[intCount]);
}
fwprintf(stdout, _TEXT("[i] Total of %d processes - didn't open %d \n"), dwPIDS, dwOpen);
}
/*
DLL Load Reason Enumerator for Microsoft Windows
Released as open source by NCC Group Plc - http://www.nccgroup.com/
Developed by Ollie Whitehouse, ollie dot whitehouse at nccgroup dot com
Released under AGPL see LICENSE for more information
*/
#pragma once
#include "stdafx.h"
#include <stdio.h>
#include <tchar.h>
#include <windows.h>
#include <Winternl.h>
#include <Psapi.h>
#include <Aclapi.h>
#include <tlhelp32.h>
#include <wtsapi32.h>
#include <strsafe.h>
#include <winevt.h>
#include <evntprov.h>
//
extern bool bFirstRun;
extern bool bConsole;
extern bool bService;
// Reimplement from Winternal.h
typedef NTSTATUS(WINAPI* _NtQueryInformationProcess)(
IN HANDLE ProcessHandle,
IN PROCESSINFOCLASS ProcessInformationClass,
OUT DWORD_PTR* ProcessInformation,
IN ULONG ProcessInformationLength,
OUT PULONG ReturnLength OPTIONAL
);
//
// Original source: https://github.com/mirror/processhacker/blob/master/2.x/trunk/phlib/include/ntpsapi.h
//
// used for the Process Cookie stuff
//
#pragma once
typedef enum _MYPROCESSINFOCLASS
{
myProcessBasicInformation, // q: PROCESS_BASIC_INFORMATION, PROCESS_EXTENDED_BASIC_INFORMATION
myProcessQuotaLimits, // qs: QUOTA_LIMITS, QUOTA_LIMITS_EX
myProcessIoCounters, // q: IO_COUNTERS
myProcessVmCounters, // q: VM_COUNTERS, VM_COUNTERS_EX, VM_COUNTERS_EX2
myProcessTimes, // q: KERNEL_USER_TIMES
myProcessBasePriority, // s: KPRIORITY
myProcessRaisePriority, // s: ULONG
myProcessDebugPort, // q: HANDLE
myProcessExceptionPort, // s: PROCESS_EXCEPTION_PORT
myProcessAccessToken, // s: PROCESS_ACCESS_TOKEN
myProcessLdtInformation, // qs: PROCESS_LDT_INFORMATION // 10
myProcessLdtSize, // s: PROCESS_LDT_SIZE
myProcessDefaultHardErrorMode, // qs: ULONG
myProcessIoPortHandlers, // (kernel-mode only) // PROCESS_IO_PORT_HANDLER_INFORMATION
myProcessPooledUsageAndLimits, // q: POOLED_USAGE_AND_LIMITS
myProcessWorkingSetWatch, // q: PROCESS_WS_WATCH_INFORMATION[]; s: void
myProcessUserModeIOPL, // qs: ULONG (requires SeTcbPrivilege)
myProcessEnableAlignmentFaultFixup, // s: BOOLEAN
myProcessPriorityClass, // qs: PROCESS_PRIORITY_CLASS
myProcessWx86Information, // qs: ULONG (requires SeTcbPrivilege) (VdmAllowed)
myProcessHandleCount, // q: ULONG, PROCESS_HANDLE_INFORMATION // 20
myProcessAffinityMask, // s: KAFFINITY
myProcessPriorityBoost, // qs: ULONG
myProcessDeviceMap, // qs: PROCESS_DEVICEMAP_INFORMATION, PROCESS_DEVICEMAP_INFORMATION_EX
myProcessSessionInformation, // q: PROCESS_SESSION_INFORMATION
myProcessForegroundInformation, // s: PROCESS_FOREGROUND_BACKGROUND
myProcessWow64Information, // q: ULONG_PTR
myProcessImageFileName, // q: UNICODE_STRING
myProcessLUIDDeviceMapsEnabled, // q: ULONG
myProcessBreakOnTermination, // qs: ULONG
myProcessDebugObjectHandle, // q: HANDLE // 30
myProcessDebugFlags, // qs: ULONG
myProcessHandleTracing, // q: PROCESS_HANDLE_TRACING_QUERY; s: size 0 disables, otherwise enables
myProcessIoPriority, // qs: IO_PRIORITY_HINT
myProcessExecuteFlags, // qs: ULONG
myProcessTlsInformation, // PROCESS_TLS_INFORMATION // ProcessResourceManagement
myProcessCookie, // q: ULONG
myProcessImageInformation, // q: SECTION_IMAGE_INFORMATION
myProcessCycleTime, // q: PROCESS_CYCLE_TIME_INFORMATION // since VISTA
myProcessPagePriority, // q: PAGE_PRIORITY_INFORMATION
myProcessInstrumentationCallback, // s: PVOID or PROCESS_INSTRUMENTATION_CALLBACK_INFORMATION // 40
myProcessThreadStackAllocation, // s: PROCESS_STACK_ALLOCATION_INFORMATION, PROCESS_STACK_ALLOCATION_INFORMATION_EX
myProcessWorkingSetWatchEx, // q: PROCESS_WS_WATCH_INFORMATION_EX[]
myProcessImageFileNameWin32, // q: UNICODE_STRING
myProcessImageFileMapping, // q: HANDLE (input)
myProcessAffinityUpdateMode, // qs: PROCESS_AFFINITY_UPDATE_MODE
myProcessMemoryAllocationMode, // qs: PROCESS_MEMORY_ALLOCATION_MODE
myProcessGroupInformation, // q: USHORT[]
myProcessTokenVirtualizationEnabled, // s: ULONG
myProcessConsoleHostProcess, // q: ULONG_PTR // ProcessOwnerInformation
myProcessWindowInformation, // q: PROCESS_WINDOW_INFORMATION // 50
myProcessHandleInformation, // q: PROCESS_HANDLE_SNAPSHOT_INFORMATION // since WIN8
myProcessMitigationPolicy, // s: PROCESS_MITIGATION_POLICY_INFORMATION
myProcessDynamicFunctionTableInformation,
myProcessHandleCheckingMode, // qs: ULONG; s: 0 disables, otherwise enables
myProcessKeepAliveCount, // q: PROCESS_KEEPALIVE_COUNT_INFORMATION
myProcessRevokeFileHandles, // s: PROCESS_REVOKE_FILE_HANDLES_INFORMATION
myProcessWorkingSetControl, // s: PROCESS_WORKING_SET_CONTROL
myProcessHandleTable, // q: ULONG[] // since WINBLUE
myProcessCheckStackExtentsMode, // qs: ULONG // KPROCESS->CheckStackExtents (CFG)
myProcessCommandLineInformation, // q: UNICODE_STRING // 60
myProcessProtectionInformation, // q: PS_PROTECTION
myProcessMemoryExhaustion, // PROCESS_MEMORY_EXHAUSTION_INFO // since THRESHOLD
myProcessFaultInformation, // PROCESS_FAULT_INFORMATION
myProcessTelemetryIdInformation, // q: PROCESS_TELEMETRY_ID_INFORMATION
myProcessCommitReleaseInformation, // PROCESS_COMMIT_RELEASE_INFORMATION
myProcessDefaultCpuSetsInformation,
myProcessAllowedCpuSetsInformation,
myProcessSubsystemProcess,
myProcessJobMemoryInformation, // q: PROCESS_JOB_MEMORY_INFO
myProcessInPrivate, // s: void // ETW // since THRESHOLD2 // 70
myProcessRaiseUMExceptionOnInvalidHandleClose, // qs: ULONG; s: 0 disables, otherwise enables
myProcessIumChallengeResponse,
myProcessChildProcessInformation, // q: PROCESS_CHILD_PROCESS_INFORMATION
myProcessHighGraphicsPriorityInformation, // qs: BOOLEAN (requires SeTcbPrivilege)
myProcessSubsystemInformation, // q: SUBSYSTEM_INFORMATION_TYPE // since REDSTONE2
myProcessEnergyValues, // q: PROCESS_ENERGY_VALUES, PROCESS_EXTENDED_ENERGY_VALUES
myProcessPowerThrottlingState, // qs: POWER_THROTTLING_PROCESS_STATE
myProcessReserved3Information, // ProcessActivityThrottlePolicy // PROCESS_ACTIVITY_THROTTLE_POLICY
myProcessWin32kSyscallFilterInformation, // q: WIN32K_SYSCALL_FILTER
myProcessDisableSystemAllowedCpuSets, // 80
myProcessWakeInformation, // PROCESS_WAKE_INFORMATION
myProcessEnergyTrackingState, // PROCESS_ENERGY_TRACKING_STATE
myProcessManageWritesToExecutableMemory, // MANAGE_WRITES_TO_EXECUTABLE_MEMORY // since REDSTONE3
myProcessCaptureTrustletLiveDump,
myProcessTelemetryCoverage,
myProcessEnclaveInformation,
myProcessEnableReadWriteVmLogging, // PROCESS_READWRITEVM_LOGGING_INFORMATION
myProcessUptimeInformation, // q: PROCESS_UPTIME_INFORMATION
myProcessImageSection, // q: HANDLE
myProcessDebugAuthInformation, // since REDSTONE4 // 90
myProcessSystemResourceManagement, // PROCESS_SYSTEM_RESOURCE_MANAGEMENT
myProcessSequenceNumber, // q: ULONGLONG
myProcessLoaderDetour, // since REDSTONE5
myProcessSecurityDomainInformation, // PROCESS_SECURITY_DOMAIN_INFORMATION
myProcessCombineSecurityDomainsInformation, // PROCESS_COMBINE_SECURITY_DOMAINS_INFORMATION
myProcessEnableLogging, // PROCESS_LOGGING_INFORMATION
myProcessLeapSecondInformation, // PROCESS_LEAP_SECOND_INFORMATION
myProcessFiberShadowStackAllocation, // PROCESS_FIBER_SHADOW_STACK_ALLOCATION_INFORMATION // since 19H1
myProcessFreeFiberShadowStackAllocation, // PROCESS_FREE_FIBER_SHADOW_STACK_ALLOCATION_INFORMATION
myProcessAltSystemCallInformation, // qs: BOOLEAN (kernel-mode only) // INT2E // since 20H1 // 100
myProcessDynamicEHContinuationTargets, // PROCESS_DYNAMIC_EH_CONTINUATION_TARGETS_INFORMATION
myProcessDynamicEnforcedCetCompatibleRanges, // PROCESS_DYNAMIC_ENFORCED_ADDRESS_RANGE_INFORMATION // since 20H2
myProcessCreateStateChange, // since WIN11
myProcessApplyStateChange,
myProcessEnableOptionalXStateFeatures,
myMaxProcessInfoClass
} MYPROCESSINFOCLASS;
// Used for ProcessCookie stuff using a different version
// of the ProcessInfoClass
typedef NTSTATUS(WINAPI* _MyNtQueryInformationProcess)(
IN HANDLE ProcessHandle,
IN MYPROCESSINFOCLASS ProcessInformationClass,
OUT DWORD_PTR* ProcessInformation,
IN ULONG ProcessInformationLength,
OUT PULONG ReturnLength OPTIONAL
);
//
// https://github.com/mirror/processhacker/blob/master/2.x/trunk/phlib/include/ntldr.h
//
#define RTL_BALANCED_NODE_RESERVED_PARENT_MASK 3
typedef struct _RTL_BALANCED_NODE
{
union
{
struct _RTL_BALANCED_NODE* Children[2];
struct
{
struct _RTL_BALANCED_NODE* Left;
struct _RTL_BALANCED_NODE* Right;
};
};
union
{
UCHAR Red : 1;
UCHAR Balance : 2;
ULONG_PTR ParentValue;
};
} RTL_BALANCED_NODE, * PRTL_BALANCED_NODE;
#define RTL_BALANCED_NODE_GET_PARENT_POINTER(Node) ((PRTL_BALANCED_NODE)((Node)->ParentValue & ~RTL_BALANCED_NODE_RESERVED_PARENT_MASK))
typedef struct _LDR_SERVICE_TAG_RECORD
{
struct _LDR_SERVICE_TAG_RECORD* Next;
ULONG ServiceTag;
} LDR_SERVICE_TAG_RECORD, * PLDR_SERVICE_TAG_RECORD;
typedef struct _LDRP_CSLIST
{
PSINGLE_LIST_ENTRY Tail;
} LDRP_CSLIST, * PLDRP_CSLIST;
typedef enum _LDR_DDAG_STATE
{
LdrModulesMerged = -5,
LdrModulesInitError = -4,
LdrModulesSnapError = -3,
LdrModulesUnloaded = -2,
LdrModulesUnloading = -1,
LdrModulesPlaceHolder = 0,
LdrModulesMapping = 1,
LdrModulesMapped = 2,
LdrModulesWaitingForDependencies = 3,
LdrModulesSnapping = 4,
LdrModulesSnapped = 5,
LdrModulesCondensed = 6,
LdrModulesReadyToInit = 7,
LdrModulesInitializing = 8,
LdrModulesReadyToRun = 9
} LDR_DDAG_STATE;
typedef struct _LDR_DDAG_NODE
{
LIST_ENTRY Modules;
PLDR_SERVICE_TAG_RECORD ServiceTagList;
ULONG LoadCount;
ULONG ReferenceCount;
ULONG DependencyCount;
union
{
LDRP_CSLIST Dependencies;
SINGLE_LIST_ENTRY RemovalLink;
};
LDRP_CSLIST IncomingDependencies;
LDR_DDAG_STATE State;
SINGLE_LIST_ENTRY CondenseLink;
ULONG PreorderNumber;
ULONG LowestLink;
} LDR_DDAG_NODE, * PLDR_DDAG_NODE;
typedef enum _LDR_DLL_LOAD_REASON
{
LoadReasonStaticDependency,
LoadReasonStaticForwarderDependency,
LoadReasonDynamicForwarderDependency,
LoadReasonDelayloadDependency,
LoadReasonDynamicLoad,
LoadReasonAsImageLoad,
LoadReasonAsDataLoad,
LoadReasonUnknown = -1
} LDR_DLL_LOAD_REASON, * PLDR_DLL_LOAD_REASON;
typedef struct my_LDR_DATA_TABLE_ENTRY
{
LIST_ENTRY InLoadOrderLinks;
LIST_ENTRY InMemoryOrderLinks;
union
{
LIST_ENTRY InInitializationOrderLinks;
LIST_ENTRY InProgressLinks;
};
PVOID DllBase;
PVOID EntryPoint;
ULONG SizeOfImage;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
union
{
UCHAR FlagGroup[4];
ULONG Flags;
struct
{
ULONG PackagedBinary : 1;
ULONG MarkedForRemoval : 1;
ULONG ImageDll : 1;
ULONG LoadNotificationsSent : 1;
ULONG TelemetryEntryProcessed : 1;
ULONG ProcessStaticImport : 1;
ULONG InLegacyLists : 1;
ULONG InIndexes : 1;
ULONG ShimDll : 1;
ULONG InExceptionTable : 1;
ULONG ReservedFlags1 : 2;
ULONG LoadInProgress : 1;
ULONG ReservedFlags2 : 1;
ULONG EntryProcessed : 1;
ULONG ReservedFlags3 : 3;
ULONG DontCallForThreads : 1;
ULONG ProcessAttachCalled : 1;
ULONG ProcessAttachFailed : 1;
ULONG CorDeferredValidate : 1;
ULONG CorImage : 1;
ULONG DontRelocate : 1;
ULONG CorILOnly : 1;
ULONG ReservedFlags5 : 3;
ULONG Redirected : 1;
ULONG ReservedFlags6 : 2;
ULONG CompatDatabaseProcessed : 1;
};
};
USHORT ObsoleteLoadCount;
USHORT TlsIndex;
LIST_ENTRY HashLinks;
ULONG TimeDateStamp;
struct _ACTIVATION_CONTEXT* EntryPointActivationContext;
PVOID PatchInformation;
PLDR_DDAG_NODE DdagNode;
LIST_ENTRY NodeModuleLink;
struct _LDRP_DLL_SNAP_CONTEXT* SnapContext;
PVOID SwitchBackContext;
RTL_BALANCED_NODE BaseAddressIndexNode;
RTL_BALANCED_NODE MappingInfoIndexNode;
ULONG_PTR OriginalBase;
LARGE_INTEGER LoadTime;
ULONG BaseNameHashValue;
LDR_DLL_LOAD_REASON LoadReason;
ULONG ImplicitPathOptions;
} myLDR_DATA_TABLE_ENTRY, * myPLDR_DATA_TABLE_ENTRY;
// http://downloads.securityfocus.com/vulnerabilities/exploits/26556.c
typedef PIMAGE_NT_HEADERS(NTAPI* RTLIMAGENTHEADER)(DWORD_PTR);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment