From dccf8e082f7cedfaddea955fdc8c834b8f4b2c2e Mon Sep 17 00:00:00 2001 From: RazviOverflow Date: Mon, 30 Jun 2025 23:11:28 +0200 Subject: [PATCH 1/5] Parametrized --delay/--sleep --- al-khaser/Al-khaser.cpp | 35 ++++++++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/al-khaser/Al-khaser.cpp b/al-khaser/Al-khaser.cpp index 71bafd9..98a73d1 100644 --- a/al-khaser/Al-khaser.cpp +++ b/al-khaser/Al-khaser.cpp @@ -70,16 +70,41 @@ void EnableChecks(std::string checkType) { int main(int argc, char* argv[]) { /* enable functions */ + UINT delayInSeconds = 600U; // default value + int enabled_checks = 0; + if (argc > 1) { - for (int i = 1; i < argc; i += 2) { - if (strcmp(argv[i], "--check") == 0 && (i + 1 < argc)) { + for (int i = 1; i < argc; ++i) { + if ((strcmp(argv[i], "--sleep") == 0 || strcmp(argv[i], "--delay") == 0) && i + 1 < argc) { + char* endptr; + errno = 0; + long val = strtol(argv[i + 1], &endptr, 10); + + if (errno == ERANGE || val > UINT_MAX || val <= 0) { + printf("[!] Invalid delay value: %s. Using default %u seconds.\n", argv[i + 1], delayInSeconds); + } + else if (endptr == argv[i + 1] || *endptr != '\0') { + printf("[!] Non-numeric delay value: %s. Using default %u seconds.\n", argv[i + 1], delayInSeconds); + } + else { + delayInSeconds = (UINT)val; + } + i++; // skip the value + } + else if ((strcmp(argv[i], "--check") == 0) && i + 1 < argc) { EnableChecks(argv[i + 1]); + enabled_checks++; + i++; // skip the value } + // Add more flags here as needed + // else if (strcmp(argv[i], "--otherflag") == 0) { ... } } } - else { + + if (!enabled_checks) { EnableDefaultChecks(); } + /* Resize the console window for better visibility */ resize_console_window(); @@ -326,9 +351,9 @@ int main(int argc, char* argv[]) /* Timing Attacks */ if (ENABLE_TIMING_ATTACKS) { print_category(TEXT("Timing-attacks")); - UINT delayInSeconds = 600U; + UINT delayInMillis = delayInSeconds * 1000U; - printf("\n[*] Delay value is set to %u minutes ...\n", delayInSeconds / 60); + printf("\n[*] Delay value is set to %u seconds (%u minutes) ...\n", delayInSeconds, delayInSeconds / 60); exec_check(timing_NtDelayexecution, delayInMillis, TEXT("Performing a sleep using NtDelayExecution ...")); exec_check(timing_sleep_loop, delayInMillis, TEXT("Performing a sleep() in a loop ...")); From 0bd43121c20f1bd9d9c46a7be763520acce68c77 Mon Sep 17 00:00:00 2001 From: RazviOverflow Date: Tue, 1 Jul 2025 10:53:46 +0200 Subject: [PATCH 2/5] Added -h/--help message. Updated README with --help message (Usage) --- README.md | 33 +++++++++++++++++++++++++++ al-khaser/Al-khaser.cpp | 50 ++++++++++++++++++++++++++++++++++++----- 2 files changed, 78 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 42b9a54..7f62321 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,39 @@ It performs a bunch of common malware tricks with the goal of seeing if you stay ![Logo](https://i.imgur.com/jEFhsJT.png) +### Usage +``` +$ ./al-khaser.exe -h +Usage: al-khaser.exe [OPTIONS] +Options: + --check Enable specific check(s). Can be used multiple times. Valid types are: + TLS (Thread Local Storage callback checks) + DEBUG (Anti-debugging checks) + INJECTION (Code injection checks) + GEN_SANDBOX (Generic sandbox checks) + VBOX (VirtualBox detection) + VMWARE (VMware detection) + VPC (Virtual PC detection) + QEMU (QEMU detection) + KVM (KVM detection) + XEN (Xen detection) + WINE (Wine detection) + PARALLELS (Parallels detection) + HYPERV (Hyper-V detection) + CODE_INJECTIONS (Additional code injection techniques) + TIMING_ATTACKS (Timing/sleep-based sandbox evasion) + DUMPING_CHECK (Dumping memory/process checks) + ANALYSIS_TOOLS (Analysis tools detection) + ANTI_DISASSM (Anti-disassembly checks) + --sleep Set sleep/delay duration in seconds (default: 600). + --delay Alias for --sleep. + -h, --help Show this help message and exit. + +Examples: + al-khaser.exe --check DEBUG --check TIMING_ATTACKS --sleep 30 + al-khaser.exe --check VMWARE --check QEMU + al-khaser.exe --sleep 30 +``` ## Download diff --git a/al-khaser/Al-khaser.cpp b/al-khaser/Al-khaser.cpp index 98a73d1..9967d52 100644 --- a/al-khaser/Al-khaser.cpp +++ b/al-khaser/Al-khaser.cpp @@ -22,6 +22,7 @@ BOOL ENABLE_TIMING_ATTACKS = FALSE; BOOL ENABLE_DUMPING_CHECK = FALSE; BOOL ENABLE_ANALYSIS_TOOLS_CHECK = FALSE; BOOL ENABLE_ANTI_DISASSM_CHECKS = FALSE; +const char* PROGRAM_NAME = "al-khaser.exe"; void EnableDefaultChecks() { @@ -66,16 +67,56 @@ void EnableChecks(std::string checkType) { else if (checkType == "ANTI_DISASSM") ENABLE_ANTI_DISASSM_CHECKS = TRUE; } +void print_help(const char* prog_name){ + printf( + "Usage: %s [OPTIONS]\n" + "Options:\n" + " --check Enable specific check(s). Can be used multiple times. Valid types are:\n" + " TLS (Thread Local Storage callback checks)\n" + " DEBUG (Anti-debugging checks)\n" + " INJECTION (Code injection checks)\n" + " GEN_SANDBOX (Generic sandbox checks)\n" + " VBOX (VirtualBox detection)\n" + " VMWARE (VMware detection)\n" + " VPC (Virtual PC detection)\n" + " QEMU (QEMU detection)\n" + " KVM (KVM detection)\n" + " XEN (Xen detection)\n" + " WINE (Wine detection)\n" + " PARALLELS (Parallels detection)\n" + " HYPERV (Hyper-V detection)\n" + " CODE_INJECTIONS (Additional code injection techniques)\n" + " TIMING_ATTACKS (Timing/sleep-based sandbox evasion)\n" + " DUMPING_CHECK (Dumping memory/process checks)\n" + " ANALYSIS_TOOLS (Analysis tools detection)\n" + " ANTI_DISASSM (Anti-disassembly checks)\n" + " --sleep Set sleep/delay duration in seconds (default: 600).\n" + " --delay Alias for --sleep.\n" + " -h, --help Show this help message and exit.\n" + "\n" + "Examples:\n" + " %s --check DEBUG --check TIMING_ATTACKS --sleep 30\n" + " %s --check VMWARE --check QEMU\n" + " %s --sleep 30\n" + "\n" + "If no --check options are given, all checks are executed by default.\n" + "If no other options are given, the default delay is 600 seconds.\n", + prog_name, prog_name, prog_name, prog_name + ); +} -int main(int argc, char* argv[]) -{ +int main(int argc, char* argv[]){ /* enable functions */ UINT delayInSeconds = 600U; // default value int enabled_checks = 0; if (argc > 1) { for (int i = 1; i < argc; ++i) { - if ((strcmp(argv[i], "--sleep") == 0 || strcmp(argv[i], "--delay") == 0) && i + 1 < argc) { + if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) { + //print_help(argv[0]); + print_help(PROGRAM_NAME); + return 0; + } else if ((strcmp(argv[i], "--sleep") == 0 || strcmp(argv[i], "--delay") == 0) && i + 1 < argc) { char* endptr; errno = 0; long val = strtol(argv[i + 1], &endptr, 10); @@ -90,8 +131,7 @@ int main(int argc, char* argv[]) delayInSeconds = (UINT)val; } i++; // skip the value - } - else if ((strcmp(argv[i], "--check") == 0) && i + 1 < argc) { + } else if ((strcmp(argv[i], "--check") == 0) && i + 1 < argc) { EnableChecks(argv[i + 1]); enabled_checks++; i++; // skip the value From f1948c4b21f3c335b3b8af1b33959fded63be7e6 Mon Sep 17 00:00:00 2001 From: RazviOverflow Date: Tue, 1 Jul 2025 19:14:23 +0200 Subject: [PATCH 3/5] Implementing statistics generation and output --- al-khaser/Al-khaser.cpp | 282 +++++++++--------- al-khaser/AntiAnalysis/process.cpp | 8 +- al-khaser/AntiVM/Generic.cpp | 42 ++- al-khaser/AntiVM/KVM.cpp | 16 +- al-khaser/AntiVM/Parallels.cpp | 16 +- al-khaser/AntiVM/Qemu.cpp | 32 +- al-khaser/AntiVM/VMWare.cpp | 45 ++- al-khaser/AntiVM/VirtualBox.cpp | 39 ++- al-khaser/AntiVM/VirtualPC.cpp | 16 +- al-khaser/AntiVM/Wine.cpp | 8 +- al-khaser/AntiVM/Xen.cpp | 16 +- .../CodeInjection/CreateRemoteThread.cpp | 3 +- al-khaser/Shared/Common.cpp | 17 ++ al-khaser/Shared/Common.h | 21 ++ al-khaser/Shared/stats.cpp | 55 ++++ al-khaser/Shared/stats.h | 35 +++ al-khaser/al-khaser.vcxproj | 2 + al-khaser/al-khaser.vcxproj.filters | 6 + al-khaser/pch.h | 3 +- 19 files changed, 467 insertions(+), 195 deletions(-) create mode 100644 al-khaser/Shared/stats.cpp create mode 100644 al-khaser/Shared/stats.h diff --git a/al-khaser/Al-khaser.cpp b/al-khaser/Al-khaser.cpp index 9967d52..6d1a06b 100644 --- a/al-khaser/Al-khaser.cpp +++ b/al-khaser/Al-khaser.cpp @@ -3,6 +3,10 @@ #include "pch.h" +// Statistics-related counters +int g_checks_passed = 0; +int g_checks_failed = 0; + BOOL ENABLE_TLS_CHECKS = FALSE; BOOL ENABLE_DEBUG_CHECKS = FALSE; @@ -99,7 +103,7 @@ void print_help(const char* prog_name){ " %s --check VMWARE --check QEMU\n" " %s --sleep 30\n" "\n" - "If no --check options are given, all checks are executed by default.\n" + "If no --check options are given, all checks are executed by default (except CODE_INJECTIONS).\n" "If no other options are given, the default delay is 600 seconds.\n", prog_name, prog_name, prog_name, prog_name ); @@ -163,149 +167,153 @@ int main(int argc, char* argv[]){ if (ENABLE_DEBUG_CHECKS) PageExceptionInitialEnum(); + /* Inititalize statistics structures*/ + stats_init(); + /* TLS checks */ if (ENABLE_TLS_CHECKS) { print_category(TEXT("TLS Callbacks")); - exec_check(&TLSCallbackProcess, TEXT("TLS process attach callback ")); - exec_check(&TLSCallbackThread, TEXT("TLS thread attach callback ")); + exec_check(CAT_TLS, &TLSCallbackProcess, TEXT("TLS process attach callback ")); + exec_check(CAT_TLS, &TLSCallbackThread, TEXT("TLS thread attach callback ")); + } /* Debugger Detection */ if (ENABLE_DEBUG_CHECKS) { print_category(TEXT("Debugger Detection")); - exec_check(&IsDebuggerPresentAPI, TEXT("Checking IsDebuggerPresent API ")); - exec_check(&IsDebuggerPresentPEB, TEXT("Checking PEB.BeingDebugged ")); - exec_check(&CheckRemoteDebuggerPresentAPI, TEXT("Checking CheckRemoteDebuggerPresent API ")); - exec_check(&NtGlobalFlag, TEXT("Checking PEB.NtGlobalFlag ")); - exec_check(&HeapFlags, TEXT("Checking ProcessHeap.Flags ")); - exec_check(&HeapForceFlags, TEXT("Checking ProcessHeap.ForceFlags ")); - exec_check(&LowFragmentationHeap, TEXT("Checking Low Fragmentation Heap")); - exec_check(&NtQueryInformationProcess_ProcessDebugPort, TEXT("Checking NtQueryInformationProcess with ProcessDebugPort ")); - exec_check(&NtQueryInformationProcess_ProcessDebugFlags, TEXT("Checking NtQueryInformationProcess with ProcessDebugFlags ")); - exec_check(&NtQueryInformationProcess_ProcessDebugObject, TEXT("Checking NtQueryInformationProcess with ProcessDebugObject ")); - exec_check(&WUDF_IsAnyDebuggerPresent, TEXT("Checking WudfIsAnyDebuggerPresent API ")); - exec_check(&WUDF_IsKernelDebuggerPresent, TEXT("Checking WudfIsKernelDebuggerPresent API ")); - exec_check(&WUDF_IsUserDebuggerPresent, TEXT("Checking WudfIsUserDebuggerPresent API ")); - exec_check(&NtSetInformationThread_ThreadHideFromDebugger, TEXT("Checking NtSetInformationThread with ThreadHideFromDebugger ")); - exec_check(&CloseHandle_InvalideHandle, TEXT("Checking CloseHandle with an invalide handle ")); - exec_check(&NtSystemDebugControl_Command, TEXT("Checking NtSystemDebugControl")); - exec_check(&UnhandledExcepFilterTest, TEXT("Checking UnhandledExcepFilterTest ")); - exec_check(&OutputDebugStringAPI, TEXT("Checking OutputDebugString ")); - exec_check(&HardwareBreakpoints, TEXT("Checking Hardware Breakpoints ")); - exec_check(&SoftwareBreakpoints, TEXT("Checking Software Breakpoints ")); - exec_check(&Interrupt_0x2d, TEXT("Checking Interupt 0x2d ")); - exec_check(&Interrupt_3, TEXT("Checking Interupt 1 ")); - exec_check(&TrapFlag, TEXT("Checking trap flag")); - exec_check(&MemoryBreakpoints_PageGuard, TEXT("Checking Memory Breakpoints PAGE GUARD ")); - exec_check(&IsParentExplorerExe, TEXT("Checking If Parent Process is explorer.exe ")); - exec_check(&CanOpenCsrss, TEXT("Checking SeDebugPrivilege ")); - exec_check(&NtQueryObject_ObjectTypeInformation, TEXT("Checking NtQueryObject with ObjectTypeInformation ")); - exec_check(&NtQueryObject_ObjectAllTypesInformation, TEXT("Checking NtQueryObject with ObjectAllTypesInformation ")); - exec_check(&NtYieldExecutionAPI, TEXT("Checking NtYieldExecution ")); - exec_check(&SetHandleInformatiom_ProtectedHandle, TEXT("Checking CloseHandle protected handle trick ")); - exec_check(&NtQuerySystemInformation_SystemKernelDebuggerInformation, TEXT("Checking NtQuerySystemInformation with SystemKernelDebuggerInformation ")); - exec_check(&SharedUserData_KernelDebugger, TEXT("Checking SharedUserData->KdDebuggerEnabled ")); - exec_check(&ProcessJob, TEXT("Checking if process is in a job ")); - exec_check(&VirtualAlloc_WriteWatch_BufferOnly, TEXT("Checking VirtualAlloc write watch (buffer only) ")); - exec_check(&VirtualAlloc_WriteWatch_APICalls, TEXT("Checking VirtualAlloc write watch (API calls) ")); - exec_check(&VirtualAlloc_WriteWatch_IsDebuggerPresent, TEXT("Checking VirtualAlloc write watch (IsDebuggerPresent) ")); - exec_check(&VirtualAlloc_WriteWatch_CodeWrite, TEXT("Checking VirtualAlloc write watch (code write) ")); - exec_check(&PageExceptionBreakpointCheck, TEXT("Checking for page exception breakpoints ")); - exec_check(&ModuleBoundsHookCheck, TEXT("Checking for API hooks outside module bounds ")); + exec_check(CAT_DEBUG, &IsDebuggerPresentAPI, TEXT("Checking IsDebuggerPresent API ")); + exec_check(CAT_DEBUG, &IsDebuggerPresentPEB, TEXT("Checking PEB.BeingDebugged ")); + exec_check(CAT_DEBUG, &CheckRemoteDebuggerPresentAPI, TEXT("Checking CheckRemoteDebuggerPresent API ")); + exec_check(CAT_DEBUG, &NtGlobalFlag, TEXT("Checking PEB.NtGlobalFlag ")); + exec_check(CAT_DEBUG, &HeapFlags, TEXT("Checking ProcessHeap.Flags ")); + exec_check(CAT_DEBUG, &HeapForceFlags, TEXT("Checking ProcessHeap.ForceFlags ")); + exec_check(CAT_DEBUG, &LowFragmentationHeap, TEXT("Checking Low Fragmentation Heap")); + exec_check(CAT_DEBUG, &NtQueryInformationProcess_ProcessDebugPort, TEXT("Checking NtQueryInformationProcess with ProcessDebugPort ")); + exec_check(CAT_DEBUG, &NtQueryInformationProcess_ProcessDebugFlags, TEXT("Checking NtQueryInformationProcess with ProcessDebugFlags ")); + exec_check(CAT_DEBUG, &NtQueryInformationProcess_ProcessDebugObject, TEXT("Checking NtQueryInformationProcess with ProcessDebugObject ")); + exec_check(CAT_DEBUG, &WUDF_IsAnyDebuggerPresent, TEXT("Checking WudfIsAnyDebuggerPresent API ")); + exec_check(CAT_DEBUG, &WUDF_IsKernelDebuggerPresent, TEXT("Checking WudfIsKernelDebuggerPresent API ")); + exec_check(CAT_DEBUG, &WUDF_IsUserDebuggerPresent, TEXT("Checking WudfIsUserDebuggerPresent API ")); + exec_check(CAT_DEBUG, &NtSetInformationThread_ThreadHideFromDebugger, TEXT("Checking NtSetInformationThread with ThreadHideFromDebugger ")); + exec_check(CAT_DEBUG, &CloseHandle_InvalideHandle, TEXT("Checking CloseHandle with an invalide handle ")); + exec_check(CAT_DEBUG, &NtSystemDebugControl_Command, TEXT("Checking NtSystemDebugControl")); + exec_check(CAT_DEBUG, &UnhandledExcepFilterTest, TEXT("Checking UnhandledExcepFilterTest ")); + exec_check(CAT_DEBUG, &OutputDebugStringAPI, TEXT("Checking OutputDebugString ")); + exec_check(CAT_DEBUG, &HardwareBreakpoints, TEXT("Checking Hardware Breakpoints ")); + exec_check(CAT_DEBUG, &SoftwareBreakpoints, TEXT("Checking Software Breakpoints ")); + exec_check(CAT_DEBUG, &Interrupt_0x2d, TEXT("Checking Interupt 0x2d ")); + exec_check(CAT_DEBUG, &Interrupt_3, TEXT("Checking Interupt 1 ")); + exec_check(CAT_DEBUG, &TrapFlag, TEXT("Checking trap flag")); + exec_check(CAT_DEBUG, &MemoryBreakpoints_PageGuard, TEXT("Checking Memory Breakpoints PAGE GUARD ")); + exec_check(CAT_DEBUG, &IsParentExplorerExe, TEXT("Checking If Parent Process is explorer.exe ")); + exec_check(CAT_DEBUG, &CanOpenCsrss, TEXT("Checking SeDebugPrivilege ")); + exec_check(CAT_DEBUG, &NtQueryObject_ObjectTypeInformation, TEXT("Checking NtQueryObject with ObjectTypeInformation ")); + exec_check(CAT_DEBUG, &NtQueryObject_ObjectAllTypesInformation, TEXT("Checking NtQueryObject with ObjectAllTypesInformation ")); + exec_check(CAT_DEBUG, &NtYieldExecutionAPI, TEXT("Checking NtYieldExecution ")); + exec_check(CAT_DEBUG, &SetHandleInformatiom_ProtectedHandle, TEXT("Checking CloseHandle protected handle trick ")); + exec_check(CAT_DEBUG, &NtQuerySystemInformation_SystemKernelDebuggerInformation, TEXT("Checking NtQuerySystemInformation with SystemKernelDebuggerInformation ")); + exec_check(CAT_DEBUG, &SharedUserData_KernelDebugger, TEXT("Checking SharedUserData->KdDebuggerEnabled ")); + exec_check(CAT_DEBUG, &ProcessJob, TEXT("Checking if process is in a job ")); + exec_check(CAT_DEBUG, &VirtualAlloc_WriteWatch_BufferOnly, TEXT("Checking VirtualAlloc write watch (buffer only) ")); + exec_check(CAT_DEBUG, &VirtualAlloc_WriteWatch_APICalls, TEXT("Checking VirtualAlloc write watch (API calls) ")); + exec_check(CAT_DEBUG, &VirtualAlloc_WriteWatch_IsDebuggerPresent, TEXT("Checking VirtualAlloc write watch (IsDebuggerPresent) ")); + exec_check(CAT_DEBUG, &VirtualAlloc_WriteWatch_CodeWrite, TEXT("Checking VirtualAlloc write watch (code write) ")); + exec_check(CAT_DEBUG, &PageExceptionBreakpointCheck, TEXT("Checking for page exception breakpoints ")); + exec_check(CAT_DEBUG, &ModuleBoundsHookCheck, TEXT("Checking for API hooks outside module bounds ")); } if (ENABLE_INJECTION_CHECKS) { print_category(TEXT("DLL Injection Detection")); - exec_check(&ScanForModules_EnumProcessModulesEx_32bit, TEXT("Enumerating modules with EnumProcessModulesEx [32-bit] ")); - exec_check(&ScanForModules_EnumProcessModulesEx_64bit, TEXT("Enumerating modules with EnumProcessModulesEx [64-bit] ")); - exec_check(&ScanForModules_EnumProcessModulesEx_All, TEXT("Enumerating modules with EnumProcessModulesEx [ALL] ")); - exec_check(&ScanForModules_ToolHelp32, TEXT("Enumerating modules with ToolHelp32 ")); - exec_check(&ScanForModules_LdrEnumerateLoadedModules, TEXT("Enumerating the process LDR via LdrEnumerateLoadedModules ")); - exec_check(&ScanForModules_LDR_Direct, TEXT("Enumerating the process LDR directly ")); - exec_check(&ScanForModules_MemoryWalk_GMI, TEXT("Walking process memory with GetModuleInformation ")); - exec_check(&ScanForModules_MemoryWalk_Hidden, TEXT("Walking process memory for hidden modules ")); - exec_check(&ScanForModules_DotNetModuleStructures, TEXT("Walking process memory for .NET module structures ")); + exec_check(CAT_INJECTION, &ScanForModules_EnumProcessModulesEx_32bit, TEXT("Enumerating modules with EnumProcessModulesEx [32-bit] ")); + exec_check(CAT_INJECTION, &ScanForModules_EnumProcessModulesEx_64bit, TEXT("Enumerating modules with EnumProcessModulesEx [64-bit] ")); + exec_check(CAT_INJECTION, &ScanForModules_EnumProcessModulesEx_All, TEXT("Enumerating modules with EnumProcessModulesEx [ALL] ")); + exec_check(CAT_INJECTION, &ScanForModules_ToolHelp32, TEXT("Enumerating modules with ToolHelp32 ")); + exec_check(CAT_INJECTION, &ScanForModules_LdrEnumerateLoadedModules, TEXT("Enumerating the process LDR via LdrEnumerateLoadedModules ")); + exec_check(CAT_INJECTION, &ScanForModules_LDR_Direct, TEXT("Enumerating the process LDR directly ")); + exec_check(CAT_INJECTION, &ScanForModules_MemoryWalk_GMI, TEXT("Walking process memory with GetModuleInformation ")); + exec_check(CAT_INJECTION, &ScanForModules_MemoryWalk_Hidden, TEXT("Walking process memory for hidden modules ")); + exec_check(CAT_INJECTION, &ScanForModules_DotNetModuleStructures, TEXT("Walking process memory for .NET module structures ")); } /* Generic sandbox detection */ if (ENABLE_GEN_SANDBOX_CHECKS) { - print_category(TEXT("Generic Sandboxe/VM Detection")); + print_category(TEXT("Generic Sandbox/VM Detection")); loaded_dlls(); known_file_names(); known_usernames(); known_hostnames(); other_known_sandbox_environment_checks(); looking_glass_vdd_processes(); - exec_check(&NumberOfProcessors, TEXT("Checking Number of processors in machine ")); - exec_check(&idt_trick, TEXT("Checking Interupt Descriptor Table location ")); - exec_check(&ldt_trick, TEXT("Checking Local Descriptor Table location ")); - exec_check(&gdt_trick, TEXT("Checking Global Descriptor Table location ")); - exec_check(&str_trick, TEXT("Checking Store Task Register ")); - exec_check(&number_cores_wmi, TEXT("Checking Number of cores in machine using WMI ")); - exec_check(&disk_size_wmi, TEXT("Checking hard disk size using WMI ")); - exec_check(&dizk_size_deviceiocontrol, TEXT("Checking hard disk size using DeviceIoControl ")); - exec_check(&setupdi_diskdrive, TEXT("Checking SetupDi_diskdrive ")); - exec_check(&mouse_movement, TEXT("Checking mouse movement ")); - exec_check(&lack_user_input, TEXT("Checking lack of user input ")); - exec_check(&memory_space, TEXT("Checking memory space using GlobalMemoryStatusEx ")); - exec_check(&disk_size_getdiskfreespace, TEXT("Checking disk size using GetDiskFreeSpaceEx ")); - exec_check(&cpuid_is_hypervisor, TEXT("Checking if CPU hypervisor field is set using cpuid(0x1)")); - exec_check(&cpuid_hypervisor_vendor, TEXT("Checking hypervisor vendor using cpuid(0x40000000)")); - exec_check(&hosting_check, TEXT("Check if Machine is hosted on Cloud")); - exec_check(&accelerated_sleep, TEXT("Check if time has been accelerated ")); - exec_check(&VMDriverServices, TEXT("VM Driver Services ")); - exec_check(&serial_number_bios_wmi, TEXT("Checking SerialNumber from BIOS using WMI ")); - exec_check(&model_computer_system_wmi, TEXT("Checking Model from ComputerSystem using WMI ")); - exec_check(&manufacturer_computer_system_wmi, TEXT("Checking Manufacturer from ComputerSystem using WMI ")); - exec_check(¤t_temperature_acpi_wmi, TEXT("Checking Current Temperature using WMI ")); - exec_check(&process_id_processor_wmi, TEXT("Checking ProcessId using WMI ")); - exec_check(&power_capabilities, TEXT("Checking power capabilities ")); - exec_check(&cpu_fan_wmi, TEXT("Checking CPU fan using WMI ")); - exec_check(&query_license_value, TEXT("Checking NtQueryLicenseValue with Kernel-VMDetection-Private ")); - exec_check(&cachememory_wmi, TEXT("Checking Win32_CacheMemory with WMI ")); - exec_check(&physicalmemory_wmi, TEXT("Checking Win32_PhysicalMemory with WMI ")); - exec_check(&memorydevice_wmi, TEXT("Checking Win32_MemoryDevice with WMI ")); - exec_check(&memoryarray_wmi, TEXT("Checking Win32_MemoryArray with WMI ")); - exec_check(&voltageprobe_wmi, TEXT("Checking Win32_VoltageProbe with WMI ")); - exec_check(&portconnector_wmi, TEXT("Checking Win32_PortConnector with WMI ")); - exec_check(&smbiosmemory_wmi, TEXT("Checking Win32_SMBIOSMemory with WMI ")); - exec_check(&perfctrs_thermalzoneinfo_wmi, TEXT("Checking ThermalZoneInfo performance counters with WMI ")); - exec_check(&cim_memory_wmi, TEXT("Checking CIM_Memory with WMI ")); - exec_check(&cim_sensor_wmi, TEXT("Checking CIM_Sensor with WMI ")); - exec_check(&cim_numericsensor_wmi, TEXT("Checking CIM_NumericSensor with WMI ")); - exec_check(&cim_temperaturesensor_wmi, TEXT("Checking CIM_TemperatureSensor with WMI ")); - exec_check(&cim_voltagesensor_wmi, TEXT("Checking CIM_VoltageSensor with WMI ")); - exec_check(&cim_physicalconnector_wmi, TEXT("Checking CIM_PhysicalConnector with WMI ")); - exec_check(&cim_slot_wmi, TEXT("Checking CIM_Slot with WMI ")); - exec_check(&pirated_windows, TEXT("Checking if Windows is Genuine ")); - exec_check(®istry_services_disk_enum, TEXT("Checking Services\\Disk\\Enum entries for VM strings ")); - exec_check(®istry_disk_enum, TEXT("Checking Enum\\IDE and Enum\\SCSI entries for VM strings ")); - exec_check(&number_SMBIOS_tables, TEXT("Checking SMBIOS tables ")); - exec_check(&firmware_ACPI, TEXT("Checking ACPI table strings ")); + exec_check(CAT_GEN_SANDBOX, &NumberOfProcessors, TEXT("Checking Number of processors in machine ")); + exec_check(CAT_GEN_SANDBOX, &idt_trick, TEXT("Checking Interupt Descriptor Table location ")); + exec_check(CAT_GEN_SANDBOX, &ldt_trick, TEXT("Checking Local Descriptor Table location ")); + exec_check(CAT_GEN_SANDBOX, &gdt_trick, TEXT("Checking Global Descriptor Table location ")); + exec_check(CAT_GEN_SANDBOX, &str_trick, TEXT("Checking Store Task Register ")); + exec_check(CAT_GEN_SANDBOX, &number_cores_wmi, TEXT("Checking Number of cores in machine using WMI ")); + exec_check(CAT_GEN_SANDBOX, &disk_size_wmi, TEXT("Checking hard disk size using WMI ")); + exec_check(CAT_GEN_SANDBOX, &dizk_size_deviceiocontrol, TEXT("Checking hard disk size using DeviceIoControl ")); + exec_check(CAT_GEN_SANDBOX, &setupdi_diskdrive, TEXT("Checking SetupDi_diskdrive ")); + exec_check(CAT_GEN_SANDBOX, &mouse_movement, TEXT("Checking mouse movement ")); + exec_check(CAT_GEN_SANDBOX, &lack_user_input, TEXT("Checking lack of user input ")); + exec_check(CAT_GEN_SANDBOX, &memory_space, TEXT("Checking memory space using GlobalMemoryStatusEx ")); + exec_check(CAT_GEN_SANDBOX, &disk_size_getdiskfreespace, TEXT("Checking disk size using GetDiskFreeSpaceEx ")); + exec_check(CAT_GEN_SANDBOX, &cpuid_is_hypervisor, TEXT("Checking if CPU hypervisor field is set using cpuid(0x1)")); + exec_check(CAT_GEN_SANDBOX, &cpuid_hypervisor_vendor, TEXT("Checking hypervisor vendor using cpuid(0x40000000)")); + exec_check(CAT_GEN_SANDBOX, &hosting_check, TEXT("Check if Machine is hosted on Cloud")); + exec_check(CAT_GEN_SANDBOX, &accelerated_sleep, TEXT("Check if time has been accelerated ")); + exec_check(CAT_GEN_SANDBOX, &VMDriverServices, TEXT("VM Driver Services ")); + exec_check(CAT_GEN_SANDBOX, &serial_number_bios_wmi, TEXT("Checking SerialNumber from BIOS using WMI ")); + exec_check(CAT_GEN_SANDBOX, &model_computer_system_wmi, TEXT("Checking Model from ComputerSystem using WMI ")); + exec_check(CAT_GEN_SANDBOX, &manufacturer_computer_system_wmi, TEXT("Checking Manufacturer from ComputerSystem using WMI ")); + exec_check(CAT_GEN_SANDBOX, ¤t_temperature_acpi_wmi, TEXT("Checking Current Temperature using WMI ")); + exec_check(CAT_GEN_SANDBOX, &process_id_processor_wmi, TEXT("Checking ProcessId using WMI ")); + exec_check(CAT_GEN_SANDBOX, &power_capabilities, TEXT("Checking power capabilities ")); + exec_check(CAT_GEN_SANDBOX, &cpu_fan_wmi, TEXT("Checking CPU fan using WMI ")); + exec_check(CAT_GEN_SANDBOX, &query_license_value, TEXT("Checking NtQueryLicenseValue with Kernel-VMDetection-Private ")); + exec_check(CAT_GEN_SANDBOX, &cachememory_wmi, TEXT("Checking Win32_CacheMemory with WMI ")); + exec_check(CAT_GEN_SANDBOX, &physicalmemory_wmi, TEXT("Checking Win32_PhysicalMemory with WMI ")); + exec_check(CAT_GEN_SANDBOX, &memorydevice_wmi, TEXT("Checking Win32_MemoryDevice with WMI ")); + exec_check(CAT_GEN_SANDBOX, &memoryarray_wmi, TEXT("Checking Win32_MemoryArray with WMI ")); + exec_check(CAT_GEN_SANDBOX, &voltageprobe_wmi, TEXT("Checking Win32_VoltageProbe with WMI ")); + exec_check(CAT_GEN_SANDBOX, &portconnector_wmi, TEXT("Checking Win32_PortConnector with WMI ")); + exec_check(CAT_GEN_SANDBOX, &smbiosmemory_wmi, TEXT("Checking Win32_SMBIOSMemory with WMI ")); + exec_check(CAT_GEN_SANDBOX, &perfctrs_thermalzoneinfo_wmi, TEXT("Checking ThermalZoneInfo performance counters with WMI ")); + exec_check(CAT_GEN_SANDBOX, &cim_memory_wmi, TEXT("Checking CIM_Memory with WMI ")); + exec_check(CAT_GEN_SANDBOX, &cim_sensor_wmi, TEXT("Checking CIM_Sensor with WMI ")); + exec_check(CAT_GEN_SANDBOX, &cim_numericsensor_wmi, TEXT("Checking CIM_NumericSensor with WMI ")); + exec_check(CAT_GEN_SANDBOX, &cim_temperaturesensor_wmi, TEXT("Checking CIM_TemperatureSensor with WMI ")); + exec_check(CAT_GEN_SANDBOX, &cim_voltagesensor_wmi, TEXT("Checking CIM_VoltageSensor with WMI ")); + exec_check(CAT_GEN_SANDBOX, &cim_physicalconnector_wmi, TEXT("Checking CIM_PhysicalConnector with WMI ")); + exec_check(CAT_GEN_SANDBOX, &cim_slot_wmi, TEXT("Checking CIM_Slot with WMI ")); + exec_check(CAT_GEN_SANDBOX, &pirated_windows, TEXT("Checking if Windows is Genuine ")); + exec_check(CAT_GEN_SANDBOX, ®istry_services_disk_enum, TEXT("Checking Services\\Disk\\Enum entries for VM strings ")); + exec_check(CAT_GEN_SANDBOX, ®istry_disk_enum, TEXT("Checking Enum\\IDE and Enum\\SCSI entries for VM strings ")); + exec_check(CAT_GEN_SANDBOX, &number_SMBIOS_tables, TEXT("Checking SMBIOS tables ")); + exec_check(CAT_GEN_SANDBOX, &firmware_ACPI, TEXT("Checking ACPI table strings ")); } /* VirtualBox Detection */ if (ENABLE_VBOX_CHECKS) { print_category(TEXT("VirtualBox Detection")); vbox_reg_key_value(); - exec_check(&vbox_dir, TEXT("Checking VirtualBox Guest Additions directory ")); + exec_check(CAT_VBOX, &vbox_dir, TEXT("Checking VirtualBox Guest Additions directory ")); vbox_files(); vbox_reg_keys(); - exec_check(&vbox_check_mac, TEXT("Checking Mac Address start with 08:00:27 ")); - exec_check(&hybridanalysismacdetect, TEXT("Checking MAC address (Hybrid Analysis) ")); + exec_check(CAT_VBOX, &vbox_check_mac, TEXT("Checking Mac Address start with 08:00:27 ")); + exec_check(CAT_VBOX, &hybridanalysismacdetect, TEXT("Checking MAC address (Hybrid Analysis) ")); vbox_devices(); - exec_check(&vbox_window_class, TEXT("Checking VBoxTrayToolWndClass / VBoxTrayToolWnd ")); - exec_check(&vbox_network_share, TEXT("Checking VirtualBox Shared Folders network provider ")); + exec_check(CAT_VBOX, &vbox_window_class, TEXT("Checking VBoxTrayToolWndClass / VBoxTrayToolWnd ")); + exec_check(CAT_VBOX, &vbox_network_share, TEXT("Checking VirtualBox Shared Folders network provider ")); vbox_processes(); - exec_check(&vbox_pnpentity_pcideviceid_wmi, TEXT("Checking Win32_PnPDevice DeviceId from WMI for VBox PCI device ")); - exec_check(&vbox_pnpentity_controllers_wmi, TEXT("Checking Win32_PnPDevice Name from WMI for VBox controller hardware ")); - exec_check(&vbox_pnpentity_vboxname_wmi, TEXT("Checking Win32_PnPDevice Name from WMI for VBOX names ")); - exec_check(&vbox_bus_wmi, TEXT("Checking Win32_Bus from WMI ")); - exec_check(&vbox_baseboard_wmi, TEXT("Checking Win32_BaseBoard from WMI ")); - exec_check(&vbox_mac_wmi, TEXT("Checking MAC address from WMI ")); - exec_check(&vbox_eventlogfile_wmi, TEXT("Checking NTEventLog from WMI ")); - exec_check(&vbox_firmware_SMBIOS, TEXT("Checking SMBIOS firmware ")); - exec_check(&vbox_firmware_ACPI, TEXT("Checking ACPI tables ")); + exec_check(CAT_VBOX, &vbox_pnpentity_pcideviceid_wmi, TEXT("Checking Win32_PnPDevice DeviceId from WMI for VBox PCI device ")); + exec_check(CAT_VBOX, &vbox_pnpentity_controllers_wmi, TEXT("Checking Win32_PnPDevice Name from WMI for VBox controller hardware ")); + exec_check(CAT_VBOX, &vbox_pnpentity_vboxname_wmi, TEXT("Checking Win32_PnPDevice Name from WMI for VBOX names ")); + exec_check(CAT_VBOX, &vbox_bus_wmi, TEXT("Checking Win32_Bus from WMI ")); + exec_check(CAT_VBOX, &vbox_baseboard_wmi, TEXT("Checking Win32_BaseBoard from WMI ")); + exec_check(CAT_VBOX, &vbox_mac_wmi, TEXT("Checking MAC address from WMI ")); + exec_check(CAT_VBOX, &vbox_eventlogfile_wmi, TEXT("Checking NTEventLog from WMI ")); + exec_check(CAT_VBOX, &vbox_firmware_SMBIOS, TEXT("Checking SMBIOS firmware ")); + exec_check(CAT_VBOX, &vbox_firmware_ACPI, TEXT("Checking ACPI tables ")); } /* VMWare Detection */ @@ -315,11 +323,11 @@ int main(int argc, char* argv[]){ vmware_reg_keys(); vmware_files(); vmware_mac(); - exec_check(&vmware_adapter_name, TEXT("Checking VMWare network adapter name ")); + exec_check(CAT_VMWARE, &vmware_adapter_name, TEXT("Checking VMWare network adapter name ")); vmware_devices(); - exec_check(&vmware_dir, TEXT("Checking VMWare directory ")); - exec_check(&vmware_firmware_SMBIOS, TEXT("Checking SMBIOS firmware ")); - exec_check(&vmware_firmware_ACPI, TEXT("Checking ACPI tables ")); + exec_check(CAT_VMWARE, &vmware_dir, TEXT("Checking VMWare directory ")); + exec_check(CAT_VMWARE, &vmware_firmware_SMBIOS, TEXT("Checking SMBIOS firmware ")); + exec_check(CAT_VMWARE, &vmware_firmware_ACPI, TEXT("Checking ACPI tables ")); } /* Virtual PC Detection */ @@ -336,8 +344,8 @@ int main(int argc, char* argv[]){ qemu_reg_keys(); qemu_processes(); qemu_dir(); - exec_check(&qemu_firmware_SMBIOS, TEXT("Checking SMBIOS firmware ")); - exec_check(&qemu_firmware_ACPI, TEXT("Checking ACPI tables ")); + exec_check(CAT_QEMU, &qemu_firmware_SMBIOS, TEXT("Checking SMBIOS firmware ")); + exec_check(CAT_QEMU, &qemu_firmware_ACPI, TEXT("Checking ACPI tables ")); } @@ -346,7 +354,7 @@ int main(int argc, char* argv[]){ print_category(TEXT("Xen Detection")); xen_reg_keys(); xen_process(); - exec_check(&xen_check_mac, TEXT("Checking Mac Address start with 08:16:3E ")); + exec_check(CAT_XEN, &xen_check_mac, TEXT("Checking Mac Address start with 08:16:3E ")); } /* KVM Detection */ @@ -354,13 +362,13 @@ int main(int argc, char* argv[]){ print_category(TEXT("KVM Detection")); kvm_files(); kvm_reg_keys(); - exec_check(&kvm_dir, TEXT("Checking KVM virio directory ")); + exec_check(CAT_KVM, &kvm_dir, TEXT("Checking KVM virio directory ")); } /* Wine Detection */ if (ENABLE_WINE_CHECKS) { print_category(TEXT("Wine Detection")); - exec_check(&wine_exports, TEXT("Checking Wine via dll exports ")); + exec_check(CAT_WINE, &wine_exports, TEXT("Checking Wine via dll exports ")); wine_reg_keys(); } @@ -369,13 +377,13 @@ int main(int argc, char* argv[]){ print_category(TEXT("Parallels Detection")); parallels_reg_keys(); parallels_process(); - exec_check(¶llels_check_mac, TEXT("Checking Mac Address start with 00:1C:42 ")); + exec_check(CAT_PARALLELS, ¶llels_check_mac, TEXT("Checking Mac Address start with 00:1C:42 ")); } if (ENABLE_HYPERV_CHECKS) { print_category(TEXT("Hyper-V Detection")); - exec_check(&check_hyperv_driver_objects, TEXT("Checking for Hyper-V driver objects ")); - exec_check(&check_hyperv_global_objects, TEXT("Checking for Hyper-V global objects ")); + exec_check(CAT_HYPERV, &check_hyperv_driver_objects, TEXT("Checking for Hyper-V driver objects ")); + exec_check(CAT_HYPERV, &check_hyperv_global_objects, TEXT("Checking for Hyper-V global objects ")); } /* Code injections techniques */ @@ -395,18 +403,18 @@ int main(int argc, char* argv[]){ UINT delayInMillis = delayInSeconds * 1000U; printf("\n[*] Delay value is set to %u seconds (%u minutes) ...\n", delayInSeconds, delayInSeconds / 60); - exec_check(timing_NtDelayexecution, delayInMillis, TEXT("Performing a sleep using NtDelayExecution ...")); - exec_check(timing_sleep_loop, delayInMillis, TEXT("Performing a sleep() in a loop ...")); - exec_check(timing_SetTimer, delayInMillis, TEXT("Delaying execution using SetTimer ...")); - exec_check(timing_timeSetEvent, delayInMillis, TEXT("Delaying execution using timeSetEvent ...")); - exec_check(timing_WaitForSingleObject, delayInMillis, TEXT("Delaying execution using WaitForSingleObject ...")); - exec_check(timing_WaitForMultipleObjects, delayInMillis, TEXT("Delaying execution using WaitForMultipleObjects ...")); - exec_check(timing_IcmpSendEcho, delayInMillis, TEXT("Delaying execution using IcmpSendEcho ...")); - exec_check(timing_CreateWaitableTimer, delayInMillis, TEXT("Delaying execution using CreateWaitableTimer ...")); - exec_check(timing_CreateTimerQueueTimer, delayInMillis, TEXT("Delaying execution using CreateTimerQueueTimer ...")); - - exec_check(&rdtsc_diff_locky, TEXT("Checking RDTSC Locky trick ")); - exec_check(&rdtsc_diff_vmexit, TEXT("Checking RDTSC which force a VM Exit (cpuid) ")); + exec_check(CAT_TIMING_ATTACKS, timing_NtDelayexecution, delayInMillis, TEXT("Performing a sleep using NtDelayExecution ...")); + exec_check(CAT_TIMING_ATTACKS, timing_sleep_loop, delayInMillis, TEXT("Performing a sleep() in a loop ...")); + exec_check(CAT_TIMING_ATTACKS, timing_SetTimer, delayInMillis, TEXT("Delaying execution using SetTimer ...")); + exec_check(CAT_TIMING_ATTACKS, timing_timeSetEvent, delayInMillis, TEXT("Delaying execution using timeSetEvent ...")); + exec_check(CAT_TIMING_ATTACKS, timing_WaitForSingleObject, delayInMillis, TEXT("Delaying execution using WaitForSingleObject ...")); + exec_check(CAT_TIMING_ATTACKS, timing_WaitForMultipleObjects, delayInMillis, TEXT("Delaying execution using WaitForMultipleObjects ...")); + exec_check(CAT_TIMING_ATTACKS, timing_IcmpSendEcho, delayInMillis, TEXT("Delaying execution using IcmpSendEcho ...")); + exec_check(CAT_TIMING_ATTACKS, timing_CreateWaitableTimer, delayInMillis, TEXT("Delaying execution using CreateWaitableTimer ...")); + exec_check(CAT_TIMING_ATTACKS, timing_CreateTimerQueueTimer, delayInMillis, TEXT("Delaying execution using CreateTimerQueueTimer ...")); + + exec_check(CAT_TIMING_ATTACKS, &rdtsc_diff_locky, TEXT("Checking RDTSC Locky trick ")); + exec_check(CAT_TIMING_ATTACKS, &rdtsc_diff_vmexit, TEXT("Checking RDTSC which force a VM Exit (cpuid) ")); } /* Malware analysis tools */ @@ -440,6 +448,8 @@ int main(int argc, char* argv[]){ SizeOfImage(); } + stats_print(); + _tprintf(_T("\n\nAnalysis done, I hope you didn't get red flags :)")); getchar(); diff --git a/al-khaser/AntiAnalysis/process.cpp b/al-khaser/AntiAnalysis/process.cpp index 0b0b1c7..9be52b6 100644 --- a/al-khaser/AntiAnalysis/process.cpp +++ b/al-khaser/AntiAnalysis/process.cpp @@ -64,9 +64,13 @@ VOID analysis_tools_process() { TCHAR msg[256] = _T(""); _stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking process of malware analysis tool: %s "), szProcesses[i]); - if (GetProcessIdFromName(szProcesses[i])) + if (GetProcessIdFromName(szProcesses[i])) { print_results(TRUE, msg); - else + stats_record(CAT_ANALYSIS_TOOLS, TRUE); + } + else { print_results(FALSE, msg); + stats_record(CAT_ANALYSIS_TOOLS, FALSE); + } } } diff --git a/al-khaser/AntiVM/Generic.cpp b/al-khaser/AntiVM/Generic.cpp index 3f83b42..ce19b95 100644 --- a/al-khaser/AntiVM/Generic.cpp +++ b/al-khaser/AntiVM/Generic.cpp @@ -35,10 +35,14 @@ VOID loaded_dlls() /* Check if process loaded modules contains the blacklisted dll */ hDll = GetModuleHandle(szDlls[i]); - if (hDll == NULL) + if (hDll == NULL){ print_results(FALSE, msg); - else + stats_record(CAT_GEN_SANDBOX, FALSE); + } + else { print_results(TRUE, msg); + stats_record(CAT_GEN_SANDBOX, TRUE); + } } } @@ -82,19 +86,27 @@ VOID known_file_names() { _stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking if process file name contains: %s "), szFilenames[i]); /* Check if file name matches any blacklisted filenames */ - if (StrCmpIW(szFilenames[i], szFileName) != 0) + if (StrCmpIW(szFilenames[i], szFileName) != 0) { print_results(FALSE, msg); - else + stats_record(CAT_GEN_SANDBOX, FALSE); + } + else { print_results(TRUE, msg); + stats_record(CAT_GEN_SANDBOX, TRUE); + } } // Some malware do check if the file name is a known hash (like md5 or sha1) PathRemoveExtensionW(szFileName); _stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking if process file name looks like a hash: %s "), szFileName); - if ((wcslen(szFileName) == 32 || wcslen(szFileName) == 40 || wcslen(szFileName) == 64) && IsHexString(szFileName)) + if ((wcslen(szFileName) == 32 || wcslen(szFileName) == 40 || wcslen(szFileName) == 64) && IsHexString(szFileName)) { print_results(TRUE, msg); - else + stats_record(CAT_GEN_SANDBOX, TRUE); + } + else { print_results(FALSE, msg); + stats_record(CAT_GEN_SANDBOX, FALSE); + } } static TCHAR* get_username() { @@ -171,6 +183,8 @@ VOID known_usernames() { } print_results(matched, msg); + stats_record(CAT_GEN_SANDBOX, matched); + } free(username); @@ -262,6 +276,8 @@ VOID known_hostnames() { } print_results(matched, msg); + stats_record(CAT_GEN_SANDBOX, matched); + } free(NetBIOSHostName); @@ -300,18 +316,21 @@ VOID other_known_sandbox_environment_checks() { matched = TRUE; } print_results(matched, (TCHAR*)_T("Checking whether username is 'Wilber' and NetBIOS name starts with 'SC' or 'SW' ")); + stats_record(CAT_GEN_SANDBOX, matched); matched = FALSE; if ((0 == StrCmp(username, _T("admin"))) && (0 == StrCmp(NetBIOSHostName, _T("SystemIT")))) { matched = TRUE; } print_results(matched, (TCHAR*)_T("Checking whether username is 'admin' and NetBIOS name is 'SystemIT' ")); + stats_record(CAT_GEN_SANDBOX, matched); matched = FALSE; if ((0 == StrCmp(username, _T("admin"))) && (0 == StrCmp(DNSHostName, _T("KLONE_X64-PC")))) { matched = TRUE; } print_results(matched, (TCHAR*)_T("Checking whether username is 'admin' and DNS hostname is 'KLONE_X64-PC' ")); + stats_record(CAT_GEN_SANDBOX, matched); matched = FALSE; if ((0 == StrCmp(username, _T("John"))) && @@ -320,6 +339,7 @@ VOID other_known_sandbox_environment_checks() { matched = TRUE; } print_results(matched, (TCHAR*)_T("Checking whether username is 'John' and two sandbox files exist ")); + stats_record(CAT_GEN_SANDBOX, matched); matched = FALSE; if ((is_FileExists((TCHAR*)_T("C:\\email.doc"))) && @@ -329,6 +349,7 @@ VOID other_known_sandbox_environment_checks() { matched = TRUE; } print_results(matched, (TCHAR*)_T("Checking whether four known sandbox 'email' file paths exist ")); + stats_record(CAT_GEN_SANDBOX, matched); matched = FALSE; if ((is_FileExists((TCHAR*)_T("C:\\a\\foobar.bmp"))) && @@ -337,6 +358,7 @@ VOID other_known_sandbox_environment_checks() { matched = TRUE; } print_results(matched, (TCHAR*)_T("Checking whether three known sandbox 'foobar' files exist ")); + stats_record(CAT_GEN_SANDBOX, matched); free(username); free(NetBIOSHostName); @@ -2249,9 +2271,13 @@ VOID looking_glass_vdd_processes() TCHAR msg[256] = _T(""); _stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking processes %s "), szProcesses[i]); - if (GetProcessIdFromName(szProcesses[i])) + if (GetProcessIdFromName(szProcesses[i])) { print_results(TRUE, msg); - else + stats_record(CAT_GEN_SANDBOX, TRUE); + } + else { print_results(FALSE, msg); + stats_record(CAT_GEN_SANDBOX, FALSE); + } } } diff --git a/al-khaser/AntiVM/KVM.cpp b/al-khaser/AntiVM/KVM.cpp index 0500675..40bd71c 100644 --- a/al-khaser/AntiVM/KVM.cpp +++ b/al-khaser/AntiVM/KVM.cpp @@ -25,10 +25,14 @@ VOID kvm_reg_keys() { TCHAR msg[256] = _T(""); _stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking reg key %s "), szKeys[i]); - if (Is_RegKeyExists(HKEY_LOCAL_MACHINE, szKeys[i])) + if (Is_RegKeyExists(HKEY_LOCAL_MACHINE, szKeys[i])) { print_results(TRUE, msg); - else + stats_record(CAT_KVM, TRUE); + } + else { print_results(FALSE, msg); + stats_record(CAT_KVM, FALSE); + } } } @@ -70,10 +74,14 @@ VOID kvm_files() PathCombine(szPath, szWinDir, szPaths[i]); TCHAR msg[256] = _T(""); _stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking file %s "), szPath); - if (is_FileExists(szPath)) + if (is_FileExists(szPath)) { print_results(TRUE, msg); - else + stats_record(CAT_KVM, TRUE); + } + else { print_results(FALSE, msg); + stats_record(CAT_KVM, FALSE); + } } if (IsWoW64()) { diff --git a/al-khaser/AntiVM/Parallels.cpp b/al-khaser/AntiVM/Parallels.cpp index d91d3b6..23c7bce 100644 --- a/al-khaser/AntiVM/Parallels.cpp +++ b/al-khaser/AntiVM/Parallels.cpp @@ -20,10 +20,14 @@ VOID parallels_reg_keys() TCHAR msg[256] = _T(""); _stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking reg key %s "), szKeys[i]); - if (Is_RegKeyExists(HKEY_LOCAL_MACHINE, szKeys[i])) + if (Is_RegKeyExists(HKEY_LOCAL_MACHINE, szKeys[i])) { print_results(TRUE, msg); - else + stats_record(CAT_PARALLELS, TRUE); + } + else { print_results(FALSE, msg); + stats_record(CAT_PARALLELS, FALSE); + } } } @@ -43,10 +47,14 @@ VOID parallels_process() { TCHAR msg[256] = _T(""); _stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking Parallels processes: %s"), szProcesses[i]); - if (GetProcessIdFromName(szProcesses[i])) + if (GetProcessIdFromName(szProcesses[i])) { print_results(TRUE, msg); - else + stats_record(CAT_PARALLELS, TRUE); + } + else { print_results(FALSE, msg); + stats_record(CAT_PARALLELS, FALSE); + } } } diff --git a/al-khaser/AntiVM/Qemu.cpp b/al-khaser/AntiVM/Qemu.cpp index ae114b6..295f365 100644 --- a/al-khaser/AntiVM/Qemu.cpp +++ b/al-khaser/AntiVM/Qemu.cpp @@ -20,10 +20,14 @@ VOID qemu_reg_key_value() { TCHAR msg[256] = _T(""); _stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking reg key %s "), szEntries[i][0]); - if (Is_RegKeyValueExists(HKEY_LOCAL_MACHINE, szEntries[i][0], szEntries[i][1], szEntries[i][2])) + if (Is_RegKeyValueExists(HKEY_LOCAL_MACHINE, szEntries[i][0], szEntries[i][1], szEntries[i][2])) { print_results(TRUE, msg); - else + stats_record(CAT_QEMU, TRUE); + } + else { print_results(FALSE, msg); + stats_record(CAT_QEMU, FALSE); + } } } @@ -46,10 +50,14 @@ VOID qemu_reg_keys() TCHAR msg[256] = _T(""); _stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking reg key %s "), szKeys[i]); - if (Is_RegKeyExists(HKEY_LOCAL_MACHINE, szKeys[i])) + if (Is_RegKeyExists(HKEY_LOCAL_MACHINE, szKeys[i])) { print_results(TRUE, msg); - else + stats_record(CAT_QEMU, TRUE); + } + else { print_results(FALSE, msg); + stats_record(CAT_QEMU, FALSE); + } } } @@ -70,10 +78,14 @@ VOID qemu_processes() { TCHAR msg[256] = _T(""); _stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking qemu processes %s "), szProcesses[i]); - if (GetProcessIdFromName(szProcesses[i])) + if (GetProcessIdFromName(szProcesses[i])) { print_results(TRUE, msg); - else + stats_record(CAT_QEMU, TRUE); + } + else { print_results(FALSE, msg); + stats_record(CAT_QEMU, FALSE); + } } } @@ -103,10 +115,14 @@ VOID qemu_dir() PathCombine(szPath, szProgramFile, szDirectories[i]); _stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking QEMU directory %s "), szPath); - if (is_DirectoryExists(szPath)) + if (is_DirectoryExists(szPath)) { print_results(TRUE, msg); - else + stats_record(CAT_QEMU, TRUE); + } + else { print_results(FALSE, msg); + stats_record(CAT_QEMU, FALSE); + } } } diff --git a/al-khaser/AntiVM/VMWare.cpp b/al-khaser/AntiVM/VMWare.cpp index 90e487d..d1dbea1 100644 --- a/al-khaser/AntiVM/VMWare.cpp +++ b/al-khaser/AntiVM/VMWare.cpp @@ -22,10 +22,14 @@ VOID vmware_reg_key_value() { TCHAR msg[256] = _T(""); _stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking reg key %s"), szEntries[i][0]); - if (Is_RegKeyValueExists(HKEY_LOCAL_MACHINE, szEntries[i][0], szEntries[i][1], szEntries[i][2])) + if (Is_RegKeyValueExists(HKEY_LOCAL_MACHINE, szEntries[i][0], szEntries[i][1], szEntries[i][2])) { print_results(TRUE, msg); - else + stats_record(CAT_VMWARE, TRUE); + } + else { print_results(FALSE, msg); + stats_record(CAT_VMWARE, FALSE); + } } } @@ -49,10 +53,14 @@ VOID vmware_reg_keys() { TCHAR msg[256] = _T(""); _stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking reg key %s "), szKeys[i]); - if (Is_RegKeyExists(HKEY_LOCAL_MACHINE, szKeys[i])) + if (Is_RegKeyExists(HKEY_LOCAL_MACHINE, szKeys[i])){ print_results(TRUE, msg); - else + stats_record(CAT_VMWARE, TRUE); + } + else { print_results(FALSE, msg); + stats_record(CAT_VMWARE, FALSE); + } } } @@ -97,10 +105,14 @@ VOID vmware_files() PathCombine(szPath, szWinDir, szPaths[i]); TCHAR msg[256] = _T(""); _stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking file %s "), szPath); - if (is_FileExists(szPath)) + if (is_FileExists(szPath)) { print_results(TRUE, msg); - else + stats_record(CAT_VMWARE, TRUE); + } + else { print_results(FALSE, msg); + stats_record(CAT_VMWARE, FALSE); + } } if (IsWoW64()) { @@ -148,10 +160,14 @@ VOID vmware_mac() { TCHAR msg[256] = _T(""); _stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking MAC starting with %s"), szMac[i][1]); - if (check_mac_addr(szMac[i][0])) + if (check_mac_addr(szMac[i][0])) { print_results(TRUE, msg); - else + stats_record(CAT_VMWARE, TRUE); + } + else { print_results(FALSE, msg); + stats_record(CAT_VMWARE, FALSE); + } } } @@ -189,9 +205,12 @@ VOID vmware_devices() if (hFile != INVALID_HANDLE_VALUE) { CloseHandle(hFile); print_results(TRUE, msg); + stats_record(CAT_VMWARE, TRUE); } - else + else { print_results(FALSE, msg); + stats_record(CAT_VMWARE, FALSE); + } } } @@ -215,10 +234,14 @@ VOID vmware_processes() { TCHAR msg[256] = _T(""); _stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking VWware process %s "), szProcesses[i]); - if (GetProcessIdFromName(szProcesses[i])) + if (GetProcessIdFromName(szProcesses[i])) { print_results(TRUE, msg); - else + stats_record(CAT_VMWARE, TRUE); + } + else { print_results(FALSE, msg); + stats_record(CAT_VMWARE, FALSE); + } } } diff --git a/al-khaser/AntiVM/VirtualBox.cpp b/al-khaser/AntiVM/VirtualBox.cpp index d31ede5..c1f1b2d 100644 --- a/al-khaser/AntiVM/VirtualBox.cpp +++ b/al-khaser/AntiVM/VirtualBox.cpp @@ -21,10 +21,14 @@ VOID vbox_reg_key_value() { TCHAR msg[256] = _T(""); _stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking reg key HARDWARE\\Description\\System - %s is set to %s"), szEntries[i][1], szEntries[i][2]); - if (Is_RegKeyValueExists(HKEY_LOCAL_MACHINE, szEntries[i][0], szEntries[i][1], szEntries[i][2])) + if (Is_RegKeyValueExists(HKEY_LOCAL_MACHINE, szEntries[i][0], szEntries[i][1], szEntries[i][2])){ print_results(TRUE, msg); - else + stats_record(CAT_VBOX, TRUE); + } + else { print_results(FALSE, msg); + stats_record(CAT_VBOX, FALSE); + } } } @@ -55,10 +59,14 @@ VOID vbox_reg_keys() { TCHAR msg[256] = _T(""); _stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking reg key %s "), szKeys[i]); - if (Is_RegKeyExists(HKEY_LOCAL_MACHINE, szKeys[i])) + if (Is_RegKeyExists(HKEY_LOCAL_MACHINE, szKeys[i])) { print_results(TRUE, msg); - else + stats_record(CAT_VBOX, TRUE); + } + else { print_results(FALSE, msg); + stats_record(CAT_VBOX, FALSE); + } } } @@ -107,10 +115,14 @@ VOID vbox_files() PathCombine(szPath, szWinDir, szPaths[i]); TCHAR msg[256] = _T(""); _stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking file %s "), szPath); - if (is_FileExists(szPath)) + if (is_FileExists(szPath)){ print_results(TRUE, msg); - else + stats_record(CAT_VBOX, TRUE); + } + else { print_results(FALSE, msg); + stats_record(CAT_VBOX, FALSE); + } } if (IsWoW64()) { @@ -167,12 +179,15 @@ VOID vbox_devices() HANDLE hFile = CreateFile(devices[i], GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); TCHAR msg[256] = _T(""); _stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking device %s "), devices[i]); - if (hFile != INVALID_HANDLE_VALUE) { + if (hFile != INVALID_HANDLE_VALUE){ CloseHandle(hFile); print_results(TRUE, msg); + stats_record(CAT_VBOX, TRUE); } - else + else { print_results(FALSE, msg); + stats_record(CAT_VBOX, FALSE); + } } } @@ -226,10 +241,14 @@ VOID vbox_processes() { TCHAR msg[256] = _T(""); _stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking VirtualBox process %s "), szProcesses[i]); - if (GetProcessIdFromName(szProcesses[i])) + if (GetProcessIdFromName(szProcesses[i])){ print_results(TRUE, msg); - else + stats_record(CAT_VBOX, TRUE); + } + else { print_results(FALSE, msg); + stats_record(CAT_VBOX, FALSE); + } } } diff --git a/al-khaser/AntiVM/VirtualPC.cpp b/al-khaser/AntiVM/VirtualPC.cpp index bf28b79..6e548d3 100644 --- a/al-khaser/AntiVM/VirtualPC.cpp +++ b/al-khaser/AntiVM/VirtualPC.cpp @@ -18,10 +18,14 @@ VOID virtual_pc_process() { TCHAR msg[256] = _T(""); _stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking Virtual PC processes %s "), szProcesses[i]); - if (GetProcessIdFromName(szProcesses[i])) + if (GetProcessIdFromName(szProcesses[i])){ print_results(TRUE, msg); - else + stats_record(CAT_VPC, TRUE); + } + else { print_results(FALSE, msg); + stats_record(CAT_VPC, FALSE); + } } } @@ -42,9 +46,13 @@ VOID virtual_pc_reg_keys() { TCHAR msg[256] = _T(""); _stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking reg key %s "), szKeys[i]); - if (Is_RegKeyExists(HKEY_LOCAL_MACHINE, szKeys[i])) + if (Is_RegKeyExists(HKEY_LOCAL_MACHINE, szKeys[i])) { print_results(TRUE, msg); - else + stats_record(CAT_VPC, TRUE); + } + else { print_results(FALSE, msg); + stats_record(CAT_VPC, FALSE); + } } } diff --git a/al-khaser/AntiVM/Wine.cpp b/al-khaser/AntiVM/Wine.cpp index 05658a8..e0f7df1 100644 --- a/al-khaser/AntiVM/Wine.cpp +++ b/al-khaser/AntiVM/Wine.cpp @@ -41,9 +41,13 @@ VOID wine_reg_keys() { TCHAR msg[256] = _T(""); _stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking reg key %s "), szKeys[i]); - if (Is_RegKeyExists(HKEY_CURRENT_USER, szKeys[i])) + if (Is_RegKeyExists(HKEY_CURRENT_USER, szKeys[i])) { print_results(TRUE, msg); - else + stats_record(CAT_WINE, TRUE); + } + else { print_results(FALSE, msg); + stats_record(CAT_WINE, FALSE); + } } } diff --git a/al-khaser/AntiVM/Xen.cpp b/al-khaser/AntiVM/Xen.cpp index f8eaa6d..cf673ad 100644 --- a/al-khaser/AntiVM/Xen.cpp +++ b/al-khaser/AntiVM/Xen.cpp @@ -19,10 +19,14 @@ VOID xen_reg_keys() { TCHAR msg[256] = _T(""); _stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking reg key %s "), szKeys[i]); - if (Is_RegKeyExists(HKEY_LOCAL_MACHINE, szKeys[i])) + if (Is_RegKeyExists(HKEY_LOCAL_MACHINE, szKeys[i])) { print_results(TRUE, msg); - else + stats_record(CAT_XEN, TRUE); + } + else { print_results(FALSE, msg); + stats_record(CAT_XEN, FALSE); + } } } @@ -41,10 +45,14 @@ VOID xen_process() { TCHAR msg[256] = _T(""); _stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking Citrix Xen process %s"), szProcesses[i]); - if (GetProcessIdFromName(szProcesses[i])) + if (GetProcessIdFromName(szProcesses[i])) { print_results(TRUE, msg); - else + stats_record(CAT_XEN, TRUE); + } + else { print_results(FALSE, msg); + stats_record(CAT_XEN, FALSE); + } } } diff --git a/al-khaser/CodeInjection/CreateRemoteThread.cpp b/al-khaser/CodeInjection/CreateRemoteThread.cpp index 20a773a..aae8dca 100644 --- a/al-khaser/CodeInjection/CreateRemoteThread.cpp +++ b/al-khaser/CodeInjection/CreateRemoteThread.cpp @@ -17,8 +17,9 @@ BOOL CreateRemoteThread_Injection() /* Get Process ID from Process name */ dwProcessId = GetProcessIdFromName(_T("notepad.exe")); - if (dwProcessId == NULL) + if (dwProcessId == NULL) { return FALSE; + } _tprintf(_T("\t[+] Getting proc id: %u\n"), dwProcessId); /* Set Debug privilege */ diff --git a/al-khaser/Shared/Common.cpp b/al-khaser/Shared/Common.cpp index 079156e..127b647 100644 --- a/al-khaser/Shared/Common.cpp +++ b/al-khaser/Shared/Common.cpp @@ -94,6 +94,23 @@ VOID exec_check(int(*callback)(), const TCHAR* szMsg) _print_check_result(result, szMsg); } +/* Run a check function pointer, print message, and record stats */ +VOID exec_check(Category category, int(*callback)(), const TCHAR* szMsg) +{ + /* Print the text to screen so we can see what's currently running */ + _print_check_text(szMsg); + + /* Call our check */ + int result = callback(); + + /* Record the result for statistics */ + stats_record((category), result); + + /* Print / Log the result */ + if (szMsg) + _print_check_result(result, szMsg); +} + VOID resize_console_window() { // Change the window title: diff --git a/al-khaser/Shared/Common.h b/al-khaser/Shared/Common.h index 14a53a5..2e16b48 100644 --- a/al-khaser/Shared/Common.h +++ b/al-khaser/Shared/Common.h @@ -1,4 +1,5 @@ #pragma once +#include "stats.h" VOID print_detected() ; VOID print_not_detected() ; @@ -14,6 +15,7 @@ VOID _print_check_text(const TCHAR* szMsg); VOID _print_check_result(int result, const TCHAR* szMsg); VOID exec_check(int(*callback)(), const TCHAR* szMsg); +VOID exec_check(Category category, int(*callback)(), const TCHAR* szMsg); // this must be defined in this header file // see: https://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file @@ -26,6 +28,25 @@ VOID exec_check(int(*callback)(T param), T param, const TCHAR* szMsg) /* Call our check */ int result = callback(param); + /* Print / Log the result */ + if (szMsg) + _print_check_result(result, szMsg); +} + + +/* For checks with one additional argument (e.g. delay) and also statistics */ +template +VOID exec_check(Category category, int(*callback)(T param), T param, const TCHAR* szMsg) +{ + /* Print the text to screen so we can see what's currently running */ + _print_check_text(szMsg); + + /* Call our check */ + int result = callback(param); + + /* Record the result for statistics */ + stats_record((category), result); + /* Print / Log the result */ if (szMsg) _print_check_result(result, szMsg); diff --git a/al-khaser/Shared/stats.cpp b/al-khaser/Shared/stats.cpp new file mode 100644 index 0000000..a5b18c2 --- /dev/null +++ b/al-khaser/Shared/stats.cpp @@ -0,0 +1,55 @@ +#include "pch.h" + +const char* category_names[CAT_COUNT] = { // New categories to be added here. Order must be same as Category enum + "TLS", + "DEBUG", + "INJECTION", + "GEN_SANDBOX", + "VBOX", + "VMWARE", + "VPC", + "QEMU", + "KVM", + "XEN", + "WINE", + "PARALLELS", + "HYPERV", + "TIMING_ATTACKS", + "ANALYSIS_TOOLS", + //"CODE_INJECTIONS", + //"ANTI_DISASSM", + //"DUMPING_CHECK" +}; + + +static CategoryStat category_stats[CAT_COUNT]; +static int total_passed = 0, total_failed = 0; + +void stats_init(void) { + memset(category_stats, 0, sizeof(category_stats)); + total_passed = 0; + total_failed = 0; +} + +void stats_record(Category cat, int result) { + if (cat < 0 || cat >= CAT_COUNT) + return; + if (result == TRUE) { + category_stats[cat].failed++; + total_failed++; + } else { + category_stats[cat].passed++; + total_passed++; + } +} + +void stats_print(void) { + printf("\n==== Per-Category Statistics ====\n"); + for (int i = 0; i < CAT_COUNT; ++i) { + printf("%-16s: Passed %3d | Failed %3d\n", + category_names[i], category_stats[i].passed, category_stats[i].failed); + } + printf("\n==== Overall Statistics ====\n"); + printf("Total checks passed: %d\n", total_passed); + printf("Total checks failed: %d\n", total_failed); +} \ No newline at end of file diff --git a/al-khaser/Shared/stats.h b/al-khaser/Shared/stats.h new file mode 100644 index 0000000..5364f83 --- /dev/null +++ b/al-khaser/Shared/stats.h @@ -0,0 +1,35 @@ +#pragma once + +// Category enum and names +typedef enum { // New categories to be added here. Order is important. + CAT_TLS, + CAT_DEBUG, + CAT_INJECTION, + CAT_GEN_SANDBOX, + CAT_VBOX, + CAT_VMWARE, + CAT_VPC, + CAT_QEMU, + CAT_KVM, + CAT_XEN, + CAT_WINE, + CAT_PARALLELS, + CAT_HYPERV, + CAT_TIMING_ATTACKS, + CAT_ANALYSIS_TOOLS, + //CAT_CODE_INJECTIONS, // Disabled by default, not part of EnableDefaultChecks() + //CAT_ANTI_DISASSM, + //CAT_DUMPING_CHECK, + CAT_COUNT // Always last -> number of categories +} Category; + +extern const char* category_names[CAT_COUNT]; + +typedef struct { + int passed; + int failed; +} CategoryStat; + +void stats_init(void); +void stats_record(Category cat, int result); // result: 1 = pass, 0 = fail +void stats_print(void); diff --git a/al-khaser/al-khaser.vcxproj b/al-khaser/al-khaser.vcxproj index 46187bd..34bacf3 100644 --- a/al-khaser/al-khaser.vcxproj +++ b/al-khaser/al-khaser.vcxproj @@ -240,6 +240,7 @@ + @@ -313,6 +314,7 @@ + diff --git a/al-khaser/al-khaser.vcxproj.filters b/al-khaser/al-khaser.vcxproj.filters index 2172159..7d61646 100644 --- a/al-khaser/al-khaser.vcxproj.filters +++ b/al-khaser/al-khaser.vcxproj.filters @@ -293,6 +293,9 @@ AntiVM\Header + + Shared\Header + @@ -484,6 +487,9 @@ AntiVM\Source + + Shared\Source + diff --git a/al-khaser/pch.h b/al-khaser/pch.h index 7ebc37b..344bc19 100644 --- a/al-khaser/pch.h +++ b/al-khaser/pch.h @@ -69,6 +69,8 @@ #include "Shared/ApiTypeDefs.h" #include "Shared/APIs.h" #include "Shared/winapifamily.h" +/* Statistics */ +#include "Shared/stats.h" /* AntiDebugs headers */ #include "AntiDebug/CheckRemoteDebuggerPresent.h" @@ -142,5 +144,4 @@ /* Anti-Disassembly */ #include "AntiDisassm/AntiDisassm.h" - #endif //PCH_H From 647d6c165360dedc758132424851718244ce3f98 Mon Sep 17 00:00:00 2001 From: RazviOverflow Date: Tue, 1 Jul 2025 19:25:54 +0200 Subject: [PATCH 4/5] Improved Category Names --- al-khaser/Shared/stats.cpp | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/al-khaser/Shared/stats.cpp b/al-khaser/Shared/stats.cpp index a5b18c2..dddb9af 100644 --- a/al-khaser/Shared/stats.cpp +++ b/al-khaser/Shared/stats.cpp @@ -1,21 +1,21 @@ #include "pch.h" const char* category_names[CAT_COUNT] = { // New categories to be added here. Order must be same as Category enum - "TLS", - "DEBUG", - "INJECTION", - "GEN_SANDBOX", - "VBOX", - "VMWARE", - "VPC", - "QEMU", - "KVM", - "XEN", - "WINE", - "PARALLELS", - "HYPERV", - "TIMING_ATTACKS", - "ANALYSIS_TOOLS", + "TLS Callbacks", + "Debugger Detection", + "DLL Injection Detection", + "Generic Sandbox/VM Detection", + "VirtualBox Detection", + "VMWare Detection", + "Virtual PC Detection", + "QEMU Detection", + "KVM Detection", + "Xen Detection", + "Wine Detection", + "Parallels Detection", + "Hyper-V Detection", + "Timitng Attacks", + "Analysis Tools", //"CODE_INJECTIONS", //"ANTI_DISASSM", //"DUMPING_CHECK" From d2ce55700a28d0ae41a4acf7e0394cd928897727 Mon Sep 17 00:00:00 2001 From: RazviOverflow Date: Tue, 1 Jul 2025 19:46:11 +0200 Subject: [PATCH 5/5] Fixed spaces --- al-khaser/Shared/stats.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/al-khaser/Shared/stats.cpp b/al-khaser/Shared/stats.cpp index dddb9af..120fb03 100644 --- a/al-khaser/Shared/stats.cpp +++ b/al-khaser/Shared/stats.cpp @@ -46,7 +46,7 @@ void stats_record(Category cat, int result) { void stats_print(void) { printf("\n==== Per-Category Statistics ====\n"); for (int i = 0; i < CAT_COUNT; ++i) { - printf("%-16s: Passed %3d | Failed %3d\n", + printf("%-40s: Passed %3d | Failed %3d\n", category_names[i], category_stats[i].passed, category_stats[i].failed); } printf("\n==== Overall Statistics ====\n");