Skip to content

Anti-anti debug and small VS fix #102

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 7 commits into
base: capemon
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions capemon.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -477,12 +477,12 @@
</ItemGroup>
<ItemGroup>
<MASM Include="CAPE\InstrHook32.asm">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild>
</MASM>
<MASM Include="CAPE\InstrHook64.asm">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
</MASM>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
Expand Down
141 changes: 139 additions & 2 deletions hook_misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
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;

Expand All @@ -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,
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;i<length;i++){
if (BlockInputInstances[i].BlockInputThreadID == ThreadId){
index = i;
CurrentState = BlockInputInstances[i].CurrentlyBlockedInput;
found = TRUE;
}
}
if (!found) {
BlockInputInstances[length-1].BlockInputThreadID = ThreadId;
index = length-1;
}
if (!CurrentState && fBlockIt)
{
BlockInputInstances[index].CurrentlyBlockedInput = TRUE;
ret = TRUE;
}
else if (CurrentState && fBlockIt)
ret = FALSE;
else if(CurrentState && !fBlockIt)
{
BlockInputInstances[index].CurrentlyBlockedInput = FALSE;
ret = TRUE;
}
else
ret = TRUE;
}
else
ret = Old_BlockInput(fBlockIt);
LOQ_bool("misc", "i", "fBlockIt", fBlockIt);
return ret;
}
4 changes: 4 additions & 0 deletions hook_process.c
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,10 @@ HOOKDEF(NTSTATUS, WINAPI, NtOpenProcess,
LOQ_ntstatus("process", "Phis", "ProcessHandle", ProcessHandle, "DesiredAccess", DesiredAccess, "ProcessIdentifier", pid, "ProcessName", ProcessName);
else
LOQ_ntstatus("process", "Phi", "ProcessHandle", ProcessHandle, "DesiredAccess", DesiredAccess, "ProcessIdentifier", pid);
//https://anti-debug.checkpoint.com/techniques/object-handles.html
if(!ProcessName)
if (!g_config.no_stealth && strcmp(ProcessName, "csrss.exe") == 0)
return NULL;

return ret;
}
Expand Down
9 changes: 8 additions & 1 deletion hook_thread.c
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,11 @@ HOOKDEF(NTSTATUS, WINAPI, RtlWow64GetThreadContext,
DWORD pid = pid_from_thread_handle(ThreadHandle);

NTSTATUS ret = Old_RtlWow64GetThreadContext(ThreadHandle, Context);

//https://anti-debug.checkpoint.com/techniques/process-memory.html
if (!g_config.no_stealth) {
// This needs to be __declspec(noinline) to prevent inlining
GetThreadContextHandler(ThreadHandle, Context);
}
LOQ_ntstatus("threading", "pi", "ThreadHandle", ThreadHandle, "ProcessId", pid);

return ret;
Expand Down Expand Up @@ -835,6 +839,9 @@ HOOKDEF(NTSTATUS, WINAPI, NtYieldExecution,
NTSTATUS ret = 0;
LOQ_void("threading", "");
ret = Old_NtYieldExecution();
//https://anti-debug.checkpoint.com/techniques/misc.html
if (!g_config.no_stealth && rand() % 2 == 1)
ret = -1;
return ret;
}

Expand Down
5 changes: 5 additions & 0 deletions hook_window.c
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,11 @@ HOOKDEF(BOOL, WINAPI, EnumWindows,
) {

BOOL ret = Old_EnumWindows(lpEnumFunc, lParam);
if (sizeof(lpEnumFunc)>5*sizeof(void *))
{
LOQ_bool("windows","p", "lpEnumFunc", lpEnumFunc);
}
else
LOQ_bool("windows", "");
return ret;
}
Expand Down
8 changes: 8 additions & 0 deletions hooks.c
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down Expand Up @@ -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),
Expand Down
18 changes: 18 additions & 0 deletions hooks.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"
2 changes: 1 addition & 1 deletion misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
8 changes: 7 additions & 1 deletion ntapi.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 {
Expand Down