diff --git a/driver/asm.asm b/driver/asm.asm index 5d3f581..62c39d3 100644 --- a/driver/asm.asm +++ b/driver/asm.asm @@ -15,7 +15,7 @@ TestINVDEmulation PROC pushfq cli - push 1 ; push some dummy data onto the stack which will exist in writeback memory + push 1 ; push some dummy data onto the stack which will exist in writeback cache wbinvd ; flush the internal cpu caches and write back all modified cache ; lines to main memory mov byte ptr [rsp], 0 ; set our dummy value to 0, this takes place inside writeback memory diff --git a/driver/callbacks.c b/driver/callbacks.c index dbb9aaf..1ed54b2 100644 --- a/driver/callbacks.c +++ b/driver/callbacks.c @@ -283,6 +283,7 @@ BOOLEAN EnumHandleCallback( GetProtectedProcessId( &protected_process_id ); PsLookupProcessByProcessId( protected_process_id, &protected_process ); + protected_process_name = PsGetProcessImageFileName( protected_process ); if ( strcmp( process_name, protected_process_name ) ) diff --git a/driver/driver.c b/driver/driver.c index 3400339..2b2df38 100644 --- a/driver/driver.c +++ b/driver/driver.c @@ -6,6 +6,8 @@ #include "hv.h" +#include "integrity.h" + PVOID callback_registration_handle; diff --git a/driver/driver.vcxproj b/driver/driver.vcxproj index 560f6da..41ba82e 100644 --- a/driver/driver.vcxproj +++ b/driver/driver.vcxproj @@ -129,6 +129,7 @@ + @@ -139,6 +140,7 @@ + diff --git a/driver/driver.vcxproj.filters b/driver/driver.vcxproj.filters index 9c4a00b..99aeb6d 100644 --- a/driver/driver.vcxproj.filters +++ b/driver/driver.vcxproj.filters @@ -45,6 +45,9 @@ Source Files + + Source Files + @@ -71,6 +74,9 @@ Header Files + + Header Files + diff --git a/driver/integrity.c b/driver/integrity.c new file mode 100644 index 0000000..8551dcb --- /dev/null +++ b/driver/integrity.c @@ -0,0 +1,66 @@ +#include "integrity.h" + +#include "common.h" +#include "modules.h" + +NTSTATUS CopyDriverExecutableRegions( + _In_ PIRP Irp +) +{ + NTSTATUS status; + SYSTEM_MODULES modules = { 0 }; + PRTL_MODULE_EXTENDED_INFO driver_info; + MEMORY_BASIC_INFORMATION region_info; + SIZE_T return_length; + PVOID current; + INT count = 0; + + status = GetSystemModuleInformation( &modules ); + + if ( !NT_SUCCESS( status ) ) + { + DEBUG_ERROR( "GetSystemModuleInformation failed with status %x", status ); + goto end; + } + + driver_info = FindSystemModuleByName( + "driver.sys", + &modules + ); + + current = driver_info->ImageBase; + + Irp->IoStatus.Information = driver_info->ImageSize; + + while (NT_SUCCESS( NtQueryVirtualMemory( + NtCurrentProcess(), + current, + MemoryBasicInformation, + ®ion_info, + sizeof( MEMORY_BASIC_INFORMATION ), + &return_length + ))) + { + if ( region_info.AllocationProtect & PAGE_EXECUTE ) + { + RtlCopyMemory( + (UINT64)Irp->AssociatedIrp.SystemBuffer + count * region_info.RegionSize, + current, + region_info.RegionSize + ); + + DEBUG_LOG( "Copied region at address: %p, with protect: %lx", current, region_info.AllocationProtect ); + } + + current = (UINT64)current + region_info.RegionSize; + } + +end: + + Irp->IoStatus.Status = status; + + if ( modules.address ) + ExFreePoolWithTag( modules.address, SYSTEM_MODULES_POOL ); + + return status; +} \ No newline at end of file diff --git a/driver/integrity.h b/driver/integrity.h new file mode 100644 index 0000000..f0feb75 --- /dev/null +++ b/driver/integrity.h @@ -0,0 +1,12 @@ +#ifndef INTEGRITY_H +#define INTEGRITY_H + +#include + +#define POOL_TAG_INTEGRITY 'intg' + +NTSTATUS CopyDriverExecutableRegions( + _In_ PIRP Irp +); + +#endif \ No newline at end of file diff --git a/driver/ioctl.c b/driver/ioctl.c index da5c16a..c8e8512 100644 --- a/driver/ioctl.c +++ b/driver/ioctl.c @@ -6,6 +6,7 @@ #include "modules.h" #include "driver.h" #include "callbacks.h" +#include "integrity.h" #include "hv.h" @@ -123,6 +124,15 @@ NTSTATUS DeviceControl( break; + case IOCTL_RETRIEVE_MODULE_EXECUTABLE_REGIONS: + + status = CopyDriverExecutableRegions( Irp ); + + if ( !NT_SUCCESS( status ) ) + DEBUG_ERROR( "Failed to retrieve executable regions" ); + + break; + default: DEBUG_ERROR( "Invalid IOCTL passed to driver" ); break; diff --git a/driver/ioctl.h b/driver/ioctl.h index 8522f1d..0beb289 100644 --- a/driver/ioctl.h +++ b/driver/ioctl.h @@ -13,6 +13,8 @@ #define IOCTL_HANDLE_REPORTS_IN_CALLBACK_QUEUE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2005, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_PERFORM_VIRTUALIZATION_CHECK CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2006, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_ENUMERATE_HANDLE_TABLES CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2007, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_RETRIEVE_MODULE_EXECUTABLE_REGIONS CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2008, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_REQUEST_TOTAL_MODULE_SIZE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2009, METHOD_BUFFERED, FILE_ANY_ACCESS) typedef struct _DRIVER_INITIATION_INFORMATION { diff --git a/driver/modules.c b/driver/modules.c index c696efd..fcfd176 100644 --- a/driver/modules.c +++ b/driver/modules.c @@ -1,7 +1,6 @@ #include "modules.h" #include "nmi.h" -#include "common.h" #define WHITELISTED_MODULE_TAG 'whte' @@ -28,11 +27,10 @@ typedef struct _WHITELISTED_REGIONS PRTL_MODULE_EXTENDED_INFO FindSystemModuleByName( _In_ LPCSTR ModuleName, - _In_ PSYSTEM_MODULES SystemModules, - _In_ PVOID Buffer + _In_ PSYSTEM_MODULES SystemModules ) { - if ( !ModuleName || !SystemModules || !Buffer ) + if ( !ModuleName || !SystemModules ) return STATUS_INVALID_PARAMETER; for ( INT index = 0; index < SystemModules->module_count; index++ ) @@ -59,7 +57,7 @@ NTSTATUS PopulateWhitelistedModuleBuffer( { LPCSTR name = WHITELISTED_MODULES[ index ]; - PRTL_MODULE_EXTENDED_INFO module = FindSystemModuleByName( name, SystemModules, Buffer ); + PRTL_MODULE_EXTENDED_INFO module = FindSystemModuleByName( name, SystemModules ); WHITELISTED_REGIONS region; region.base = (UINT64)module->ImageBase; @@ -352,7 +350,8 @@ NTSTATUS ValidateDriverObjects( PVOID whitelisted_regions_buffer = ExAllocatePool2( POOL_FLAG_NON_PAGED, WHITELISTED_MODULE_COUNT * MODULE_MAX_STRING_SIZE, - WHITELISTED_MODULE_TAG ); + WHITELISTED_MODULE_TAG + ); if ( !whitelisted_regions_buffer ) goto end; diff --git a/driver/modules.h b/driver/modules.h index 6d5a7c3..7e615af 100644 --- a/driver/modules.h +++ b/driver/modules.h @@ -3,6 +3,7 @@ #include #include +#include "common.h" #define REPORT_MODULE_VALIDATION_FAILURE 60 #define MODULE_VALIDATION_FAILURE_MAX_REPORT_COUNT 20 @@ -60,4 +61,9 @@ NTSTATUS HandleValidateDriversIOCTL( _In_ PIRP Irp ); +PRTL_MODULE_EXTENDED_INFO FindSystemModuleByName( + _In_ LPCSTR ModuleName, + _In_ PSYSTEM_MODULES SystemModules +); + #endif diff --git a/user/client.cpp b/user/client.cpp index 792ead9..008db1f 100644 --- a/user/client.cpp +++ b/user/client.cpp @@ -2,75 +2,76 @@ #include "common.h" -global::Client::Client( LPTSTR PipeName ) +#include + +global::Client::Client( std::shared_ptr ThreadPool, LPTSTR PipeName ) { - this->pipe_name = PipeName; - this->pipe_handle = CreateFile( - this->pipe_name, - GENERIC_READ | GENERIC_WRITE, - 0, - NULL, - OPEN_EXISTING, - 0, - NULL - ); - - if ( this->pipe_handle == INVALID_HANDLE_VALUE ) - { - LOG_ERROR( "CreateFile failed with status 0x%x", GetLastError() ); - return; - } - - /* test the write function */ - //global::headers::PIPE_PACKET_HEADER header; - //header.message_type = REQUEST_PATTERNS_TO_BE_SCANNED; - //this->WriteToPipe( &header, sizeof( global::headers::PIPE_PACKET_HEADER ) ); + this->thread_pool = ThreadPool; + this->pipe = std::make_shared( PipeName ); } -void global::Client::WriteToPipe( PVOID Buffer, SIZE_T Size ) +/* +* Request an item from the server +*/ +void global::Client::ServerRequest() { - DWORD bytes_written; - - WriteFile( - this->pipe_handle, - Buffer, - Size, - &bytes_written, - NULL - ); - - if ( bytes_written == 0 ) - { - LOG_ERROR( "WriteFile failed with status code 0x%x", GetLastError() ); - return; - } - - LOG_INFO( "Sent bytes over pipe" ); } -void global::Client::ReadPipe(PVOID Buffer, SIZE_T Size) +/* +* Send an item to the server +*/ +void global::Client::ServerSend(PVOID Buffer, SIZE_T Size, INT RequestId) { - BOOL status = FALSE; - DWORD bytes_read; + mutex.lock(); - do + global::headers::PIPE_PACKET_HEADER header; + header.message_type = SERVER_SEND_PACKET_ID; + memcpy( this->send_buffer, &header, sizeof( global::headers::PIPE_PACKET_HEADER ) ); + + LONG total_size_of_headers = sizeof( global::headers::PIPE_PACKET_HEADER ) + sizeof( global::headers::PIPE_PACKET_SEND_EXTENSION_HEADER ); + + if ( Size > ( SEND_BUFFER_SIZE - total_size_of_headers ) ) { - status = ReadFile( - this->pipe_handle, - Buffer, - Size, - &bytes_read, - NULL - ); + INT total_packets = std::ceil( Size / ( SEND_BUFFER_SIZE - total_size_of_headers ) ); + LONG remaining_bytes = Size; - if ( !status && GetLastError() != ERROR_MORE_DATA ) - break; + for ( INT count = 0; count < total_packets; count++ ) + { + global::headers::PIPE_PACKET_SEND_EXTENSION_HEADER header_extension; + header_extension.request_id = RequestId; + header_extension.total_incoming_packet_count = total_packets; + header_extension.total_incoming_packet_size = Size; + header_extension.current_packet_number = count; + header_extension.packet_size = ( count + 1 ) == total_packets ? remaining_bytes : SEND_BUFFER_SIZE; - } while ( !status ); + memcpy( PVOID( ( UINT64 )this->send_buffer + sizeof( global::headers::PIPE_PACKET_HEADER ) ), + &header_extension, sizeof(global::headers::PIPE_PACKET_SEND_EXTENSION_HEADER)); - if ( !status ) - { - LOG_ERROR( "ReadFile failed with status 0x%x", GetLastError() ); - return; + memcpy( + PVOID( ( UINT64 )this->send_buffer + total_size_of_headers ), Buffer, + ( UINT64 )header_extension.packet_size - total_size_of_headers + ); + + this->pipe->WriteToPipe( this->send_buffer, header_extension.packet_size ); + + remaining_bytes = remaining_bytes - header_extension.packet_size; + } } + else + { + global::headers::PIPE_PACKET_SEND_EXTENSION_HEADER header_extension; + header_extension.request_id = RequestId; + header_extension.total_incoming_packet_count = 1; + header_extension.total_incoming_packet_size = Size; + header_extension.current_packet_number = 1; + header_extension.packet_size = Size; + + memcpy( PVOID( ( UINT64 )this->send_buffer + sizeof( global::headers::PIPE_PACKET_HEADER ) ), + &header_extension, sizeof( global::headers::PIPE_PACKET_SEND_EXTENSION_HEADER ) ); + + this->pipe->WriteToPipe( this->send_buffer, header_extension.packet_size ); + } + + RtlZeroMemory( this->send_buffer, SEND_BUFFER_SIZE ); + mutex.unlock(); } diff --git a/user/client.h b/user/client.h index a6eac4d..42227f2 100644 --- a/user/client.h +++ b/user/client.h @@ -1,32 +1,152 @@ -#ifndef CLIENT_H -#define CLIENT_H +#ifndef REPORT_H +#define REPORT_H #include -#define REPORT_PACKET_ID 1 -#define REQUEST_PATTERNS_TO_BE_SCANNED 2 +#include "threadpool.h" +#include "pipe.h" +#include + +#define REPORT_BUFFER_SIZE 1024 +#define SEND_BUFFER_SIZE 8192 + +#define MAX_SIGNATURE_SIZE 256 + +#define MODULE_VALIDATION_FAILURE_MAX_REPORT_COUNT 20 + +#define REPORT_CODE_MODULE_VERIFICATION 10 +#define REPORT_CODE_START_ADDRESS_VERIFICATION 20 +#define REPORT_PAGE_PROTECTION_VERIFICATION 30 +#define REPORT_PATTERN_SCAN_FAILURE 40 +#define REPORT_NMI_CALLBACK_FAILURE 50 +#define REPORT_MODULE_VALIDATION_FAILURE 60 +#define REPORT_ILLEGAL_HANDLE_OPERATION 70 + +enum REPORT_CODES +{ + USERMODE_MODULE = 10, + START_ADDRESS = 20, + PAGE_PROTECTION = 30, + PATTERN_SCAN = 40, + NMI_CALLBACK = 50, + SYSTEM_MODULE = 60, + HANDLE_OPERATION = 70 +}; + +#define SERVER_SEND_MODULE_INTEGRITY_CHECK 10 + +enum SERVER_SEND_CODES +{ + MODULE_INTEGRITY_CHECK = 10 +}; namespace global { class Client { - HANDLE pipe_handle; - LPTSTR pipe_name; + std::shared_ptr thread_pool; + std::shared_ptr pipe; + std::mutex mutex; + + byte report_buffer[ REPORT_BUFFER_SIZE ]; + byte send_buffer[ SEND_BUFFER_SIZE ]; public: - Client(LPTSTR PipeName); - void WriteToPipe( PVOID Buffer, SIZE_T Size ); - void ReadPipe( PVOID Buffer, SIZE_T Size ); + Client( std::shared_ptr ThreadPool, LPTSTR PipeName ); + + /* lock buffer, attach header, copy report, send to service then clear buffer */ + template + void ReportViolation( T* Report ) + { + mutex.lock(); + + global::headers::PIPE_PACKET_HEADER header; + header.message_type = REPORT_PACKET_ID; + memcpy( this->report_buffer, &header, sizeof( global::headers::PIPE_PACKET_HEADER ) ); + + memcpy( PVOID( ( UINT64 )this->report_buffer + sizeof( global::headers::PIPE_PACKET_HEADER ) ), Report, sizeof( T ) ); + this->pipe->WriteToPipe( this->report_buffer, sizeof(T) + sizeof( global::headers::PIPE_PACKET_HEADER ) ); + RtlZeroMemory( this->report_buffer, REPORT_BUFFER_SIZE ); + + mutex.unlock(); + } + + void ServerRequest(); + + void ServerSend( PVOID Buffer, SIZE_T Size, INT RequestId ); }; - namespace headers + namespace report_structures { - struct PIPE_PACKET_HEADER + struct MODULE_VERIFICATION_CHECKSUM_FAILURE { - int message_type; + INT report_code; + UINT64 module_base_address; + UINT64 module_size; + std::string module_name; + }; + + struct PROCESS_THREAD_START_FAILURE + { + INT report_code; + LONG thread_id; + UINT64 start_address; + }; + + struct PAGE_PROTECTION_FAILURE + { + INT report_code; + UINT64 page_base_address; + LONG allocation_protection; + LONG allocation_state; + LONG allocation_type; + }; + + struct PATTERN_SCAN_FAILURE + { + INT report_code; + INT signature_id; + UINT64 address; + }; + + struct NMI_CALLBACK_FAILURE + { + INT report_code; + INT were_nmis_disabled; + UINT64 kthread_address; + UINT64 invalid_rip; + }; + + struct MODULE_VALIDATION_FAILURE_HEADER + { + INT module_count; + }; + + struct MODULE_VALIDATION_FAILURE + { + INT report_code; + INT report_type; + UINT64 driver_base_address; + UINT64 driver_size; + CHAR driver_name[ 128 ]; + }; + + struct OPEN_HANDLE_FAILURE_REPORT_HEADER + { + INT count; + }; + + struct OPEN_HANDLE_FAILURE_REPORT + { + INT report_code; + INT is_kernel_handle; + LONG process_id; + LONG thread_id; + LONG desired_access; + CHAR process_name[ 64 ]; }; } } -#endif \ No newline at end of file +#endif diff --git a/user/km/driver.cpp b/user/km/driver.cpp index b845740..907f021 100644 --- a/user/km/driver.cpp +++ b/user/km/driver.cpp @@ -4,7 +4,7 @@ #include "../common.h" -kernelmode::Driver::Driver( LPCWSTR DriverName, std::shared_ptr ReportInterface ) +kernelmode::Driver::Driver( LPCWSTR DriverName, std::shared_ptr ReportInterface ) { this->driver_name = DriverName; this->report_interface = ReportInterface; @@ -284,6 +284,16 @@ void kernelmode::Driver::CheckHandleTableEntries() LOG_ERROR( "CheckHandleTableEntries failed with status %x", status ); } +void kernelmode::Driver::RequestModuleExecutableRegions() +{ + BOOLEAN status; +} + +void kernelmode::Driver::RequestTotalModuleSize() +{ + +} + void kernelmode::Driver::ValidateKPRCBThreads() { diff --git a/user/km/driver.h b/user/km/driver.h index 1115970..1fb65b3 100644 --- a/user/km/driver.h +++ b/user/km/driver.h @@ -4,7 +4,7 @@ #include #include "../threadpool.h" -#include "../report.h" +#include "../client.h" #define IOCCTL_RUN_NMI_CALLBACKS CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2001, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_VALIDATE_DRIVER_OBJECTS CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2002, METHOD_BUFFERED, FILE_ANY_ACCESS) @@ -13,6 +13,9 @@ #define IOCTL_HANDLE_REPORTS_IN_CALLBACK_QUEUE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2005, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_PERFORM_VIRTUALIZATION_CHECK CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2006, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_ENUMERATE_HANDLE_TABLES CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2007, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_RETRIEVE_MODULE_EXECUTABLE_REGIONS CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2008, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_REQUEST_TOTAL_MODULE_SIZE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2009, METHOD_BUFFERED, FILE_ANY_ACCESS) + #define MAX_HANDLE_REPORTS_PER_IRP 10 @@ -22,13 +25,14 @@ namespace kernelmode { HANDLE driver_handle; LPCWSTR driver_name; - std::shared_ptr report_interface; + std::shared_ptr report_interface; void QueryReportQueue(); + void RequestTotalModuleSize(); public: - Driver(LPCWSTR DriverName, std::shared_ptr ReportInterface ); + Driver(LPCWSTR DriverName, std::shared_ptr ReportInterface ); void RunNmiCallbacks(); void VerifySystemModules(); @@ -38,6 +42,7 @@ namespace kernelmode void ValidateKPRCBThreads(); void CheckDriverHeartbeat(); void CheckHandleTableEntries(); + void RequestModuleExecutableRegions(); /* todo: driver integrity check */ }; diff --git a/user/km/kmanager.cpp b/user/km/kmanager.cpp index f8057a9..c67a85e 100644 --- a/user/km/kmanager.cpp +++ b/user/km/kmanager.cpp @@ -1,6 +1,6 @@ #include "kmanager.h" -kernelmode::KManager::KManager( LPCWSTR DriverName, std::shared_ptr ThreadPool, std::shared_ptr ReportInterface) +kernelmode::KManager::KManager( LPCWSTR DriverName, std::shared_ptr ThreadPool, std::shared_ptr ReportInterface) { this->driver_interface = std::make_unique(DriverName, ReportInterface); this->thread_pool = ThreadPool; diff --git a/user/km/kmanager.h b/user/km/kmanager.h index e8aac89..20a6b62 100644 --- a/user/km/kmanager.h +++ b/user/km/kmanager.h @@ -3,7 +3,7 @@ #include -#include "../report.h" +#include "..\client.h" #include "..\threadpool.h" #include "driver.h" @@ -15,7 +15,7 @@ namespace kernelmode std::unique_ptr driver_interface; std::shared_ptr thread_pool; public: - KManager( LPCWSTR DriverName, std::shared_ptr ThreadPool, std::shared_ptr ReportInterface); + KManager( LPCWSTR DriverName, std::shared_ptr ThreadPool, std::shared_ptr ReportInterface); void RunNmiCallbacks(); void VerifySystemModules(); diff --git a/user/main.cpp b/user/main.cpp index 8a5aed2..8a88866 100644 --- a/user/main.cpp +++ b/user/main.cpp @@ -5,7 +5,7 @@ #include "common.h" #include "threadpool.h" -#include "report.h" +#include "client.h" #include "../user/um/umanager.h" #include "../user/km/kmanager.h" @@ -23,7 +23,7 @@ DWORD WINAPI Init(HINSTANCE hinstDLL) LPCWSTR driver_name = L"\\\\.\\DonnaAC"; std::shared_ptr thread_pool = std::make_shared( 4 ); - std::shared_ptr report_interface = std::make_shared( thread_pool, pipe_name ); + std::shared_ptr report_interface = std::make_shared( thread_pool, pipe_name ); usermode::UManager umanager( thread_pool, report_interface ); kernelmode::KManager kmanager( driver_name, thread_pool, report_interface); diff --git a/user/pipe.cpp b/user/pipe.cpp new file mode 100644 index 0000000..ed206cc --- /dev/null +++ b/user/pipe.cpp @@ -0,0 +1,76 @@ +#include "pipe.h" + +#include "common.h" + +global::Pipe::Pipe( LPTSTR PipeName ) +{ + this->pipe_name = PipeName; + this->pipe_handle = CreateFile( + this->pipe_name, + GENERIC_READ | GENERIC_WRITE, + 0, + NULL, + OPEN_EXISTING, + 0, + NULL + ); + + if ( this->pipe_handle == INVALID_HANDLE_VALUE ) + { + LOG_ERROR( "CreateFile failed with status 0x%x", GetLastError() ); + return; + } + + /* test the write function */ + //global::headers::PIPE_PACKET_HEADER header; + //header.message_type = REQUEST_PATTERNS_TO_BE_SCANNED; + //this->WriteToPipe( &header, sizeof( global::headers::PIPE_PACKET_HEADER ) ); +} + +void global::Pipe::WriteToPipe( PVOID Buffer, SIZE_T Size ) +{ + DWORD bytes_written; + + WriteFile( + this->pipe_handle, + Buffer, + Size, + &bytes_written, + NULL + ); + + if ( bytes_written == 0 ) + { + LOG_ERROR( "WriteFile failed with status code 0x%x", GetLastError() ); + return; + } + + LOG_INFO( "Sent bytes over pipe" ); +} + +void global::Pipe::ReadPipe(PVOID Buffer, SIZE_T Size) +{ + BOOL status = FALSE; + DWORD bytes_read; + + do + { + status = ReadFile( + this->pipe_handle, + Buffer, + Size, + &bytes_read, + NULL + ); + + if ( !status && GetLastError() != ERROR_MORE_DATA ) + break; + + } while ( !status ); + + if ( !status ) + { + LOG_ERROR( "ReadFile failed with status 0x%x", GetLastError() ); + return; + } +} diff --git a/user/pipe.h b/user/pipe.h new file mode 100644 index 0000000..f25023a --- /dev/null +++ b/user/pipe.h @@ -0,0 +1,48 @@ +#ifndef PIPE_H +#define PIPE_H + +#include + +#define REPORT_PACKET_ID 1 +#define SERVER_REQUEST_PACKET_ID 2 +#define SERVER_SEND_PACKET_ID 3 + +namespace global +{ + class Pipe + { + HANDLE pipe_handle; + LPTSTR pipe_name; + + public: + Pipe(LPTSTR PipeName); + + void WriteToPipe( PVOID Buffer, SIZE_T Size ); + void ReadPipe( PVOID Buffer, SIZE_T Size ); + }; + + namespace headers + { + struct PIPE_PACKET_HEADER + { + INT message_type; + }; + + struct PIPE_PACKET_REQUEST_EXTENSION_HEADER + { + INT request_id; + }; + + struct PIPE_PACKET_SEND_EXTENSION_HEADER + { + INT request_id; + INT current_packet_number; + INT total_incoming_packet_count; + LONG packet_size; + LONG total_incoming_packet_size; + }; + + } +} + +#endif \ No newline at end of file diff --git a/user/report.cpp b/user/report.cpp deleted file mode 100644 index 3b66fed..0000000 --- a/user/report.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#include "report.h" - -#include "common.h" - -global::Report::Report( std::shared_ptr ThreadPool, LPTSTR PipeName ) -{ - this->thread_pool = ThreadPool; - this->client = std::make_shared( PipeName ); -} diff --git a/user/report.h b/user/report.h deleted file mode 100644 index f8d483c..0000000 --- a/user/report.h +++ /dev/null @@ -1,128 +0,0 @@ -#ifndef REPORT_H -#define REPORT_H - -#include - -#include "threadpool.h" -#include "client.h" -#include - -#define REPORT_BUFFER_SIZE 1024 -#define MAX_SIGNATURE_SIZE 256 -#define MODULE_VALIDATION_FAILURE_MAX_REPORT_COUNT 20 - -#define REPORT_CODE_MODULE_VERIFICATION 10 -#define REPORT_CODE_START_ADDRESS_VERIFICATION 20 -#define REPORT_PAGE_PROTECTION_VERIFICATION 30 -#define REPORT_PATTERN_SCAN_FAILURE 40 -#define REPORT_NMI_CALLBACK_FAILURE 50 -#define REPORT_MODULE_VALIDATION_FAILURE 60 -#define REPORT_ILLEGAL_HANDLE_OPERATION 70 - - - -namespace global -{ - class Report - { - std::shared_ptr thread_pool; - std::shared_ptr client; - std::mutex mutex; - byte buffer[ REPORT_BUFFER_SIZE ]; - - public: - - Report( std::shared_ptr ThreadPool, LPTSTR PipeName ); - - /* lock buffer, attach header, copy report, send to service then clear buffer */ - template - void ReportViolation( T* Report ) - { - mutex.lock(); - - global::headers::PIPE_PACKET_HEADER header; - header.message_type = REPORT_PACKET_ID; - memcpy( this->buffer, &header, sizeof( global::headers::PIPE_PACKET_HEADER ) ); - - memcpy( PVOID( ( UINT64 )this->buffer + sizeof( global::headers::PIPE_PACKET_HEADER ) ), Report, sizeof( T ) ); - this->client->WriteToPipe( buffer, sizeof(T) + sizeof( global::headers::PIPE_PACKET_HEADER ) ); - RtlZeroMemory( this->buffer, REPORT_BUFFER_SIZE ); - - mutex.unlock(); - } - }; - - namespace report_structures - { - struct MODULE_VERIFICATION_CHECKSUM_FAILURE - { - INT report_code; - UINT64 module_base_address; - UINT64 module_size; - std::string module_name; - }; - - struct PROCESS_THREAD_START_FAILURE - { - INT report_code; - LONG thread_id; - UINT64 start_address; - }; - - struct PAGE_PROTECTION_FAILURE - { - INT report_code; - UINT64 page_base_address; - LONG allocation_protection; - LONG allocation_state; - LONG allocation_type; - }; - - struct PATTERN_SCAN_FAILURE - { - INT report_code; - INT signature_id; - UINT64 address; - }; - - struct NMI_CALLBACK_FAILURE - { - INT report_code; - INT were_nmis_disabled; - UINT64 kthread_address; - UINT64 invalid_rip; - }; - - struct MODULE_VALIDATION_FAILURE_HEADER - { - INT module_count; - }; - - struct MODULE_VALIDATION_FAILURE - { - INT report_code; - INT report_type; - UINT64 driver_base_address; - UINT64 driver_size; - CHAR driver_name[ 128 ]; - }; - - struct OPEN_HANDLE_FAILURE_REPORT_HEADER - { - INT count; - - }; - - struct OPEN_HANDLE_FAILURE_REPORT - { - INT report_code; - INT is_kernel_handle; - LONG process_id; - LONG thread_id; - LONG desired_access; - CHAR process_name[ 64 ]; - }; - } -} - -#endif diff --git a/user/um/process.cpp b/user/um/process.cpp index 354b73a..ab6dffa 100644 --- a/user/um/process.cpp +++ b/user/um/process.cpp @@ -4,14 +4,14 @@ #include "../um/imports.h" #include "memory.h" -#include "../report.h" +#include "../client.h" #include #include const static char MASK_BYTE = '\x00'; -usermode::Process::Process( std::shared_ptr ReportInterface ) +usermode::Process::Process( std::shared_ptr ReportInterface ) { this->process_handle = GetCurrentProcess(); this->process_id = GetCurrentProcessId(); diff --git a/user/um/process.h b/user/um/process.h index b11b47d..c66c4dd 100644 --- a/user/um/process.h +++ b/user/um/process.h @@ -6,7 +6,7 @@ #include #include -#include "../report.h" +#include "../client.h" #include "../threadpool.h" #include "../um/imports.h" @@ -27,7 +27,7 @@ namespace usermode std::mutex mutex; std::unique_ptr function_imports; std::vector in_memory_module_checksums; - std::shared_ptr report_interface; + std::shared_ptr report_interface; HANDLE GetHandleToProcessGivenName( std::string ProcessName ); std::vector GetProcessThreadsStartAddresses(); @@ -38,7 +38,7 @@ namespace usermode public: - Process( std::shared_ptr ReportInterface ); + Process( std::shared_ptr ReportInterface ); void ValidateProcessThreads(); void ScanProcessMemory(); diff --git a/user/um/umanager.cpp b/user/um/umanager.cpp index 33bb3b2..58dabbd 100644 --- a/user/um/umanager.cpp +++ b/user/um/umanager.cpp @@ -6,7 +6,7 @@ #include -usermode::UManager::UManager( std::shared_ptr ThreadPool, std::shared_ptr ReportInterface ) +usermode::UManager::UManager( std::shared_ptr ThreadPool, std::shared_ptr ReportInterface ) { this->thread_pool = ThreadPool; this->process = std::make_unique(ReportInterface); diff --git a/user/um/umanager.h b/user/um/umanager.h index 6560116..74b3a47 100644 --- a/user/um/umanager.h +++ b/user/um/umanager.h @@ -8,7 +8,7 @@ #include #include -#include "../report.h" +#include "..\client.h" #include "process.h" @@ -25,7 +25,7 @@ namespace usermode std::shared_ptr thread_pool; public: - UManager( std::shared_ptr ThreadPool, std::shared_ptr ReportInterface ); + UManager( std::shared_ptr ThreadPool, std::shared_ptr ReportInterface ); ~UManager(); void ValidateProcessThreads(); diff --git a/user/user.vcxproj b/user/user.vcxproj index b5886a7..ee4e026 100644 --- a/user/user.vcxproj +++ b/user/user.vcxproj @@ -129,7 +129,7 @@ - + @@ -137,14 +137,14 @@ - + - + - + diff --git a/user/user.vcxproj.filters b/user/user.vcxproj.filters index c818462..e9a5415 100644 --- a/user/user.vcxproj.filters +++ b/user/user.vcxproj.filters @@ -36,10 +36,10 @@ Source Files - + Source Files - + Source Files @@ -65,10 +65,10 @@ Header Files - + Header Files - + Header Files