diff --git a/driver/apc.c b/driver/apc.c index 602f310..e3ceec1 100644 --- a/driver/apc.c +++ b/driver/apc.c @@ -3,6 +3,8 @@ #include "driver.h" #include "imports.h" +#include "lib/stdlib.h" + VOID GetApcContextByIndex(_Out_ PVOID* Context, _In_ INT Index) { diff --git a/driver/callbacks.c b/driver/callbacks.c index a54084b..2819b37 100644 --- a/driver/callbacks.c +++ b/driver/callbacks.c @@ -10,6 +10,8 @@ #include "crypt.h" #include "util.h" +#include "lib/stdlib.h" + #include "containers/tree.h" #include "containers/map.h" @@ -117,7 +119,7 @@ DriverListEntryToExtendedModuleInfo(_In_ PDRIVER_LIST_ENTRY Entry, { Extended->ImageBase = Entry->ImageBase; Extended->ImageSize = Entry->ImageSize; - RtlCopyMemory( + IntCopyMemory( Extended->FullPathName, Entry->path, sizeof(Extended->FullPathName)); } @@ -167,7 +169,7 @@ InitialiseDriverList() entry->ImageBase = module_entry->ImageBase; entry->ImageSize = module_entry->ImageSize; - RtlCopyMemory(entry->path, + IntCopyMemory(entry->path, module_entry->FullPathName, sizeof(module_entry->FullPathName)); @@ -355,7 +357,7 @@ ImageLoadNotifyRoutineCallback(_In_opt_ PUNICODE_STRING FullImageName, if (FullImageName) { UnicodeToCharBufString( FullImageName, module.FullPathName, sizeof(module.FullPathName)); - RtlCopyMemory( + IntCopyMemory( entry->path, module.FullPathName, sizeof(module.FullPathName)); } @@ -602,7 +604,7 @@ STATIC BOOLEAN CanInitiateDeferredHashing(_In_ LPCSTR ProcessName, _In_ PDRIVER_LIST_HEAD Head) { - return !strcmp(ProcessName, "winlogon.exe") && Head->work_item ? TRUE + return !IntCompareString(ProcessName, "winlogon.exe") && Head->work_item ? TRUE : FALSE; } @@ -793,7 +795,7 @@ IsWhitelistedHandleOpenProcess(_In_ LPCSTR ProcessName) { for (UINT32 index = 0; index < PROCESS_HANDLE_OPEN_WHITELIST_COUNT; index++) { - if (!strcmp(ProcessName, PROCESS_HANDLE_OPEN_WHITELIST[index])) + if (!IntCompareString(ProcessName, PROCESS_HANDLE_OPEN_WHITELIST[index])) return TRUE; } @@ -806,7 +808,7 @@ IsDowngradeHandleOpenProcess(_In_ LPCSTR ProcessName) { for (UINT32 index = 0; index < PROCESS_HANDLE_OPEN_DOWNGRADE_COUNT; index++) { - if (!strcmp(ProcessName, PROCESS_HANDLE_OPEN_DOWNGRADE[index])) + if (!IntCompareString(ProcessName, PROCESS_HANDLE_OPEN_DOWNGRADE[index])) return TRUE; } @@ -868,7 +870,7 @@ ObPreOpCallbackRoutine(_In_ PVOID RegistrationContext, if (!protected_process_name || !target_process_name) goto end; - if (strcmp(protected_process_name, target_process_name)) + if (IntCompareString(protected_process_name, target_process_name)) goto end; /* * WerFault is some windows 11 application that cries when it @@ -879,7 +881,7 @@ ObPreOpCallbackRoutine(_In_ PVOID RegistrationContext, * perhapds check some certificate or something. */ if (IsDowngradeHandleOpenProcess(process_creator_name) || - !strcmp(process_creator_name, target_process_name)) { + !IntCompareString(process_creator_name, target_process_name)) { /* We will downgrade these handles later */ // DEBUG_LOG("Handles created by CSRSS, LSASS and // WerFault are allowed for now..."); @@ -921,7 +923,7 @@ ObPreOpCallbackRoutine(_In_ PVOID RegistrationContext, report->access = OperationInformation->Parameters ->CreateHandleInformation.DesiredAccess; - RtlCopyMemory(report->process_name, + IntCopyMemory(report->process_name, process_creator_name, HANDLE_REPORT_PROCESS_NAME_MAX_LENGTH); @@ -1012,7 +1014,7 @@ EnumHandleCallback(_In_ PHANDLE_TABLE HandleTable, protected_process_name = ImpPsGetProcessImageFileName(protected_process); - if (strcmp(process_name, protected_process_name)) + if (IntCompareString(process_name, protected_process_name)) goto end; DEBUG_VERBOSE( @@ -1053,8 +1055,8 @@ EnumHandleCallback(_In_ PHANDLE_TABLE HandleTable, DEBUG_VERBOSE("Stripped PROCESS_VM_READ"); } - if (!strcmp(process_name, "csrss.exe") || - !strcmp(process_name, "lsass.exe")) { + if (!IntCompareString(process_name, "csrss.exe") || + !IntCompareString(process_name, "lsass.exe")) { DEBUG_VERBOSE( "Required system process allowed, only stripping some permissions"); goto end; @@ -1116,7 +1118,7 @@ EnumHandleCallback(_In_ PHANDLE_TABLE HandleTable, report->thread_id = 0; report->access = handle_access_mask; - RtlCopyMemory(&report->process_name, + IntCopyMemory(&report->process_name, process_name, HANDLE_REPORT_PROCESS_NAME_MAX_LENGTH); @@ -1190,7 +1192,7 @@ TimerObjectValidateProcessModuleCallback(_In_ PPROCESS_MAP_MODULE_ENTRY Entry, return; } - if (RtlCompareMemory(hash, session->module.module_hash, sizeof(hash)) != + if (IntCompareMemory(hash, session->module.module_hash, sizeof(hash)) != sizeof(hash)) { DEBUG_ERROR("User module hash not matching!! MODIFIED!"); return; diff --git a/driver/containers/map.c b/driver/containers/map.c index 3ef3186..042628c 100644 --- a/driver/containers/map.c +++ b/driver/containers/map.c @@ -1,5 +1,7 @@ #include "map.h" +#include "../lib/stdlib.h" + VOID RtlHashmapDelete(_In_ PRTL_HASHMAP Hashmap) { diff --git a/driver/containers/tree.c b/driver/containers/tree.c index db3f6b4..2845a9a 100644 --- a/driver/containers/tree.c +++ b/driver/containers/tree.c @@ -1,5 +1,7 @@ #include "tree.h" +#include "../lib/stdlib.h" + /* * Basic red-black tree implementation. Currently, the enumeration routines are * recursive, which may not be the best idea given the environment this is meant diff --git a/driver/crypt.c b/driver/crypt.c index 1c1e0f6..38884c8 100644 --- a/driver/crypt.c +++ b/driver/crypt.c @@ -8,6 +8,8 @@ #include "types/tpm20.h" #include "types/tpmptp.h" +#include "lib/stdlib.h" + #include #include @@ -58,14 +60,14 @@ CryptEncryptImportsArray(_In_ PUINT64 Array, _In_ UINT32 Entries) __m256i load_block = {0}; __m256i xored_block = {0}; - RtlCopyMemory(¤t_block, + IntCopyMemory(¤t_block, &Array[block_index * block_size], sizeof(__m256i)); load_block = _mm256_loadu_si256(¤t_block); xored_block = _mm256_xor_si256(load_block, *imports_key); - RtlCopyMemory(&Array[block_index * block_size], + IntCopyMemory(&Array[block_index * block_size], &xored_block, sizeof(__m256i)); } @@ -80,7 +82,7 @@ CryptDecryptImportBlock(_In_ PUINT64 Array, _In_ UINT32 BlockIndex) __m256i* imports_key = GetDriverImportsKey(); UINT32 block_size = sizeof(__m256i) / sizeof(UINT64); - RtlCopyMemory(&load_block, + IntCopyMemory(&load_block, &Array[BlockIndex * block_size], sizeof(__m256i)); @@ -174,7 +176,7 @@ CryptBuildBlobForKeyImport(_In_ PACTIVE_SESSION Session) blob->dwVersion = BCRYPT_KEY_DATA_BLOB_VERSION1; blob->cbKeyData = AES_256_KEY_SIZE; - RtlCopyMemory((UINT64)blob + sizeof(BCRYPT_KEY_DATA_BLOB_HEADER), + IntCopyMemory((UINT64)blob + sizeof(BCRYPT_KEY_DATA_BLOB_HEADER), Session->aes_key, AES_256_KEY_SIZE); @@ -218,7 +220,7 @@ CryptEncryptBuffer(_In_ PVOID Buffer, _In_ UINT32 BufferLength) /* The IV is consumed during every encrypt / decrypt procedure, so to ensure * we have access to the iv we need to create a local copy.*/ - RtlCopyMemory(local_iv, session->iv, sizeof(session->iv)); + IntCopyMemory(local_iv, session->iv, sizeof(session->iv)); /* We arent encrypting the first 16 bytes */ buffer = buffer + AES_256_BLOCK_SIZE; diff --git a/driver/driver.c b/driver/driver.c index 5267b0d..782dd1a 100644 --- a/driver/driver.c +++ b/driver/driver.c @@ -3,7 +3,6 @@ #include "common.h" #include "io.h" #include "callbacks.h" - #include "hv.h" #include "pool.h" #include "thread.h" @@ -15,6 +14,8 @@ #include "session.h" #include "hw.h" +#include "lib/stdlib.h" + #include STATIC @@ -140,7 +141,8 @@ PDRIVER_CONFIG GetDecryptedDriverConfig() { return (PDRIVER_CONFIG)CryptDecryptPointerOutOfPlace64( - (PUINT64)&g_DriverConfig, g_DeviceExtensionKey); + (PUINT64)&g_DriverConfig, + g_DeviceExtensionKey); } #define POOL_TAG_CONFIG 'conf' @@ -220,8 +222,9 @@ BOOLEAN IsNmiInProgress() { PAGED_CODE(); - return InterlockedCompareExchange( - &GetDecryptedDriverConfig()->nmi_status, TRUE, FALSE) != 0; + return InterlockedCompareExchange(&GetDecryptedDriverConfig()->nmi_status, + TRUE, + FALSE) != 0; } PSHARED_MAPPING @@ -597,7 +600,7 @@ RegistryPathQueryCallbackRoutine(IN PWSTR ValueName, if (!temp_buffer) return STATUS_MEMORY_NOT_ALLOCATED; - RtlCopyMemory(temp_buffer, ValueData, ValueLength); + IntCopyMemory(temp_buffer, ValueData, ValueLength); cfg->driver_path.Buffer = (PWCH)temp_buffer; cfg->driver_path.Length = ValueLength; @@ -606,14 +609,16 @@ RegistryPathQueryCallbackRoutine(IN PWSTR ValueName, if (ImpRtlCompareUnicodeString(&value_name, &display_name, FALSE) == FALSE) { - temp_buffer = ImpExAllocatePool2( - POOL_FLAG_PAGED, ValueLength + 20, POOL_TAG_STRINGS); + temp_buffer = ImpExAllocatePool2(POOL_FLAG_PAGED, + ValueLength + 20, + POOL_TAG_STRINGS); if (!temp_buffer) return STATUS_MEMORY_NOT_ALLOCATED; - RtlCopyMemory(temp_buffer, ValueData, ValueLength); - wcscpy((PWCH)((UINT64)temp_buffer + ValueLength - 2), L".sys"); + IntCopyMemory(temp_buffer, ValueData, ValueLength); + IntWideStringCopy((PWCH)((UINT64)temp_buffer + ValueLength - 2), + L".sys"); cfg->unicode_driver_name.Buffer = (PWCH)temp_buffer; cfg->unicode_driver_name.Length = ValueLength + 20; @@ -647,8 +652,10 @@ GetSystemProcessorType() __cpuid(cpuid, 0); - DEBUG_VERBOSE( - "Cpuid: EBX: %lx, ECX: %lx, EDX: %lx", cpuid[1], cpuid[2], cpuid[3]); + DEBUG_VERBOSE("Cpuid: EBX: %lx, ECX: %lx, EDX: %lx", + cpuid[1], + cpuid[2], + cpuid[3]); if (cpuid[EBX_REGISTER] == CPUID_AUTHENTIC_AMD_EBX && cpuid[ECX_REGISTER] == CPUID_AUTHENTIC_AMD_ECX && @@ -690,9 +697,9 @@ ParseSmbiosForGivenSystemEnvironment() return status; } - if (strstr(&cfg->system_information.vendor, "VMware, Inc")) + if (IntFindSubstring(&cfg->system_information.vendor, "VMware, Inc")) cfg->system_information.environment = Vmware; - else if (strstr(&cfg->system_information.vendor, "innotek GmbH")) + else if (IntFindSubstring(&cfg->system_information.vendor, "innotek GmbH")) cfg->system_information.environment = VirtualBox; else cfg->system_information.environment = NativeWindows; @@ -807,8 +814,11 @@ DrvLoadRetrieveDriverNameFromRegistry(_In_ PUNICODE_STRING RegistryPath) query[1].EntryContext = NULL; query[1].QueryRoutine = RegistryPathQueryCallbackRoutine; - status = RtlxQueryRegistryValues( - RTL_REGISTRY_ABSOLUTE, RegistryPath->Buffer, &query, NULL, NULL); + status = RtlxQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, + RegistryPath->Buffer, + &query, + NULL, + NULL); if (!NT_SUCCESS(status)) { DEBUG_ERROR("RtlxQueryRegistryValues failed with status %x", status); @@ -821,8 +831,9 @@ DrvLoadRetrieveDriverNameFromRegistry(_In_ PUNICODE_STRING RegistryPath) * name since we need the .sys extension when querying the system * modules for our driver. */ - status = ImpRtlUnicodeStringToAnsiString( - &cfg->ansi_driver_name, &cfg->unicode_driver_name, TRUE); + status = ImpRtlUnicodeStringToAnsiString(&cfg->ansi_driver_name, + &cfg->unicode_driver_name, + TRUE); if (!NT_SUCCESS(status)) { DEBUG_ERROR("RtlUnicodeStringToAnsiString failed with status %x", @@ -895,8 +906,10 @@ InitialiseHashingAlgorithmProvider() NTSTATUS status = STATUS_UNSUCCESSFUL; BCRYPT_ALG_HANDLE* handle = GetCryptHandle_Sha256(); - status = BCryptOpenAlgorithmProvider( - handle, BCRYPT_SHA256_ALGORITHM, NULL, BCRYPT_PROV_DISPATCH); + status = BCryptOpenAlgorithmProvider(handle, + BCRYPT_SHA256_ALGORITHM, + NULL, + BCRYPT_PROV_DISPATCH); if (!NT_SUCCESS(status)) DEBUG_ERROR("BCryptOpenAlgorithmProvider: %x", status); diff --git a/driver/driver.vcxproj b/driver/driver.vcxproj index 82e8032..3913d81 100644 --- a/driver/driver.vcxproj +++ b/driver/driver.vcxproj @@ -253,6 +253,7 @@ + @@ -275,6 +276,7 @@ + diff --git a/driver/driver.vcxproj.filters b/driver/driver.vcxproj.filters index 05f8a97..2292c0a 100644 --- a/driver/driver.vcxproj.filters +++ b/driver/driver.vcxproj.filters @@ -75,6 +75,9 @@ Source Files + + Source Files + @@ -146,6 +149,9 @@ Header Files + + Header Files + diff --git a/driver/hv.c b/driver/hv.c index dec7d5b..3b2a3b7 100644 --- a/driver/hv.c +++ b/driver/hv.c @@ -5,6 +5,8 @@ #include "common.h" #include "io.h" +#include "lib/stdlib.h" + #ifdef ALLOC_PRAGMA # pragma alloc_text(PAGE, PerformVirtualizationDetection) #endif @@ -101,7 +103,7 @@ PerformVirtualizationDetection(_Inout_ PIRP Irp) Irp->IoStatus.Information = sizeof(HYPERVISOR_DETECTION_REPORT); - RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, + IntCopyMemory(Irp->AssociatedIrp.SystemBuffer, &report, sizeof(HYPERVISOR_DETECTION_REPORT)); diff --git a/driver/hw.c b/driver/hw.c index 087ed59..8ae3a62 100644 --- a/driver/hw.c +++ b/driver/hw.c @@ -4,6 +4,8 @@ #include "crypt.h" #include "imports.h" +#include "lib/stdlib.h" + #define PCI_VENDOR_ID_OFFSET 0x00 #define PCI_DEVICE_ID_OFFSET 0x02 diff --git a/driver/imports.c b/driver/imports.c index 97220aa..c74f824 100644 --- a/driver/imports.c +++ b/driver/imports.c @@ -5,6 +5,8 @@ #include "crypt.h" #include +#include "lib/stdlib.h" + PVOID ImpResolveNtImport(PDRIVER_OBJECT DriverObject, PCZPSTR ExportName) { @@ -52,7 +54,7 @@ ImpResolveNtImport(PDRIVER_OBJECT DriverObject, PCZPSTR ExportName) for (INT index = 0; index < export_dir->NumberOfNames; index++) { name = (PCHAR)((UINT64)image_base + export_name_table[index]); - if (strcmp(name, ExportName)) + if (IntCompareString(name, ExportName)) continue; ordinal = ordinals_table[index]; diff --git a/driver/integrity.c b/driver/integrity.c index 97fc9b4..47fbb4e 100644 --- a/driver/integrity.c +++ b/driver/integrity.c @@ -11,6 +11,8 @@ #include "pe.h" #include "crypt.h" +#include "lib/stdlib.h" + #include #include #include @@ -163,7 +165,7 @@ GetDriverImageSize(_Inout_ PIRP Irp) Irp->IoStatus.Information = sizeof(ULONG); - RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, + IntCopyMemory(Irp->AssociatedIrp.SystemBuffer, &driver_info->ImageSize, sizeof(ULONG)); @@ -208,7 +210,7 @@ GetModuleInformationByName(_Out_ PRTL_MODULE_EXTENDED_INFO ModuleInfo, ModuleInfo->ImageBase = driver_info->ImageBase; ModuleInfo->ImageSize = driver_info->ImageSize; - RtlCopyMemory(ModuleInfo->FullPathName, + IntCopyMemory(ModuleInfo->FullPathName, driver_info->FullPathName, sizeof(ModuleInfo->FullPathName)); @@ -357,7 +359,7 @@ StoreModuleExecutableRegionsInBuffer(_Out_ PVOID* Buffer, num_executable_sections, total_packet_size); - RtlCopyMemory(*Buffer, &header, sizeof(INTEGRITY_CHECK_HEADER)); + IntCopyMemory(*Buffer, &header, sizeof(INTEGRITY_CHECK_HEADER)); *BytesWritten = total_packet_size + sizeof(INTEGRITY_CHECK_HEADER); return status; } @@ -484,7 +486,7 @@ RetrieveInMemoryModuleExecutableSections(_Inout_ PIRP Irp) } Irp->IoStatus.Information = bytes_written; - RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, buffer, bytes_written); + IntCopyMemory(Irp->AssociatedIrp.SystemBuffer, buffer, bytes_written); end: if (buffer) @@ -577,7 +579,7 @@ GetStringAtIndexFromSMBIOSTable(_In_ PSMBIOS_TABLE_HEADER Table, UINT64 dest = (UINT64)Buffer + current_string_char_index; - RtlCopyMemory(dest, current_string_char, sizeof(CHAR)); + IntCopyMemory(dest, current_string_char, sizeof(CHAR)); current_string_char_index++; goto increment; } @@ -741,7 +743,7 @@ STATIC BOOLEAN CompareHashes(_In_ PVOID Hash1, _In_ PVOID Hash2, _In_ UINT32 Length) { - return RtlCompareMemory(Hash1, Hash2, Length) == Length ? TRUE : FALSE; + return IntCompareMemory(Hash1, Hash2, Length) == Length ? TRUE : FALSE; } STATIC @@ -765,7 +767,7 @@ ReportInvalidProcessModule(_In_ PPROCESS_MODULE_INFORMATION Module) report->image_base = Module->module_base; report->image_size = Module->module_size; - RtlCopyMemory(report->module_path, + IntCopyMemory(report->module_path, Module->module_path, sizeof(report->module_path)); @@ -967,7 +969,7 @@ HashUserModule(_In_ PPROCESS_MAP_MODULE_ENTRY Entry, goto end; } - RtlCopyMemory(OutBuffer, memory_hash, memory_hash_size); + IntCopyMemory(OutBuffer, memory_hash, memory_hash_size); end: @@ -993,7 +995,7 @@ STATIC SIZE_T GetStorageDescriptorSerialLength(_In_ PCHAR SerialNumber) { - return strnlen_s(SerialNumber, DEVICE_DRIVE_0_SERIAL_CODE_LENGTH) + 1; + return IntStringLength(SerialNumber, DEVICE_DRIVE_0_SERIAL_CODE_LENGTH) + 1; } FORCEINLINE @@ -1109,7 +1111,7 @@ GetHardDiskDriveSerialNumber(_Inout_ PVOID ConfigDrive0Serial, goto end; } - RtlCopyMemory(ConfigDrive0Serial, serial_number, serial_length); + IntCopyMemory(ConfigDrive0Serial, serial_number, serial_length); end: @@ -1298,6 +1300,48 @@ InitiateEptFunctionAddressArrays() return STATUS_SUCCESS; } +STATIC +VOID +ReportEptHook(_In_ UINT64 ControlAverage, + _In_ UINT64 ReadAverage, + _In_ WCHAR FunctionName) +{ + NTSTATUS status = STATUS_UNSUCCESSFUL; + UINT32 len = 0; + PEPT_HOOK_REPORT report = NULL; + UNICODE_STRING string = {0}; + + len = CryptRequestRequiredBufferLength(sizeof(EPT_HOOK_REPORT)); + report = ImpExAllocatePool2(POOL_FLAG_NON_PAGED, len, REPORT_POOL_TAG); + + if (!report) + return; + + INIT_REPORT_PACKET(report, REPORT_EPT_HOOK, 0); + + report->control_average = ControlAverage; + report->read_average = ReadAverage; + + RtlInitUnicodeString(&string, FunctionName); + + status = UnicodeToCharBufString(&string, + report->function_name, + sizeof(report->function_name)); + + if (!NT_SUCCESS(status)) + DEBUG_ERROR("UnicodeToCharBufString: %x", status); + + status = CryptEncryptBuffer(report, len); + + if (!NT_SUCCESS(status)) { + DEBUG_ERROR("CryptEncryptBuffer: %lx", status); + ImpExFreePoolWithTag(report, len); + return; + } + + IrpQueueSchedulePacket(report, len); +} + NTSTATUS DetectEptHooksInKeyFunctions() { @@ -1361,8 +1405,9 @@ DetectEptHooksInKeyFunctions() "EPT hook detected at function: %llx with execution time of: %llx", PROTECTED_FUNCTION_ADDRESSES[index], instruction_time); - - /* close game etc. */ + ReportEptHook(control_average, + instruction_time, + PROTECTED_FUNCTION_ADDRESSES[index]); } } @@ -1380,7 +1425,7 @@ FindWinLogonProcess(_In_ PPROCESS_LIST_ENTRY Node, _In_opt_ PVOID Context) process_name = ImpPsGetProcessImageFileName(Node->process); - if (!strcmp(process_name, "winlogon.exe")) + if (!IntCompareString(process_name, "winlogon.exe")) *process = Node->process; } @@ -1552,7 +1597,7 @@ HashModule(_In_ PRTL_MODULE_EXTENDED_INFO Module, _Out_ PVOID Hash) goto end; } - RtlCopyMemory(Hash, memory_hash, memory_hash_size); + IntCopyMemory(Hash, memory_hash, memory_hash_size); end: @@ -1594,7 +1639,7 @@ ReportModifiedSystemImage(_In_ PRTL_MODULE_EXTENDED_INFO Module) report->image_base = Module->ImageBase; report->image_size = Module->ImageSize; - RtlCopyMemory(report->path_name, + IntCopyMemory(report->path_name, Module->FullPathName, sizeof(report->path_name)); @@ -1689,7 +1734,7 @@ ReportModifiedSelfDriverImage(_In_ PRTL_MODULE_EXTENDED_INFO Module) packet->image_base = Module->ImageBase; packet->image_size = Module->ImageSize; - RtlCopyMemory(packet->path_name, + IntCopyMemory(packet->path_name, Module->FullPathName, sizeof(packet->path_name)); @@ -2057,7 +2102,7 @@ GetOsVersionInformation(_Out_ PRTL_OSVERSIONINFOW VersionInfo) VersionInfo->dwOSVersionInfoSize = info.dwOSVersionInfoSize; VersionInfo->dwPlatformId = info.dwPlatformId; - RtlCopyMemory(VersionInfo->szCSDVersion, + IntCopyMemory(VersionInfo->szCSDVersion, info.szCSDVersion, sizeof(VersionInfo->szCSDVersion)); diff --git a/driver/io.c b/driver/io.c index 1fc573d..6023793 100644 --- a/driver/io.c +++ b/driver/io.c @@ -14,6 +14,8 @@ #include "hw.h" #include "containers/map.h" +#include "lib/stdlib.h" + STATIC NTSTATUS DispatchApcOperation(_In_ PAPC_OPERATION_ID Operation); @@ -178,7 +180,7 @@ IrpQueueCompleteDeferredPacket(_In_ PDEFERRED_REPORT Report, _In_ PIRP Irp) IncrementPacketMetics(queue, type); - RtlCopyMemory( + IntCopyMemory( Irp->AssociatedIrp.SystemBuffer, Report->buffer, Report->buffer_size); Irp->IoStatus.Status = STATUS_SUCCESS; @@ -331,7 +333,7 @@ IrpQueueCompletePacket(_In_ PVOID Buffer, _In_ ULONG BufferSize) irp->IoStatus.Status = STATUS_SUCCESS; irp->IoStatus.Information = BufferSize; - RtlCopyMemory(irp->AssociatedIrp.SystemBuffer, Buffer, BufferSize); + IntCopyMemory(irp->AssociatedIrp.SystemBuffer, Buffer, BufferSize); ImpExFreePoolWithTag(Buffer, REPORT_POOL_TAG); ImpIofCompleteRequest(irp, IO_NO_INCREMENT); return status; @@ -1022,7 +1024,7 @@ DeviceControl(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp) Irp->IoStatus.Information = sizeof(SYSTEM_INFORMATION); - RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, + IntCopyMemory(Irp->AssociatedIrp.SystemBuffer, system_information, sizeof(SYSTEM_INFORMATION)); diff --git a/driver/lib/stdlib.c b/driver/lib/stdlib.c new file mode 100644 index 0000000..cb87c3e --- /dev/null +++ b/driver/lib/stdlib.c @@ -0,0 +1,84 @@ +#include "stdlib.h" + +VOID +IntCopyMemory(_In_ PVOID Destination, _In_ PVOID Source, _In_ SIZE_T Length) +{ + PUCHAR dest = (PUCHAR)Destination; + PUCHAR src = (PUCHAR)Source; + + for (SIZE_T index = 0; index < Length; index++) + dest[index] = src[index]; +} + +SIZE_T +IntStringLength(_In_ PCHAR String, _In_ SIZE_T MaxLength) +{ + SIZE_T length = 0; + + while (length < MaxLength && String[length] != '\0') + length++; + + return length; +} + +SIZE_T +IntCompareMemory(_In_ PVOID Source1, _In_ PVOID Source2, _In_ SIZE_T Length) +{ + PUCHAR src1 = (PUCHAR)Source1; + PUCHAR src2 = (PUCHAR)Source2; + + for (SIZE_T i = 0; i < Length; i++) { + if (src1[i] != src2[i]) + return i; + } + + return Length; +} + +PCHAR +IntFindSubstring(_In_ PCHAR String1, _In_ PCHAR String2) +{ + if (*String2 == '\0') { + return String1; + } + + for (PCHAR s1 = String1; *s1 != '\0'; s1++) { + PCHAR p1 = s1; + PCHAR p2 = String2; + + while (*p1 != '\0' && *p2 != '\0' && *p1 == *p2) { + p1++; + p2++; + } + + if (*p2 == '\0') + return s1; + } + + return NULL; +} + +INT32 +IntCompareString(_In_ PCHAR String1, _In_ PCHAR String2) +{ + while (*String1 != '\0' && *String2 != '\0') { + if (*String1 != *String2) + return (INT32)(*String1 - *String2); + + String1++; + String2++; + } + + return (INT32)(*String1 - *String2); +} + +PWCHAR +IntWideStringCopy(_In_ PWCHAR Destination, _In_ PWCHAR Source) +{ + PWCHAR dest = Destination; + + while ((*dest++ = *Source++) != '\0') + ; + + return Destination; +} \ No newline at end of file diff --git a/driver/lib/stdlib.h b/driver/lib/stdlib.h new file mode 100644 index 0000000..8e7e606 --- /dev/null +++ b/driver/lib/stdlib.h @@ -0,0 +1,25 @@ +#ifndef STDLIB_H +#define STDLIB_H + +#include "../common.h" + +VOID +IntCopyMemory(_In_ PVOID Destination, _In_ PVOID Source, _In_ SIZE_T Length); + + +SIZE_T +IntStringLength(_In_ PCHAR String, _In_ SIZE_T MaxLength); + +SIZE_T +IntCompareMemory(_In_ PVOID Source1, _In_ PVOID Source2, _In_ SIZE_T Length); + +PCHAR +IntFindSubstring(_In_ PCHAR String1, _In_ PCHAR String2); + +INT32 +IntCompareString(_In_ PCHAR String1, _In_ PCHAR String2); + +PWCHAR +IntWideStringCopy(_In_ PWCHAR Destination, _In_ PWCHAR Source); + +#endif \ No newline at end of file diff --git a/driver/modules.c b/driver/modules.c index 0b08568..6586b34 100644 --- a/driver/modules.c +++ b/driver/modules.c @@ -11,6 +11,8 @@ #include "pe.h" #include "thread.h" +#include "lib/stdlib.h" + #define WHITELISTED_MODULE_TAG 'whte' #define NMI_DELAY 200 * 10000 @@ -170,7 +172,7 @@ FindSystemModuleByName(_In_ LPCSTR ModuleName, (PRTL_MODULE_EXTENDED_INFO)SystemModules->address; for (INT index = 0; index < SystemModules->module_count; index++) { - if (strstr(modules[index].FullPathName, ModuleName)) { + if (IntFindSubstring(modules[index].FullPathName, ModuleName)) { return &modules[index]; } } @@ -669,7 +671,7 @@ ReportMissingCidTableEntry(_In_ PNMI_CONTEXT Context) report->thread_id = ImpPsGetThreadId(Context->kthread); report->thread_address = Context->kthread; - RtlCopyMemory(report->thread, Context->kthread, sizeof(report->thread)); + IntCopyMemory(report->thread, Context->kthread, sizeof(report->thread)); status = CryptEncryptBuffer(report, len); @@ -734,7 +736,7 @@ DoesRetInstructionCauseException(_In_ UINT64 ReturnAddress) /* Shoudln't really ever occur */ __try { - RtlCopyMemory(&opcodes, ReturnAddress, sizeof(opcodes)); + IntCopyMemory(&opcodes, ReturnAddress, sizeof(opcodes)); } __except (EXCEPTION_EXECUTE_HANDLER) { return FALSE; @@ -1342,7 +1344,7 @@ ReportDpcStackwalkViolation(_In_ PDPC_CONTEXT Context, report->kthread_address = PsGetCurrentThread(); report->invalid_rip = Frame; - // RtlCopyMemory(report->driver, + // IntCopyMemory(report->driver, // (UINT64)Context[core].stack_frame[frame] // - 0x50, // APC_STACKWALK_BUFFER_SIZE); @@ -1658,7 +1660,7 @@ ReportDataTableInvalidRoutine(_In_ TABLE_ID TableId, _In_ UINT64 Address) report->table_id = TableId; report->index = 0; - RtlCopyMemory(report->routine, Address, DATA_TABLE_ROUTINE_BUF_SIZE); + IntCopyMemory(report->routine, Address, DATA_TABLE_ROUTINE_BUF_SIZE); status = CryptEncryptBuffer(report, len); @@ -1827,7 +1829,7 @@ FindModuleByName(_In_ PSYSTEM_MODULES Modules, _In_ PCHAR ModuleName) for (UINT32 index = 0; index < Modules->module_count; index++) { PRTL_MODULE_EXTENDED_INFO entry = &((PRTL_MODULE_EXTENDED_INFO)(Modules->address))[index]; - if (strstr(entry->FullPathName, ModuleName)) + if (IntFindSubstring(entry->FullPathName, ModuleName)) return entry; } diff --git a/driver/pe.c b/driver/pe.c index 45c698a..6dfb9c0 100644 --- a/driver/pe.c +++ b/driver/pe.c @@ -1,5 +1,7 @@ #include "pe.h" +#include "lib/stdlib.h" + PNT_HEADER_64 PeGetNtHeaderSafe(_In_ PVOID Image) { @@ -126,7 +128,7 @@ PeFindExportByName(_In_ PVOID Image, _In_ PCHAR Name) for (UINT32 index = 0; index < export->NumberOfNames; index++) { PCHAR export = RVA(PCHAR, Image, names[index]); - if (!strcmp(Name, export)) + if (!IntCompareString(Name, export)) return RVA( PVOID, Image, functions[ordinals[index]]); } diff --git a/driver/pool.c b/driver/pool.c index edbcfe8..f411682 100644 --- a/driver/pool.c +++ b/driver/pool.c @@ -8,6 +8,8 @@ #include "imports.h" #include "crypt.h" +#include "lib/stdlib.h" + #define PAGE_BASE_SIZE 0x1000 #define POOL_TAG_SIZE 0x004 @@ -127,7 +129,7 @@ GetGlobalDebuggerData() if (!debugger_data) goto end; - RtlCopyMemory(debugger_data, + IntCopyMemory(debugger_data, dump_header->KdDebuggerDataBlock, sizeof(KDDEBUGGER_DATA64)); @@ -732,7 +734,7 @@ FindUnlinkedProcesses() INIT_REPORT_PACKET(report, REPORT_INVALID_PROCESS_ALLOCATION, 0); - RtlCopyMemory( + IntCopyMemory( report->process, allocation, REPORT_INVALID_PROCESS_BUFFER_SIZE); status = CryptEncryptBuffer(report, packet_size); diff --git a/driver/session.c b/driver/session.c index a4ae1fc..9540b50 100644 --- a/driver/session.c +++ b/driver/session.c @@ -4,6 +4,8 @@ #include "crypt.h" #include "util.h" +#include "lib/stdlib.h" + NTSTATUS SessionInitialiseStructure() { @@ -152,13 +154,13 @@ SessionInitialise(_In_ PIRP Irp) session->process = process; session->cookie = initiation->cookie; - RtlCopyMemory(session->aes_key, initiation->aes_key, AES_256_KEY_SIZE); - RtlCopyMemory(session->iv, initiation->aes_iv, AES_256_IV_SIZE); + IntCopyMemory(session->aes_key, initiation->aes_key, AES_256_KEY_SIZE); + IntCopyMemory(session->iv, initiation->aes_iv, AES_256_IV_SIZE); session->module.base_address = initiation->module_info.base_address; session->module.size = initiation->module_info.size; - RtlCopyMemory( + IntCopyMemory( session->module.path, initiation->module_info.path, MAX_MODULE_PATH); DEBUG_VERBOSE("Module base: %llx", session->module.base_address); diff --git a/driver/thread.c b/driver/thread.c index 0e65f2b..624ee1a 100644 --- a/driver/thread.c +++ b/driver/thread.c @@ -11,6 +11,8 @@ #include "containers/tree.h" #include "crypt.h" +#include "lib/stdlib.h" + #ifdef ALLOC_PRAGMA # pragma alloc_text(PAGE, DetectThreadsAttachedToProtectedProcess) # pragma alloc_text(PAGE, DoesThreadHaveValidCidEntry) diff --git a/driver/types/types.h b/driver/types/types.h index f22a6f6..d7417c5 100644 --- a/driver/types/types.h +++ b/driver/types/types.h @@ -16,6 +16,7 @@ #define REPORT_PATCHED_SYSTEM_MODULE 150 #define REPORT_SELF_DRIVER_PATCHED 160 #define REPORT_BLACKLISTED_PCIE_DEVICE 170 +#define REPORT_EPT_HOOK 180 #define REPORT_SUBTYPE_NO_BACKING_MODULE 0x0 #define REPORT_SUBTYPE_INVALID_DISPATCH 0x1 @@ -201,6 +202,13 @@ typedef struct _SYSTEM_MODULE_INTEGRITY_CHECK_REPORT { } SYSTEM_MODULE_INTEGRITY_CHECK_REPORT, *PSYSTEM_MODULE_INTEGRITY_CHECK_REPORT; +typedef struct _EPT_HOOK_REPORT { + REPORT_PACKET_HEADER header; + UINT64 control_average; + UINT64 read_average; + CHAR function_name[128]; +} EPT_HOOK_REPORT, *PEPT_HOOK_REPORT; + typedef struct _DRIVER_SELF_INTEGRITY_CHECK_REPORT { REPORT_PACKET_HEADER header; UINT64 image_base; diff --git a/driver/util.c b/driver/util.c index 2a4f8cf..ace82e3 100644 --- a/driver/util.c +++ b/driver/util.c @@ -1,5 +1,7 @@ #include "common.h" +#include "lib/stdlib.h" + LARGE_INTEGER GenerateRandSeed() { @@ -62,7 +64,7 @@ UnicodeToCharBufString(_In_ PUNICODE_STRING UnicodeString, return STATUS_BUFFER_TOO_SMALL; } - RtlCopyMemory(OutBuffer, string.Buffer, string.Length); + IntCopyMemory(OutBuffer, string.Buffer, string.Length); RtlFreeAnsiString(&string); return STATUS_SUCCESS; diff --git a/module/helper.cpp b/module/helper.cpp index 233e0b0..641dc43 100644 --- a/module/helper.cpp +++ b/module/helper.cpp @@ -201,6 +201,15 @@ print_report_packet(void* buffer) LOG_INFO("********************************"); break; } + case kernel_interface::report_id::report_ept_hook: { + kernel_interface::ept_hook_failure* r14 = + reinterpret_cast(buffer); + LOG_INFO("control_average: %llx", r14->control_average); + LOG_INFO("read_average: %llx", r14->read_average); + LOG_INFO("function_name: %s", r14->function_name); + LOG_INFO("********************************"); + break; + } default: LOG_INFO("Invalid report type."); break; } } diff --git a/module/kernel_interface/kernel_interface.h b/module/kernel_interface/kernel_interface.h index 01ab98d..05c783c 100644 --- a/module/kernel_interface/kernel_interface.h +++ b/module/kernel_interface/kernel_interface.h @@ -27,7 +27,8 @@ enum report_id { report_invalid_process_module = 140, report_patched_system_module = 150, report_self_driver_patched = 160, - report_blacklisted_pcie_device = 170 + report_blacklisted_pcie_device = 170, + report_ept_hook = 180 }; #define AES_256_BLOCK_SIZE 16 @@ -78,6 +79,13 @@ struct module_validation_failure { char driver_name[128]; }; +struct ept_hook_failure { + report_header report_header; + uint64_t control_average; + uint64_t read_average; + char function_name[128]; +}; + enum table_id { hal_dispatch = 0, hal_private_dispatch }; struct data_table_routine_report {