mirror of
https://github.com/donnaskiez/ac.git
synced 2024-11-21 22:24:08 +01:00
refactor some more
This commit is contained in:
parent
80b34ea2f1
commit
8685725415
4 changed files with 103 additions and 103 deletions
|
@ -8,6 +8,7 @@
|
|||
#include "imports.h"
|
||||
#include "session.h"
|
||||
#include "util.h"
|
||||
#include "pe.h"
|
||||
|
||||
#include <bcrypt.h>
|
||||
#include <initguid.h>
|
||||
|
@ -205,6 +206,33 @@ IsSectionExecutable(_In_ PIMAGE_SECTION_HEADER Section)
|
|||
return Section->Characteristics & IMAGE_SCN_MEM_EXECUTE ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
FORCEINLINE
|
||||
STATIC
|
||||
BOOLEAN
|
||||
IsModuleAddressSafe(_In_ PVOID Base, _In_ BOOLEAN x86)
|
||||
{
|
||||
return !MmIsAddressValid(Base) && !x86 ? FALSE : TRUE;
|
||||
}
|
||||
|
||||
FORCEINLINE
|
||||
STATIC
|
||||
UINT32
|
||||
GetSectionTotalPacketSize(_In_ PIMAGE_SECTION_HEADER Section)
|
||||
{
|
||||
return Section->SizeOfRawData + sizeof(IMAGE_SECTION_HEADER);
|
||||
}
|
||||
|
||||
FORCEINLINE
|
||||
STATIC
|
||||
VOID
|
||||
InitIntegrityCheckHeader(_Out_ PINTEGRITY_CHECK_HEADER Header,
|
||||
_In_ UINT32 SectionCount,
|
||||
_In_ UINT32 TotalSize)
|
||||
{
|
||||
Header->executable_section_count = SectionCount;
|
||||
Header->total_packet_size = TotalSize + sizeof(INTEGRITY_CHECK_HEADER);
|
||||
}
|
||||
|
||||
STATIC
|
||||
NTSTATUS
|
||||
StoreModuleExecutableRegionsInBuffer(_Out_ PVOID* Buffer,
|
||||
|
@ -215,21 +243,24 @@ StoreModuleExecutableRegionsInBuffer(_Out_ PVOID* Buffer,
|
|||
{
|
||||
PAGED_CODE();
|
||||
|
||||
NTSTATUS status = STATUS_UNSUCCESSFUL;
|
||||
PIMAGE_DOS_HEADER dos_header = NULL;
|
||||
PLOCAL_NT_HEADER nt_header = NULL;
|
||||
PIMAGE_SECTION_HEADER section = NULL;
|
||||
ULONG total_packet_size = 0;
|
||||
ULONG num_sections = 0;
|
||||
ULONG num_executable_sections = 0;
|
||||
UINT64 buffer_base = 0;
|
||||
ULONG bytes_returned = 0;
|
||||
MM_COPY_ADDRESS address = {0};
|
||||
ULONG buffer_size = 0;
|
||||
NTSTATUS status = STATUS_UNSUCCESSFUL;
|
||||
PIMAGE_DOS_HEADER dos_header = NULL;
|
||||
PNT_HEADER_64 nt_header = NULL;
|
||||
PIMAGE_SECTION_HEADER section = NULL;
|
||||
ULONG total_packet_size = 0;
|
||||
ULONG num_sections = 0;
|
||||
ULONG num_executable_sections = 0;
|
||||
UINT64 buffer_base = 0;
|
||||
ULONG bytes_returned = 0;
|
||||
MM_COPY_ADDRESS address = {0};
|
||||
INTEGRITY_CHECK_HEADER header = {0};
|
||||
|
||||
if (!ModuleBase || !ModuleSize)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
||||
if (!IsModuleAddressSafe(ModuleBase, IsModulex86))
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
|
||||
/*
|
||||
* The reason we allocate a buffer to temporarily hold the section data
|
||||
* is that we don't know the total size until after we iterate over the
|
||||
|
@ -237,37 +268,20 @@ StoreModuleExecutableRegionsInBuffer(_Out_ PVOID* Buffer,
|
|||
* our reponse until we enumerate and count all executable sections for
|
||||
* the file.
|
||||
*/
|
||||
buffer_size = ModuleSize + sizeof(INTEGRITY_CHECK_HEADER);
|
||||
|
||||
*BytesWritten = 0;
|
||||
*Buffer = ImpExAllocatePool2(
|
||||
POOL_FLAG_NON_PAGED, buffer_size, POOL_TAG_INTEGRITY);
|
||||
*Buffer = ImpExAllocatePool2(POOL_FLAG_NON_PAGED,
|
||||
ModuleSize + sizeof(INTEGRITY_CHECK_HEADER),
|
||||
POOL_TAG_INTEGRITY);
|
||||
|
||||
if (*Buffer == NULL)
|
||||
return STATUS_MEMORY_NOT_ALLOCATED;
|
||||
|
||||
/*
|
||||
* Note: Verifier doesn't like it when we map the module so rather then
|
||||
* mapping it to our address space we will simply use MmCopyMemory on
|
||||
* the module to avoid upsetting verifier
|
||||
* :)
|
||||
*/
|
||||
dos_header = (PIMAGE_DOS_HEADER)ModuleBase;
|
||||
|
||||
if (!MmIsAddressValid(dos_header) && !IsModulex86) {
|
||||
ImpExFreePoolWithTag(*Buffer, POOL_TAG_INTEGRITY);
|
||||
*Buffer = NULL;
|
||||
return STATUS_INVALID_ADDRESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* The IMAGE_DOS_HEADER.e_lfanew stores the offset of the
|
||||
* IMAGE_NT_HEADER from the base of the image.
|
||||
*/
|
||||
nt_header = (struct _IMAGE_NT_HEADERS64*)((UINT64)ModuleBase +
|
||||
dos_header->e_lfanew);
|
||||
|
||||
num_sections = nt_header->FileHeader.NumberOfSections;
|
||||
nt_header = PeGetNtHeader(ModuleBase);
|
||||
num_sections = GetSectionCount(nt_header);
|
||||
|
||||
/*
|
||||
* The IMAGE_FIRST_SECTION macro takes in an IMAGE_NT_HEADER and returns
|
||||
|
@ -283,7 +297,6 @@ StoreModuleExecutableRegionsInBuffer(_Out_ PVOID* Buffer,
|
|||
}
|
||||
|
||||
address.VirtualAddress = section;
|
||||
|
||||
status = ImpMmCopyMemory((UINT64)buffer_base + total_packet_size,
|
||||
address,
|
||||
sizeof(IMAGE_SECTION_HEADER),
|
||||
|
@ -291,14 +304,12 @@ StoreModuleExecutableRegionsInBuffer(_Out_ PVOID* Buffer,
|
|||
&bytes_returned);
|
||||
|
||||
if (!NT_SUCCESS(status)) {
|
||||
DEBUG_ERROR("MmCopyMemory failed with status %x", status);
|
||||
ImpExFreePoolWithTag(*Buffer, POOL_TAG_INTEGRITY);
|
||||
*Buffer = NULL;
|
||||
return status;
|
||||
}
|
||||
|
||||
address.VirtualAddress = (UINT64)ModuleBase + section->PointerToRawData;
|
||||
|
||||
status = ImpMmCopyMemory((UINT64)buffer_base + total_packet_size +
|
||||
sizeof(IMAGE_SECTION_HEADER),
|
||||
address,
|
||||
|
@ -307,22 +318,18 @@ StoreModuleExecutableRegionsInBuffer(_Out_ PVOID* Buffer,
|
|||
&bytes_returned);
|
||||
|
||||
if (!NT_SUCCESS(status)) {
|
||||
DEBUG_ERROR("MmCopyMemory failed with status %x", status);
|
||||
ImpExFreePoolWithTag(*Buffer, POOL_TAG_INTEGRITY);
|
||||
*Buffer = NULL;
|
||||
return status;
|
||||
}
|
||||
|
||||
total_packet_size +=
|
||||
section->SizeOfRawData + sizeof(IMAGE_SECTION_HEADER);
|
||||
total_packet_size += GetSectionTotalPacketSize(section);
|
||||
num_executable_sections++;
|
||||
section++;
|
||||
}
|
||||
|
||||
INTEGRITY_CHECK_HEADER header = {0};
|
||||
header.executable_section_count = num_executable_sections;
|
||||
header.total_packet_size =
|
||||
total_packet_size + sizeof(INTEGRITY_CHECK_HEADER);
|
||||
InitIntegrityCheckHeader(
|
||||
&header, num_executable_sections, total_packet_size);
|
||||
|
||||
RtlCopyMemory(*Buffer, &header, sizeof(INTEGRITY_CHECK_HEADER));
|
||||
*BytesWritten = total_packet_size + sizeof(INTEGRITY_CHECK_HEADER);
|
||||
|
@ -331,11 +338,10 @@ StoreModuleExecutableRegionsInBuffer(_Out_ PVOID* Buffer,
|
|||
|
||||
STATIC
|
||||
NTSTATUS
|
||||
MapDiskImageIntoVirtualAddressSpace(_Inout_ PHANDLE SectionHandle,
|
||||
_Outptr_result_bytebuffer_(*Size)
|
||||
PVOID* Section,
|
||||
MapDiskImageIntoVirtualAddressSpace(_Inout_ PHANDLE SectionHandle,
|
||||
_Out_ PVOID* Section,
|
||||
_In_ PUNICODE_STRING Path,
|
||||
_Out_ _Deref_out_range_(>, 0) PSIZE_T Size)
|
||||
_Out_ PSIZE_T Size)
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
||||
|
@ -1197,20 +1203,18 @@ UINT64
|
|||
MeasureReads(_In_ PVOID Address, _In_ ULONG Count)
|
||||
{
|
||||
UINT64 read_average = 0;
|
||||
UINT64 old_irql = 0;
|
||||
KIRQL irql = {0};
|
||||
|
||||
MeasureInstructionRead(Address);
|
||||
|
||||
old_irql = __readcr8();
|
||||
__writecr8(HIGH_LEVEL);
|
||||
|
||||
KeRaiseIrql(HIGH_LEVEL, &irql);
|
||||
_disable();
|
||||
|
||||
for (ULONG iteration = 0; iteration < Count; iteration++)
|
||||
read_average += MeasureInstructionRead(Address);
|
||||
|
||||
_enable();
|
||||
__writecr8(old_irql);
|
||||
KeLowerIrql(irql);
|
||||
|
||||
DEBUG_VERBOSE("EPT Detection - Read Average: %llx", read_average);
|
||||
|
||||
|
|
|
@ -75,9 +75,9 @@ typedef struct _NMI_CONTEXT {
|
|||
} NMI_CONTEXT, *PNMI_CONTEXT;
|
||||
|
||||
STATIC
|
||||
NTSTATUS
|
||||
PopulateWhitelistedModuleBuffer(_Inout_ PVOID Buffer,
|
||||
_In_ PSYSTEM_MODULES SystemModules);
|
||||
VOID
|
||||
PopulateWhitelistedModuleBuffer(_Inout_ PWHITELISTED_REGIONS Whitelist,
|
||||
_In_ PSYSTEM_MODULES SystemModules);
|
||||
|
||||
STATIC
|
||||
NTSTATUS
|
||||
|
@ -160,48 +160,27 @@ FindSystemModuleByName(_In_ LPCSTR ModuleName,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
FORCEINLINE
|
||||
STATIC
|
||||
VOID
|
||||
InitWhitelistedRegionStructure(_Out_ PWHITELISTED_REGIONS Region,
|
||||
_In_ UINT64 Base,
|
||||
_In_ UINT64 End)
|
||||
{
|
||||
Region->base = Base;
|
||||
Region->end = End;
|
||||
}
|
||||
|
||||
STATIC
|
||||
NTSTATUS
|
||||
PopulateWhitelistedModuleBuffer(_Inout_ PVOID Buffer,
|
||||
_In_ PSYSTEM_MODULES SystemModules)
|
||||
PopulateWhitelistedModuleBuffer(_Inout_ PWHITELISTED_REGIONS Whitelist,
|
||||
_In_ PSYSTEM_MODULES SystemModules)
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
||||
if (!Buffer || !SystemModules)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
||||
for (INT index = 0; index < WHITELISTED_MODULE_COUNT; index++) {
|
||||
LPCSTR name = WHITELISTED_MODULES[index];
|
||||
LPCSTR entry = WHITELISTED_MODULES[index];
|
||||
|
||||
PRTL_MODULE_EXTENDED_INFO module =
|
||||
FindSystemModuleByName(name, SystemModules);
|
||||
FindSystemModuleByName(entry, SystemModules);
|
||||
|
||||
/* not everyone will contain all whitelisted modules */
|
||||
if (!module)
|
||||
continue;
|
||||
|
||||
WHITELISTED_REGIONS region = {0};
|
||||
InitWhitelistedRegionStructure(®ion,
|
||||
(UINT64)module->ImageBase,
|
||||
region.base + module->ImageSize);
|
||||
|
||||
UINT64 destination =
|
||||
(UINT64)Buffer + index * sizeof(WHITELISTED_REGIONS);
|
||||
RtlCopyMemory(destination, ®ion, sizeof(WHITELISTED_REGIONS));
|
||||
PWHITELISTED_REGIONS region = &Whitelist[index];
|
||||
region->base = (UINT64)module->ImageBase;
|
||||
region->end = (UINT64)module->ImageBase + module->ImageSize;
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
STATIC
|
||||
|
@ -400,7 +379,7 @@ STATIC
|
|||
VOID
|
||||
ValidateDriverObjects(_In_ PSYSTEM_MODULES Modules,
|
||||
_In_ POBJECT_DIRECTORY_ENTRY Entry,
|
||||
_In_ PVOID Whitelist)
|
||||
_In_ PWHITELISTED_REGIONS Whitelist)
|
||||
{
|
||||
NTSTATUS status = STATUS_UNSUCCESSFUL;
|
||||
POBJECT_DIRECTORY_ENTRY entry = Entry;
|
||||
|
@ -412,7 +391,7 @@ ValidateDriverObjects(_In_ PSYSTEM_MODULES Modules,
|
|||
ReportInvalidDriverObject(driver, REPORT_SUBTYPE_NO_BACKING_MODULE);
|
||||
}
|
||||
|
||||
if (!DoesDriverHaveInvalidDispatchRoutine(driver, Modules, Whitelist)) {
|
||||
if (DoesDriverHaveInvalidDispatchRoutine(driver, Modules, Whitelist)) {
|
||||
ReportInvalidDriverObject(driver, REPORT_SUBTYPE_INVALID_DISPATCH);
|
||||
}
|
||||
|
||||
|
@ -430,13 +409,13 @@ ValidateDriverObjectsWrapper(_In_ PSYSTEM_MODULES SystemModules)
|
|||
{
|
||||
PAGED_CODE();
|
||||
|
||||
HANDLE handle = NULL;
|
||||
OBJECT_ATTRIBUTES attributes = {0};
|
||||
PVOID directory = {0};
|
||||
UNICODE_STRING directory_name = {0};
|
||||
PVOID whitelisted_regions_buffer = NULL;
|
||||
NTSTATUS status = STATUS_UNSUCCESSFUL;
|
||||
POBJECT_DIRECTORY directory_object = NULL;
|
||||
HANDLE handle = NULL;
|
||||
OBJECT_ATTRIBUTES attributes = {0};
|
||||
PVOID directory = {0};
|
||||
UNICODE_STRING directory_name = {0};
|
||||
PWHITELISTED_REGIONS whitelist = NULL;
|
||||
NTSTATUS status = STATUS_UNSUCCESSFUL;
|
||||
POBJECT_DIRECTORY directory_object = NULL;
|
||||
|
||||
ImpRtlInitUnicodeString(&directory_name, L"\\Driver");
|
||||
|
||||
|
@ -477,16 +456,15 @@ ValidateDriverObjectsWrapper(_In_ PSYSTEM_MODULES SystemModules)
|
|||
|
||||
ImpExAcquirePushLockExclusiveEx(&directory_object->Lock, NULL);
|
||||
|
||||
whitelisted_regions_buffer =
|
||||
ImpExAllocatePool2(POOL_FLAG_NON_PAGED,
|
||||
WHITELISTED_MODULE_COUNT * MODULE_MAX_STRING_SIZE,
|
||||
WHITELISTED_MODULE_TAG);
|
||||
whitelist = ImpExAllocatePool2(POOL_FLAG_NON_PAGED,
|
||||
WHITELISTED_MODULE_COUNT *
|
||||
sizeof(WHITELISTED_REGIONS),
|
||||
WHITELISTED_MODULE_TAG);
|
||||
|
||||
if (!whitelisted_regions_buffer)
|
||||
if (!whitelist)
|
||||
goto end;
|
||||
|
||||
status = PopulateWhitelistedModuleBuffer(whitelisted_regions_buffer,
|
||||
SystemModules);
|
||||
PopulateWhitelistedModuleBuffer(whitelist, SystemModules);
|
||||
|
||||
if (!NT_SUCCESS(status)) {
|
||||
DEBUG_ERROR("PopulateWhitelistedModuleBuffer failed with status %x",
|
||||
|
@ -496,13 +474,12 @@ ValidateDriverObjectsWrapper(_In_ PSYSTEM_MODULES SystemModules)
|
|||
|
||||
for (INT index = 0; index < NUMBER_HASH_BUCKETS; index++) {
|
||||
POBJECT_DIRECTORY_ENTRY entry = directory_object->HashBuckets[index];
|
||||
ValidateDriverObjects(SystemModules, entry, whitelisted_regions_buffer);
|
||||
ValidateDriverObjects(SystemModules, entry, whitelist);
|
||||
}
|
||||
|
||||
end:
|
||||
if (whitelisted_regions_buffer)
|
||||
ImpExFreePoolWithTag(whitelisted_regions_buffer,
|
||||
WHITELISTED_MODULE_TAG);
|
||||
if (whitelist)
|
||||
ImpExFreePoolWithTag(whitelist, WHITELISTED_MODULE_TAG);
|
||||
|
||||
ImpExReleasePushLockExclusiveEx(&directory_object->Lock, 0);
|
||||
ImpObDereferenceObject(directory);
|
||||
|
|
|
@ -34,6 +34,12 @@ PeGetExportDirectory(_In_ PVOID Image,
|
|||
PIMAGE_EXPORT_DIRECTORY, Image, ExportDataDirectory->VirtualAddress);
|
||||
}
|
||||
|
||||
UINT32
|
||||
GetSectionCount(_In_ PNT_HEADER_64 Header)
|
||||
{
|
||||
return Header->FileHeader.NumberOfSections;
|
||||
}
|
||||
|
||||
PVOID
|
||||
PeFindExportByName(_In_ PVOID Image, _In_ PCHAR Name)
|
||||
{
|
||||
|
|
13
driver/pe.h
13
driver/pe.h
|
@ -9,4 +9,17 @@
|
|||
PVOID
|
||||
PeFindExportByName(_In_ PVOID Image, _In_ PCHAR Name);
|
||||
|
||||
PNT_HEADER_64
|
||||
PeGetNtHeader(_In_ PVOID Image);
|
||||
|
||||
PIMAGE_DATA_DIRECTORY
|
||||
PeGetExportDataDirectory(_In_ PVOID Image);
|
||||
|
||||
PIMAGE_EXPORT_DIRECTORY
|
||||
PeGetExportDirectory(_In_ PVOID Image,
|
||||
_In_ PIMAGE_DATA_DIRECTORY ExportDataDirectory);
|
||||
|
||||
UINT32
|
||||
GetSectionCount(_In_ PNT_HEADER_64 Header);
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue