This commit is contained in:
lhodges1 2023-09-05 19:16:32 +10:00
parent 893104cfe5
commit 44e5ed6232
14 changed files with 210 additions and 305 deletions

View file

@ -990,6 +990,12 @@ typedef struct _RAW_SMBIOS_TABLE_02 {
}RAW_SMBIOS_TABLE_02, *PRAW_SMBIOS_TABLE_02;
typedef struct _RTL_RELATIVE_NAME {
UNICODE_STRING RelativeName;
HANDLE ContainingDirectory;
void* CurDirRef;
} RTL_RELATIVE_NAME, * PRTL_RELATIVE_NAME;
NTKERNELAPI
BOOLEAN
ExEnumHandleTable(
@ -1066,6 +1072,13 @@ KeCapturePersistentThreadState(
__in PDUMP_HEADER DumpHeader
);
BOOLEAN NTAPI RtlDosPathNameToRelativeNtPathName_U(
_In_ PCWSTR DosFileName,
_Out_ PUNICODE_STRING NtFileName,
_Out_opt_ PWSTR* FilePath,
_Out_opt_ PRTL_RELATIVE_NAME RelativeName
);
C_ASSERT( FIELD_OFFSET( DUMP_HEADER, Signature ) == 0 );
C_ASSERT( FIELD_OFFSET( DUMP_HEADER, ValidDump ) == 4 );
C_ASSERT( FIELD_OFFSET( DUMP_HEADER, MajorVersion ) == 8 );

View file

@ -332,17 +332,15 @@ NTSTATUS DriverEntry(
BOOLEAN flag = FALSE;
NTSTATUS status;
//status = InitialiseDriverConfigOnDriverEntry( RegistryPath );
status = InitialiseDriverConfigOnDriverEntry( RegistryPath );
//if ( !NT_SUCCESS( status ) )
//{
// DEBUG_ERROR( "InitialiseDriverConfigOnDriverEntry failed with status %x", status );
// return status;
//}
if ( !NT_SUCCESS( status ) )
{
DEBUG_ERROR( "InitialiseDriverConfigOnDriverEntry failed with status %x", status );
return status;
}
//InitialiseProcessConfigOnDriverEntry();
QueryDiskDriverForDiskInformation();
InitialiseProcessConfigOnDriverEntry();
status = IoCreateDevice(
DriverObject,

View file

@ -146,8 +146,6 @@ NTSTATUS StoreModuleExecutableRegionsInBuffer(
for ( ULONG index = 0; index < num_sections; index++ )
{
DEBUG_LOG( "section name: %s, size: %lx", section->Name, section->SizeOfRawData );
if ( section->Characteristics & IMAGE_SCN_MEM_EXECUTE )
{
/*
@ -726,7 +724,7 @@ NTSTATUS RetrieveInMemoryModuleExecutableSections(
* 729 system- and OEM-specific structures and allows upper-level software to easily traverse the
* 730 structure table. (See structure-termination examples later in this clause.)
*
* TLDR is that if the first character proceeding the structure is a null byte, then there are no strings,
* TLDR is that if the first two characters proceeding the structure are null terminators, then there are no strings,
* otherwise to find the end of the string section simply iterate until there is a double null terminator.
*
* source: https://www.dmtf.org/sites/default/files/standards/documents/DSP0134_2.7.1.pdf
@ -824,7 +822,7 @@ NTSTATUS ParseSMBIOSTable(
SMBIOS_TABLE,
NULL,
NULL,
firmware_table_buffer_size,
NULL,
&firmware_table_buffer_size
);
@ -861,17 +859,17 @@ NTSTATUS ParseSMBIOSTable(
smbios_table_header = ( PSMBIOS_TABLE_HEADER )(&smbios_data->SMBIOSTableData[0] );
/*
* The System Information table is equal to Type == 1 and contains the UUID of the motherboard
* The System Information table is equal to Type == 2 and contains the serial number of the motherboard
* in the computer among various other things.
*
* source: https://www.dmtf.org/sites/default/files/standards/documents/DSP0134_2.7.1.pdf line 823
*/
while ( smbios_table_header->Type != SMBIOS_SYSTEM_INFORMATION_TYPE_2_TABLE )
while ( smbios_table_header->Type != VMWARE_SMBIOS_TABLE )
GetNextSMBIOSStructureInTable( &smbios_table_header );
status = GetStringAtIndexFromSMBIOSTable(
smbios_table_header,
MOTHERBOARD_SERIAL_CODE_TABLE_INDEX,
VMWARE_SMBIOS_TABLE_INDEX,
ConfigMotherboardSerialNumber,
ConfigMotherboardSerialNumberSize
);
@ -891,97 +889,96 @@ end:
}
/*
* WIP
* Because the infrastructure has already been setup to validate modules in the driver, that
* is how I will validate the usermode modules as well. Another reason is that the win32 api
* makes it very easy to take a snapshot of the modules and enumerate them with easy to use
* functions and macros.
*
* 1. Take a snapshot of the modules in the process from our dll
* 2. pass the image base, image size and the image path to our driver via an IRP
* 3. from our driver, to first verify the in memory module, attach to our protected process
* and using the base + size simply use StoreModuleExecutableRegionsInBuffer()
* 4. Next we use the path to map the image on disk into memory, and pass the image to
* StoreModuleExecutableRegionsInBuffer() just as we did before.
* 5. With the 2 buffers that contain both images executable regions, we hash them and compare
* for anomalies.
*/
NTSTATUS QueryDiskDriverForDiskInformation()
NTSTATUS ValidateProcessLoadedModule(
_In_ PIRP Irp
)
{
NTSTATUS status;
HANDLE handle;
PVOID buffer = NULL;
OBJECT_ATTRIBUTES object_attributes;
PIO_STATUS_BLOCK status_block = { 0 };
STORAGE_DESCRIPTOR_HEADER storage_descriptor_header = { 0 };
PSTORAGE_DEVICE_DESCRIPTOR storage_device_descriptor = NULL;
UNICODE_STRING physical_drive_path;
BOOLEAN bstatus;
PROCESS_MODULE_VALIDATION_RESULT validation_result;
PPROCESS_MODULE_INFORMATION module_info;
PKPROCESS process;
KAPC_STATE apc_state;
PVOID in_memory_buffer = NULL;
PVOID disk_buffer = NULL;
PVOID in_memory_hash = NULL;
PVOID disk_hash = NULL;
ULONG in_memory_hash_size = NULL;
ULONG disk_hash_size = NULL;
SIZE_T bytes_written = NULL;
UNICODE_STRING module_path;
RtlInitUnicodeString( &physical_drive_path, L"\\DosDevices\\PhysicalDrive0" );
module_info = ( PPROCESS_MODULE_INFORMATION )Irp->AssociatedIrp.SystemBuffer;
InitializeObjectAttributes(
&object_attributes,
&physical_drive_path,
OBJ_KERNEL_HANDLE,
NULL,
NULL
);
GetProtectedProcessEProcess( &process );
status = ZwOpenFile(
&handle,
FILE_READ_DATA | FILE_READ_ATTRIBUTES | SYNCHRONIZE,
&object_attributes,
&status_block,
FILE_SHARE_READ,
FILE_SYNCHRONOUS_IO_NONALERT
in_memory_buffer = ExAllocatePool2( POOL_FLAG_NON_PAGED, module_info->module_size, POOL_TAG_INTEGRITY );
if ( !in_memory_buffer )
return STATUS_ABANDONED;
KeStackAttachProcess( process, &apc_state );
status = StoreModuleExecutableRegionsInBuffer(
&in_memory_buffer,
module_info->module_base,
module_info->module_size,
&bytes_written
);
if ( !NT_SUCCESS( status ) )
{
DEBUG_ERROR( "Failed to open handle to PhysicalDrive0 with status %x", status );
return status;
DEBUG_ERROR( "StoreModuleExecutableRegionsInBuffer failed with status %x", status );
KeUnstackDetachProcess( &apc_state );
goto end;
}
status = ZwDeviceIoControlFile(
handle,
NULL,
NULL,
NULL,
&status_block,
IOCTL_STORAGE_QUERY_PROPERTY,
NULL,
NULL,
&storage_descriptor_header,
sizeof( storage_descriptor_header )
KeUnstackDetachProcess( &apc_state );
status = ComputeHashOfBuffer(
in_memory_buffer,
bytes_written,
&in_memory_hash,
&in_memory_hash_size
);
if ( !NT_SUCCESS( status ) )
{
DEBUG_ERROR( "ZwDeviceIoControlFile failed with status %x", status );
DEBUG_ERROR( "ComputeHashOfBuffer failed with status %x:", status );
goto end;
}
buffer = ExAllocatePool2( POOL_FLAG_NON_PAGED, storage_descriptor_header.Size, POOL_TAG_INTEGRITY );
RtlInitUnicodeString( &module_path, &module_info->module_path );
if ( !buffer )
goto end;
validation_result.is_module_valid = TRUE;
Irp->IoStatus.Information = sizeof( PROCESS_MODULE_VALIDATION_RESULT );
status = ZwDeviceIoControlFile(
handle,
NULL,
NULL,
NULL,
&status_block,
IOCTL_STORAGE_QUERY_PROPERTY,
NULL,
NULL,
buffer,
storage_descriptor_header.Size
RtlCopyMemory(
Irp->AssociatedIrp.SystemBuffer,
&validation_result,
sizeof( PROCESS_MODULE_VALIDATION_RESULT )
);
if ( !NT_SUCCESS( status ) )
{
DEBUG_ERROR( "ZwDeviceIoControlFile failed with status %x", status );
goto end;
}
DEBUG_LOG( "Storage descritpr size: %lx", storage_descriptor_header.Size );
storage_device_descriptor = ( PSTORAGE_DEVICE_DESCRIPTOR )buffer;
DEBUG_LOG( "Serial number offset: %lx", storage_device_descriptor->SerialNumberOffset );
end:
if ( buffer )
ExFreePoolWithTag( buffer, POOL_TAG_INTEGRITY );
if ( in_memory_buffer )
ExFreePoolWithTag( in_memory_buffer, POOL_TAG_INTEGRITY );
if ( in_memory_hash )
ExFreePoolWithTag( in_memory_hash, POOL_TAG_INTEGRITY );
ZwClose( handle );
}

View file

@ -4,152 +4,30 @@
#include <ntifs.h>
#include "common.h"
#define IOCTL_STORAGE_QUERY_PROPERTY CTL_CODE(0x0000002d, 0x0500, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define SMBIOS_TABLE 'RSMB'
#define SMBIOS_SYSTEM_INFORMATION_TYPE_2_TABLE 2
#define NULL_TERMINATOR '\0'
#define MOTHERBOARD_SERIAL_CODE_TABLE_INDEX 4
typedef enum _STORAGE_BUS_TYPE {
BusTypeUnknown = 0x00,
BusTypeScsi,
BusTypeAtapi,
BusTypeAta,
BusType1394,
BusTypeSsa,
BusTypeFibre,
BusTypeUsb,
BusTypeRAID,
BusTypeiScsi,
BusTypeSas,
BusTypeSata,
BusTypeSd,
BusTypeMmc,
BusTypeVirtual,
BusTypeFileBackedVirtual,
BusTypeSpaces,
BusTypeNvme,
BusTypeSCM,
BusTypeUfs,
BusTypeMax,
BusTypeMaxReserved = 0x7F
} STORAGE_BUS_TYPE, * PSTORAGE_BUS_TYPE;
/* for testing purposes */
#define VMWARE_SMBIOS_TABLE 1
#define VMWARE_SMBIOS_TABLE_INDEX 3
//
// Standard property descriptor header. All property pages should use this
// as their first element or should contain these two elements
//
#define MAX_MODULE_PATH 256
typedef struct _STORAGE_DESCRIPTOR_HEADER {
typedef struct _PROCESS_MODULE_INFORMATION
{
PVOID module_base;
SIZE_T module_size;
WCHAR module_path[ MAX_MODULE_PATH ];
UINT32 Version;
}PROCESS_MODULE_INFORMATION, *PPROCESS_MODULE_INFORMATION;
UINT32 Size;
typedef struct _PROCESS_MODULE_VALIDATION_RESULT
{
INT is_module_valid;
} STORAGE_DESCRIPTOR_HEADER, * PSTORAGE_DESCRIPTOR_HEADER;
//
// Device property descriptor - this is really just a rehash of the inquiry
// data retrieved from a scsi device
//
// This may only be retrieved from a target device. Sending this to the bus
// will result in an error
//
typedef struct _STORAGE_DEVICE_DESCRIPTOR {
//
// Sizeof(STORAGE_DEVICE_DESCRIPTOR)
//
UINT32 Version;
//
// Total size of the descriptor, including the space for additional
// data and id strings
//
UINT32 Size;
//
// The SCSI-2 device type
//
BYTE DeviceType;
//
// The SCSI-2 device type modifier (if any) - this may be zero
//
BYTE DeviceTypeModifier;
//
// Flag indicating whether the device's media (if any) is removable. This
// field should be ignored for media-less devices
//
BOOLEAN RemovableMedia;
//
// Flag indicating whether the device can support mulitple outstanding
// commands. The actual synchronization in this case is the responsibility
// of the port driver.
//
BOOLEAN CommandQueueing;
//
// Byte offset to the zero-terminated ascii string containing the device's
// vendor id string. For devices with no such ID this will be zero
//
UINT32 VendorIdOffset;
//
// Byte offset to the zero-terminated ascii string containing the device's
// product id string. For devices with no such ID this will be zero
//
UINT32 ProductIdOffset;
//
// Byte offset to the zero-terminated ascii string containing the device's
// product revision string. For devices with no such string this will be
// zero
//
UINT32 ProductRevisionOffset;
//
// Byte offset to the zero-terminated ascii string containing the device's
// serial number. For devices with no serial number this will be zero
//
UINT32 SerialNumberOffset;
//
// Contains the bus type (as defined above) of the device. It should be
// used to interpret the raw device properties at the end of this structure
// (if any)
//
STORAGE_BUS_TYPE BusType;
//
// The number of bytes of bus-specific data which have been appended to
// this descriptor
//
UINT32 RawPropertiesLength;
//
// Place holder for the first byte of the bus specific property data
//
BYTE RawDeviceProperties[ 1 ];
} STORAGE_DEVICE_DESCRIPTOR, * PSTORAGE_DEVICE_DESCRIPTOR;
}PROCESS_MODULE_VALIDATION_RESULT, *PPROCESS_MODULE_VALIDATION_RESULT;
NTSTATUS CopyDriverExecutableRegions(
_In_ PIRP Irp
@ -172,6 +50,8 @@ NTSTATUS ParseSMBIOSTable(
_In_ SIZE_T ConfigMotherboardSerialNumberSize
);
NTSTATUS QueryDiskDriverForDiskInformation();
NTSTATUS ValidateProcessLoadedModule(
_In_ PIRP Irp
);
#endif

View file

@ -241,6 +241,15 @@ NTSTATUS DeviceControl(
break;
case IOCTL_VALIDATE_PROCESS_LOADED_MODULE:
status = ValidateProcessLoadedModule( Irp );
if ( !NT_SUCCESS( status ) )
DEBUG_ERROR( "ValidateProcessLoadedModule failed with status %x", status );
break;
default:
DEBUG_ERROR( "Invalid IOCTL passed to driver" );
break;

View file

@ -19,6 +19,7 @@
#define IOCTL_VALIDATE_KPRCB_CURRENT_THREAD CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2012, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_PERFORM_INTEGRITY_CHECK CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2013, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_DETECT_ATTACHED_THREADS CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2014, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_VALIDATE_PROCESS_LOADED_MODULE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2015, METHOD_BUFFERED, FILE_ANY_ACCESS)
typedef struct _DRIVER_INITIATION_INFORMATION
{

View file

@ -511,3 +511,71 @@ VOID kernelmode::Driver::CheckDriverHeartbeat()
{
}
VOID kernelmode::Driver::VerifyProcessLoadedModuleExecutableRegions()
{
HANDLE process_modules_handle;
MODULEENTRY32 module_entry;
BOOLEAN status;
PROCESS_MODULE_INFORMATION module_information;
PROCESS_MODULE_VALIDATION_RESULT validation_result;
DWORD bytes_returned;
process_modules_handle = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, GetCurrentProcessId() );
if ( process_modules_handle == INVALID_HANDLE_VALUE )
{
LOG_ERROR( "CreateToolHelp32Snapshot with TH32CS_SNAPMODULE failed with status 0x%x", GetLastError() );
return;
}
module_entry.dwSize = sizeof( MODULEENTRY32 );
if ( !Module32First( process_modules_handle, &module_entry ) )
{
LOG_ERROR( "Module32First failed with status 0x%x", GetLastError() );
return;
}
do
{
module_information.module_base = module_entry.modBaseAddr;
module_information.module_size = module_entry.modBaseSize;
memcpy( module_information.module_path, module_entry.szExePath, MAX_MODULE_PATH );
status = DeviceIoControl(
this->driver_handle,
IOCTL_VALIDATE_PROCESS_LOADED_MODULE,
&module_information,
sizeof( module_information ),
&validation_result,
sizeof( validation_result ),
&bytes_returned,
NULL
);
if ( status == NULL || bytes_returned == NULL )
{
LOG_ERROR( "failed to validate process module with status %x", GetLastError() );
continue;
}
LOG_INFO( "Bytes returned: %lx", bytes_returned );
/* compare the current checksum to the previously calculated checksum */
//if ( this->in_memory_module_checksums[ index ] != in_memory_check_sum )
//{
// global::report_structures::MODULE_VERIFICATION_CHECKSUM_FAILURE report;
// report.report_code = REPORT_CODE_MODULE_VERIFICATION;
// report.module_base_address = (UINT64)module_entry.modBaseAddr;
// report.module_size = module_entry.modBaseSize;
// std::wstring wstr( module_entry.szModule );
// report.module_name = std::string( wstr.begin(), wstr.end() );
// this->report_interface->ReportViolation( &report );
//}
} while ( Module32Next( process_modules_handle, &module_entry ) );
end:
CloseHandle( process_modules_handle );
}

View file

@ -19,9 +19,12 @@
#define IOCTL_VALIDATE_KPRCB_CURRENT_THREAD CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2012, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_PERFORM_INTEGRITY_CHECK CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2013, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_DETECT_ATTACHED_THREADS CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2014, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_VALIDATE_PROCESS_LOADED_MODULE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2015, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define MAX_REPORTS_PER_IRP 20
#define MAX_MODULE_PATH 256
namespace kernelmode
{
class Driver
@ -51,6 +54,7 @@ namespace kernelmode
VOID ScanForUnlinkedProcess();
VOID PerformIntegrityCheck();
VOID CheckForAttachedThreads();
VOID VerifyProcessLoadedModuleExecutableRegions();
};
struct DRIVER_INITIATION_INFORMATION
@ -63,6 +67,18 @@ namespace kernelmode
INT aperf_msr_timing_check;
INT invd_emulation_check;
};
struct PROCESS_MODULE_INFORMATION
{
PVOID module_base;
SIZE_T module_size;
WCHAR module_path[ MAX_MODULE_PATH ];
};
struct PROCESS_MODULE_VALIDATION_RESULT
{
INT is_module_valid;
};
}
#endif

View file

@ -50,3 +50,8 @@ VOID kernelmode::KManager::CheckForAttachedThreads()
{
this->thread_pool->QueueJob( [ this ]() { this->driver_interface->CheckForAttachedThreads(); } );
}
VOID kernelmode::KManager::ValidateProcessModules()
{
this->thread_pool->QueueJob( [ this ]() { this->driver_interface->VerifyProcessLoadedModuleExecutableRegions(); } );
}

View file

@ -26,6 +26,7 @@ namespace kernelmode
VOID ScanPoolsForUnlinkedProcesses();
VOID PerformIntegrityCheck();
VOID CheckForAttachedThreads();
VOID ValidateProcessModules();
};
}

View file

@ -30,7 +30,7 @@ DWORD WINAPI Init(HINSTANCE hinstDLL)
while ( !GetAsyncKeyState( VK_DELETE ) )
{
kmanager.MonitorCallbackReports();
kmanager.ValidateProcessModules();
std::this_thread::sleep_for( std::chrono::milliseconds( 10000 ) );
}

View file

@ -16,7 +16,6 @@ usermode::Process::Process( std::shared_ptr<global::Client> ReportInterface )
this->process_handle = GetCurrentProcess();
this->process_id = GetCurrentProcessId();
this->function_imports = std::make_unique<Imports>();
this->VerifyLoadedModuleChecksums( true );
this->report_interface = ReportInterface;
}
@ -315,79 +314,4 @@ void usermode::Process::CheckPageProtection( MEMORY_BASIC_INFORMATION* Page )
report.allocation_type = Page->Type;
this->report_interface->ReportViolation( &report );
}
}
void usermode::Process::VerifyLoadedModuleChecksums(bool Init)
{
HANDLE process_modules_handle;
MODULEENTRY32 module_entry;
PVOID mapped_image;
DWORD in_memory_header_sum;
DWORD in_memory_check_sum;
DWORD result;
INT index = 0;
std::vector<DWORD> temp;
process_modules_handle = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, this->process_id );
if ( process_modules_handle == INVALID_HANDLE_VALUE )
{
LOG_ERROR( "CreateToolHelp32Snapshot with TH32CS_SNAPMODULE failed with status 0x%x", GetLastError() );
return;
}
module_entry.dwSize = sizeof( MODULEENTRY32 );
if ( !Module32First( process_modules_handle, &module_entry ) )
{
LOG_ERROR( "Module32First failed with status 0x%x", GetLastError() );
return;
}
do
{
/* compute checksum for the in memory module */
mapped_image = CheckSumMappedFile(
module_entry.modBaseAddr,
module_entry.modBaseSize,
&in_memory_header_sum,
&in_memory_check_sum
);
if ( !mapped_image )
{
LOG_ERROR( "CheckSumMappedFile failed with status 0x%x", GetLastError() );
goto end;
}
/* if we are initiliasing simply fill the vector with checksums */
if ( Init )
{
this->in_memory_module_checksums.push_back( in_memory_check_sum );
continue;
}
/* compare the current checksum to the previously calculated checksum */
if ( this->in_memory_module_checksums[ index ] != in_memory_check_sum )
{
global::report_structures::MODULE_VERIFICATION_CHECKSUM_FAILURE report;
report.report_code = REPORT_CODE_MODULE_VERIFICATION;
report.module_base_address = (UINT64)module_entry.modBaseAddr;
report.module_size = module_entry.modBaseSize;
std::wstring wstr( module_entry.szModule );
report.module_name = std::string( wstr.begin(), wstr.end() );
this->report_interface->ReportViolation( &report );
}
//store the new checksums in a temp vector
temp.push_back( in_memory_check_sum );
index++;
} while ( Module32Next( process_modules_handle, &module_entry ) );
if (!Init )
this->in_memory_module_checksums = temp;
end:
CloseHandle( process_modules_handle );
}

View file

@ -9,6 +9,7 @@
#include "../client.h"
#include "../threadpool.h"
#include "../um/imports.h"
#include "../km/kmanager.h"
#define ThreadQuerySetWin32StartAddress 9
@ -30,7 +31,6 @@ namespace usermode
std::shared_ptr<global::Client> report_interface;
HANDLE GetHandleToProcessGivenName( std::string ProcessName );
std::vector<UINT64> GetProcessThreadsStartAddresses();
bool CheckIfAddressLiesWithinValidProcessModule( UINT64 Address, bool* Result );
bool GetProcessBaseAddress( UINT64* Result );
void CheckPageProtection( MEMORY_BASIC_INFORMATION* Page );
@ -42,7 +42,6 @@ namespace usermode
void ValidateProcessThreads();
void ScanProcessMemory();
void VerifyLoadedModuleChecksums(bool Init);
};
}

View file

@ -34,9 +34,3 @@ void usermode::UManager::ValidateProcessMemory()
{
this->thread_pool->QueueJob( [ this ]() {this->process->ScanProcessMemory(); } );
}
void usermode::UManager::ValidateProcessModules()
{
this->thread_pool->QueueJob( [ this ]() {this->process->VerifyLoadedModuleChecksums( false ); } );
}