44 #define for_each_region(_var_name) list_for_each(gIntegrityRegions, INTEGRITY_REGION, _var_name) 71 if ((Descriptor->Gva >= pIntRegion->Gva &&
72 Descriptor->Gva < pIntRegion->Gva + pIntRegion->Length) ||
73 (Descriptor->Gva + Descriptor->Length > pIntRegion->Gva &&
74 Descriptor->Gva + Descriptor->Length <= pIntRegion->Gva + pIntRegion->Length) ||
75 (pIntRegion->Gva >= Descriptor->Gva &&
76 pIntRegion->Gva < Descriptor->Gva + Descriptor->Length) ||
77 (pIntRegion->Gva + pIntRegion->Length > Descriptor->Gva &&
78 pIntRegion->Gva + pIntRegion->Length < Descriptor->Gva + Descriptor->Length))
80 WARNING(
"[WARNING] Found integrity regions overlapped @ %llx (0x%08X) - @ %llx (0x%08X)",
81 pIntRegion->Gva, pIntRegion->Length, Descriptor->Gva, Descriptor->Length);
98 _Out_ void **Descriptor
137 BYTE *pOriginalContent = NULL;
140 QWORD gva = VirtualAddress;
160 if (NULL == pIntegrityRegion)
187 ERROR(
"[ERROR] Failed mapping GVA 0x%016llx to host: 0x%08x\n", VirtualAddress, status);
188 goto cleanup_and_leave;
193 if (pOriginalContent)
195 memcpy(pOriginalContent, p, size);
196 pOriginalContent += size;
205 }
while (gva < VirtualAddress + Length);
207 pIntegrityRegion->
Gva = VirtualAddress;
208 pIntegrityRegion->
Length = Length;
209 pIntegrityRegion->
Type = Type;
212 pIntegrityRegion->
Callback = Callback;
213 pIntegrityRegion->
Context = Context;
220 TRACE(
"[INFO] Add integrity region @ %llx (%d).\n", pIntegrityRegion->
Gva, pIntegrityRegion->
Length);
222 *Descriptor = pIntegrityRegion;
268 QWORD gva = IntegrityRegion->Gva;
269 DWORD left = IntegrityRegion->Length;
271 BYTE *pOriginalContent = IntegrityRegion->OriginalContent;
283 ERROR(
"[ERROR] Failed mapping GVA 0x%016llx to host: 0x%08x\n", IntegrityRegion->Gva, status);
284 goto cleanup_and_exit;
289 if (NULL != pOriginalContent)
291 memcpy(pOriginalContent, p, size);
292 pOriginalContent += size;
300 }
while (gva < IntegrityRegion->Gva + IntegrityRegion->Length);
302 IntegrityRegion->OriginalHash = crc32;
314 _In_ void *Descriptor
332 TRACE(
"[INFO] Remove integrity region @ %llx (%d).", pIntegrityRegion->
Gva, pIntegrityRegion->
Length);
349 _In_ void *Descriptor
367 TRACE(
"[INFO] Deleting integrity region @ %llx (%d) after calling callbacks.", pIntegrityRegion->
Gva,
368 pIntegrityRegion->
Length);
402 QWORD gva = pIntRegion->Gva;
403 DWORD left = pIntRegion->Length;
408 if (pIntRegion->Deleted)
445 }
while (gva < pIntRegion->Gva + pIntRegion->Length);
452 if (crc32 != pIntRegion->OriginalHash)
454 pIntRegion->ViolationCount++;
456 if (NULL != pIntRegion->Callback)
459 status = pIntRegion->Callback(pIntRegion);
462 ERROR(
"[ERROR] Integrity violation callback failed with status: 0x%08x\n", status);
465 else if (pIntRegion->ModifiedHash != crc32)
467 pIntRegion->ModifiedHash = crc32;
475 if (pIntRegion->Deleted)
495 LOG(
"Gva: 0x%016llx, Length: %d, OriginalContent: %p, Type: %d, OriginalHash: 0x%08x\n",
496 pIntRegion->Gva, pIntRegion->Length, pIntRegion->OriginalContent, pIntRegion->Type,
497 pIntRegion->OriginalHash);
520 LOG(
"[ERROR] There should be no regions remaining... Got one on %llx!\n", pIntRegion->Gva);
INTSTATUS IntVirtMemUnmap(void **HostPtr)
Unmaps a memory range previously mapped with IntVirtMemMap.
INTSTATUS IntIntegrityDeleteRegion(void *Descriptor)
Marks the given integrity region for deletion. It will be removed after calling all the integrity cal...
#define for_each_region(_var_name)
Useful macro for iterating through the list of INTEGRITY_REGION structures.
INTSTATUS IntIntegrityAddRegion(QWORD VirtualAddress, DWORD Length, INTRO_OBJECT_TYPE Type, void *Context, PFUNC_IntegrityViolationCallback Callback, BOOLEAN CopyContent, void **Descriptor)
Creates an INTEGRITY_REGION object and adds it to the gIntegrityRegions list.
QWORD SystemCr3
The Cr3 used to map the kernel.
#define INT_STATUS_SUCCESS
#define PAGE_REMAINING(addr)
#define INT_SUCCESS(Status)
void * Context
User supplied context, see IntIntegrityAddRegion for an example.
BOOLEAN ProtectionActivated
PFUNC_IntegrityViolationCallback Callback
The callback to be called when a violation occurs.
TIMER_FRIENDLY INTSTATUS IntIntegrityCheckAll(void)
The function which is called once every second and checks all the integrity regions.
#define HpAllocWithTag(Len, Tag)
int INTSTATUS
The status data type.
INTSTATUS(* PFUNC_IntegrityViolationCallback)(void *IntegrityRegion)
Integrity violation callback.
INTRO_GUEST_TYPE OSType
The type of the guest.
LIST_ENTRY Link
Link to the next integrity region.
DWORD ViolationCount
The number of detected modifications on the given region.
static BOOLEAN IntIntegrityIsOverlappedRegions(INTEGRITY_REGION *Descriptor)
Checks if an integrity region is overlapped with any of the integrity regions already in the list...
INTRO_OBJECT_TYPE Type
The associated INTRO_OBJECT_TYPE with the protected region.
INTSTATUS IntGpaCacheRelease(PGPA_CACHE Cache, QWORD Gpa)
Release a previously used cached entry.
enum _INTRO_OBJECT_TYPE INTRO_OBJECT_TYPE
The type of the object protected by an EPT hook.
#define INITIAL_CRC_VALUE
#define IS_KERNEL_POINTER_LIX(p)
BOOLEAN Deleted
Set TRUE for postpone deleting of integrity regions (e.g. deleting from callback) ...
static BOOLEAN RemoveEntryList(LIST_ENTRY *Entry)
BOOLEAN Guest64
True if this is a 64-bit guest, False if it is a 32-bit guest.
INTSTATUS IntIntegrityUninit(void)
Uninits the integrity mechanism by removing every integrity region from the list. ...
INTSTATUS IntTranslateVirtualAddress(QWORD Gva, QWORD Cr3, QWORD *PhysicalAddress)
Translates a guest virtual address to a guest physical address.
void * GpaCache
The currently used GPA cache.
#define IS_KERNEL_POINTER_WIN(is64, p)
Checks if a guest virtual address resides inside the Windows kernel address space.
#define HpFreeAndNullWithTag(Add, Tag)
static void InsertTailList(LIST_ENTRY *ListHead, LIST_ENTRY *Entry)
void IntIntegrityDump(void)
Dumps all the INTEGRITY_REGION structures from gIntegrityRegions. Used mainly for debugging...
QWORD Gva
The guest virtual address where the region starts.
INTSTATUS IntIntegrityRemoveRegion(void *Descriptor)
Removes an integrity region from the gIntegrityRegions list.
__must_check INTSTATUS IntVirtMemMap(QWORD Gva, DWORD Length, QWORD Cr3, DWORD Flags, void **HostPtr)
Maps a guest virtual memory range inside Introcore virtual address space.
MM Mm
Guest memory information, such as paging mode, system Cr3 value, etc.
GUEST_STATE gGuest
The current guest state.
static LIST_HEAD gIntegrityRegions
The global list of integrity regions, represented by INTEGRITY_REGION structures. ...
void * OriginalContent
A buffer containing the original bytes of the associated region.
DWORD Crc32ComputeFast(const void *Buffer, size_t Size, DWORD InitialCrc)
INTSTATUS IntGpaCacheFindAndAdd(PGPA_CACHE Cache, QWORD Gpa, void **Hva)
Search for an entry in the GPA cache, and add it, if it wasn't found.
#define LIST_HEAD_INIT(Name)
INTSTATUS IntIntegrityRecalculate(INTEGRITY_REGION *IntegrityRegion)
Recalculates the hash and reads the original content again for a given region.
#define INT_STATUS_INVALID_PARAMETER_1
DWORD Length
The length of the current region, in bytes.
#define INT_STATUS_INVALID_PARAMETER_2
#define INT_STATUS_INSUFFICIENT_RESOURCES