mirror of
https://github.com/donnaskiez/ac.git
synced 2024-11-21 22:24:08 +01:00
fix bug
This commit is contained in:
parent
4797892900
commit
a043150844
10 changed files with 138 additions and 38 deletions
|
@ -133,10 +133,11 @@ typedef struct _DRIVER_CONFIG
|
|||
typedef struct _PROCESS_CONFIG
|
||||
{
|
||||
BOOLEAN initialised;
|
||||
LONG um_handle;
|
||||
LONG km_handle;
|
||||
ULONG um_handle;
|
||||
ULONG km_handle;
|
||||
PEPROCESS process;
|
||||
OB_CALLBACKS_CONFIG ob_cb_config;
|
||||
UINT16 cookie;
|
||||
KGUARDED_MUTEX lock;
|
||||
|
||||
}PROCESS_CONFIG, * PPROCESS_CONFIG;
|
||||
|
@ -144,6 +145,23 @@ typedef struct _PROCESS_CONFIG
|
|||
DRIVER_CONFIG driver_config = { 0 };
|
||||
PROCESS_CONFIG process_config = { 0 };
|
||||
|
||||
/*
|
||||
* ioctl_flag consists of the first 16 bits of the Function part of the CTL code
|
||||
* cookie_value consists of a static 16 bit value generated by the user mode app on startup
|
||||
* which is then passed to the driver and stored.
|
||||
*/
|
||||
typedef union _SECURITY_COOKIE
|
||||
{
|
||||
struct
|
||||
{
|
||||
UINT32 ioctl_flag : 16;
|
||||
UINT32 cookie_value : 16;
|
||||
}bits;
|
||||
|
||||
UINT32 flags;
|
||||
|
||||
}SECURITY_COOKIE, *PSECURITY_COOKIE;
|
||||
|
||||
#define POOL_TAG_CONFIG 'conf'
|
||||
|
||||
/*
|
||||
|
@ -761,6 +779,19 @@ end:
|
|||
return status;
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(APC_LEVEL)
|
||||
_Acquires_lock_(_Lock_kind_mutex_)
|
||||
_Releases_lock_(_Lock_kind_mutex_)
|
||||
VOID
|
||||
ImageLoadSetProcessId(
|
||||
_In_ HANDLE ProcessId
|
||||
)
|
||||
{
|
||||
KeAcquireGuardedMutex(&process_config.lock);
|
||||
process_config.km_handle = (ULONG)ProcessId;
|
||||
KeReleaseGuardedMutex(&process_config.lock);
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(APC_LEVEL)
|
||||
_Acquires_lock_(_Lock_kind_mutex_)
|
||||
_Releases_lock_(_Lock_kind_mutex_)
|
||||
|
@ -785,18 +816,34 @@ ProcLoadInitialiseProcessConfig(
|
|||
|
||||
information = (PDRIVER_INITIATION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
|
||||
|
||||
status = PsLookupProcessByProcessId(information->protected_process_id, &eprocess);
|
||||
KeAcquireGuardedMutex(&process_config.lock);
|
||||
|
||||
process_config.um_handle = information->protected_process_id;
|
||||
|
||||
/*
|
||||
* What if we pass an invalid handle here? not good.
|
||||
*/
|
||||
status = PsLookupProcessByProcessId(process_config.um_handle, &eprocess);
|
||||
|
||||
if (!NT_SUCCESS(status))
|
||||
return status;
|
||||
{
|
||||
status = STATUS_INVALID_PARAMETER;
|
||||
goto end;
|
||||
}
|
||||
|
||||
KeAcquireGuardedMutex(&process_config.lock);
|
||||
process_config.km_handle = PsGetProcessId(eprocess);
|
||||
|
||||
if (!process_config.km_handle)
|
||||
{
|
||||
status = STATUS_INVALID_PARAMETER;
|
||||
goto end;
|
||||
}
|
||||
|
||||
process_config.process = eprocess;
|
||||
process_config.um_handle = information->protected_process_id;
|
||||
process_config.km_handle = PsGetProcessId(eprocess);
|
||||
process_config.initialised = TRUE;
|
||||
|
||||
end:
|
||||
KeReleaseGuardedMutex(&process_config.lock);
|
||||
|
||||
return status;
|
||||
|
@ -1017,6 +1064,18 @@ DrvLoadEnableNotifyRoutines()
|
|||
return status;
|
||||
}
|
||||
|
||||
//status = PsSetLoadImageNotifyRoutine(ImageLoadNotifyRoutine);
|
||||
|
||||
//if (!NT_SUCCESS(status))
|
||||
//{
|
||||
// DEBUG_ERROR("PsSetCreateProcessNotifyRoutine failed with status %x", status);
|
||||
// PsRemoveCreateThreadNotifyRoutine(ThreadCreateNotifyRoutine);
|
||||
// PsSetCreateProcessNotifyRoutine(ProcessCreateNotifyRoutine, TRUE);
|
||||
// DrvUnloadFreeThreadList();
|
||||
// DrvUnloadFreeProcessList();
|
||||
// return status;
|
||||
//}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
|
|
@ -157,6 +157,14 @@ GetCallbackConfigStructure(
|
|||
_Out_ POB_CALLBACKS_CONFIG* CallbackConfiguration
|
||||
);
|
||||
|
||||
_IRQL_requires_max_(APC_LEVEL)
|
||||
_Acquires_lock_(_Lock_kind_mutex_)
|
||||
_Releases_lock_(_Lock_kind_mutex_)
|
||||
VOID
|
||||
ImageLoadSetProcessId(
|
||||
_In_ HANDLE ProcessId
|
||||
);
|
||||
|
||||
_IRQL_requires_max_(APC_LEVEL)
|
||||
_Acquires_lock_(_Lock_kind_mutex_)
|
||||
_Releases_lock_(_Lock_kind_mutex_)
|
||||
|
|
|
@ -1080,6 +1080,9 @@ end:
|
|||
* StoreModuleExecutableRegionsInBuffer() just as we did before.
|
||||
* 5. With the 2 buffers that contain both images executable regions, we hash them and compare
|
||||
* for anomalies.
|
||||
*
|
||||
* note: Its important to realise that since these are user mode modules, they are often hooked
|
||||
* by various legitimate programs - such as discord, nvidia etc. So this needs to be rethinked.
|
||||
*/
|
||||
NTSTATUS
|
||||
ValidateProcessLoadedModule(
|
||||
|
@ -1088,23 +1091,23 @@ ValidateProcessLoadedModule(
|
|||
{
|
||||
PAGED_CODE();
|
||||
|
||||
NTSTATUS status;
|
||||
BOOLEAN bstatus;
|
||||
PROCESS_MODULE_VALIDATION_RESULT validation_result;
|
||||
PPROCESS_MODULE_INFORMATION module_info;
|
||||
PKPROCESS process;
|
||||
KAPC_STATE apc_state;
|
||||
NTSTATUS status = STATUS_ABANDONED;
|
||||
BOOLEAN bstatus = FALSE;
|
||||
PROCESS_MODULE_VALIDATION_RESULT validation_result = { 0 };
|
||||
PPROCESS_MODULE_INFORMATION module_info = NULL;
|
||||
PKPROCESS process = NULL;
|
||||
KAPC_STATE apc_state = { 0 };
|
||||
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;
|
||||
ULONG in_memory_hash_size = 0;
|
||||
ULONG disk_hash_size = 0;
|
||||
SIZE_T bytes_written = 0;
|
||||
UNICODE_STRING module_path = { 0 };
|
||||
HANDLE section_handle = NULL;
|
||||
PVOID section = NULL;
|
||||
ULONG section_size = NULL;
|
||||
ULONG section_size = 0;
|
||||
|
||||
status = ValidateIrpInputBuffer(Irp, sizeof(PROCESS_MODULE_INFORMATION));
|
||||
|
||||
|
@ -1222,7 +1225,7 @@ ValidateProcessLoadedModule(
|
|||
);
|
||||
|
||||
end:
|
||||
|
||||
|
||||
if (section_handle != NULL)
|
||||
ZwClose(section_handle);
|
||||
|
||||
|
@ -1269,6 +1272,10 @@ GetHardDiskDriveSerialNumber(
|
|||
|
||||
RtlInitUnicodeString(&physical_drive_path, L"\\DosDevices\\PhysicalDrive0");
|
||||
|
||||
/*
|
||||
* No need to use the flag OBJ_FORCE_ACCESS_CHECK since we arent passing a handle given
|
||||
* to us from usermode.
|
||||
*/
|
||||
InitializeObjectAttributes(
|
||||
&attributes,
|
||||
&physical_drive_path,
|
||||
|
@ -1945,6 +1952,16 @@ ValidateSystemModules()
|
|||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* After some further research it appears that performing integrity checks the same way as validating
|
||||
* other modules is not as straight forward as there are many (thousands) of hooks that take place in
|
||||
* a legitmate ntoskrnl.exe image.
|
||||
*
|
||||
* Initial ideas are to maybe only validate the text sections of key functions such as MmCopyMemory,
|
||||
* though this is quite manual and the potential to miss functions could be common.
|
||||
*
|
||||
* Need to do some more research & testing in this department.
|
||||
*/
|
||||
NTSTATUS
|
||||
ValidateNtoskrnl()
|
||||
{
|
||||
|
|
|
@ -75,8 +75,8 @@ DispatchApcOperation(
|
|||
}
|
||||
|
||||
/*
|
||||
* Obviously, its important we check that the output buffer size for each IRP is big enough
|
||||
* to hold whatever we are passing back to usermode.
|
||||
* Obviously, its important we check that the input and output buffer sizes for each IRP is big
|
||||
* enough to hold the incoming and outgoing information.
|
||||
*
|
||||
* Another important thing to note is that the windows IO manager will only zero out the size
|
||||
* of the input buffer. Given that we use METHOD_BUFFERED for all communication, the input
|
||||
|
@ -151,7 +151,7 @@ DeviceControl(
|
|||
|
||||
NTSTATUS status = STATUS_SUCCESS;
|
||||
PIO_STACK_LOCATION stack_location = IoGetCurrentIrpStackLocation(Irp);
|
||||
HANDLE handle;
|
||||
HANDLE handle = NULL;
|
||||
PKTHREAD thread = NULL;
|
||||
BOOLEAN security_flag = FALSE;
|
||||
|
||||
|
@ -503,6 +503,8 @@ DeviceCreate(
|
|||
|
||||
DEBUG_LOG("Handle opened to DonnaAC");
|
||||
|
||||
|
||||
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return Irp->IoStatus.Status;
|
||||
}
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
typedef struct _DRIVER_INITIATION_INFORMATION
|
||||
{
|
||||
LONG protected_process_id;
|
||||
ULONG protected_process_id;
|
||||
|
||||
} DRIVER_INITIATION_INFORMATION, * PDRIVER_INITIATION_INFORMATION;
|
||||
|
||||
|
|
|
@ -461,6 +461,9 @@ ValidateDriverObjectHasBackingModule(
|
|||
PRTL_MODULE_EXTENDED_INFO system_module = (PRTL_MODULE_EXTENDED_INFO)(
|
||||
(uintptr_t)ModuleInformation->address + i * sizeof(RTL_MODULE_EXTENDED_INFO));
|
||||
|
||||
if (system_module->ImageSize == 0 || system_module->ImageBase == 0)
|
||||
return STATUS_INVALID_MEMBER;
|
||||
|
||||
if (system_module->ImageBase == DriverObject->DriverStart)
|
||||
{
|
||||
*Result = TRUE;
|
||||
|
@ -477,7 +480,7 @@ ValidateDriverObjectHasBackingModule(
|
|||
//https://imphash.medium.com/windows-process-internals-a-few-concepts-to-know-before-jumping-on-memory-forensics-part-3-4a0e195d947b
|
||||
NTSTATUS
|
||||
GetSystemModuleInformation(
|
||||
_Inout_ PSYSTEM_MODULES ModuleInformation
|
||||
_Out_ PSYSTEM_MODULES ModuleInformation
|
||||
)
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
@ -511,7 +514,7 @@ GetSystemModuleInformation(
|
|||
if (!driver_information)
|
||||
{
|
||||
DEBUG_ERROR("Failed to allocate pool LOL");
|
||||
return STATUS_ABANDONED;
|
||||
return STATUS_MEMORY_NOT_ALLOCATED;
|
||||
}
|
||||
|
||||
/* Query the modules again this time passing a pointer to the allocated buffer */
|
||||
|
@ -635,8 +638,8 @@ ValidateDriverObjects(
|
|||
|
||||
while (sub_entry)
|
||||
{
|
||||
BOOLEAN flag = FALSE;
|
||||
PDRIVER_OBJECT current_driver = sub_entry->Object;
|
||||
BOOLEAN flag;
|
||||
|
||||
/* validate driver has backing module */
|
||||
|
||||
|
@ -752,7 +755,7 @@ HandleValidateDriversIOCTL(
|
|||
goto end;
|
||||
}
|
||||
|
||||
MODULE_VALIDATION_FAILURE_HEADER header;
|
||||
MODULE_VALIDATION_FAILURE_HEADER header = { 0 };
|
||||
|
||||
header.module_count = head->count >= MODULE_VALIDATION_FAILURE_MAX_REPORT_COUNT
|
||||
? MODULE_VALIDATION_FAILURE_MAX_REPORT_COUNT
|
||||
|
@ -964,7 +967,7 @@ AnalyseNmiData(
|
|||
* single report.
|
||||
*/
|
||||
|
||||
NMI_CALLBACK_FAILURE report;
|
||||
NMI_CALLBACK_FAILURE report = { 0 };
|
||||
report.report_code = REPORT_NMI_CALLBACK_FAILURE;
|
||||
report.kthread_address = thread_data->kthread_address;
|
||||
report.invalid_rip = stack_frame;
|
||||
|
@ -1310,14 +1313,14 @@ ApcNormalRoutine(
|
|||
VOID
|
||||
FlipKThreadMiscFlagsFlag(
|
||||
_In_ PKTHREAD Thread,
|
||||
_In_ LONG FlagIndex,
|
||||
_In_ ULONG FlagIndex,
|
||||
_In_ BOOLEAN NewValue
|
||||
)
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
||||
PLONG misc_flags = (PLONG)((UINT64)Thread + KTHREAD_MISC_FLAGS_OFFSET);
|
||||
LONG mask = 1U << FlagIndex;
|
||||
ULONG mask = 1ul << FlagIndex;
|
||||
|
||||
if (NewValue)
|
||||
*misc_flags |= mask;
|
||||
|
@ -1348,7 +1351,11 @@ ValidateThreadViaKernelApcCallback(
|
|||
PAPC_STACKWALK_CONTEXT context = (PAPC_STACKWALK_CONTEXT)Context;
|
||||
LPCSTR process_name = PsGetProcessImageFileName(ThreadListEntry->owning_process);
|
||||
|
||||
/* we dont want to schedule an apc to threads owned by the kernel */
|
||||
/*
|
||||
* we dont want to schedule an apc to threads owned by the kernel
|
||||
*
|
||||
* Actually we do... todo: fix this.
|
||||
*/
|
||||
if (ThreadListEntry->owning_process == PsInitialSystemProcess || !Context)
|
||||
return;
|
||||
|
||||
|
@ -1546,7 +1553,7 @@ LaunchInterProcessInterrupt(
|
|||
{
|
||||
PAGED_CODE();
|
||||
|
||||
NTSTATUS status;
|
||||
NTSTATUS status = STATUS_SUCCESS;
|
||||
SYSTEM_MODULES system_modules = { 0 };
|
||||
NMI_CONTEXT ipi_context = { 0 };
|
||||
PVOID callback_handle;
|
||||
|
@ -1564,13 +1571,20 @@ LaunchInterProcessInterrupt(
|
|||
ExAllocatePool2(POOL_FLAG_NON_PAGED, ipi_context.core_count * STACK_FRAME_POOL_SIZE, STACK_FRAMES_POOL);
|
||||
|
||||
if (!ipi_context.stack_frames)
|
||||
{
|
||||
status = STATUS_MEMORY_NOT_ALLOCATED;
|
||||
goto end;
|
||||
}
|
||||
|
||||
|
||||
ipi_context.thread_data_pool =
|
||||
ExAllocatePool2(POOL_FLAG_NON_PAGED, ipi_context.core_count * sizeof(NMI_CALLBACK_DATA), THREAD_DATA_POOL);
|
||||
|
||||
if (!ipi_context.thread_data_pool)
|
||||
{
|
||||
status = STATUS_MEMORY_NOT_ALLOCATED;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/*
|
||||
* We query the system modules each time since they can potentially
|
||||
|
|
|
@ -71,7 +71,7 @@ typedef struct _APC_STACKWALK_CONTEXT
|
|||
|
||||
NTSTATUS
|
||||
GetSystemModuleInformation(
|
||||
_Inout_ PSYSTEM_MODULES ModuleInformation
|
||||
_Out_ PSYSTEM_MODULES ModuleInformation
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
|
@ -113,7 +113,7 @@ IsInstructionPointerInInvalidRegion(
|
|||
BOOLEAN
|
||||
FlipKThreadMiscFlagsFlag(
|
||||
_In_ PKTHREAD Thread,
|
||||
_In_ LONG FlagIndex,
|
||||
_In_ ULONG FlagIndex,
|
||||
_In_ BOOLEAN NewValue
|
||||
);
|
||||
|
||||
|
|
|
@ -180,11 +180,11 @@ HandlePeriodicGlobalReportQueueQuery(
|
|||
INT count = 0;
|
||||
NTSTATUS status = STATUS_SUCCESS;
|
||||
PVOID report = NULL;
|
||||
SIZE_T total_size = NULL;
|
||||
SIZE_T total_size = 0;
|
||||
PVOID report_buffer = NULL;
|
||||
ULONG report_buffer_size = 0;
|
||||
PREPORT_HEADER report_header;
|
||||
GLOBAL_REPORT_QUEUE_HEADER header;
|
||||
PREPORT_HEADER report_header = NULL;
|
||||
GLOBAL_REPORT_QUEUE_HEADER header = { 0 };
|
||||
|
||||
KeAcquireGuardedMutex(&report_queue_config.lock);
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ std::wstring cstr_to_wstr(std::string cstr)
|
|||
return std::wstring(cstr.begin(), cstr.end());
|
||||
}
|
||||
|
||||
DWORD get_proc_id_by_name(std::string& process_name)
|
||||
DWORD get_proc_id_by_name(const std::string& process_name)
|
||||
{
|
||||
PROCESSENTRY32 entry = { 0 };
|
||||
entry.dwSize = sizeof(PROCESSENTRY32);
|
||||
|
|
|
@ -87,7 +87,7 @@ namespace kernelmode
|
|||
|
||||
struct DRIVER_INITIATION_INFORMATION
|
||||
{
|
||||
LONG protected_process_id;
|
||||
ULONG protected_process_id;
|
||||
};
|
||||
|
||||
struct HYPERVISOR_DETECTION_REPORT
|
||||
|
|
Loading…
Reference in a new issue