This commit is contained in:
lhodges1 2023-08-23 03:32:25 +10:00
parent 102b258bd8
commit 77525c1ccf
28 changed files with 469 additions and 240 deletions

View file

@ -15,7 +15,7 @@ TestINVDEmulation PROC
pushfq pushfq
cli 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 wbinvd ; flush the internal cpu caches and write back all modified cache
; lines to main memory ; lines to main memory
mov byte ptr [rsp], 0 ; set our dummy value to 0, this takes place inside writeback memory mov byte ptr [rsp], 0 ; set our dummy value to 0, this takes place inside writeback memory

View file

@ -283,6 +283,7 @@ BOOLEAN EnumHandleCallback(
GetProtectedProcessId( &protected_process_id ); GetProtectedProcessId( &protected_process_id );
PsLookupProcessByProcessId( protected_process_id, &protected_process ); PsLookupProcessByProcessId( protected_process_id, &protected_process );
protected_process_name = PsGetProcessImageFileName( protected_process ); protected_process_name = PsGetProcessImageFileName( protected_process );
if ( strcmp( process_name, protected_process_name ) ) if ( strcmp( process_name, protected_process_name ) )

View file

@ -6,6 +6,8 @@
#include "hv.h" #include "hv.h"
#include "integrity.h"
PVOID callback_registration_handle; PVOID callback_registration_handle;

View file

@ -129,6 +129,7 @@
<ClCompile Include="callbacks.c" /> <ClCompile Include="callbacks.c" />
<ClCompile Include="driver.c" /> <ClCompile Include="driver.c" />
<ClCompile Include="hv.c" /> <ClCompile Include="hv.c" />
<ClCompile Include="integrity.c" />
<ClCompile Include="ioctl.c" /> <ClCompile Include="ioctl.c" />
<ClCompile Include="modules.c" /> <ClCompile Include="modules.c" />
<ClCompile Include="nmi.c" /> <ClCompile Include="nmi.c" />
@ -139,6 +140,7 @@
<ClInclude Include="common.h" /> <ClInclude Include="common.h" />
<ClInclude Include="driver.h" /> <ClInclude Include="driver.h" />
<ClInclude Include="hv.h" /> <ClInclude Include="hv.h" />
<ClInclude Include="integrity.h" />
<ClInclude Include="ioctl.h" /> <ClInclude Include="ioctl.h" />
<ClInclude Include="modules.h" /> <ClInclude Include="modules.h" />
<ClInclude Include="nmi.h" /> <ClInclude Include="nmi.h" />

View file

@ -45,6 +45,9 @@
<ClCompile Include="hv.c"> <ClCompile Include="hv.c">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="integrity.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="driver.h"> <ClInclude Include="driver.h">
@ -71,6 +74,9 @@
<ClInclude Include="hv.h"> <ClInclude Include="hv.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="integrity.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<MASM Include="asm.asm"> <MASM Include="asm.asm">

66
driver/integrity.c Normal file
View file

@ -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,
&region_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;
}

12
driver/integrity.h Normal file
View file

@ -0,0 +1,12 @@
#ifndef INTEGRITY_H
#define INTEGRITY_H
#include <ntifs.h>
#define POOL_TAG_INTEGRITY 'intg'
NTSTATUS CopyDriverExecutableRegions(
_In_ PIRP Irp
);
#endif

View file

