Last active
October 11, 2023 10:26
-
-
Save olliencc/2ebe7c1305f45175fc3972b99a769a2f to your computer and use it in GitHub Desktop.
Enumerates why each DLL loaded for each process via PEB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
This was the first version - the newer version also includes *When* it was loaded also. | |
https://gist.github.com/olliencc/e166a64ca211c51eb69111f26ce57bc1 | |
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
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)(LARGE_INTEGER*, DWORD*); | |
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 }; | |
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, 4); | |
DWORD 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 buffer[26]; | |
wcsftime(buffer, 26, _TEXT("%Y-%m-%d %H:%M:%S"), &tmDest); | |
*/ | |
//fwprintf(stdout, _TEXT("[i] [%d][%s] Load Reason for %s is %s - %d - loaded @ %s\n"), dwPID, cProcess, strDLL, strReason,wReason, buffer); | |
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); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
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