diff --git a/capemon.vcxproj b/capemon.vcxproj
index e01a1f7..f98b0c7 100644
--- a/capemon.vcxproj
+++ b/capemon.vcxproj
@@ -477,12 +477,12 @@
+ true
true
- false
+ true
true
- false
diff --git a/hook_misc.c b/hook_misc.c
index e532d1c..5286d37 100644
--- a/hook_misc.c
+++ b/hook_misc.c
@@ -36,6 +36,7 @@ along with this program. If not, see .
extern char *our_process_name;
extern void ProcessMessage(DWORD ProcessId, DWORD ThreadId);
extern const char* GetLanguageName(LANGID langID);
+extern NTSTATUS pNtQueryObject(HANDLE Handle, OBJECT_INFORMATION_CLASS ObjectInformationClass, PVOID ObjectInformation, ULONG ObjectInformationLength, PULONG ReturnLength);
extern BOOL TraceRunning;
@@ -44,6 +45,11 @@ extern BOOL Trace(struct _EXCEPTION_POINTERS* ExceptionInfo);
LPTOP_LEVEL_EXCEPTION_FILTER TopLevelExceptionFilter;
BOOL PlugXConfigDumped, CompressedPE;
DWORD ExportAddress;
+struct BlockInputThreadInstance {
+ BOOL CurrentlyBlockedInput;
+ DWORD BlockInputThreadID;
+};
+static struct BlockInputThreadInstance BlockInputInstances[256]; //Should be enough for most situations
HOOKDEF(HHOOK, WINAPI, SetWindowsHookExA,
__in int idHook,
@@ -424,13 +430,37 @@ HOOKDEF(NTSTATUS, WINAPI, NtClose,
LOQ_ntstatus("system", "ps", "Handle", Handle, "Alert", "Tried to close Cuckoo's log handle");
return ret;
}
- ret = Old_NtClose(Handle);
+ //https://anti-debug.checkpoint.com/techniques/object-handles.html
+ ULONG Size = 0;
+ ULONG Size2 = 0;
+ NTSTATUS Status = pNtQueryObject(Handle, 0, &Size, sizeof(Size), &Size);
+ void* Buff = (void*)calloc(1, Size);
+ BOOLEAN valid_handle;
+ if (!Buff)
+ valid_handle = NT_SUCCESS(pNtQueryObject(Handle, 0, Buff, Size, &Size2));
+ else
+ valid_handle = FALSE;
+ if (!g_config.no_stealth && valid_handle)
+ {
+ __try
+ {
+ Old_NtClose(Handle);
+ ret = STATUS_SUCCESS;
+ }
+ __except(EXCEPTION_EXECUTE_HANDLER)
+ {
+ ret = STATUS_SUCCESS;
+ }
+ }
+ else
+ ret = Old_NtClose(Handle);
LOQ_ntstatus("system", "p", "Handle", Handle);
if(NT_SUCCESS(ret)) {
remove_file_from_log_tracking(Handle);
DumpSectionViewsForHandle(Handle);
file_close(Handle);
}
+ free(Buff);
return ret;
}
@@ -796,6 +826,22 @@ HOOKDEF(NTSTATUS, WINAPI, NtQueryInformationProcess,
) {
NTSTATUS ret = Old_NtQueryInformationProcess(ProcessHandle, ProcessInformationClass, ProcessInformation, ProcessInformationLength, ReturnLength);
LOQ_ntstatus("process", "ib", "ProcessInformationClass", ProcessInformationClass, "ProcessInformation", ProcessInformationLength, ProcessInformation);
+ //https://anti-debug.checkpoint.com/techniques/debug-flags.html#using-win32-api-checkremotedebuggerpresent
+ if (!g_config.no_stealth && ProcessInformationClass == ProcessDebugPort)
+ {
+ if (ProcessInformationLength >= sizeof(HANDLE))
+ *(HANDLE*)ProcessInformation = 0;
+ }
+ else if (!g_config.no_stealth && ProcessInformationClass == ProcessDebugFlags)
+ {
+ if (ProcessInformationLength >= sizeof(ULONG))
+ *(ULONG*)ProcessInformation = 1;
+ }
+ else if (!g_config.no_stealth && ProcessInformationClass == ProcessDebugObjectHandle)
+ {
+ if (ProcessInformationLength >= sizeof(HANDLE))
+ *(HANDLE*)ProcessInformation = 0;
+ }
return ret;
}
@@ -832,7 +878,12 @@ HOOKDEF(NTSTATUS, WINAPI, NtQuerySystemInformation,
PLARGE_INTEGER perf_info = (PLARGE_INTEGER)SystemInformation;
perf_info->HighPart |= 2;
}
-
+ //https://anti-debug.checkpoint.com/techniques/debug-flags.html#using-win32-api-checkremotedebuggerpresent
+ if (!g_config.no_stealth && SystemInformationClass == SystemKernelDebuggerInformation)
+ {
+ PSYSTEM_KERNEL_DEBUGGER_INFORMATION perf_info = (PSYSTEM_KERNEL_DEBUGGER_INFORMATION)SystemInformation;
+ perf_info->DebuggerNotPresent = 1;
+ }
return ret;
}
@@ -1961,3 +2012,89 @@ HOOKDEF(ULONG, __fastcall, vDbgPrintExWithPrefixInternal,
return Old_vDbgPrintExWithPrefixInternal(Prefix, ComponentId, Level, Format, arglist, HandleBreakpoint);
}
+
+HOOKDEF(BOOL, WINAPI, NtDebugActiveProcess,
+ _In_ HANDLE ProcessHandle,
+ _In_ HANDLE DebugObjectHandle
+){
+ DWORD pid = pid_from_process_handle(ProcessHandle);
+ DWORD debug_pid = pid_from_process_handle(DebugObjectHandle);
+ BOOL ret = Old_NtDebugActiveProcess(ProcessHandle, DebugObjectHandle);
+ LOQ_bool("misc", "ll", "ProcessID", pid, "DebugObject", debug_pid);
+ //https://anti-debug.checkpoint.com/techniques/interactive.html
+ if (!g_config.no_stealth && is_protected_pid(pid) && g_config.debugger)
+ ret = TRUE;
+ return ret;
+}
+
+HOOKDEF(NTSTATUS, WINAPI, DbgUiDebugActiveProcess,
+ _In_ HANDLE ProcessHandle
+){
+ DWORD pid = pid_from_process_handle(ProcessHandle);
+ NTSTATUS ret = Old_DbgUiDebugActiveProcess(ProcessHandle);
+ LOQ_ntstatus("misc", "l", "ProcessID", pid);
+ //https://anti-debug.checkpoint.com/techniques/interactive.html
+ if (!g_config.no_stealth && is_protected_pid(pid) && g_config.debugger)
+ return TRUE;
+ return ret;
+}
+
+HOOKDEF(NTSTATUS, WINAPI, GenerateConsoleCtrlEvent,
+ _In_ DWORD dwCtrlEvent,
+ _In_ DWORD dwProcessGroupId
+){
+ //https://anti-debug.checkpoint.com/techniques/interactive.html
+ //Assuming the ProcessGroupID is the pid in this case make sense because it would be a case where it's targeted specifically ?
+ NTSTATUS ret = Old_GenerateConsoleCtrlEvent(dwCtrlEvent,dwProcessGroupId);
+ LOQ_ntstatus("misc", "ll", "CtrlEvent", dwCtrlEvent, "ProcessGroupID", dwProcessGroupId);
+ if (!g_config.no_stealth && g_config.debugger && is_protected_pid(dwProcessGroupId)) {
+ ret = TRUE;
+ }
+ return ret;
+}
+
+//https://anti-debug.checkpoint.com/techniques/interactive.html
+HOOKDEF(BOOL, WINAPI, BlockInput,
+ _In_ BOOL fBlockIt
+){
+ BOOL ret;
+ if(!g_config.no_stealth)
+ {
+
+ int length = sizeof(BlockInputInstances) / sizeof(struct BlockInputThreadInstance);
+ DWORD ThreadId = GetCurrentThreadId();
+ BOOL found = FALSE;
+ int index = 0;
+ BOOL CurrentState = FALSE;
+ //Don't run the real deal since it's an effective way to block a debugger and a way to detect hooking.
+ for(int i=0;i5*sizeof(void *))
+ {
+ LOQ_bool("windows","p", "lpEnumFunc", lpEnumFunc);
+ }
+ else
LOQ_bool("windows", "");
return ret;
}
diff --git a/hooks.c b/hooks.c
index 2f32106..73676c4 100644
--- a/hooks.c
+++ b/hooks.c
@@ -417,6 +417,10 @@ hook_t full_hooks[] = {
HOOK(oleaut32, VarBstrCat),
HOOK_NOTAIL(usp10, ScriptIsComplex, 3),
HOOK_NOTAIL(inseng,DownloadFile,3),
+ HOOK(ntdll, DbgUiDebugActiveProcess),
+ HOOK(ntdll, NtDebugActiveProcess),
+ HOOK(Kernel32, GenerateConsoleCtrlEvent),
+ HOOK(User32, BlockInput),
#ifndef _WIN64
HOOK(ntdll, RtlDosPathNameToNtPathName_U),
HOOK(ntdll, NtQueryLicenseValue),
@@ -1333,6 +1337,10 @@ hook_t office_hooks[] = {
HOOK(oleaut32, VarBstrCat),
HOOK_NOTAIL(usp10, ScriptIsComplex, 3),
HOOK_NOTAIL(inseng,DownloadFile,3),
+ HOOK(ntdll, DbgUiDebugActiveProcess),
+ HOOK(ntdll, NtDebugActiveProcess),
+ HOOK(Kernel32, GenerateConsoleCtrlEvent),
+ HOOK(User32, BlockInput),
#ifndef _WIN64
HOOK(ntdll, RtlDosPathNameToNtPathName_U),
HOOK(ntdll, NtQueryLicenseValue),
diff --git a/hooks.h b/hooks.h
index 58502ac..5c8bd6a 100644
--- a/hooks.h
+++ b/hooks.h
@@ -3737,4 +3737,22 @@ HOOKDEF(ULONG, __fastcall, vDbgPrintExWithPrefixInternal,
__in BOOLEAN HandleBreakpoint
);
+HOOKDEF(BOOL, WINAPI, NtDebugActiveProcess,
+ _In_ HANDLE ProcessHandle,
+ _In_ HANDLE DebugObjectHandle
+);
+
+HOOKDEF(NTSTATUS, WINAPI, DbgUiDebugActiveProcess,
+ _In_ HANDLE ProcessHandle
+);
+
+HOOKDEF(NTSTATUS, WINAPI, GenerateConsoleCtrlEvent,
+ _In_ DWORD dwCtrlEvent,
+ _In_ DWORD dwProcessGroupId
+);
+
+HOOKDEF(BOOL, WINAPI, BlockInput,
+ _In_ BOOL fBlockIt
+);
+
#include "hook_vbscript.h"
diff --git a/misc.c b/misc.c
index e224e72..806ce32 100644
--- a/misc.c
+++ b/misc.c
@@ -37,7 +37,7 @@ static _NtQueryInformationProcess pNtQueryInformationProcess;
static _NtQueryInformationThread pNtQueryInformationThread;
static _RtlGenRandom pRtlGenRandom;
static _NtQueryAttributesFile pNtQueryAttributesFile;
-static _NtQueryObject pNtQueryObject;
+_NtQueryObject pNtQueryObject;
static _NtQueryKey pNtQueryKey;
static _NtDelayExecution pNtDelayExecution;
static _NtQuerySystemInformation pNtQuerySystemInformation;
diff --git a/ntapi.h b/ntapi.h
index 69eed2a..81816ba 100644
--- a/ntapi.h
+++ b/ntapi.h
@@ -271,6 +271,11 @@ typedef struct _SYSTEM_PROCESS_INFORMATION {
SYSTEM_THREAD Threads[0];
} SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION;
+typedef struct _SYSTEM_KERNEL_DEBUGGER_INFORMATION {
+ BOOLEAN DebuggerEnabled;
+ BOOLEAN DebuggerNotPresent;
+} SYSTEM_KERNEL_DEBUGGER_INFORMATION, *PSYSTEM_KERNEL_DEBUGGER_INFORMATION;
+
typedef struct _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION {
LARGE_INTEGER IdleTime;
LARGE_INTEGER KernelTime;
@@ -312,7 +317,8 @@ typedef enum _SYSTEM_INFORMATION_CLASS {
SystemVdmBopInformation,
SystemFileCacheInformation,
SystemInterruptInformation = 23,
- SystemExceptionInformation = 33
+ SystemExceptionInformation = 33,
+ SystemKernelDebuggerInformation = 35
} SYSTEM_INFORMATION_CLASS, *PSYSTEM_INFORMATION_CLASS;
typedef struct _SYSTEM_BASIC_INFORMATION {