@ -6,6 +6,7 @@
#include "modules.h" #include "modules.h"
#include "driver.h" #include "driver.h"
#include "callbacks.h" #include "callbacks.h"
#include "integrity.h"
#include "hv.h" #include "hv.h"
@ -123,6 +124,15 @@ NTSTATUS DeviceControl(
break; break;
case IOCTL_RETRIEVE_MODULE_EXECUTABLE_REGIONS:
status = CopyDriverExecutableRegions( Irp );
if ( !NT_SUCCESS( status ) )
DEBUG_ERROR( "Failed to retrieve executable regions" );
break;
default: default:
DEBUG_ERROR( "Invalid IOCTL passed to driver" ); DEBUG_ERROR( "Invalid IOCTL passed to driver" );
break; break;

View file

@ -13,6 +13,8 @@
#define IOCTL_HANDLE_REPORTS_IN_CALLBACK_QUEUE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2005, METHOD_BUFFERED, FILE_ANY_ACCESS) #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_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_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 typedef struct _DRIVER_INITIATION_INFORMATION
{ {

View file

@ -1,7 +1,6 @@
#include "modules.h" #include "modules.h"
#include "nmi.h" #include "nmi.h"
#include "common.h"
#define WHITELISTED_MODULE_TAG 'whte' #define WHITELISTED_MODULE_TAG 'whte'
@ -28,11 +27,10 @@ typedef struct _WHITELISTED_REGIONS
PRTL_MODULE_EXTENDED_INFO FindSystemModuleByName( PRTL_MODULE_EXTENDED_INFO FindSystemModuleByName(
_In_ LPCSTR ModuleName, _In_ LPCSTR ModuleName,
_In_ PSYSTEM_MODULES SystemModules, _In_ PSYSTEM_MODULES SystemModules
_In_ PVOID Buffer
) )
{ {
if ( !ModuleName || !SystemModules || !Buffer ) if ( !ModuleName || !SystemModules )
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
for ( INT index = 0; index < SystemModules->module_count; index++ ) for ( INT index = 0; index < SystemModules->module_count; index++ )
@ -59,7 +57,7 @@ NTSTATUS PopulateWhitelistedModuleBuffer(
{ {
LPCSTR name = WHITELISTED_MODULES[ index ]; 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; WHITELISTED_REGIONS region;
region.base = (UINT64)module->ImageBase; region.base = (UINT64)module->ImageBase;
@ -352,7 +350,8 @@ NTSTATUS ValidateDriverObjects(
PVOID whitelisted_regions_buffer = ExAllocatePool2( PVOID whitelisted_regions_buffer = ExAllocatePool2(
POOL_FLAG_NON_PAGED, POOL_FLAG_NON_PAGED,
WHITELISTED_MODULE_COUNT * MODULE_MAX_STRING_SIZE, WHITELISTED_MODULE_COUNT * MODULE_MAX_STRING_SIZE,
WHITELISTED_MODULE_TAG ); WHITELISTED_MODULE_TAG
);
if ( !whitelisted_regions_buffer ) if ( !whitelisted_regions_buffer )
goto end; goto end;

View file

@ -3,6 +3,7 @@
#include <ntifs.h> #include <ntifs.h>
#include <intrin.h> #include <intrin.h>
#include "common.h"
#define REPORT_MODULE_VALIDATION_FAILURE 60 #define REPORT_MODULE_VALIDATION_FAILURE 60
#define MODULE_VALIDATION_FAILURE_MAX_REPORT_COUNT 20 #define MODULE_VALIDATION_FAILURE_MAX_REPORT_COUNT 20
@ -60,4 +61,9 @@ NTSTATUS HandleValidateDriversIOCTL(
_In_ PIRP Irp _In_ PIRP Irp
); );
PRTL_MODULE_EXTENDED_INFO FindSystemModuleByName(
_In_ LPCSTR ModuleName,
_In_ PSYSTEM_MODULES SystemModules
);
#endif #endif

View file

@ -2,75 +2,76 @@
#include "common.h" #include "common.h"
global::Client::Client( LPTSTR PipeName ) #include <cmath>
global::Client::Client( std::shared_ptr<global::ThreadPool> ThreadPool, LPTSTR PipeName )
{ {
this->pipe_name = PipeName; this->thread_pool = ThreadPool;
this->pipe_handle = CreateFile( this->pipe = std::make_shared<global::Pipe>( PipeName );
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::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; mutex.lock();
DWORD bytes_read;
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( INT total_packets = std::ceil( Size / ( SEND_BUFFER_SIZE - total_size_of_headers ) );
this->pipe_handle, LONG remaining_bytes = Size;
Buffer,
Size,
&bytes_read,
NULL
);
if ( !status && GetLastError() != ERROR_MORE_DATA ) for ( INT count = 0; count < total_packets; count++ )
break; {
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 ) memcpy(
{ PVOID( ( UINT64 )this->send_buffer + total_size_of_headers ), Buffer,
LOG_ERROR( "ReadFile failed with status 0x%x", GetLastError() ); ( UINT64 )header_extension.packet_size - total_size_of_headers
return; );
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();
} }

View file

@ -1,32 +1,152 @@
#ifndef CLIENT_H #ifndef REPORT_H
#define CLIENT_H #define REPORT_H
#include <Windows.h> #include <Windows.h>
#define REPORT_PACKET_ID 1 #include "threadpool.h"
#define REQUEST_PATTERNS_TO_BE_SCANNED 2 #include "pipe.h"
#include <TlHelp32.h>
#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 namespace global
{ {
class Client class Client
{ {
HANDLE pipe_handle; std::shared_ptr<global::ThreadPool> thread_pool;
LPTSTR pipe_name; std::shared_ptr<global::Pipe> pipe;
std::mutex mutex;
byte report_buffer[ REPORT_BUFFER_SIZE ];
byte send_buffer[ SEND_BUFFER_SIZE ];
public: public:
Client(LPTSTR PipeName);
void WriteToPipe( PVOID Buffer, SIZE_T Size ); Client( std::shared_ptr<global::ThreadPool> ThreadPool, LPTSTR PipeName );
void ReadPipe( PVOID Buffer, SIZE_T Size );
/* lock buffer, attach header, copy report, send to service then clear buffer */
template <typename T>
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 #endif

View file

@ -4,7 +4,7 @@
#include "../common.h" #include "../common.h"
kernelmode::Driver::Driver( LPCWSTR DriverName, std::shared_ptr<global::Report> ReportInterface ) kernelmode::Driver::Driver( LPCWSTR DriverName, std::shared_ptr<global::Client> ReportInterface )
{ {
this->driver_name = DriverName; this->driver_name = DriverName;
this->report_interface = ReportInterface; this->report_interface = ReportInterface;
@ -284,6 +284,16 @@ void kernelmode::Driver::CheckHandleTableEntries()
LOG_ERROR( "CheckHandleTableEntries failed with status %x", status ); LOG_ERROR( "CheckHandleTableEntries failed with status %x", status );
} }
void kernelmode::Driver::RequestModuleExecutableRegions()
{
BOOLEAN status;
}
void kernelmode::Driver::RequestTotalModuleSize()
{
}
void kernelmode::Driver::ValidateKPRCBThreads() void kernelmode::Driver::ValidateKPRCBThreads()
{ {

View file

@ -4,7 +4,7 @@
#include <Windows.h> #include <Windows.h>
#include "../threadpool.h" #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 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) #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_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_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_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 #define MAX_HANDLE_REPORTS_PER_IRP 10
@ -22,13 +25,14 @@ namespace kernelmode
{ {
HANDLE driver_handle; HANDLE driver_handle;
LPCWSTR driver_name; LPCWSTR driver_name;
std::shared_ptr<global::Report> report_interface; std::shared_ptr<global::Client> report_interface;
void QueryReportQueue(); void QueryReportQueue();
void RequestTotalModuleSize();
public: public:
Driver(LPCWSTR DriverName, std::shared_ptr<global::Report> ReportInterface ); Driver(LPCWSTR DriverName, std::shared_ptr<global::Client> ReportInterface );
void RunNmiCallbacks(); void RunNmiCallbacks();
void VerifySystemModules(); void VerifySystemModules();
@ -38,6 +42,7 @@ namespace kernelmode
void ValidateKPRCBThreads(); void ValidateKPRCBThreads();
void CheckDriverHeartbeat(); void CheckDriverHeartbeat();
void CheckHandleTableEntries(); void CheckHandleTableEntries();
void RequestModuleExecutableRegions();
/* todo: driver integrity check */ /* todo: driver integrity check */
}; };

View file

@ -1,6 +1,6 @@
#include "kmanager.h" #include "kmanager.h"
kernelmode::KManager::KManager( LPCWSTR DriverName, std::shared_ptr<global::ThreadPool> ThreadPool, std::shared_ptr<global::Report> ReportInterface) kernelmode::KManager::KManager( LPCWSTR DriverName, std::shared_ptr<global::ThreadPool> ThreadPool, std::shared_ptr<global::Client> ReportInterface)
{ {
this->driver_interface = std::make_unique<Driver>(DriverName, ReportInterface); this->driver_interface = std::make_unique<Driver>(DriverName, ReportInterface);
this->thread_pool = ThreadPool; this->thread_pool = ThreadPool;

View file

@ -3,7 +3,7 @@
#include <windows.h> #include <windows.h>
#include "../report.h" #include "..\client.h"
#include "..\threadpool.h" #include "..\threadpool.h"
#include "driver.h" #include "driver.h"
@ -15,7 +15,7 @@ namespace kernelmode
std::unique_ptr<Driver> driver_interface; std::unique_ptr<Driver> driver_interface;
std::shared_ptr<global::ThreadPool> thread_pool; std::shared_ptr<global::ThreadPool> thread_pool;
public: public:
KManager( LPCWSTR DriverName, std::shared_ptr<global::ThreadPool> ThreadPool, std::shared_ptr<global::Report> ReportInterface); KManager( LPCWSTR DriverName, std::shared_ptr<global::ThreadPool> ThreadPool, std::shared_ptr<global::Client> ReportInterface);
void RunNmiCallbacks(); void RunNmiCallbacks();
void VerifySystemModules(); void VerifySystemModules();

View file

@ -5,7 +5,7 @@
#include "common.h" #include "common.h"
#include "threadpool.h" #include "threadpool.h"
#include "report.h" #include "client.h"
#include "../user/um/umanager.h" #include "../user/um/umanager.h"
#include "../user/km/kmanager.h" #include "../user/km/kmanager.h"
@ -23,7 +23,7 @@ DWORD WINAPI Init(HINSTANCE hinstDLL)
LPCWSTR driver_name = L"\\\\.\\DonnaAC"; LPCWSTR driver_name = L"\\\\.\\DonnaAC";
std::shared_ptr<global::ThreadPool> thread_pool = std::make_shared<global::ThreadPool>( 4 ); std::shared_ptr<global::ThreadPool> thread_pool = std::make_shared<global::ThreadPool>( 4 );
std::shared_ptr<global::Report> report_interface = std::make_shared<global::Report>( thread_pool, pipe_name ); std::shared_ptr<global::Client> report_interface = std::make_shared<global::Client>( thread_pool, pipe_name );
usermode::UManager umanager( thread_pool, report_interface ); usermode::UManager umanager( thread_pool, report_interface );
kernelmode::KManager kmanager( driver_name, thread_pool, report_interface); kernelmode::KManager kmanager( driver_name, thread_pool, report_interface);

76
user/pipe.cpp Normal file
View file

@ -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;
}
}

48
user/pipe.h Normal file
View file

@ -0,0 +1,48 @@
#ifndef PIPE_H
#define PIPE_H
#include <Windows.h>
#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

View file

@ -1,9 +0,0 @@
#include "report.h"
#include "common.h"
global::Report::Report( std::shared_ptr<global::ThreadPool> ThreadPool, LPTSTR PipeName )
{
this->thread_pool = ThreadPool;
this->client = std::make_shared<global::Client>( PipeName );
}

View file

@ -1,128 +0,0 @@
#ifndef REPORT_H
#define REPORT_H
#include <Windows.h>
#include "threadpool.h"
#include "client.h"
#include <TlHelp32.h>
#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<global::ThreadPool> thread_pool;
std::shared_ptr<global::Client> client;
std::mutex mutex;
byte buffer[ REPORT_BUFFER_SIZE ];
public:
Report( std::shared_ptr<global::ThreadPool> ThreadPool, LPTSTR PipeName );
/* lock buffer, attach header, copy report, send to service then clear buffer */
template <typename T>
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

View file

@ -4,14 +4,14 @@
#include "../um/imports.h" #include "../um/imports.h"
#include "memory.h" #include "memory.h"
#include "../report.h" #include "../client.h"
#include <ImageHlp.h> #include <ImageHlp.h>
#include <iostream> #include <iostream>
const static char MASK_BYTE = '\x00'; const static char MASK_BYTE = '\x00';
usermode::Process::Process( std::shared_ptr<global::Report> ReportInterface ) usermode::Process::Process( std::shared_ptr<global::Client> ReportInterface )
{ {
this->process_handle = GetCurrentProcess(); this->process_handle = GetCurrentProcess();
this->process_id = GetCurrentProcessId(); this->process_id = GetCurrentProcessId();

View file

@ -6,7 +6,7 @@
#include <TlHelp32.h> #include <TlHelp32.h>
#include <string> #include <string>
#include "../report.h" #include "../client.h"
#include "../threadpool.h" #include "../threadpool.h"
#include "../um/imports.h" #include "../um/imports.h"
@ -27,7 +27,7 @@ namespace usermode
std::mutex mutex; std::mutex mutex;
std::unique_ptr<Imports> function_imports; std::unique_ptr<Imports> function_imports;
std::vector<DWORD> in_memory_module_checksums; std::vector<DWORD> in_memory_module_checksums;
std::shared_ptr<global::Report> report_interface; std::shared_ptr<global::Client> report_interface;
HANDLE GetHandleToProcessGivenName( std::string ProcessName ); HANDLE GetHandleToProcessGivenName( std::string ProcessName );
std::vector<UINT64> GetProcessThreadsStartAddresses(); std::vector<UINT64> GetProcessThreadsStartAddresses();
@ -38,7 +38,7 @@ namespace usermode
public: public:
Process( std::shared_ptr<global::Report> ReportInterface ); Process( std::shared_ptr<global::Client> ReportInterface );
void ValidateProcessThreads(); void ValidateProcessThreads();
void ScanProcessMemory(); void ScanProcessMemory();

View file

@ -6,7 +6,7 @@
#include <TlHelp32.h> #include <TlHelp32.h>
usermode::UManager::UManager( std::shared_ptr<global::ThreadPool> ThreadPool, std::shared_ptr<global::Report> ReportInterface ) usermode::UManager::UManager( std::shared_ptr<global::ThreadPool> ThreadPool, std::shared_ptr<global::Client> ReportInterface )
{ {
this->thread_pool = ThreadPool; this->thread_pool = ThreadPool;
this->process = std::make_unique<Process>(ReportInterface); this->process = std::make_unique<Process>(ReportInterface);

View file

@ -8,7 +8,7 @@
#include <thread> #include <thread>
#include <vector> #include <vector>
#include "../report.h" #include "..\client.h"
#include "process.h" #include "process.h"
@ -25,7 +25,7 @@ namespace usermode
std::shared_ptr<global::ThreadPool> thread_pool; std::shared_ptr<global::ThreadPool> thread_pool;
public: public:
UManager( std::shared_ptr<global::ThreadPool> ThreadPool, std::shared_ptr<global::Report> ReportInterface ); UManager( std::shared_ptr<global::ThreadPool> ThreadPool, std::shared_ptr<global::Client> ReportInterface );
~UManager(); ~UManager();
void ValidateProcessThreads(); void ValidateProcessThreads();

View file

@ -129,7 +129,7 @@
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="client.cpp" /> <ClCompile Include="pipe.cpp" />
<ClCompile Include="km\driver.cpp" /> <ClCompile Include="km\driver.cpp" />
<ClCompile Include="km\kmanager.cpp" /> <ClCompile Include="km\kmanager.cpp" />
<ClCompile Include="main.cpp" /> <ClCompile Include="main.cpp" />
@ -137,14 +137,14 @@
<ClCompile Include="um\process.cpp" /> <ClCompile Include="um\process.cpp" />
<ClCompile Include="threadpool.cpp" /> <ClCompile Include="threadpool.cpp" />
<ClCompile Include="um\umanager.cpp" /> <ClCompile Include="um\umanager.cpp" />
<ClCompile Include="report.cpp" /> <ClCompile Include="client.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="client.h" /> <ClInclude Include="pipe.h" />
<ClInclude Include="common.h" /> <ClInclude Include="common.h" />
<ClInclude Include="km\driver.h" /> <ClInclude Include="km\driver.h" />
<ClInclude Include="km\kmanager.h" /> <ClInclude Include="km\kmanager.h" />
<ClInclude Include="report.h" /> <ClInclude Include="client.h" />
<ClInclude Include="um\imports.h" /> <ClInclude Include="um\imports.h" />
<ClInclude Include="um\process.h" /> <ClInclude Include="um\process.h" />
<ClInclude Include="threadpool.h" /> <ClInclude Include="threadpool.h" />

View file

@ -36,10 +36,10 @@
<ClCompile Include="km\driver.cpp"> <ClCompile Include="km\driver.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="report.cpp"> <ClCompile Include="client.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="client.cpp"> <ClCompile Include="pipe.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
</ItemGroup> </ItemGroup>
@ -65,10 +65,10 @@
<ClInclude Include="km\driver.h"> <ClInclude Include="km\driver.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="report.h"> <ClInclude Include="client.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="client.h"> <ClInclude Include="pipe.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
</ItemGroup> </ItemGroup>