mirror of
https://github.com/donnaskiez/ac.git
synced 2024-11-21 22:24:08 +01:00
e
This commit is contained in:
parent
63a13f0c4d
commit
4321236a0f
8 changed files with 137 additions and 11 deletions
|
@ -30,6 +30,7 @@ NTSTATUS DeviceControl(
|
|||
|
||||
case IOCTL_VALIDATE_DRIVER_OBJECTS:
|
||||
|
||||
/* KeWaitForSingleObject with infinite time must be called from IRQL <= APC_LEVEL */
|
||||
PAGED_CODE();
|
||||
|
||||
/*
|
||||
|
|
|
@ -3,6 +3,47 @@
|
|||
#include "nmi.h"
|
||||
#include "common.h"
|
||||
|
||||
NTSTATUS ValidateDriverIOCTLDispatchRegion(
|
||||
_In_ PDRIVER_OBJECT Driver,
|
||||
_In_ PSYSTEM_MODULES Modules,
|
||||
_In_ PBOOLEAN Flag
|
||||
)
|
||||
{
|
||||
NTSTATUS status;
|
||||
UINT64 current_function;
|
||||
|
||||
UINT64 base = ( UINT64 )Driver->DriverStart;
|
||||
UINT64 end = base + Driver->DriverSize;
|
||||
|
||||
*Flag = TRUE;
|
||||
|
||||
/*
|
||||
* If the dispatch routine points to a location that is not in the confines of
|
||||
* the module, report it. Basic check but every effective for catching driver
|
||||
* dispatch hooking.
|
||||
*/
|
||||
|
||||
for ( INT index = 0; index < IRP_MJ_MAXIMUM_FUNCTION + 1; index++ )
|
||||
{
|
||||
current_function = *(UINT64*)
|
||||
( ( UINT64 )Driver->MajorFunction + index * sizeof( PVOID ) );
|
||||
|
||||
DEBUG_LOG( "Current function: %llx", current_function );
|
||||
|
||||
if ( current_function == NULL )
|
||||
continue;
|
||||
|
||||
if ( current_function >= base && current_function <= end )
|
||||
{
|
||||
DEBUG_LOG( "THIS ADDRESS IS INSIDE ITS REGIUON :)" );
|
||||
continue;
|
||||
}
|
||||
|
||||
DEBUG_ERROR( "Driver with invalid IOCTL dispatch routine found" );
|
||||
*Flag = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
VOID InitDriverList(
|
||||
_In_ PINVALID_DRIVERS_HEAD ListHead
|
||||
)
|
||||
|
@ -13,7 +54,8 @@ VOID InitDriverList(
|
|||
|
||||
VOID AddDriverToList(
|
||||
_In_ PINVALID_DRIVERS_HEAD InvalidDriversHead,
|
||||
_In_ PDRIVER_OBJECT Driver
|
||||
_In_ PDRIVER_OBJECT Driver,
|
||||
_In_ INT Reason
|
||||
)
|
||||
{
|
||||
PINVALID_DRIVER new_entry = ExAllocatePool2(
|
||||
|
@ -26,6 +68,7 @@ VOID AddDriverToList(
|
|||
return;
|
||||
|
||||
new_entry->driver = Driver;
|
||||
new_entry->reason = Reason;
|
||||
new_entry->next = InvalidDriversHead->first_entry;
|
||||
InvalidDriversHead->first_entry = new_entry;
|
||||
}
|
||||
|
@ -215,6 +258,8 @@ NTSTATUS ValidateDriverObjects(
|
|||
PDRIVER_OBJECT current_driver = sub_entry->Object;
|
||||
BOOLEAN flag;
|
||||
|
||||
/* validate driver has backing module */
|
||||
|
||||
if ( !NT_SUCCESS( ValidateDriverObjectHasBackingModule(
|
||||
SystemModules,
|
||||
current_driver,
|
||||
|
@ -231,7 +276,32 @@ NTSTATUS ValidateDriverObjects(
|
|||
if ( !flag )
|
||||
{
|
||||
InvalidDriverListHead->count += 1;
|
||||
AddDriverToList( InvalidDriverListHead, current_driver );
|
||||
AddDriverToList( InvalidDriverListHead, current_driver, REASON_NO_BACKING_MODULE );
|
||||
}
|
||||
|
||||
/* validate drivers IOCTL dispatch routines */
|
||||
|
||||
if ( !NT_SUCCESS( ValidateDriverIOCTLDispatchRegion(
|
||||
current_driver,
|
||||
SystemModules,
|
||||
&flag
|
||||
) ) )
|
||||
{
|
||||
DEBUG_LOG( "Error validating drivers IOCTL routines" );
|
||||
ExReleasePushLockExclusiveEx( &directory_object->Lock, 0 );
|
||||
ObDereferenceObject( directory );
|
||||
ZwClose( handle );
|
||||
return STATUS_ABANDONED;
|
||||
}
|
||||
|
||||
if ( !flag )
|
||||
{
|
||||
InvalidDriverListHead->count += 1;
|
||||
AddDriverToList( InvalidDriverListHead, current_driver, REASON_INVALID_IOCTL_DISPATCH );
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_LOG( "All drivers have valid dispatch routines :)" );
|
||||
}
|
||||
|
||||
sub_entry = sub_entry->ChainLink;
|
||||
|
@ -310,6 +380,7 @@ NTSTATUS HandleValidateDriversIOCTL(
|
|||
|
||||
MODULE_VALIDATION_FAILURE report;
|
||||
report.report_code = REPORT_MODULE_VALIDATION_FAILURE;
|
||||
report.report_type = head->first_entry->reason;
|
||||
report.driver_base_address = head->first_entry->driver->DriverStart;
|
||||
report.driver_size = head->first_entry->driver->Size;
|
||||
|
||||
|
|
|
@ -9,6 +9,9 @@
|
|||
|
||||
#define MODULE_REPORT_DRIVER_NAME_BUFFER_SIZE 128
|
||||
|
||||
#define REASON_NO_BACKING_MODULE 1
|
||||
#define REASON_INVALID_IOCTL_DISPATCH 2
|
||||
|
||||
typedef struct _MODULE_VALIDATION_FAILURE_HEADER
|
||||
{
|
||||
INT module_count;
|
||||
|
@ -18,6 +21,7 @@ typedef struct _MODULE_VALIDATION_FAILURE_HEADER
|
|||
typedef struct _MODULE_VALIDATION_FAILURE
|
||||
{
|
||||
INT report_code;
|
||||
INT report_type;
|
||||
UINT64 driver_base_address;
|
||||
UINT64 driver_size;
|
||||
PCHAR driver_name[ 128 ];
|
||||
|
@ -27,6 +31,7 @@ typedef struct _MODULE_VALIDATION_FAILURE
|
|||
typedef struct _INVALID_DRIVER
|
||||
{
|
||||
struct _INVALID_DRIVER* next;
|
||||
INT reason;
|
||||
PDRIVER_OBJECT driver;
|
||||
|
||||
}INVALID_DRIVER, * PINVALID_DRIVER;
|
||||
|
|
|
@ -44,5 +44,28 @@ namespace service
|
|||
public int SignatureId;
|
||||
public UInt64 Address;
|
||||
}
|
||||
|
||||
public struct NMI_CALLBACK_FAILURE
|
||||
{
|
||||
public int ReportCode;
|
||||
public int WereNmisDisabled;
|
||||
public UInt64 KThreadAddress;
|
||||
public UInt64 InvalidRip;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
public unsafe struct MODULE_VALIDATION_FAILURE
|
||||
{
|
||||
[FieldOffset(0)]
|
||||
public int ReportCode;
|
||||
[FieldOffset(0)]
|
||||
public int ReportType;
|
||||
[FieldOffset(0)]
|
||||
public UInt64 DriverBaseAddress;
|
||||
[FieldOffset(0)]
|
||||
public UInt64 DriverSize;
|
||||
[FieldOffset(0)]
|
||||
public fixed char ModuleName[128];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,10 +16,12 @@ namespace service
|
|||
private byte[] _headerBuf;
|
||||
private int _headerBufSize;
|
||||
|
||||
private const int REPORT_CODE_MODULE_VERIFICATION = 10;
|
||||
private const int REPORT_CODE_START_ADDRESS_VERIFICATION = 20;
|
||||
private const int REPORT_PROCESS_MODULE_FAILURE = 10;
|
||||
private const int REPORT_PROCESS_THREAD_START_ADDRESS_FAILURE = 20;
|
||||
private const int REPORT_PAGE_PROTECTION_VERIFICATION = 30;
|
||||
private const int REPORT_PATTERN_SCAN_FAILURE = 40;
|
||||
private const int REPORT_NMI_CALLBACK_FAILURE = 50;
|
||||
private const int REPORT_KERNEL_MODULE_FAILURE = 60;
|
||||
|
||||
private const int MESSAGE_TYPE_REPORT = 1;
|
||||
private const int MESSAGE_TYPE_REQUEST = 2;
|
||||
|
@ -94,7 +96,7 @@ namespace service
|
|||
|
||||
switch (reportCode)
|
||||
{
|
||||
case REPORT_CODE_MODULE_VERIFICATION:
|
||||
case REPORT_PROCESS_MODULE_FAILURE:
|
||||
|
||||
var checksumFailurePacket = BytesToStructure<MODULE_VERIFICATION_CHECKSUM_FAILURE>();
|
||||
|
||||
|
@ -108,7 +110,7 @@ namespace service
|
|||
|
||||
goto end;
|
||||
|
||||
case REPORT_CODE_START_ADDRESS_VERIFICATION:
|
||||
case REPORT_PROCESS_THREAD_START_ADDRESS_FAILURE:
|
||||
|
||||
var startAddressFailurePacket = BytesToStructure<PROCESS_THREAD_START_FAILURE>();
|
||||
|
||||
|
@ -143,6 +145,29 @@ namespace service
|
|||
|
||||
goto end;
|
||||
|
||||
case REPORT_NMI_CALLBACK_FAILURE:
|
||||
|
||||
var nmiCallbackFailure = BytesToStructure<NMI_CALLBACK_FAILURE>();
|
||||
|
||||
_logger.LogInformation("Report code: {0}, WereNmisDisabled: {1}, KThreadAddress: {2}, InvalidRip: {3}",
|
||||
nmiCallbackFailure.ReportCode,
|
||||
nmiCallbackFailure.WereNmisDisabled,
|
||||
nmiCallbackFailure.KThreadAddress,
|
||||
nmiCallbackFailure.InvalidRip);
|
||||
|
||||
goto end;
|
||||
|
||||
case REPORT_KERNEL_MODULE_FAILURE:
|
||||
|
||||
var kernelModuleFailure = BytesToStructure<MODULE_VALIDATION_FAILURE>();
|
||||
|
||||
_logger.LogInformation("Report code: {0}, DriverBaseAddress: {1}, DriverSize: {2}",
|
||||
kernelModuleFailure.ReportCode,
|
||||
kernelModuleFailure.DriverBaseAddress,
|
||||
kernelModuleFailure.DriverSize);
|
||||
|
||||
goto end;
|
||||
|
||||
default:
|
||||
_logger.LogError("Invalid report code received");
|
||||
goto end;
|
||||
|
|
|
@ -53,6 +53,11 @@ void kernelmode::Driver::RunNmiCallbacks()
|
|||
this->report_interface->ReportViolation( &report );
|
||||
}
|
||||
|
||||
/*
|
||||
* 1. Checks that every device object has a system module to back it
|
||||
* 2. Checks the IOCTL dispatch routines to ensure they lie within the module
|
||||
*/
|
||||
|
||||
void kernelmode::Driver::VerifySystemModules()
|
||||
{
|
||||
BOOLEAN status;
|
||||
|
@ -154,10 +159,6 @@ void kernelmode::Driver::CheckForHypervisor()
|
|||
{
|
||||
}
|
||||
|
||||
void kernelmode::Driver::VerifySystemModulesIOCTLDispatchHandler()
|
||||
{
|
||||
}
|
||||
|
||||
void kernelmode::Driver::CheckDriverHeartbeat()
|
||||
{
|
||||
}
|
||||
|
|
|
@ -28,7 +28,6 @@ namespace kernelmode
|
|||
void DisableProcessLoadNotifyCallbacks();
|
||||
void ValidateKPRCBThreads();
|
||||
void CheckForHypervisor();
|
||||
void VerifySystemModulesIOCTLDispatchHandler();
|
||||
void CheckDriverHeartbeat();
|
||||
/* todo: driver integrity check */
|
||||
};
|
||||
|
|
|
@ -100,6 +100,7 @@ namespace global
|
|||
struct MODULE_VALIDATION_FAILURE
|
||||
{
|
||||
INT report_code;
|
||||
INT report_type;
|
||||
UINT64 driver_base_address;
|
||||
UINT64 driver_size;
|
||||
BYTE driver_name[ 128 ];
|
||||
|
|
Loading…
Reference in a new issue