Files
jdu2600-Get-InjectedThreadEx/Get-InjectedThreadEx/CfgBitMap.cpp
T
2023-09-29 09:43:35 +08:00

50 lines
2.2 KiB
C++

#include "Get-InjectedThreadEx.h"
BOOL InSystemImageRange(PVOID Address) {
return Address >= (PVOID)0x7FF800000000 && Address < (PVOID)0x7FFFFFFF0000;
}
constexpr UINT64 XFG_MASK_UNSET = ~0xFFFDBFFF7EDFFB71; // mask of unset bits
constexpr UINT64 XFG_MASK_SET = 0x8000060010500070; // mask of set bits
constexpr UINT64 XFG_MASK_ALL = XFG_MASK_UNSET | XFG_MASK_SET;
BOOL IsValidXfgHash(UINT64 xfgHash) {
return XFG_MASK_SET == (xfgHash & XFG_MASK_ALL);
}
static PULONG_PTR FindCfgBitMap() {
// Find non-exported ntdll!LdrSystemDllInitBlock.CfgBitMap by looking at the first instruction of LdrControlFlowGuardEnforced
// 48833d [80be1400], 00 CMP qword ptr[LdrSystemDllInitBlock.CfgBitMap], 0x0
#pragma warning(suppress: 6387) // ntdll is always loaded
auto pLdrControlFlowGuardEnforced = GetProcAddress(GetModuleHandleW(L"ntdll.dll"), "LdrControlFlowGuardEnforced");
if (NULL == pLdrControlFlowGuardEnforced)
return NULL;
auto ppCfgBitMap = (PULONG_PTR*)((ULONG_PTR)pLdrControlFlowGuardEnforced + 8 + *(DWORD*)((ULONG_PTR)pLdrControlFlowGuardEnforced + 3));
MEMORY_BASIC_INFORMATION mbi;
if (!VirtualQuery(*ppCfgBitMap, &mbi, sizeof(mbi)) || MEM_MAPPED != mbi.Type || *ppCfgBitMap != mbi.AllocationBase) {
LogError("FATAL: ntdll!LdrSystemDllInitBlock.CfgBitMap not found\n");
ExitProcess(1);
}
return *ppCfgBitMap;
}
constexpr auto CFG_INVALID = 0b00; // no address in this range is a valid target
constexpr auto CFG_ALL_VALID = 0b11; // all addresses in this range are valid.
constexpr auto CFG_ALIGNED_VALID = 0b01; // the only valid target is 16-byte aligned
constexpr auto CFG_EXPORT_SUPPRESSED = 0b10; // this range contains an export-suppressed target
BOOL GetCfgBitsForAddress(PVOID address, PULONG pCfgBits) {
static auto pCfgBitMap = FindCfgBitMap();
const PULONG_PTR pLocalEntry = pCfgBitMap + ((ULONG_PTR)address >> 9);
const ULONG cfgOffset = (((ULONG_PTR)(address)) >> 3) & 0x3E;
ULONG_PTR localEntry;
// We use ReadProcessMemory to safely read the volatile CfgBitMap.
if (ReadProcessMemory(GetCurrentProcess(), pLocalEntry, &localEntry, sizeof(localEntry), NULL)) {
*pCfgBits = (localEntry >> cfgOffset) & 0b11;
return TRUE;
}
return FALSE;
}