From 4b98479701c9d3c75b51bcbdb9b1e57bebc09f9a Mon Sep 17 00:00:00 2001 From: pxcs Date: Mon, 2 Sep 2024 22:46:45 +0800 Subject: [PATCH] bypass contributions --- byp/.editorconfig | 11 + byp/.gitattributes | 53 + byp/.gitignore | 72 + byp/blackmarlinexec.sln | 45 + byp/sbexecution/AntiAnalysis/pch.h | 1 + byp/sbexecution/AntiAnalysis/process.cpp | 60 + byp/sbexecution/AntiAnalysis/process.h | 11 + byp/sbexecution/AntiDebug/BeingDebugged.cpp | 36 + byp/sbexecution/AntiDebug/BeingDebugged.h | 3 + .../AntiDebug/CheckRemoteDebuggerPresent.cpp | 32 + .../AntiDebug/CheckRemoteDebuggerPresent.h | 1 + .../AntiDebug/CloseHandle_InvalidHandle.cpp | 43 + .../AntiDebug/CloseHandle_InvalidHandle.h | 1 + .../AntiDebug/HardwareBreakpoints.cpp | 41 + .../AntiDebug/HardwareBreakpoints.h | 1 + byp/sbexecution/AntiDebug/Interrupt_0x2d.cpp | 37 + byp/sbexecution/AntiDebug/Interrupt_0x2d.h | 1 + byp/sbexecution/AntiDebug/Interrupt_3.cpp | 43 + byp/sbexecution/AntiDebug/Interrupt_3.h | 3 + .../AntiDebug/IsDebuggerPresent.cpp | 28 + byp/sbexecution/AntiDebug/IsDebuggerPresent.h | 3 + .../AntiDebug/LowFragmentationHeap.cpp | 61 + .../AntiDebug/LowFragmentationHeap.h | 6 + .../AntiDebug/MemoryBreakpoints_PageGuard.cpp | 47 + .../AntiDebug/MemoryBreakpoints_PageGuard.h | 3 + .../AntiDebug/ModuleBoundsHookCheck.cpp | 108 + .../AntiDebug/ModuleBoundsHookCheck.h | 3 + byp/sbexecution/AntiDebug/NtGlobalFlag.cpp | 63 + byp/sbexecution/AntiDebug/NtGlobalFlag.h | 3 + ...ryInformationProcess_ProcessDebugFlags.cpp | 26 + ...ueryInformationProcess_ProcessDebugFlags.h | 3 + ...yInformationProcess_ProcessDebugObject.cpp | 49 + ...eryInformationProcess_ProcessDebugObject.h | 5 + ...eryInformationProcess_ProcessDebugPort.cpp | 35 + ...QueryInformationProcess_ProcessDebugPort.h | 3 + .../NtQueryObject_AllTypesInformation.cpp | 87 + .../NtQueryObject_ObjectInformation.h | 24 + .../NtQueryObject_ObjectTypeInformation.cpp | 54 + ...mation_SystemKernelDebuggerInformation.cpp | 30 + ...ormation_SystemKernelDebuggerInformation.h | 9 + ...formationThread_ThreadHideFromDebugger.cpp | 133 ++ ...InformationThread_ThreadHideFromDebugger.h | 3 + .../AntiDebug/NtSystemDebugControl.cpp | 19 + .../AntiDebug/NtSystemDebugControl.h | 1 + .../AntiDebug/NtYieldExecution.cpp | 38 + byp/sbexecution/AntiDebug/NtYieldExecution.h | 5 + .../AntiDebug/OutputDebugStringAPI.cpp | 34 + .../AntiDebug/OutputDebugStringAPI.h | 3 + .../PageExceptionBreakpointCheck.cpp | 139 ++ .../AntiDebug/PageExceptionBreakpointCheck.h | 4 + byp/sbexecution/AntiDebug/ParentProcess.cpp | 85 + byp/sbexecution/AntiDebug/ParentProcess.h | 11 + .../AntiDebug/ProcessHeap_Flags.cpp | 66 + byp/sbexecution/AntiDebug/ProcessHeap_Flags.h | 3 + .../AntiDebug/ProcessHeap_ForceFlags.cpp | 68 + .../AntiDebug/ProcessHeap_ForceFlags.h | 3 + byp/sbexecution/AntiDebug/ProcessJob.cpp | 78 + byp/sbexecution/AntiDebug/ProcessJob.h | 9 + byp/sbexecution/AntiDebug/ScanForModules.cpp | 711 ++++++ byp/sbexecution/AntiDebug/ScanForModules.h | 11 + .../AntiDebug/SeDebugPrivilege.cpp | 36 + byp/sbexecution/AntiDebug/SeDebugPrivilege.h | 3 + .../AntiDebug/SetHandleInformation_API.cpp | 33 + .../AntiDebug/SetHandleInformation_API.h | 3 + .../SharedUserData_KernelDebugger.cpp | 32 + .../AntiDebug/SharedUserData_KernelDebugger.h | 3 + .../AntiDebug/SoftwareBreakpoints.cpp | 44 + .../AntiDebug/SoftwareBreakpoints.h | 3 + byp/sbexecution/AntiDebug/TLS_callbacks.cpp | 136 ++ byp/sbexecution/AntiDebug/TLS_callbacks.h | 10 + byp/sbexecution/AntiDebug/TrapFlag.cpp | 51 + byp/sbexecution/AntiDebug/TrapFlag.h | 3 + .../UnhandledExceptionFilter_Handler.cpp | 27 + .../UnhandledExceptionFilter_Handler.h | 3 + .../AntiDebug/WUDF_IsDebuggerPresent.cpp | 35 + .../AntiDebug/WUDF_IsDebuggerPresent.h | 3 + byp/sbexecution/AntiDebug/WriteWatch.cpp | 296 +++ byp/sbexecution/AntiDebug/WriteWatch.h | 6 + byp/sbexecution/AntiDebug/int2d_x64.asm | 10 + byp/sbexecution/AntiDebug/int2d_x86.asm | 11 + byp/sbexecution/AntiDebug/pch.h | 1 + byp/sbexecution/AntiDisassm/AntiDisassm.cpp | 74 + byp/sbexecution/AntiDisassm/AntiDisassm.h | 8 + .../AntiDisassm/AntiDisassm_x64.asm | 75 + .../AntiDisassm/AntiDisassm_x86.asm | 111 + byp/sbexecution/AntiDisassm/pch.h | 1 + .../AntiDump/ErasePEHeaderFromMemory.cpp | 25 + .../AntiDump/ErasePEHeaderFromMemory.h | 3 + byp/sbexecution/AntiDump/SizeOfImage.cpp | 23 + byp/sbexecution/AntiDump/SizeOfImage.h | 3 + byp/sbexecution/AntiDump/pch.h | 1 + byp/sbexecution/AntiVM/Generic.cpp | 2046 +++++++++++++++++ byp/sbexecution/AntiVM/Generic.h | 52 + byp/sbexecution/AntiVM/HyperV.cpp | 70 + byp/sbexecution/AntiVM/HyperV.h | 4 + byp/sbexecution/AntiVM/KVM.cpp | 99 + byp/sbexecution/AntiVM/KVM.h | 5 + byp/sbexecution/AntiVM/Parallels.cpp | 36 + byp/sbexecution/AntiVM/Parallels.h | 4 + byp/sbexecution/AntiVM/Qemu.cpp | 167 ++ byp/sbexecution/AntiVM/Qemu.h | 7 + byp/sbexecution/AntiVM/Services.cpp | 117 + byp/sbexecution/AntiVM/Services.h | 4 + byp/sbexecution/AntiVM/VMWare.cpp | 297 +++ byp/sbexecution/AntiVM/VMWare.h | 12 + byp/sbexecution/AntiVM/VirtualBox.cpp | 920 ++++++++ byp/sbexecution/AntiVM/VirtualBox.h | 21 + byp/sbexecution/AntiVM/VirtualPC.cpp | 49 + byp/sbexecution/AntiVM/VirtualPC.h | 5 + byp/sbexecution/AntiVM/Wine.cpp | 49 + byp/sbexecution/AntiVM/Wine.h | 4 + byp/sbexecution/AntiVM/Xen.cpp | 36 + byp/sbexecution/AntiVM/Xen.h | 4 + byp/sbexecution/AntiVM/pch.h | 1 + .../CodeInjection/CreateRemoteThread.cpp | 97 + .../CodeInjection/CreateRemoteThread.h | 3 + .../CodeInjection/GetSetThreadContext.cpp | 132 ++ .../CodeInjection/GetSetThreadContext.h | 3 + .../CodeInjection/InjectedDLL/InjectedDLL.cpp | 39 + .../CodeInjection/InjectedDLL/InjectedDLL.h | 2 + .../InjectedDLL/InjectedDLL.vcxproj | 163 ++ .../InjectedDLL/InjectedDLL.vcxproj.filters | 32 + .../CodeInjection/InjectedDLL/definitions.def | 3 + .../CodeInjection/NtCreateThreadEx.cpp | 141 ++ .../CodeInjection/NtCreateThreadEx.h | 3 + .../CodeInjection/QueueUserAPC.cpp | 171 ++ byp/sbexecution/CodeInjection/QueueUserAPC.h | 4 + .../CodeInjection/RtlCreateUserThread.cpp | 127 + .../CodeInjection/RtlCreateUserThread.h | 3 + .../CodeInjection/SetWindowsHooksEx.cpp | 61 + .../CodeInjection/SetWindowsHooksEx.h | 3 + byp/sbexecution/CodeInjection/pch.h | 1 + byp/sbexecution/OfficeMacro/al-khaser.docm | Bin 0 -> 17744 bytes byp/sbexecution/OfficeMacro/macros.vba | 29 + byp/sbexecution/Shared/APIs.cpp | 181 ++ byp/sbexecution/Shared/APIs.h | 130 ++ byp/sbexecution/Shared/ApiTypeDefs.cpp | 1 + byp/sbexecution/Shared/ApiTypeDefs.h | 136 ++ byp/sbexecution/Shared/Common.cpp | 199 ++ byp/sbexecution/Shared/Common.h | 32 + byp/sbexecution/Shared/Utils.cpp | 1121 +++++++++ byp/sbexecution/Shared/Utils.h | 45 + byp/sbexecution/Shared/VersionHelpers.h | 166 ++ byp/sbexecution/Shared/WinStructs.h | 133 ++ byp/sbexecution/Shared/log.cpp | 104 + byp/sbexecution/Shared/log.h | 19 + byp/sbexecution/Shared/pch.h | 1 + byp/sbexecution/Shared/winapifamily.h | 183 ++ byp/sbexecution/TimingAttacks/pch.h | 1 + byp/sbexecution/TimingAttacks/timing.cpp | 375 +++ byp/sbexecution/TimingAttacks/timing.h | 14 + byp/sbexecution/blackmarlinexec.cpp | 377 +++ byp/sbexecution/blackmarlinexec.filters | 509 ++++ byp/sbexecution/blackmarlinexec.vcxproj | 351 +++ byp/sbexecution/packages.config | 4 + byp/sbexecution/pch.cpp | 5 + byp/sbexecution/pch.h | 142 ++ byp/tools/ATAIdentifyDump/ATAIdentifyDump.cpp | 442 ++++ .../ATAIdentifyDump/ATAIdentifyDump.vcxproj | 169 ++ .../ATAIdentifyDump.vcxproj.filters | 33 + .../ATAIdentifyDump/IdentifyDeviceData.h | 250 ++ byp/tools/ATAIdentifyDump/pch.cpp | 1 + byp/tools/ATAIdentifyDump/pch.h | 9 + .../struct_dump_codegen.linq | 213 ++ 164 files changed, 14014 insertions(+) create mode 100644 byp/.editorconfig create mode 100644 byp/.gitattributes create mode 100644 byp/.gitignore create mode 100644 byp/blackmarlinexec.sln create mode 100644 byp/sbexecution/AntiAnalysis/pch.h create mode 100644 byp/sbexecution/AntiAnalysis/process.cpp create mode 100644 byp/sbexecution/AntiAnalysis/process.h create mode 100644 byp/sbexecution/AntiDebug/BeingDebugged.cpp create mode 100644 byp/sbexecution/AntiDebug/BeingDebugged.h create mode 100644 byp/sbexecution/AntiDebug/CheckRemoteDebuggerPresent.cpp create mode 100644 byp/sbexecution/AntiDebug/CheckRemoteDebuggerPresent.h create mode 100644 byp/sbexecution/AntiDebug/CloseHandle_InvalidHandle.cpp create mode 100644 byp/sbexecution/AntiDebug/CloseHandle_InvalidHandle.h create mode 100644 byp/sbexecution/AntiDebug/HardwareBreakpoints.cpp create mode 100644 byp/sbexecution/AntiDebug/HardwareBreakpoints.h create mode 100644 byp/sbexecution/AntiDebug/Interrupt_0x2d.cpp create mode 100644 byp/sbexecution/AntiDebug/Interrupt_0x2d.h create mode 100644 byp/sbexecution/AntiDebug/Interrupt_3.cpp create mode 100644 byp/sbexecution/AntiDebug/Interrupt_3.h create mode 100644 byp/sbexecution/AntiDebug/IsDebuggerPresent.cpp create mode 100644 byp/sbexecution/AntiDebug/IsDebuggerPresent.h create mode 100644 byp/sbexecution/AntiDebug/LowFragmentationHeap.cpp create mode 100644 byp/sbexecution/AntiDebug/LowFragmentationHeap.h create mode 100644 byp/sbexecution/AntiDebug/MemoryBreakpoints_PageGuard.cpp create mode 100644 byp/sbexecution/AntiDebug/MemoryBreakpoints_PageGuard.h create mode 100644 byp/sbexecution/AntiDebug/ModuleBoundsHookCheck.cpp create mode 100644 byp/sbexecution/AntiDebug/ModuleBoundsHookCheck.h create mode 100644 byp/sbexecution/AntiDebug/NtGlobalFlag.cpp create mode 100644 byp/sbexecution/AntiDebug/NtGlobalFlag.h create mode 100644 byp/sbexecution/AntiDebug/NtQueryInformationProcess_ProcessDebugFlags.cpp create mode 100644 byp/sbexecution/AntiDebug/NtQueryInformationProcess_ProcessDebugFlags.h create mode 100644 byp/sbexecution/AntiDebug/NtQueryInformationProcess_ProcessDebugObject.cpp create mode 100644 byp/sbexecution/AntiDebug/NtQueryInformationProcess_ProcessDebugObject.h create mode 100644 byp/sbexecution/AntiDebug/NtQueryInformationProcess_ProcessDebugPort.cpp create mode 100644 byp/sbexecution/AntiDebug/NtQueryInformationProcess_ProcessDebugPort.h create mode 100644 byp/sbexecution/AntiDebug/NtQueryObject_AllTypesInformation.cpp create mode 100644 byp/sbexecution/AntiDebug/NtQueryObject_ObjectInformation.h create mode 100644 byp/sbexecution/AntiDebug/NtQueryObject_ObjectTypeInformation.cpp create mode 100644 byp/sbexecution/AntiDebug/NtQuerySystemInformation_SystemKernelDebuggerInformation.cpp create mode 100644 byp/sbexecution/AntiDebug/NtQuerySystemInformation_SystemKernelDebuggerInformation.h create mode 100644 byp/sbexecution/AntiDebug/NtSetInformationThread_ThreadHideFromDebugger.cpp create mode 100644 byp/sbexecution/AntiDebug/NtSetInformationThread_ThreadHideFromDebugger.h create mode 100644 byp/sbexecution/AntiDebug/NtSystemDebugControl.cpp create mode 100644 byp/sbexecution/AntiDebug/NtSystemDebugControl.h create mode 100644 byp/sbexecution/AntiDebug/NtYieldExecution.cpp create mode 100644 byp/sbexecution/AntiDebug/NtYieldExecution.h create mode 100644 byp/sbexecution/AntiDebug/OutputDebugStringAPI.cpp create mode 100644 byp/sbexecution/AntiDebug/OutputDebugStringAPI.h create mode 100644 byp/sbexecution/AntiDebug/PageExceptionBreakpointCheck.cpp create mode 100644 byp/sbexecution/AntiDebug/PageExceptionBreakpointCheck.h create mode 100644 byp/sbexecution/AntiDebug/ParentProcess.cpp create mode 100644 byp/sbexecution/AntiDebug/ParentProcess.h create mode 100644 byp/sbexecution/AntiDebug/ProcessHeap_Flags.cpp create mode 100644 byp/sbexecution/AntiDebug/ProcessHeap_Flags.h create mode 100644 byp/sbexecution/AntiDebug/ProcessHeap_ForceFlags.cpp create mode 100644 byp/sbexecution/AntiDebug/ProcessHeap_ForceFlags.h create mode 100644 byp/sbexecution/AntiDebug/ProcessJob.cpp create mode 100644 byp/sbexecution/AntiDebug/ProcessJob.h create mode 100644 byp/sbexecution/AntiDebug/ScanForModules.cpp create mode 100644 byp/sbexecution/AntiDebug/ScanForModules.h create mode 100644 byp/sbexecution/AntiDebug/SeDebugPrivilege.cpp create mode 100644 byp/sbexecution/AntiDebug/SeDebugPrivilege.h create mode 100644 byp/sbexecution/AntiDebug/SetHandleInformation_API.cpp create mode 100644 byp/sbexecution/AntiDebug/SetHandleInformation_API.h create mode 100644 byp/sbexecution/AntiDebug/SharedUserData_KernelDebugger.cpp create mode 100644 byp/sbexecution/AntiDebug/SharedUserData_KernelDebugger.h create mode 100644 byp/sbexecution/AntiDebug/SoftwareBreakpoints.cpp create mode 100644 byp/sbexecution/AntiDebug/SoftwareBreakpoints.h create mode 100644 byp/sbexecution/AntiDebug/TLS_callbacks.cpp create mode 100644 byp/sbexecution/AntiDebug/TLS_callbacks.h create mode 100644 byp/sbexecution/AntiDebug/TrapFlag.cpp create mode 100644 byp/sbexecution/AntiDebug/TrapFlag.h create mode 100644 byp/sbexecution/AntiDebug/UnhandledExceptionFilter_Handler.cpp create mode 100644 byp/sbexecution/AntiDebug/UnhandledExceptionFilter_Handler.h create mode 100644 byp/sbexecution/AntiDebug/WUDF_IsDebuggerPresent.cpp create mode 100644 byp/sbexecution/AntiDebug/WUDF_IsDebuggerPresent.h create mode 100644 byp/sbexecution/AntiDebug/WriteWatch.cpp create mode 100644 byp/sbexecution/AntiDebug/WriteWatch.h create mode 100644 byp/sbexecution/AntiDebug/int2d_x64.asm create mode 100644 byp/sbexecution/AntiDebug/int2d_x86.asm create mode 100644 byp/sbexecution/AntiDebug/pch.h create mode 100644 byp/sbexecution/AntiDisassm/AntiDisassm.cpp create mode 100644 byp/sbexecution/AntiDisassm/AntiDisassm.h create mode 100644 byp/sbexecution/AntiDisassm/AntiDisassm_x64.asm create mode 100644 byp/sbexecution/AntiDisassm/AntiDisassm_x86.asm create mode 100644 byp/sbexecution/AntiDisassm/pch.h create mode 100644 byp/sbexecution/AntiDump/ErasePEHeaderFromMemory.cpp create mode 100644 byp/sbexecution/AntiDump/ErasePEHeaderFromMemory.h create mode 100644 byp/sbexecution/AntiDump/SizeOfImage.cpp create mode 100644 byp/sbexecution/AntiDump/SizeOfImage.h create mode 100644 byp/sbexecution/AntiDump/pch.h create mode 100644 byp/sbexecution/AntiVM/Generic.cpp create mode 100644 byp/sbexecution/AntiVM/Generic.h create mode 100644 byp/sbexecution/AntiVM/HyperV.cpp create mode 100644 byp/sbexecution/AntiVM/HyperV.h create mode 100644 byp/sbexecution/AntiVM/KVM.cpp create mode 100644 byp/sbexecution/AntiVM/KVM.h create mode 100644 byp/sbexecution/AntiVM/Parallels.cpp create mode 100644 byp/sbexecution/AntiVM/Parallels.h create mode 100644 byp/sbexecution/AntiVM/Qemu.cpp create mode 100644 byp/sbexecution/AntiVM/Qemu.h create mode 100644 byp/sbexecution/AntiVM/Services.cpp create mode 100644 byp/sbexecution/AntiVM/Services.h create mode 100644 byp/sbexecution/AntiVM/VMWare.cpp create mode 100644 byp/sbexecution/AntiVM/VMWare.h create mode 100644 byp/sbexecution/AntiVM/VirtualBox.cpp create mode 100644 byp/sbexecution/AntiVM/VirtualBox.h create mode 100644 byp/sbexecution/AntiVM/VirtualPC.cpp create mode 100644 byp/sbexecution/AntiVM/VirtualPC.h create mode 100644 byp/sbexecution/AntiVM/Wine.cpp create mode 100644 byp/sbexecution/AntiVM/Wine.h create mode 100644 byp/sbexecution/AntiVM/Xen.cpp create mode 100644 byp/sbexecution/AntiVM/Xen.h create mode 100644 byp/sbexecution/AntiVM/pch.h create mode 100644 byp/sbexecution/CodeInjection/CreateRemoteThread.cpp create mode 100644 byp/sbexecution/CodeInjection/CreateRemoteThread.h create mode 100644 byp/sbexecution/CodeInjection/GetSetThreadContext.cpp create mode 100644 byp/sbexecution/CodeInjection/GetSetThreadContext.h create mode 100644 byp/sbexecution/CodeInjection/InjectedDLL/InjectedDLL.cpp create mode 100644 byp/sbexecution/CodeInjection/InjectedDLL/InjectedDLL.h create mode 100644 byp/sbexecution/CodeInjection/InjectedDLL/InjectedDLL.vcxproj create mode 100644 byp/sbexecution/CodeInjection/InjectedDLL/InjectedDLL.vcxproj.filters create mode 100644 byp/sbexecution/CodeInjection/InjectedDLL/definitions.def create mode 100644 byp/sbexecution/CodeInjection/NtCreateThreadEx.cpp create mode 100644 byp/sbexecution/CodeInjection/NtCreateThreadEx.h create mode 100644 byp/sbexecution/CodeInjection/QueueUserAPC.cpp create mode 100644 byp/sbexecution/CodeInjection/QueueUserAPC.h create mode 100644 byp/sbexecution/CodeInjection/RtlCreateUserThread.cpp create mode 100644 byp/sbexecution/CodeInjection/RtlCreateUserThread.h create mode 100644 byp/sbexecution/CodeInjection/SetWindowsHooksEx.cpp create mode 100644 byp/sbexecution/CodeInjection/SetWindowsHooksEx.h create mode 100644 byp/sbexecution/CodeInjection/pch.h create mode 100644 byp/sbexecution/OfficeMacro/al-khaser.docm create mode 100644 byp/sbexecution/OfficeMacro/macros.vba create mode 100644 byp/sbexecution/Shared/APIs.cpp create mode 100644 byp/sbexecution/Shared/APIs.h create mode 100644 byp/sbexecution/Shared/ApiTypeDefs.cpp create mode 100644 byp/sbexecution/Shared/ApiTypeDefs.h create mode 100644 byp/sbexecution/Shared/Common.cpp create mode 100644 byp/sbexecution/Shared/Common.h create mode 100644 byp/sbexecution/Shared/Utils.cpp create mode 100644 byp/sbexecution/Shared/Utils.h create mode 100644 byp/sbexecution/Shared/VersionHelpers.h create mode 100644 byp/sbexecution/Shared/WinStructs.h create mode 100644 byp/sbexecution/Shared/log.cpp create mode 100644 byp/sbexecution/Shared/log.h create mode 100644 byp/sbexecution/Shared/pch.h create mode 100644 byp/sbexecution/Shared/winapifamily.h create mode 100644 byp/sbexecution/TimingAttacks/pch.h create mode 100644 byp/sbexecution/TimingAttacks/timing.cpp create mode 100644 byp/sbexecution/TimingAttacks/timing.h create mode 100644 byp/sbexecution/blackmarlinexec.cpp create mode 100644 byp/sbexecution/blackmarlinexec.filters create mode 100644 byp/sbexecution/blackmarlinexec.vcxproj create mode 100644 byp/sbexecution/packages.config create mode 100644 byp/sbexecution/pch.cpp create mode 100644 byp/sbexecution/pch.h create mode 100644 byp/tools/ATAIdentifyDump/ATAIdentifyDump.cpp create mode 100644 byp/tools/ATAIdentifyDump/ATAIdentifyDump.vcxproj create mode 100644 byp/tools/ATAIdentifyDump/ATAIdentifyDump.vcxproj.filters create mode 100644 byp/tools/ATAIdentifyDump/IdentifyDeviceData.h create mode 100644 byp/tools/ATAIdentifyDump/pch.cpp create mode 100644 byp/tools/ATAIdentifyDump/pch.h create mode 100644 byp/tools/StructDumpCodegen/struct_dump_codegen.linq diff --git a/byp/.editorconfig b/byp/.editorconfig new file mode 100644 index 00000000..66154009 --- /dev/null +++ b/byp/.editorconfig @@ -0,0 +1,11 @@ +; Top-most EditorConfig file +root = true + +; Windows-style newlines +[*] +end_of_line = CRLF + +; Tab indentation +[*.{cpp,h}] +indent_style = tab +tab_width = 4 \ No newline at end of file diff --git a/byp/.gitattributes b/byp/.gitattributes new file mode 100644 index 00000000..a0784126 --- /dev/null +++ b/byp/.gitattributes @@ -0,0 +1,53 @@ +############################################################################### +# Set default behavior to automatically normalize line endings. +############################################################################### +* text=auto + +############################################################################### +# Set the merge driver for project and solution files +# +# Merging from the command prompt will add diff markers to the files if there +# are conflicts (Merging from VS is not affected by the settings below, in VS +# the diff markers are never inserted). Diff markers may cause the following +# file extensions to fail to load in VS. An alternative would be to treat +# these files as binary and thus will always conflict and require user +# intervention with every merge. To do so, just comment the entries below and +# uncomment the group further below +############################################################################### + +*.sln text eol=crlf +*.csproj text eol=crlf +*.vbproj text eol=crlf +*.vcxproj text eol=crlf +*.vcproj text eol=crlf +*.dbproj text eol=crlf +*.fsproj text eol=crlf +*.lsproj text eol=crlf +*.wixproj text eol=crlf +*.modelproj text eol=crlf +*.sqlproj text eol=crlf +*.wmaproj text eol=crlf + +*.xproj text eol=crlf +*.props text eol=crlf +*.filters text eol=crlf +*.vcxitems text eol=crlf + + +#*.sln merge=binary +#*.csproj merge=binary +#*.vbproj merge=binary +#*.vcxproj merge=binary +#*.vcproj merge=binary +#*.dbproj merge=binary +#*.fsproj merge=binary +#*.lsproj merge=binary +#*.wixproj merge=binary +#*.modelproj merge=binary +#*.sqlproj merge=binary +#*.wwaproj merge=binary + +#*.xproj merge=binary +#*.props merge=binary +#*.filters merge=binary +#*.vcxitems merge=binary diff --git a/byp/.gitignore b/byp/.gitignore new file mode 100644 index 00000000..69a917ba --- /dev/null +++ b/byp/.gitignore @@ -0,0 +1,72 @@ +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# Precompiled Headers +*.gch +*.pch + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.out +*.app + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opensdf +*.sdf +*.cachefile + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +build/ +bld/ +[Bb]in/ +[Oo]bj/ +*.VC.opendb + +# Visual C++ Solution +*.VC.db + +# NuGet packages +packages/ + +# Alkhaser log file +log.txt + +# Packages +packages/ diff --git a/byp/blackmarlinexec.sln b/byp/blackmarlinexec.sln new file mode 100644 index 00000000..fff5c167 --- /dev/null +++ b/byp/blackmarlinexec.sln @@ -0,0 +1,45 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.28010.2026 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "al-khaser", "al-khaser\al-khaser.vcxproj", "{77AEFBC3-0ECE-46AD-A113-966AAAA838E1}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tools", "Tools", "{71BFEE2B-52EC-4526-90F5-D91D98B9C786}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ATAIdentifyDump", "Tools\ATAIdentifyDump\ATAIdentifyDump.vcxproj", "{245D8670-A888-4ECC-9B51-80584E55B701}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {77AEFBC3-0ECE-46AD-A113-966AAAA838E1}.Debug|x64.ActiveCfg = Debug|x64 + {77AEFBC3-0ECE-46AD-A113-966AAAA838E1}.Debug|x64.Build.0 = Debug|x64 + {77AEFBC3-0ECE-46AD-A113-966AAAA838E1}.Debug|x86.ActiveCfg = Debug|Win32 + {77AEFBC3-0ECE-46AD-A113-966AAAA838E1}.Debug|x86.Build.0 = Debug|Win32 + {77AEFBC3-0ECE-46AD-A113-966AAAA838E1}.Release|x64.ActiveCfg = Release|x64 + {77AEFBC3-0ECE-46AD-A113-966AAAA838E1}.Release|x64.Build.0 = Release|x64 + {77AEFBC3-0ECE-46AD-A113-966AAAA838E1}.Release|x86.ActiveCfg = Release|Win32 + {77AEFBC3-0ECE-46AD-A113-966AAAA838E1}.Release|x86.Build.0 = Release|Win32 + {245D8670-A888-4ECC-9B51-80584E55B701}.Debug|x64.ActiveCfg = Debug|x64 + {245D8670-A888-4ECC-9B51-80584E55B701}.Debug|x64.Build.0 = Debug|x64 + {245D8670-A888-4ECC-9B51-80584E55B701}.Debug|x86.ActiveCfg = Debug|Win32 + {245D8670-A888-4ECC-9B51-80584E55B701}.Debug|x86.Build.0 = Debug|Win32 + {245D8670-A888-4ECC-9B51-80584E55B701}.Release|x64.ActiveCfg = Release|x64 + {245D8670-A888-4ECC-9B51-80584E55B701}.Release|x64.Build.0 = Release|x64 + {245D8670-A888-4ECC-9B51-80584E55B701}.Release|x86.ActiveCfg = Release|Win32 + {245D8670-A888-4ECC-9B51-80584E55B701}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {245D8670-A888-4ECC-9B51-80584E55B701} = {71BFEE2B-52EC-4526-90F5-D91D98B9C786} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {0772817E-132F-4922-8377-5DA07255372F} + EndGlobalSection +EndGlobal diff --git a/byp/sbexecution/AntiAnalysis/pch.h b/byp/sbexecution/AntiAnalysis/pch.h new file mode 100644 index 00000000..e7df92d7 --- /dev/null +++ b/byp/sbexecution/AntiAnalysis/pch.h @@ -0,0 +1 @@ +#include "../pch.h" \ No newline at end of file diff --git a/byp/sbexecution/AntiAnalysis/process.cpp b/byp/sbexecution/AntiAnalysis/process.cpp new file mode 100644 index 00000000..4c70ebd8 --- /dev/null +++ b/byp/sbexecution/AntiAnalysis/process.cpp @@ -0,0 +1,60 @@ +#include "pch.h" +#pragma once +#include "process.h" + +/* +Check for process list +*/ + +VOID analysis_tools_process() +{ + const TCHAR *szProcesses[] = { + _T("ollydbg.exe"), // OllyDebug debugger + _T("ProcessHacker.exe"), // Process Hacker + _T("tcpview.exe"), // Part of Sysinternals Suite + _T("autoruns.exe"), // Part of Sysinternals Suite + _T("autorunsc.exe"), // Part of Sysinternals Suite + _T("filemon.exe"), // Part of Sysinternals Suite + _T("procmon.exe"), // Part of Sysinternals Suite + _T("regmon.exe"), // Part of Sysinternals Suite + _T("procexp.exe"), // Part of Sysinternals Suite + _T("idaq.exe"), // IDA Pro Interactive Disassembler + _T("idaq64.exe"), // IDA Pro Interactive Disassembler + _T("ImmunityDebugger.exe"), // ImmunityDebugger + _T("Wireshark.exe"), // Wireshark packet sniffer + _T("dumpcap.exe"), // Network traffic dump tool + _T("HookExplorer.exe"), // Find various types of runtime hooks + _T("ImportREC.exe"), // Import Reconstructor + _T("PETools.exe"), // PE Tool + _T("LordPE.exe"), // LordPE + _T("SysInspector.exe"), // ESET SysInspector + _T("proc_analyzer.exe"), // Part of SysAnalyzer iDefense + _T("sysAnalyzer.exe"), // Part of SysAnalyzer iDefense + _T("sniff_hit.exe"), // Part of SysAnalyzer iDefense + _T("windbg.exe"), // Microsoft WinDbg + _T("joeboxcontrol.exe"), // Part of Joe Sandbox + _T("joeboxserver.exe"), // Part of Joe Sandbox + _T("joeboxserver.exe"), // Part of Joe Sandbox + _T("ResourceHacker.exe"), // Resource Hacker + _T("x32dbg.exe"), // x32dbg + _T("x64dbg.exe"), // x64dbg + _T("Fiddler.exe"), // Fiddler + _T("httpdebugger.exe"), // Http Debugger + _T("cheatengine-i386.exe"), // Cheat Engine + _T("cheatengine-x86_64.exe"), // Cheat Engine + _T("cheatengine-x86_64-SSE4-AVX2.exe"), // Cheat Engine + _T("frida-helper-32.exe"), // Frida + _T("frida-helper-64.exe"), // Frida + }; + + WORD iLength = sizeof(szProcesses) / sizeof(szProcesses[0]); + for (int i = 0; i < iLength; i++) + { + 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])) + print_results(TRUE, msg); + else + print_results(FALSE, msg); + } +} diff --git a/byp/sbexecution/AntiAnalysis/process.h b/byp/sbexecution/AntiAnalysis/process.h new file mode 100644 index 00000000..f71e75b3 --- /dev/null +++ b/byp/sbexecution/AntiAnalysis/process.h @@ -0,0 +1,11 @@ +#pragma once + +VOID analysis_tools_process(); + +/* + +avpui.exe +avgui.exe +bdagent.exe + +*/ \ No newline at end of file diff --git a/byp/sbexecution/AntiDebug/BeingDebugged.cpp b/byp/sbexecution/AntiDebug/BeingDebugged.cpp new file mode 100644 index 00000000..e3721b0f --- /dev/null +++ b/byp/sbexecution/AntiDebug/BeingDebugged.cpp @@ -0,0 +1,36 @@ +#include "pch.h" +#include "BeingDebugged.h" + + +BOOL +IsDebuggerPresentPEB( + VOID +) +/*++ + +Routine Description: + + Checks if the BeingDebugged flag is set in the Process Environment Block (PEB). + This is effectively the same code that IsDebuggerPresent() executes internally. + The PEB pointer is fetched from DWORD FS:[0x30] on x86_32 and QWORD GS:[0x60] on x86_64. + +Arguments: + + None + +Return Value: + + TRUE - if debugger was detected + FALSE - otherwise +--*/ +{ +#if defined (ENV64BIT) + PPEB pPeb = (PPEB)__readgsqword(0x60); + +#elif defined(ENV32BIT) + PPEB pPeb = (PPEB)__readfsdword(0x30); + +#endif + + return pPeb->BeingDebugged == 1; +} diff --git a/byp/sbexecution/AntiDebug/BeingDebugged.h b/byp/sbexecution/AntiDebug/BeingDebugged.h new file mode 100644 index 00000000..6fedf60c --- /dev/null +++ b/byp/sbexecution/AntiDebug/BeingDebugged.h @@ -0,0 +1,3 @@ +#pragma once + +BOOL IsDebuggerPresentPEB(); diff --git a/byp/sbexecution/AntiDebug/CheckRemoteDebuggerPresent.cpp b/byp/sbexecution/AntiDebug/CheckRemoteDebuggerPresent.cpp new file mode 100644 index 00000000..9008b8cf --- /dev/null +++ b/byp/sbexecution/AntiDebug/CheckRemoteDebuggerPresent.cpp @@ -0,0 +1,32 @@ +#include "pch.h" +#include "CheckRemoteDebuggerPresent.h" + +BOOL +CheckRemoteDebuggerPresentAPI ( + VOID + ) +/*++ + +Routine Description: + + CheckRemoteDebuggerPresent() is another Win32 Debugging API function; + it can be used to check if a remote process is being debugged. However, + we can also use this as another method for checking if our own process + is being debugged. This API internally calls the NTDLL export + NtQueryInformationProcess function with the PROCESSINFOCLASS set to + 7 (ProcessDebugPort). + +Arguments: + + None + +Return Value: + + TRUE - if debugger was detected + FALSE - otherwise +--*/ +{ + BOOL bIsDbgPresent = FALSE; + CheckRemoteDebuggerPresent(GetCurrentProcess(), &bIsDbgPresent); + return bIsDbgPresent; +} diff --git a/byp/sbexecution/AntiDebug/CheckRemoteDebuggerPresent.h b/byp/sbexecution/AntiDebug/CheckRemoteDebuggerPresent.h new file mode 100644 index 00000000..bafff1ed --- /dev/null +++ b/byp/sbexecution/AntiDebug/CheckRemoteDebuggerPresent.h @@ -0,0 +1 @@ +BOOL CheckRemoteDebuggerPresentAPI(); \ No newline at end of file diff --git a/byp/sbexecution/AntiDebug/CloseHandle_InvalidHandle.cpp b/byp/sbexecution/AntiDebug/CloseHandle_InvalidHandle.cpp new file mode 100644 index 00000000..3ad72e7e --- /dev/null +++ b/byp/sbexecution/AntiDebug/CloseHandle_InvalidHandle.cpp @@ -0,0 +1,43 @@ +#include "pch.h" + + + /* + APIs making use of the ZwClose syscall (such as CloseHandle, indirectly) + can be used to detect a debugger. When a process is debugged, calling ZwClose + with an invalid handle will generate a STATUS_INVALID_HANDLE (0xC0000008) exception. + As with all anti-debugs that rely on information made directly available. +*/ + + +BOOL NtClose_InvalideHandle() +{ + auto NtClose_ = static_cast(API::GetAPI(API_IDENTIFIER::API_NtClose)); + + __try { + NtClose_(reinterpret_cast(0x99999999ULL)); + } + __except (EXCEPTION_EXECUTE_HANDLER) { + return TRUE; + } + + return FALSE; + +} + +BOOL CloseHandle_InvalideHandle() +{ + // Let's try first with user mode API: CloseHandle + __try { + CloseHandle(reinterpret_cast(0x99999999ULL)); + } + __except (EXCEPTION_EXECUTE_HANDLER) { + return TRUE; + } + + // Direct call to NtClose to bypass user mode hooks + if (NtClose_InvalideHandle()) + return TRUE; + else + return FALSE; +} + diff --git a/byp/sbexecution/AntiDebug/CloseHandle_InvalidHandle.h b/byp/sbexecution/AntiDebug/CloseHandle_InvalidHandle.h new file mode 100644 index 00000000..0364973e --- /dev/null +++ b/byp/sbexecution/AntiDebug/CloseHandle_InvalidHandle.h @@ -0,0 +1 @@ +BOOL CloseHandle_InvalideHandle(); \ No newline at end of file diff --git a/byp/sbexecution/AntiDebug/HardwareBreakpoints.cpp b/byp/sbexecution/AntiDebug/HardwareBreakpoints.cpp new file mode 100644 index 00000000..b7331dda --- /dev/null +++ b/byp/sbexecution/AntiDebug/HardwareBreakpoints.cpp @@ -0,0 +1,41 @@ +#include "pch.h" + +#include "HardwareBreakpoints.h" + +/* +Hardware breakpoints are a technology implemented by Intel in their processor architecture, +and are controlled by the use of special registers known as Dr0-Dr7. +Dr0 through Dr3 are 32 bit registers that hold the address of the breakpoint . +*/ + + +BOOL HardwareBreakpoints() +{ + BOOL bResult = FALSE; + + // This structure is key to the function and is the + // medium for detection and removal + PCONTEXT ctx = PCONTEXT(VirtualAlloc(NULL, sizeof(CONTEXT), MEM_COMMIT, PAGE_READWRITE)); + + if (ctx) { + + SecureZeroMemory(ctx, sizeof(CONTEXT)); + + // The CONTEXT structure is an in/out parameter therefore we have + // to set the flags so Get/SetThreadContext knows what to set or get. + ctx->ContextFlags = CONTEXT_DEBUG_REGISTERS; + + // Get the registers + if (GetThreadContext(GetCurrentThread(), ctx)) { + + // Now we can check for hardware breakpoints, its not + // necessary to check Dr6 and Dr7, however feel free to + if (ctx->Dr0 != 0 || ctx->Dr1 != 0 || ctx->Dr2 != 0 || ctx->Dr3 != 0) + bResult = TRUE; + } + + VirtualFree(ctx, 0, MEM_RELEASE); + } + + return bResult; +} diff --git a/byp/sbexecution/AntiDebug/HardwareBreakpoints.h b/byp/sbexecution/AntiDebug/HardwareBreakpoints.h new file mode 100644 index 00000000..d6f2c31f --- /dev/null +++ b/byp/sbexecution/AntiDebug/HardwareBreakpoints.h @@ -0,0 +1 @@ +BOOL HardwareBreakpoints(); \ No newline at end of file diff --git a/byp/sbexecution/AntiDebug/Interrupt_0x2d.cpp b/byp/sbexecution/AntiDebug/Interrupt_0x2d.cpp new file mode 100644 index 00000000..2dfc262a --- /dev/null +++ b/byp/sbexecution/AntiDebug/Interrupt_0x2d.cpp @@ -0,0 +1,37 @@ +#include "pch.h" + +#include "Interrupt_0x2d.h" + +/* +The Interrupt_0x2d function will check to see if a debugger is attached to the current process. It does this by setting up +SEH and using the Int 2D instruction which will only cause an exception if there is no debugger. Also when used in OllyDBG +it will skip a byte in the disassembly which could be used to detect the debugger. + +Vectored Exception Handling is used here because SEH is an anti-debug trick in itself. +*/ + +extern "C" void __int2d(); + +static BOOL SwallowedException = TRUE; + +static LONG CALLBACK VectoredHandler( + _In_ PEXCEPTION_POINTERS ExceptionInfo +) +{ + SwallowedException = FALSE; + if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_BREAKPOINT) + { + //The Int 2D instruction already increased EIP/RIP so we don't do that (although it wouldnt hurt). + return EXCEPTION_CONTINUE_EXECUTION; + } + return EXCEPTION_CONTINUE_SEARCH; +} + +BOOL Interrupt_0x2d() +{ + PVOID Handle = AddVectoredExceptionHandler(1, VectoredHandler); + SwallowedException = TRUE; + __int2d(); + RemoveVectoredExceptionHandler(Handle); + return SwallowedException; +} diff --git a/byp/sbexecution/AntiDebug/Interrupt_0x2d.h b/byp/sbexecution/AntiDebug/Interrupt_0x2d.h new file mode 100644 index 00000000..9d997e06 --- /dev/null +++ b/byp/sbexecution/AntiDebug/Interrupt_0x2d.h @@ -0,0 +1 @@ +BOOL Interrupt_0x2d(); \ No newline at end of file diff --git a/byp/sbexecution/AntiDebug/Interrupt_3.cpp b/byp/sbexecution/AntiDebug/Interrupt_3.cpp new file mode 100644 index 00000000..571bc6e6 --- /dev/null +++ b/byp/sbexecution/AntiDebug/Interrupt_3.cpp @@ -0,0 +1,43 @@ +#include "pch.h" + +#include "Interrupt_3.h" + +/* +INT 3 generates a call to trap in the debugger and is triggered by opcode 0xCC within the executing process. +When a debugger is attached, the 0xCC execution will cause the debugger to catch the breakpoint and handle +the resulting exception. If a debugger is not attached, the exception is passed through to a structured +exception handler thus informing the process that no debugger is present. + +Vectored Exception Handling is used here because SEH is an anti-debug trick in itself. +*/ + +static BOOL SwallowedException = TRUE; + +static LONG CALLBACK VectoredHandler( + _In_ PEXCEPTION_POINTERS ExceptionInfo +) +{ + SwallowedException = FALSE; + if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_BREAKPOINT) + { + //Increase EIP/RIP to continue execution. +#ifdef _WIN64 + ExceptionInfo->ContextRecord->Rip++; +#else + ExceptionInfo->ContextRecord->Eip++; +#endif + return EXCEPTION_CONTINUE_EXECUTION; + } + return EXCEPTION_CONTINUE_SEARCH; +} + + + +BOOL Interrupt_3() +{ + PVOID Handle = AddVectoredExceptionHandler(1, VectoredHandler); + SwallowedException = TRUE; + __debugbreak(); + RemoveVectoredExceptionHandler(Handle); + return SwallowedException; +} diff --git a/byp/sbexecution/AntiDebug/Interrupt_3.h b/byp/sbexecution/AntiDebug/Interrupt_3.h new file mode 100644 index 00000000..4b67d61f --- /dev/null +++ b/byp/sbexecution/AntiDebug/Interrupt_3.h @@ -0,0 +1,3 @@ +#pragma once + +BOOL Interrupt_3(); \ No newline at end of file diff --git a/byp/sbexecution/AntiDebug/IsDebuggerPresent.cpp b/byp/sbexecution/AntiDebug/IsDebuggerPresent.cpp new file mode 100644 index 00000000..77bf9478 --- /dev/null +++ b/byp/sbexecution/AntiDebug/IsDebuggerPresent.cpp @@ -0,0 +1,28 @@ +#include "pch.h" +#include "IsDebuggerPresent.h" + +BOOL +IsDebuggerPresentAPI ( + VOID + ) +/*++ + +Routine Description: + + Calls the IsDebuggerPresent() API. This function is part of the + Win32 Debugging API and it returns TRUE if a user mode debugger + is present. Internally, it simply returns the value of the + PEB->BeingDebugged flag. + +Arguments: + + None + +Return Value: + + TRUE - if debugger was detected + FALSE - otherwise +--*/ +{ + return IsDebuggerPresent(); +} diff --git a/byp/sbexecution/AntiDebug/IsDebuggerPresent.h b/byp/sbexecution/AntiDebug/IsDebuggerPresent.h new file mode 100644 index 00000000..97dad4ae --- /dev/null +++ b/byp/sbexecution/AntiDebug/IsDebuggerPresent.h @@ -0,0 +1,3 @@ +#pragma once + +BOOL IsDebuggerPresentAPI(); \ No newline at end of file diff --git a/byp/sbexecution/AntiDebug/LowFragmentationHeap.cpp b/byp/sbexecution/AntiDebug/LowFragmentationHeap.cpp new file mode 100644 index 00000000..a19a048b --- /dev/null +++ b/byp/sbexecution/AntiDebug/LowFragmentationHeap.cpp @@ -0,0 +1,61 @@ +#include "pch.h" +#include "LowFragmentationHeap.h" + + +BOOL +LowFragmentationHeap( + VOID +) +/*++ + +Routine Description: + Originally found by Souhail Hammou: + http://rce4fun.blogspot.com/2014/02/anti-debugging-trick-checking-for-low.html + Under a debugger, the process does not have a Low Fragmentation Heap (LFH) + The routine simply checks whether the nt!_HEAP.FrontEndHeap is NULL. + +Arguments: + + None + +Return Value: + + TRUE - if debugger was detected + FALSE - otherwise +--*/ +{ + + PINT_PTR FrontEndHeap = NULL; + + // Get the default process heap. + HANDLE hHeap = GetProcessHeap(); + + // The FrontEndHeap offset of the _HEAP structure + // is found on different locations depending of the OS. + + if (IsWindowsVista() || IsWindows7()) { +#if defined (ENV64BIT) + FrontEndHeap = (PINT_PTR)((CHAR*)hHeap + 0x178); + +#elif defined(ENV32BIT) + FrontEndHeap = (PINT_PTR)((CHAR*)hHeap + 0xd4); +#endif + } + + if (IsWindows8or8PointOne()) { +#if defined (ENV64BIT) + FrontEndHeap = (PINT_PTR)((CHAR*)hHeap + 0x170); + +#elif defined(ENV32BIT) + FrontEndHeap = (PINT_PTR)((CHAR*)hHeap + 0xd0); +#endif + } + + // In Windows 10. the offset changes very often. + // Ignoring it from now. + if (FrontEndHeap && *FrontEndHeap == NULL) { + return TRUE; + } + + return FALSE; +} diff --git a/byp/sbexecution/AntiDebug/LowFragmentationHeap.h b/byp/sbexecution/AntiDebug/LowFragmentationHeap.h new file mode 100644 index 00000000..5bb67c68 --- /dev/null +++ b/byp/sbexecution/AntiDebug/LowFragmentationHeap.h @@ -0,0 +1,6 @@ +#pragma once + +BOOL +LowFragmentationHeap( + VOID +); \ No newline at end of file diff --git a/byp/sbexecution/AntiDebug/MemoryBreakpoints_PageGuard.cpp b/byp/sbexecution/AntiDebug/MemoryBreakpoints_PageGuard.cpp new file mode 100644 index 00000000..6e2062d9 --- /dev/null +++ b/byp/sbexecution/AntiDebug/MemoryBreakpoints_PageGuard.cpp @@ -0,0 +1,47 @@ +#include "pch.h" + +#include "MemoryBreakpoints_PageGuard.h" + +/* +In essence, what occurs is that we allocate a dynamic buffer and write a RET to the buffer. +We then mark the page as a guard page and push a potential return address onto the stack. Next, we jump to our page, +and if we're under a debugger, specifically OllyDBG, then we will hit the RET instruction and return to the address we pushed onto +the stack before we jumped to our page. Otherwise, a STATUS_GUARD_PAGE_VIOLATION exception will occur, and we know we're not being +debugged by OllyDBG. +*/ + +BOOL MemoryBreakpoints_PageGuard() +{ + UCHAR *pMem = NULL; + SYSTEM_INFO SystemInfo = { 0 }; + DWORD OldProtect = 0; + PVOID pAllocation = NULL; // Get the page size for the system + + // Retrieves information about the current system. + GetSystemInfo(&SystemInfo); + + // Allocate memory + pAllocation = VirtualAlloc(NULL, SystemInfo.dwPageSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); + if (pAllocation == NULL) + return FALSE; + + // Write a ret to the buffer (opcode 0xc3) + RtlFillMemory(pAllocation, 1, 0xC3); + + // Make the page a guard page + if (VirtualProtect(pAllocation, SystemInfo.dwPageSize, PAGE_EXECUTE_READWRITE | PAGE_GUARD, &OldProtect) == 0) + return FALSE; + + __try + { + ((void(*)())pAllocation)(); // Exception or execution, which shall it be :D? + } + __except (GetExceptionCode() == STATUS_GUARD_PAGE_VIOLATION ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) + { + VirtualFree(pAllocation, 0, MEM_RELEASE); + return FALSE; + } + + VirtualFree(pAllocation, 0, MEM_RELEASE); + return TRUE; +} diff --git a/byp/sbexecution/AntiDebug/MemoryBreakpoints_PageGuard.h b/byp/sbexecution/AntiDebug/MemoryBreakpoints_PageGuard.h new file mode 100644 index 00000000..9a319ad0 --- /dev/null +++ b/byp/sbexecution/AntiDebug/MemoryBreakpoints_PageGuard.h @@ -0,0 +1,3 @@ +#pragma once + +BOOL MemoryBreakpoints_PageGuard(); \ No newline at end of file diff --git a/byp/sbexecution/AntiDebug/ModuleBoundsHookCheck.cpp b/byp/sbexecution/AntiDebug/ModuleBoundsHookCheck.cpp new file mode 100644 index 00000000..cd6ab430 --- /dev/null +++ b/byp/sbexecution/AntiDebug/ModuleBoundsHookCheck.cpp @@ -0,0 +1,108 @@ +#include "pch.h" + +/* + +This check works by asking for the addresses of a whole load of APIs from a library, then checking that the resulting pointer is within that library's memory addrress space. + +Note that this is an incomplete set of APIs on purpose. Some APIs are redirected to alternative implementations on Windows 10, and those APIs have been omitted. + +*/ + +char apis_kernel32[] = "ActivateActCtx ActivateActCtxWorker AddAtomA AddAtomW AddConsoleAliasA AddConsoleAliasW AddIntegrityLabelToBoundaryDescriptor AddLocalAlternateComputerNameA AddLocalAlternateComputerNameW AddRefActCtx AddRefActCtxWorker AddResourceAttributeAce AddSIDToBoundaryDescriptor AddScopedPolicyIDAce AddSecureMemoryCacheCallback AdjustCalendarDate AllocConsole AllocateUserPhysicalPages AllocateUserPhysicalPagesNuma ApplicationRecoveryFinished ApplicationRecoveryInProgress AreFileApisANSI AssignProcessToJobObject AttachConsole BackupRead BackupSeek BackupWrite BaseCheckAppcompatCache BaseCheckAppcompatCacheEx BaseCheckAppcompatCacheExWorker BaseCheckAppcompatCacheWorker BaseCheckElevation BaseCleanupAppcompatCacheSupport BaseCleanupAppcompatCacheSupportWorker BaseDestroyVDMEnvironment BaseDllReadWriteIniFile BaseDumpAppcompatCache BaseDumpAppcompatCacheWorker BaseElevationPostProcessing BaseFlushAppcompatCache BaseFlushAppcompatCacheWorker BaseFormatObjectAttributes BaseFormatTimeOut BaseFreeAppCompatDataForProcessWorker BaseGenerateAppCompatData BaseGetNamedObjectDirectory BaseInitAppcompatCacheSupport BaseInitAppcompatCacheSupportWorker BaseIsAppcompatInfrastructureDisabled BaseIsAppcompatInfrastructureDisabledWorker BaseIsDosApplication BaseQueryModuleData BaseReadAppCompatDataForProcessWorker BaseSetLastNTError BaseThreadInitThunk BaseUpdateAppcompatCache BaseUpdateAppcompatCacheWorker BaseUpdateVDMEntry BaseVerifyUnicodeString BaseWriteErrorElevationRequiredEvent Basep8BitStringToDynamicUnicodeString BasepAllocateActivationContextActivationBlock BasepAnsiStringToDynamicUnicodeString BasepAppContainerEnvironmentExtension BasepAppXExtension BasepCheckAppCompat BasepCheckWebBladeHashes BasepCheckWinSaferRestrictions BasepConstructSxsCreateProcessMessage BasepCopyEncryption BasepFreeActivationContextActivationBlock BasepFreeAppCompatData BasepGetAppCompatData BasepGetComputerNameFromNtPath BasepGetExeArchType BasepInitAppCompatData BasepIsProcessAllowed " \ +"BasepMapModuleHandle BasepNotifyLoadStringResource BasepPostSuccessAppXExtension BasepProcessInvalidImage BasepQueryAppCompat BasepQueryModuleChpeSettings BasepReleaseAppXContext BasepReleaseSxsCreateProcessUtilityStruct BasepReportFault BasepSetFileEncryptionCompression Beep BeginUpdateResourceA BeginUpdateResourceW BindIoCompletionCallback BuildCommDCBA BuildCommDCBAndTimeoutsA BuildCommDCBAndTimeoutsW BuildCommDCBW CallNamedPipeA CallNamedPipeW CallbackMayRunLong CancelDeviceWakeupRequest CancelIo CancelIoEx CancelSynchronousIo CancelTimerQueueTimer CancelWaitableTimer ChangeTimerQueueTimer CheckAllowDecryptedRemoteDestinationPolicy CheckElevation CheckElevationEnabled CheckForReadOnlyResource CheckForReadOnlyResourceFilter CheckNameLegalDOS8Dot3A CheckNameLegalDOS8Dot3W CheckRemoteDebuggerPresent CheckTokenCapability CheckTokenMembershipEx ClearCommBreak ClearCommError CloseConsoleHandle CloseHandle ClosePrivateNamespace CloseProfileUserMapping CmdBatNotification CommConfigDialogA CommConfigDialogW CompareCalendarDates CompareFileTime CompareStringA CompareStringEx CompareStringOrdinal CompareStringW ConnectNamedPipe ConsoleMenuControl ContinueDebugEvent ConvertCalDateTimeToSystemTime ConvertDefaultLocale ConvertFiberToThread ConvertNLSDayOfWeekToWin32DayOfWeek ConvertSystemTimeToCalDateTime ConvertThreadToFiber ConvertThreadToFiberEx CopyContext CopyFile2 CopyFileA CopyFileExA CopyFileExW CopyFileTransactedA CopyFileTransactedW CopyFileW CopyLZFile CreateActCtxA CreateActCtxW CreateActCtxWWorker CreateBoundaryDescriptorA CreateBoundaryDescriptorW CreateConsoleScreenBuffer CreateDirectoryA CreateDirectoryExA CreateDirectoryExW CreateDirectoryTransactedA CreateDirectoryTransactedW CreateDirectoryW CreateEventA CreateEventExA CreateEventExW CreateEventW CreateFiber CreateFiberEx CreateFile2 CreateFileA CreateFileMappingA CreateFileMappingNumaA CreateFileMappingNumaW CreateFileMappingW CreateFileTransactedA CreateFileTransactedW CreateFileW CreateHardLinkA CreateHardLinkTransactedA " \ +"CreateHardLinkTransactedW CreateHardLinkW CreateIoCompletionPort CreateJobObjectA CreateJobObjectW CreateJobSet CreateMailslotA CreateMailslotW CreateMemoryResourceNotification CreateMutexA CreateMutexExA CreateMutexExW CreateMutexW CreateNamedPipeA CreateNamedPipeW CreatePipe CreatePrivateNamespaceA CreatePrivateNamespaceW CreateProcessA CreateProcessAsUserA CreateProcessAsUserW CreateProcessInternalA CreateProcessInternalW CreateProcessW CreateRemoteThread CreateSemaphoreA CreateSemaphoreExA CreateSemaphoreExW CreateSemaphoreW CreateSymbolicLinkA CreateSymbolicLinkTransactedA CreateSymbolicLinkTransactedW CreateSymbolicLinkW CreateTapePartition CreateThread CreateThreadpool CreateThreadpoolCleanupGroup CreateThreadpoolIo CreateThreadpoolTimer CreateThreadpoolWait CreateThreadpoolWork CreateTimerQueue CreateTimerQueueTimer CreateToolhelp32Snapshot CreateUmsCompletionList CreateUmsThreadContext CreateWaitableTimerA CreateWaitableTimerExA CreateWaitableTimerExW CreateWaitableTimerW DeactivateActCtx DeactivateActCtxWorker DebugActiveProcess DebugActiveProcessStop DebugBreak DebugBreakProcess DebugSetProcessKillOnExit DefineDosDeviceA DefineDosDeviceW DelayLoadFailureHook DeleteAtom DeleteBoundaryDescriptor DeleteFiber DeleteFileA DeleteFileTransactedA DeleteFileTransactedW DeleteFileW DeleteSynchronizationBarrier DeleteTimerQueue DeleteTimerQueueEx DeleteTimerQueueTimer DeleteUmsCompletionList DeleteUmsThreadContext DeleteVolumeMountPointA DeleteVolumeMountPointW DequeueUmsCompletionListItems DeviceIoControl DisableThreadLibraryCalls DisableThreadProfiling DisconnectNamedPipe DnsHostnameToComputerNameA DnsHostnameToComputerNameExW DnsHostnameToComputerNameW DosDateTimeToFileTime DosPathToSessionPathA DosPathToSessionPathW DuplicateConsoleHandle DuplicateEncryptionInfoFileExt DuplicateHandle EnableThreadProfiling EndUpdateResourceA EndUpdateResourceW EnterSynchronizationBarrier EnterUmsSchedulingMode EnumCalendarInfoA EnumCalendarInfoExA EnumCalendarInfoExEx EnumCalendarInfoExW " \ +"EnumCalendarInfoW EnumDateFormatsA EnumDateFormatsExA EnumDateFormatsExEx EnumDateFormatsExW EnumDateFormatsW EnumLanguageGroupLocalesA EnumLanguageGroupLocalesW EnumResourceLanguagesA EnumResourceLanguagesExA EnumResourceLanguagesExW EnumResourceLanguagesW EnumResourceNamesA EnumResourceNamesExA EnumResourceNamesExW EnumResourceNamesW EnumResourceTypesA EnumResourceTypesExA EnumResourceTypesExW EnumResourceTypesW EnumSystemCodePagesA EnumSystemCodePagesW EnumSystemFirmwareTables EnumSystemGeoID EnumSystemGeoNames EnumSystemLanguageGroupsA EnumSystemLanguageGroupsW EnumSystemLocalesA EnumSystemLocalesEx EnumSystemLocalesW EnumTimeFormatsA EnumTimeFormatsEx EnumTimeFormatsW EnumUILanguagesA EnumUILanguagesW EnumerateLocalComputerNamesA EnumerateLocalComputerNamesW EraseTape EscapeCommFunction ExecuteUmsThread ExitProcess ExitVDM ExpandEnvironmentStringsA ExpandEnvironmentStringsW ExpungeConsoleCommandHistoryA ExpungeConsoleCommandHistoryW FatalAppExitA FatalAppExitW FatalExit FileTimeToDosDateTime FileTimeToLocalFileTime FileTimeToSystemTime FillConsoleOutputAttribute FillConsoleOutputCharacterA FillConsoleOutputCharacterW FindActCtxSectionGuid FindActCtxSectionGuidWorker FindActCtxSectionStringA FindActCtxSectionStringW FindActCtxSectionStringWWorker FindAtomA FindAtomW FindClose FindCloseChangeNotification FindFirstChangeNotificationA FindFirstChangeNotificationW FindFirstFileA FindFirstFileExA FindFirstFileExW FindFirstFileNameTransactedW FindFirstFileNameW FindFirstFileTransactedA FindFirstFileTransactedW FindFirstFileW FindFirstStreamTransactedW FindFirstVolumeA FindFirstVolumeMountPointA FindFirstVolumeMountPointW FindFirstVolumeW FindNLSString FindNLSStringEx FindNextChangeNotification FindNextFileA FindNextFileNameW FindNextFileW FindNextVolumeA FindNextVolumeMountPointA FindNextVolumeMountPointW FindNextVolumeW FindResourceA FindResourceExA FindResourceExW FindResourceW FindStringOrdinal FindVolumeClose FindVolumeMountPointClose FlsAlloc FlsFree FlsGetValue FlsSetValue " \ +"FlushConsoleInputBuffer FlushFileBuffers FlushInstructionCache FlushViewOfFile FoldStringA FoldStringW FormatMessageA FormatMessageW FreeConsole FreeEnvironmentStringsA FreeEnvironmentStringsW FreeLibrary FreeLibraryAndExitThread FreeMemoryJobObject FreeResource FreeUserPhysicalPages GenerateConsoleCtrlEvent GetACP GetActiveProcessorCount GetActiveProcessorGroupCount GetAppContainerAce GetAppContainerNamedObjectPath GetApplicationRecoveryCallback GetApplicationRecoveryCallbackWorker GetApplicationRestartSettings GetApplicationRestartSettingsWorker GetAtomNameA GetAtomNameW GetBinaryType GetBinaryTypeA GetBinaryTypeW GetCPInfo GetCPInfoExA GetCPInfoExW GetCachedSigningLevel GetCalendarDateFormat GetCalendarDateFormatEx GetCalendarDaysInMonth GetCalendarDifferenceInDays GetCalendarInfoA GetCalendarInfoEx GetCalendarInfoW GetCalendarMonthsInYear GetCalendarSupportedDateRange GetCalendarWeekNumber GetComPlusPackageInstallStatus GetCommConfig GetCommMask GetCommModemStatus GetCommProperties GetCommState GetCommTimeouts GetCommandLineA GetCommandLineW GetCompressedFileSizeA GetCompressedFileSizeTransactedA GetCompressedFileSizeTransactedW GetCompressedFileSizeW GetComputerNameA GetComputerNameExA GetComputerNameExW GetComputerNameW GetConsoleAliasA GetConsoleAliasExesA GetConsoleAliasExesLengthA GetConsoleAliasExesLengthW GetConsoleAliasExesW GetConsoleAliasW GetConsoleAliasesA GetConsoleAliasesLengthA GetConsoleAliasesLengthW GetConsoleAliasesW GetConsoleCP GetConsoleCharType GetConsoleCommandHistoryA GetConsoleCommandHistoryLengthA GetConsoleCommandHistoryLengthW GetConsoleCommandHistoryW GetConsoleCursorInfo GetConsoleCursorMode GetConsoleDisplayMode GetConsoleFontInfo GetConsoleFontSize GetConsoleHardwareState GetConsoleHistoryInfo GetConsoleInputWaitHandle GetConsoleKeyboardLayoutNameA GetConsoleKeyboardLayoutNameW GetConsoleMode GetConsoleNlsMode GetConsoleOriginalTitleA GetConsoleOriginalTitleW GetConsoleOutputCP GetConsoleProcessList GetConsoleScreenBufferInfo GetConsoleScreenBufferInfoEx " \ +"GetConsoleSelectionInfo GetConsoleTitleA GetConsoleTitleW GetConsoleWindow GetCurrencyFormatA GetCurrencyFormatEx GetCurrencyFormatW GetCurrentActCtx GetCurrentActCtxWorker GetCurrentConsoleFont GetCurrentConsoleFontEx GetCurrentDirectoryA GetCurrentDirectoryW GetCurrentProcess GetCurrentProcessId GetCurrentThread GetCurrentThreadId GetCurrentUmsThread GetDateFormatA GetDateFormatAWorker GetDateFormatEx GetDateFormatW GetDateFormatWWorker GetDefaultCommConfigA GetDefaultCommConfigW GetDevicePowerState GetDiskFreeSpaceA GetDiskFreeSpaceExA GetDiskFreeSpaceExW GetDiskFreeSpaceW GetDllDirectoryA GetDllDirectoryW GetDriveTypeA GetDriveTypeW GetDurationFormat GetDurationFormatEx GetDynamicTimeZoneInformation GetEnabledXStateFeatures GetEncryptedFileVersionExt GetEnvironmentStrings GetEnvironmentStringsA GetEnvironmentStringsW GetEnvironmentVariableA GetEnvironmentVariableW GetEraNameCountedString GetErrorMode GetExitCodeProcess GetExitCodeThread GetExpandedNameA GetExpandedNameW GetFileAttributesA GetFileAttributesExA GetFileAttributesExW GetFileAttributesTransactedA GetFileAttributesTransactedW GetFileAttributesW GetFileBandwidthReservation GetFileInformationByHandle GetFileInformationByHandleEx GetFileMUIInfo GetFileMUIPath GetFileSize GetFileSizeEx GetFileTime GetFileType GetFinalPathNameByHandleA GetFinalPathNameByHandleW GetFirmwareEnvironmentVariableA GetFirmwareEnvironmentVariableExA GetFirmwareEnvironmentVariableExW GetFirmwareEnvironmentVariableW GetFirmwareType GetFullPathNameA GetFullPathNameTransactedA GetFullPathNameTransactedW GetFullPathNameW GetGeoInfoA GetGeoInfoEx GetGeoInfoW GetHandleInformation GetLargePageMinimum GetLargestConsoleWindowSize GetLastError GetLocalTime GetLocaleInfoA GetLocaleInfoEx GetLocaleInfoW GetLogicalDriveStringsA GetLogicalDriveStringsW GetLogicalDrives GetLogicalProcessorInformation GetLongPathNameA GetLongPathNameTransactedA GetLongPathNameTransactedW GetLongPathNameW GetMailslotInfo GetMaximumProcessorCount GetMaximumProcessorGroupCount " \ +"GetMemoryErrorHandlingCapabilities GetModuleFileNameA GetModuleFileNameW GetModuleHandleA GetModuleHandleExA GetModuleHandleExW GetModuleHandleW GetNLSVersion GetNLSVersionEx GetNamedPipeAttribute GetNamedPipeClientComputerNameA GetNamedPipeClientComputerNameW GetNamedPipeClientProcessId GetNamedPipeClientSessionId GetNamedPipeHandleStateA GetNamedPipeHandleStateW GetNamedPipeServerProcessId GetNamedPipeServerSessionId GetNativeSystemInfo GetNextUmsListItem GetNextVDMCommand GetNumaAvailableMemoryNode GetNumaAvailableMemoryNodeEx GetNumaHighestNodeNumber GetNumaNodeNumberFromHandle GetNumaNodeProcessorMask GetNumaNodeProcessorMaskEx GetNumaProcessorNode GetNumaProcessorNodeEx GetNumaProximityNode GetNumaProximityNodeEx GetNumberFormatA GetNumberFormatEx GetNumberFormatW GetNumberOfConsoleFonts GetNumberOfConsoleInputEvents GetNumberOfConsoleMouseButtons GetOEMCP GetOverlappedResult GetPhysicallyInstalledSystemMemory GetPriorityClass GetPrivateProfileIntA GetPrivateProfileIntW GetPrivateProfileSectionA GetPrivateProfileSectionNamesA GetPrivateProfileSectionNamesW GetPrivateProfileSectionW GetPrivateProfileStringA GetPrivateProfileStringW GetPrivateProfileStructA GetPrivateProfileStructW GetProcAddress GetProcessAffinityMask GetProcessDEPPolicy GetProcessGroupAffinity GetProcessHandleCount GetProcessHeap GetProcessHeaps GetProcessId GetProcessIdOfThread GetProcessInformation GetProcessIoCounters GetProcessPreferredUILanguages GetProcessPriorityBoost GetProcessShutdownParameters GetProcessTimes GetProcessVersion GetProcessWorkingSetSize GetProcessWorkingSetSizeEx GetProductInfo GetProfileIntA GetProfileIntW GetProfileSectionA GetProfileSectionW GetProfileStringA GetProfileStringW GetQueuedCompletionStatus GetQueuedCompletionStatusEx GetShortPathNameA GetShortPathNameW GetStartupInfoA GetStartupInfoW GetStdHandle GetStringScripts GetStringTypeA GetStringTypeExA GetStringTypeExW GetStringTypeW GetSystemDEPPolicy GetSystemDefaultLCID GetSystemDefaultLangID GetSystemDefaultLocaleName " \ +"GetSystemDefaultUILanguage GetSystemDirectoryA GetSystemDirectoryW GetSystemFileCacheSize GetSystemFirmwareTable GetSystemInfo GetSystemPowerStatus GetSystemPreferredUILanguages GetSystemRegistryQuota GetSystemTime GetSystemTimeAdjustment GetSystemTimeAsFileTime GetSystemTimePreciseAsFileTime GetSystemTimes GetSystemWindowsDirectoryA GetSystemWindowsDirectoryW GetSystemWow64DirectoryA GetSystemWow64DirectoryW GetTapeParameters GetTapePosition GetTapeStatus GetTempFileNameA GetTempFileNameW GetTempPathA GetTempPathW GetThreadContext GetThreadErrorMode GetThreadGroupAffinity GetThreadIOPendingFlag GetThreadId GetThreadIdealProcessorEx GetThreadInformation GetThreadLocale GetThreadPreferredUILanguages GetThreadPriority GetThreadPriorityBoost GetThreadSelectorEntry GetThreadTimes GetThreadUILanguage GetTickCount GetTickCount64 GetTimeFormatA GetTimeFormatAWorker GetTimeFormatEx GetTimeFormatW GetTimeFormatWWorker GetTimeZoneInformation GetTimeZoneInformationForYear GetUILanguageInfo GetUmsCompletionListEvent GetUmsSystemThreadInformation GetUserDefaultGeoName GetUserDefaultLCID GetUserDefaultLangID GetUserDefaultLocaleName GetUserDefaultUILanguage GetUserGeoID GetUserPreferredUILanguages GetVDMCurrentDirectories GetVersion GetVersionExA GetVersionExW GetVolumeInformationA GetVolumeInformationByHandleW GetVolumeInformationW GetVolumeNameForVolumeMountPointA GetVolumeNameForVolumeMountPointW GetVolumePathNameA GetVolumePathNameW GetVolumePathNamesForVolumeNameA GetVolumePathNamesForVolumeNameW GetWindowsDirectoryA GetWindowsDirectoryW GetWriteWatch GetXStateFeaturesMask GlobalAddAtomA GlobalAddAtomExA GlobalAddAtomExW GlobalAddAtomW GlobalAlloc GlobalCompact GlobalDeleteAtom GlobalFindAtomA GlobalFindAtomW GlobalFix GlobalFlags GlobalFree GlobalGetAtomNameA GlobalGetAtomNameW GlobalHandle GlobalLock GlobalMemoryStatus GlobalMemoryStatusEx GlobalReAlloc GlobalSize GlobalUnWire GlobalUnfix GlobalUnlock GlobalWire Heap32First Heap32ListFirst Heap32ListNext Heap32Next HeapCompact " \ +"HeapCreate HeapDestroy HeapFree HeapLock HeapQueryInformation HeapSetInformation HeapSummary HeapUnlock HeapValidate HeapWalk IdnToAscii IdnToNameprepUnicode IdnToUnicode InitAtomTable InitializeContext InitializeCriticalSectionAndSpinCount InitializeCriticalSectionEx InitializeSynchronizationBarrier InvalidateConsoleDIBits IsBadCodePtr IsBadHugeReadPtr IsBadHugeWritePtr IsBadReadPtr IsBadStringPtrA IsBadStringPtrW IsBadWritePtr IsCalendarLeapDay IsCalendarLeapMonth IsCalendarLeapYear IsDBCSLeadByte IsDBCSLeadByteEx IsDebuggerPresent IsNLSDefinedString IsNativeVhdBoot IsNormalizedString IsProcessInJob IsProcessorFeaturePresent IsSystemResumeAutomatic IsThreadAFiber IsValidCalDateTime IsValidCodePage IsValidLanguageGroup IsValidLocale IsValidLocaleName IsValidNLSVersion IsWow64Process K32EmptyWorkingSet K32EnumDeviceDrivers K32EnumPageFilesA K32EnumPageFilesW K32EnumProcessModules K32EnumProcessModulesEx K32EnumProcesses K32GetDeviceDriverBaseNameA K32GetDeviceDriverBaseNameW K32GetDeviceDriverFileNameA K32GetDeviceDriverFileNameW K32GetMappedFileNameA K32GetMappedFileNameW K32GetModuleBaseNameA K32GetModuleBaseNameW K32GetModuleFileNameExA K32GetModuleFileNameExW K32GetModuleInformation K32GetPerformanceInfo K32GetProcessImageFileNameA K32GetProcessImageFileNameW K32GetProcessMemoryInfo K32GetWsChanges K32GetWsChangesEx K32InitializeProcessForWsWatch K32QueryWorkingSet K32QueryWorkingSetEx LCIDToLocaleName LCMapStringA LCMapStringEx LCMapStringW LZClose LZCloseFile LZCopy LZCreateFileW LZDone LZInit LZOpenFileA LZOpenFileW LZRead LZSeek LZStart LoadAppInitDlls LoadLibraryA LoadLibraryExA LoadLibraryExW LoadLibraryW LoadModule LoadPackagedLibrary LoadResource LoadStringBaseExW LoadStringBaseW LocalAlloc LocalCompact LocalFileTimeToFileTime LocalFlags LocalFree LocalHandle LocalLock LocalReAlloc LocalShrink LocalSize LocalUnlock LocaleNameToLCID LocateXStateFeature LockFile LockFileEx LockResource MapUserPhysicalPages MapUserPhysicalPagesScatter MapViewOfFile MapViewOfFileEx " \ +"MapViewOfFileExNuma Module32First Module32FirstW Module32Next Module32NextW MoveFileA MoveFileExA MoveFileExW MoveFileTransactedA MoveFileTransactedW MoveFileW MoveFileWithProgressA MoveFileWithProgressW MulDiv MultiByteToWideChar NeedCurrentDirectoryForExePathA NeedCurrentDirectoryForExePathW NlsCheckPolicy NlsEventDataDescCreate NlsGetCacheUpdateCount NlsUpdateLocale NlsUpdateSystemLocale NlsWriteEtwEvent NormalizeString NotifyMountMgr NotifyUILanguageChange NtVdm64CreateProcessInternalW OOBEComplete OpenConsoleW OpenConsoleWStub OpenEventA OpenEventW OpenFile OpenFileById OpenFileMappingA OpenFileMappingW OpenJobObjectA OpenJobObjectW OpenMutexA OpenMutexW OpenPrivateNamespaceA OpenPrivateNamespaceW OpenProcess OpenProfileUserMapping OpenSemaphoreA OpenSemaphoreW OpenThread OpenWaitableTimerA OpenWaitableTimerW OutputDebugStringA OutputDebugStringW PeekConsoleInputA PeekConsoleInputW PeekNamedPipe PostQueuedCompletionStatus PowerClearRequest PowerCreateRequest PowerSetRequest PrepareTape PrivCopyFileExW PrivMoveFileIdentityW Process32First Process32FirstW Process32Next Process32NextW ProcessIdToSessionId PssCaptureSnapshot PssDuplicateSnapshot PssFreeSnapshot PssQuerySnapshot PssWalkMarkerCreate PssWalkMarkerFree PssWalkMarkerGetPosition PssWalkMarkerRewind PssWalkMarkerSeek PssWalkMarkerSeekToBeginning PssWalkMarkerSetPosition PssWalkMarkerTell PssWalkSnapshot PulseEvent PurgeComm QueryActCtxSettingsW QueryActCtxSettingsWWorker QueryActCtxW QueryActCtxWWorker QueryDosDeviceA QueryDosDeviceW QueryFullProcessImageNameA QueryFullProcessImageNameW QueryIdleProcessorCycleTime QueryIdleProcessorCycleTimeEx QueryInformationJobObject QueryIoRateControlInformationJobObject QueryMemoryResourceNotification QueryPerformanceCounter QueryPerformanceFrequency QueryProcessAffinityUpdateMode QueryProcessCycleTime QueryThreadCycleTime QueryThreadProfiling QueryThreadpoolStackInformation QueryUmsThreadInformation QueryUnbiasedInterruptTime QueueUserAPC QueueUserWorkItem QuirkGetData2Worker " \ +"QuirkGetDataWorker QuirkIsEnabled2Worker QuirkIsEnabled3Worker QuirkIsEnabledForPackage2Worker QuirkIsEnabledForPackage3Worker QuirkIsEnabledForPackage4Worker QuirkIsEnabledForPackageWorker QuirkIsEnabledForProcessWorker QuirkIsEnabledWorker RaiseException RaiseInvalid16BitExeError ReOpenFile ReadConsoleA ReadConsoleInputA ReadConsoleInputW ReadConsoleOutputA ReadConsoleOutputAttribute ReadConsoleOutputCharacterA ReadConsoleOutputCharacterW ReadConsoleOutputW ReadConsoleW ReadDirectoryChangesExW ReadDirectoryChangesW ReadFile ReadFileEx ReadFileScatter ReadProcessMemory ReadThreadProfilingData RegCloseKey RegCopyTreeW RegCreateKeyExA RegCreateKeyExW RegDeleteKeyExA RegDeleteKeyExW RegDeleteTreeA RegDeleteTreeW RegDeleteValueA RegDeleteValueW RegDisablePredefinedCacheEx RegEnumKeyExA RegEnumKeyExW RegEnumValueA RegEnumValueW RegFlushKey RegGetKeySecurity RegGetValueA RegGetValueW RegLoadKeyA RegLoadKeyW RegLoadMUIStringA RegLoadMUIStringW RegNotifyChangeKeyValue RegOpenCurrentUser RegOpenKeyExA RegOpenKeyExW RegOpenUserClassesRoot RegQueryInfoKeyA RegQueryInfoKeyW RegQueryValueExA RegQueryValueExW RegRestoreKeyA RegRestoreKeyW RegSaveKeyExA RegSaveKeyExW RegSetKeySecurity RegSetValueExA RegSetValueExW RegUnLoadKeyA RegUnLoadKeyW RegisterApplicationRecoveryCallback RegisterApplicationRestart RegisterBadMemoryNotification RegisterConsoleIME RegisterConsoleOS2 RegisterConsoleVDM RegisterWaitForInputIdle RegisterWaitForSingleObject RegisterWaitForSingleObjectEx RegisterWaitUntilOOBECompleted RegisterWowBaseHandlers RegisterWowExec ReleaseActCtx ReleaseActCtxWorker ReleaseMutex ReleaseSemaphore RemoveDirectoryA RemoveDirectoryTransactedA RemoveDirectoryTransactedW RemoveDirectoryW RemoveLocalAlternateComputerNameA RemoveLocalAlternateComputerNameW RemoveSecureMemoryCacheCallback ReplaceFile ReplaceFileA ReplaceFileW ReplacePartitionUnit RequestDeviceWakeup RequestWakeupLatency ResetEvent ResetWriteWatch ResolveLocaleName ResumeThread RtlAddFunctionTable RtlCaptureContext RtlCaptureStackBackTrace " \ +"RtlCompareMemory RtlCopyMemory RtlDeleteFunctionTable RtlFillMemory RtlInstallFunctionTableCallback RtlLookupFunctionEntry RtlMoveMemory RtlPcToFileHeader RtlRaiseException RtlRestoreContext RtlUnwind RtlUnwindEx RtlVirtualUnwind ScrollConsoleScreenBufferA ScrollConsoleScreenBufferW SearchPathA SearchPathW SetCachedSigningLevel SetCalendarInfoA SetCalendarInfoW SetComPlusPackageInstallStatus SetCommBreak SetCommConfig SetCommMask SetCommState SetCommTimeouts SetComputerNameA SetComputerNameEx2W SetComputerNameExA SetComputerNameExW SetComputerNameW SetConsoleActiveScreenBuffer SetConsoleCP SetConsoleCtrlHandler SetConsoleCursor SetConsoleCursorInfo SetConsoleCursorMode SetConsoleCursorPosition SetConsoleDisplayMode SetConsoleFont SetConsoleHardwareState SetConsoleHistoryInfo SetConsoleIcon SetConsoleKeyShortcuts SetConsoleLocalEUDC SetConsoleMaximumWindowSize SetConsoleMenuClose SetConsoleMode SetConsoleNlsMode SetConsoleNumberOfCommandsA SetConsoleNumberOfCommandsW SetConsoleOS2OemFormat SetConsoleOutputCP SetConsolePalette SetConsoleScreenBufferInfoEx SetConsoleScreenBufferSize SetConsoleTextAttribute SetConsoleTitleA SetConsoleTitleW SetConsoleWindowInfo SetCurrentConsoleFontEx SetCurrentDirectoryA SetCurrentDirectoryW SetDefaultCommConfigA SetDefaultCommConfigW SetDllDirectoryA SetDllDirectoryW SetDynamicTimeZoneInformation SetEndOfFile SetEnvironmentStringsA SetEnvironmentStringsW SetEnvironmentVariableA SetEnvironmentVariableW SetErrorMode SetEvent SetFileApisToANSI SetFileApisToOEM SetFileAttributesA SetFileAttributesTransactedA SetFileAttributesTransactedW SetFileAttributesW SetFileBandwidthReservation SetFileCompletionNotificationModes SetFileInformationByHandle SetFileIoOverlappedRange SetFilePointer SetFilePointerEx SetFileShortNameA SetFileShortNameW SetFileTime SetFileValidData SetFirmwareEnvironmentVariableA SetFirmwareEnvironmentVariableExA SetFirmwareEnvironmentVariableExW SetFirmwareEnvironmentVariableW SetHandleCount SetHandleInformation SetInformationJobObject " \ +"SetIoRateControlInformationJobObject SetLastError SetLocalPrimaryComputerNameA SetLocalPrimaryComputerNameW SetLocalTime SetLocaleInfoA SetLocaleInfoW SetMailslotInfo SetMessageWaitingIndicator SetNamedPipeAttribute SetNamedPipeHandleState SetPriorityClass SetProcessAffinityMask SetProcessAffinityUpdateMode SetProcessDEPPolicy SetProcessInformation SetProcessPreferredUILanguages SetProcessPriorityBoost SetProcessShutdownParameters SetProcessWorkingSetSize SetProcessWorkingSetSizeEx SetSearchPathMode SetStdHandle SetStdHandleEx SetSystemFileCacheSize SetSystemPowerState SetSystemTime SetSystemTimeAdjustment SetTapeParameters SetTapePosition SetTermsrvAppInstallMode SetThreadAffinityMask SetThreadContext SetThreadErrorMode SetThreadExecutionState SetThreadGroupAffinity SetThreadIdealProcessor SetThreadIdealProcessorEx SetThreadInformation SetThreadLocale SetThreadPreferredUILanguages SetThreadPriority SetThreadPriorityBoost SetThreadStackGuarantee SetThreadUILanguage SetThreadpoolStackInformation SetThreadpoolThreadMinimum SetTimeZoneInformation SetTimerQueueTimer SetUmsThreadInformation SetUnhandledExceptionFilter SetUserGeoID SetUserGeoName SetVDMCurrentDirectories SetVolumeLabelA SetVolumeLabelW SetVolumeMountPointA SetVolumeMountPointW SetVolumeMountPointWStub SetWaitableTimer SetXStateFeaturesMask SetupComm ShowConsoleCursor SignalObjectAndWait SizeofResource Sleep SleepEx SortCloseHandle SortGetHandle SuspendThread SwitchToFiber SwitchToThread SystemTimeToFileTime SystemTimeToTzSpecificLocalTime TerminateJobObject TerminateProcess TerminateThread TermsrvAppInstallMode TermsrvConvertSysRootToUserDir TermsrvCreateRegEntry TermsrvDeleteKey TermsrvDeleteValue TermsrvGetPreSetValue TermsrvGetWindowsDirectoryA TermsrvGetWindowsDirectoryW TermsrvOpenRegEntry TermsrvOpenUserClasses TermsrvRestoreKey TermsrvSetKeySecurity TermsrvSetValueKey TermsrvSyncUserIniFileExt Thread32First Thread32Next TlsAlloc TlsFree TlsGetValue TlsSetValue Toolhelp32ReadProcessMemory TransactNamedPipe " \ +"TransmitCommChar TrySubmitThreadpoolCallback TzSpecificLocalTimeToSystemTime UTRegister UTUnRegister UmsThreadYield UnhandledExceptionFilter UnlockFile UnlockFileEx UnmapViewOfFile UnregisterApplicationRecoveryCallback UnregisterApplicationRestart UnregisterBadMemoryNotification UnregisterConsoleIME UnregisterWait UnregisterWaitEx UnregisterWaitUntilOOBECompleted UpdateCalendarDayOfWeek UpdateResourceA UpdateResourceW VDMConsoleOperation VDMOperationStarted VerLanguageNameA VerLanguageNameW VerifyConsoleIoHandle VerifyScripts VerifyVersionInfoA VerifyVersionInfoW VirtualAlloc VirtualAllocEx VirtualAllocExNuma VirtualFree VirtualFreeEx VirtualLock VirtualProtect VirtualProtectEx VirtualQuery VirtualQueryEx VirtualUnlock WTSGetActiveConsoleSessionId WaitCommEvent WaitForDebugEvent WaitForMultipleObjects WaitForMultipleObjectsEx WaitForSingleObject WaitForSingleObjectEx WaitNamedPipeA WaitNamedPipeW WerGetFlags WerGetFlagsWorker WerRegisterAdditionalProcess WerRegisterAppLocalDump WerRegisterCustomMetadata WerRegisterExcludedMemoryBlock WerRegisterFile WerRegisterFileWorker WerRegisterMemoryBlock WerRegisterMemoryBlockWorker WerRegisterRuntimeExceptionModule WerRegisterRuntimeExceptionModuleWorker WerSetFlags WerSetFlagsWorker WerUnregisterAdditionalProcess WerUnregisterAppLocalDump WerUnregisterCustomMetadata WerUnregisterExcludedMemoryBlock WerUnregisterFile WerUnregisterFileWorker WerUnregisterMemoryBlock WerUnregisterMemoryBlockWorker WerUnregisterRuntimeExceptionModule WerUnregisterRuntimeExceptionModuleWorker WerpGetDebugger WerpInitiateRemoteRecovery WerpLaunchAeDebug WerpNotifyLoadStringResourceWorker WerpNotifyUseStringResourceWorker WideCharToMultiByte WinExec Wow64DisableWow64FsRedirection Wow64EnableWow64FsRedirection Wow64GetThreadContext Wow64GetThreadSelectorEntry Wow64RevertWow64FsRedirection Wow64SetThreadContext Wow64SuspendThread WriteConsoleA WriteConsoleInputA WriteConsoleInputVDMA WriteConsoleInputVDMW WriteConsoleInputW WriteConsoleOutputA WriteConsoleOutputAttribute " \ +"WriteConsoleOutputCharacterA WriteConsoleOutputCharacterW WriteConsoleOutputW WriteConsoleW WriteFile WriteFileEx WriteFileGather WritePrivateProfileSectionA WritePrivateProfileSectionW WritePrivateProfileStringA WritePrivateProfileStringW WritePrivateProfileStructA WritePrivateProfileStructW WriteProcessMemory WriteProfileSectionA WriteProfileSectionW WriteProfileStringA WriteProfileStringW WriteTapemark ZombifyActCtx ZombifyActCtxWorker _hread _hwrite _lclose _lcreat _llseek _lopen _lread _lwrite lstrcat lstrcatA lstrcatW lstrcmp lstrcmpA lstrcmpW lstrcmpi lstrcmpiA lstrcmpiW lstrcpy lstrcpyA lstrcpyW lstrcpyn lstrcpynA lstrcpynW lstrlen lstrlenA lstrlenW timeBeginPeriod timeEndPeriod timeGetDevCaps timeGetSystemTime timeGetTime uaw_lstrcmpW uaw_lstrcmpiW uaw_lstrlenW uaw_wcschr uaw_wcscpy uaw_wcsicmp uaw_wcslen uaw_wcsrchr"; + +char apis_ntdll[] = "A_SHAFinal A_SHAInit A_SHAUpdate AlpcAdjustCompletionListConcurrencyCount AlpcFreeCompletionListMessage AlpcGetCompletionListLastMessageInformation AlpcGetCompletionListMessageAttributes AlpcGetHeaderSize AlpcGetMessageAttribute AlpcGetMessageFromCompletionList AlpcGetOutstandingCompletionListMessageCount AlpcInitializeMessageAttribute AlpcMaxAllowedMessageLength AlpcRegisterCompletionList AlpcRegisterCompletionListWorkerThread AlpcRundownCompletionList AlpcUnregisterCompletionList AlpcUnregisterCompletionListWorkerThread ApiSetQueryApiSetPresence CsrAllocateCaptureBuffer CsrAllocateMessagePointer CsrCaptureMessageBuffer CsrCaptureMessageMultiUnicodeStringsInPlace CsrCaptureMessageString CsrCaptureTimeout CsrClientCallServer CsrClientConnectToServer CsrFreeCaptureBuffer CsrGetProcessId CsrIdentifyAlertableThread CsrSetPriorityClass CsrVerifyRegion DbgBreakPoint DbgPrint DbgPrintEx DbgPrintReturnControlC DbgPrompt DbgQueryDebugFilterState DbgSetDebugFilterState DbgUiConnectToDbg DbgUiContinue DbgUiConvertStateChangeStructure DbgUiConvertStateChangeStructureEx DbgUiDebugActiveProcess DbgUiGetThreadDebugObject DbgUiIssueRemoteBreakin DbgUiRemoteBreakin DbgUiSetThreadDebugObject DbgUiStopDebugging DbgUiWaitStateChange DbgUserBreakPoint EtwCheckCoverage EtwCreateTraceInstanceId EtwDeliverDataBlock EtwEnumerateProcessRegGuids EtwEventActivityIdControl EtwEventEnabled EtwEventProviderEnabled EtwEventRegister EtwEventSetInformation EtwEventUnregister EtwEventWrite EtwEventWriteEndScenario EtwEventWriteEx EtwEventWriteFull EtwEventWriteNoRegistration EtwEventWriteStartScenario EtwEventWriteString EtwEventWriteTransfer EtwGetTraceEnableFlags EtwGetTraceEnableLevel EtwGetTraceLoggerHandle EtwLogTraceEvent EtwNotificationRegister EtwNotificationUnregister EtwProcessPrivateLoggerRequest EtwRegisterSecurityProvider EtwRegisterTraceGuidsA EtwRegisterTraceGuidsW EtwReplyNotification EtwSendNotification EtwSetMark EtwTraceEventInstance EtwTraceMessage EtwTraceMessageVa " \ +"EtwUnregisterTraceGuids EtwWriteUMSecurityEvent EtwpCreateEtwThread EtwpGetCpuSpeed EvtIntReportAuthzEventAndSourceAsync EvtIntReportEventAndSourceAsync ExpInterlockedPopEntrySListEnd ExpInterlockedPopEntrySListFault ExpInterlockedPopEntrySListResume KiRaiseUserExceptionDispatcher KiUserApcDispatcher KiUserCallbackDispatcher KiUserExceptionDispatcher KiUserInvertedFunctionTable LdrAccessResource LdrAddDllDirectory LdrAddLoadAsDataTable LdrAddRefDll LdrAppxHandleIntegrityFailure LdrCallEnclave LdrControlFlowGuardEnforced LdrCreateEnclave LdrDeleteEnclave LdrDisableThreadCalloutsForDll LdrEnumResources LdrEnumerateLoadedModules LdrFastFailInLoaderCallout LdrFindEntryForAddress LdrFindResourceDirectory_U LdrFindResourceEx_U LdrFindResource_U LdrFlushAlternateResourceModules LdrGetDllDirectory LdrGetDllFullName LdrGetDllHandle LdrGetDllHandleByMapping LdrGetDllHandleByName LdrGetDllHandleEx LdrGetDllPath LdrGetFailureData LdrGetFileNameFromLoadAsDataTable LdrGetKnownDllSectionHandle LdrGetProcedureAddress LdrGetProcedureAddressEx LdrGetProcedureAddressForCaller LdrInitShimEngineDynamic LdrInitializeEnclave LdrInitializeThunk LdrLoadAlternateResourceModule LdrLoadAlternateResourceModuleEx LdrLoadDll LdrLoadEnclaveModule LdrLockLoaderLock LdrOpenImageFileOptionsKey LdrProcessInitializationComplete LdrProcessRelocationBlock LdrProcessRelocationBlockEx LdrQueryImageFileExecutionOptions LdrQueryImageFileExecutionOptionsEx LdrQueryImageFileKeyOption LdrQueryModuleServiceTags LdrQueryOptionalDelayLoadedAPI LdrQueryProcessModuleInformation LdrRegisterDllNotification LdrRemoveDllDirectory LdrRemoveLoadAsDataTable LdrResFindResource LdrResFindResourceDirectory LdrResGetRCConfig LdrResRelease LdrResSearchResource LdrResolveDelayLoadedAPI LdrResolveDelayLoadsFromDll LdrRscIsTypeExist LdrSetAppCompatDllRedirectionCallback LdrSetDefaultDllDirectories LdrSetDllDirectory LdrSetDllManifestProber LdrSetImplicitPathOptions LdrSetMUICacheType LdrShutdownProcess LdrShutdownThread LdrStandardizeSystemPath " \ +"LdrSystemDllInitBlock LdrUnloadAlternateResourceModule LdrUnloadAlternateResourceModuleEx LdrUnloadDll LdrUnlockLoaderLock LdrUnregisterDllNotification LdrUpdatePackageSearchPath LdrVerifyImageMatchesChecksum LdrVerifyImageMatchesChecksumEx LdrpResGetMappingSize LdrpResGetResourceDirectory MD4Final MD4Init MD4Update MD5Final MD5Init MD5Update NlsAnsiCodePage NlsMbCodePageTag NlsMbOemCodePageTag NtAcceptConnectPort NtAccessCheck NtAccessCheckAndAuditAlarm NtAccessCheckByType NtAccessCheckByTypeAndAuditAlarm NtAccessCheckByTypeResultList NtAccessCheckByTypeResultListAndAuditAlarm NtAccessCheckByTypeResultListAndAuditAlarmByHandle NtAcquireProcessActivityReference NtAddAtom NtAddAtomEx NtAddBootEntry NtAddDriverEntry NtAdjustGroupsToken NtAdjustPrivilegesToken NtAdjustTokenClaimsAndDeviceGroups NtAlertResumeThread NtAlertThread NtAlertThreadByThreadId NtAllocateLocallyUniqueId NtAllocateReserveObject NtAllocateUserPhysicalPages NtAllocateUuids NtAllocateVirtualMemory NtAllocateVirtualMemoryEx NtAlpcAcceptConnectPort NtAlpcCancelMessage NtAlpcConnectPort NtAlpcConnectPortEx NtAlpcCreatePort NtAlpcCreatePortSection NtAlpcCreateResourceReserve NtAlpcCreateSectionView NtAlpcCreateSecurityContext NtAlpcDeletePortSection NtAlpcDeleteResourceReserve NtAlpcDeleteSectionView NtAlpcDeleteSecurityContext NtAlpcDisconnectPort NtAlpcImpersonateClientContainerOfPort NtAlpcImpersonateClientOfPort NtAlpcOpenSenderProcess NtAlpcOpenSenderThread NtAlpcQueryInformation NtAlpcQueryInformationMessage NtAlpcRevokeSecurityContext NtAlpcSendWaitReceivePort NtAlpcSetInformation NtApphelpCacheControl NtAreMappedFilesTheSame NtAssignProcessToJobObject NtAssociateWaitCompletionPacket NtCallEnclave NtCallbackReturn NtCancelIoFile NtCancelIoFileEx NtCancelSynchronousIoFile NtCancelTimer NtCancelTimer2 NtCancelWaitCompletionPacket NtClearEvent NtClose NtCloseObjectAuditAlarm NtCommitComplete NtCommitEnlistment NtCommitRegistryTransaction NtCommitTransaction NtCompactKeys NtCompareObjects NtCompareSigningLevels " \ +"NtCompareTokens NtCompleteConnectPort NtCompressKey NtConnectPort NtContinue NtConvertBetweenAuxiliaryCounterAndPerformanceCounter NtCreateDebugObject NtCreateDirectoryObject NtCreateDirectoryObjectEx NtCreateEnclave NtCreateEnlistment NtCreateEvent NtCreateEventPair NtCreateFile NtCreateIRTimer NtCreateIoCompletion NtCreateJobObject NtCreateJobSet NtCreateKey NtCreateKeyTransacted NtCreateKeyedEvent NtCreateLowBoxToken NtCreateMailslotFile NtCreateMutant NtCreateNamedPipeFile NtCreatePagingFile NtCreatePartition NtCreatePort NtCreatePrivateNamespace NtCreateProcess NtCreateProcessEx NtCreateProfile NtCreateProfileEx NtCreateRegistryTransaction NtCreateResourceManager NtCreateSection NtCreateSemaphore NtCreateSymbolicLinkObject NtCreateThread NtCreateThreadEx NtCreateTimer NtCreateTimer2 NtCreateToken NtCreateTokenEx NtCreateTransaction NtCreateTransactionManager NtCreateUserProcess NtCreateWaitCompletionPacket NtCreateWaitablePort NtCreateWnfStateName NtCreateWorkerFactory NtDebugActiveProcess NtDebugContinue NtDelayExecution NtDeleteAtom NtDeleteBootEntry NtDeleteDriverEntry NtDeleteFile NtDeleteKey NtDeleteObjectAuditAlarm NtDeletePrivateNamespace NtDeleteValueKey NtDeleteWnfStateData NtDeleteWnfStateName NtDeviceIoControlFile NtDisableLastKnownGood NtDisplayString NtDrawText NtDuplicateObject NtDuplicateToken NtEnableLastKnownGood NtEnumerateBootEntries NtEnumerateDriverEntries NtEnumerateKey NtEnumerateSystemEnvironmentValuesEx NtEnumerateTransactionObject NtEnumerateValueKey NtExtendSection NtFilterBootOption NtFilterToken NtFilterTokenEx NtFindAtom NtFlushBuffersFile NtFlushBuffersFileEx NtFlushInstallUILanguage NtFlushInstructionCache NtFlushKey NtFlushProcessWriteBuffers NtFlushVirtualMemory NtFlushWriteBuffer NtFreeUserPhysicalPages NtFreeVirtualMemory NtFreezeRegistry NtFreezeTransactions NtFsControlFile NtGetCachedSigningLevel NtGetCompleteWnfStateSubscription NtGetContextThread NtGetCurrentProcessorNumber NtGetCurrentProcessorNumberEx NtGetDevicePowerState " \ +"NtGetMUIRegistryInfo NtGetNextProcess NtGetNextThread NtGetNlsSectionPtr NtGetNotificationResourceManager NtGetTickCount NtGetWriteWatch NtImpersonateAnonymousToken NtImpersonateClientOfPort NtImpersonateThread NtInitializeEnclave NtInitializeNlsFiles NtInitializeRegistry NtInitiatePowerAction NtIsProcessInJob NtIsSystemResumeAutomatic NtIsUILanguageComitted NtListenPort NtLoadDriver NtLoadEnclaveData NtLoadHotPatch NtLoadKey NtLoadKey2 NtLoadKeyEx NtLockFile NtLockProductActivationKeys NtLockRegistryKey NtLockVirtualMemory NtMakePermanentObject NtMakeTemporaryObject NtManagePartition NtMapCMFModule NtMapUserPhysicalPages NtMapUserPhysicalPagesScatter NtMapViewOfSection NtMapViewOfSectionEx NtModifyBootEntry NtModifyDriverEntry NtNotifyChangeDirectoryFile NtNotifyChangeDirectoryFileEx NtNotifyChangeKey NtNotifyChangeMultipleKeys NtNotifyChangeSession NtOpenDirectoryObject NtOpenEnlistment NtOpenEvent NtOpenEventPair NtOpenFile NtOpenIoCompletion NtOpenJobObject NtOpenKey NtOpenKeyEx NtOpenKeyTransacted NtOpenKeyTransactedEx NtOpenKeyedEvent NtOpenMutant NtOpenObjectAuditAlarm NtOpenPartition NtOpenPrivateNamespace NtOpenProcess NtOpenProcessToken NtOpenProcessTokenEx NtOpenRegistryTransaction NtOpenResourceManager NtOpenSection NtOpenSemaphore NtOpenSession NtOpenSymbolicLinkObject NtOpenThread NtOpenThreadToken NtOpenThreadTokenEx NtOpenTimer NtOpenTransaction NtOpenTransactionManager NtPlugPlayControl NtPowerInformation NtPrePrepareComplete NtPrePrepareEnlistment NtPrepareComplete NtPrepareEnlistment NtPrivilegeCheck NtPrivilegeObjectAuditAlarm NtPrivilegedServiceAuditAlarm NtPropagationComplete NtPropagationFailed NtProtectVirtualMemory NtPulseEvent NtQueryAttributesFile NtQueryAuxiliaryCounterFrequency NtQueryBootEntryOrder NtQueryBootOptions NtQueryDebugFilterState NtQueryDefaultLocale NtQueryDefaultUILanguage NtQueryDirectoryFile NtQueryDirectoryFileEx NtQueryDirectoryObject NtQueryDriverEntryOrder NtQueryEaFile NtQueryEvent NtQueryFullAttributesFile NtQueryInformationAtom " \ +"NtQueryInformationByName NtQueryInformationEnlistment NtQueryInformationFile NtQueryInformationJobObject NtQueryInformationPort NtQueryInformationProcess NtQueryInformationResourceManager NtQueryInformationThread NtQueryInformationToken NtQueryInformationTransaction NtQueryInformationTransactionManager NtQueryInformationWorkerFactory NtQueryInstallUILanguage NtQueryIntervalProfile NtQueryIoCompletion NtQueryKey NtQueryLicenseValue NtQueryMultipleValueKey NtQueryMutant NtQueryObject NtQueryOpenSubKeys NtQueryOpenSubKeysEx NtQueryPerformanceCounter NtQueryPortInformationProcess NtQueryQuotaInformationFile NtQuerySection NtQuerySecurityAttributesToken NtQuerySecurityObject NtQuerySecurityPolicy NtQuerySemaphore NtQuerySymbolicLinkObject NtQuerySystemEnvironmentValue NtQuerySystemEnvironmentValueEx NtQuerySystemInformation NtQuerySystemInformationEx NtQuerySystemTime NtQueryTimer NtQueryTimerResolution NtQueryValueKey NtQueryVirtualMemory NtQueryVolumeInformationFile NtQueryWnfStateData NtQueryWnfStateNameInformation NtQueueApcThread NtQueueApcThreadEx NtRaiseException NtRaiseHardError NtReadFile NtReadFileScatter NtReadOnlyEnlistment NtReadRequestData NtReadVirtualMemory NtRecoverEnlistment NtRecoverResourceManager NtRecoverTransactionManager NtRegisterProtocolAddressInformation NtRegisterThreadTerminatePort NtReleaseKeyedEvent NtReleaseMutant NtReleaseSemaphore NtReleaseWorkerFactoryWorker NtRemoveIoCompletion NtRemoveIoCompletionEx NtRemoveProcessDebug NtRenameKey NtRenameTransactionManager NtReplaceKey NtReplacePartitionUnit NtReplyPort NtReplyWaitReceivePort NtReplyWaitReceivePortEx NtReplyWaitReplyPort NtRequestPort NtRequestWaitReplyPort NtResetEvent NtResetWriteWatch NtRestoreKey NtResumeProcess NtResumeThread NtRevertContainerImpersonation NtRollbackComplete NtRollbackEnlistment NtRollbackRegistryTransaction NtRollbackTransaction NtRollforwardTransactionManager NtSaveKey NtSaveKeyEx NtSaveMergedKeys NtSecureConnectPort NtSerializeBoot NtSetBootEntryOrder NtSetBootOptions " \ +"NtSetCachedSigningLevel NtSetCachedSigningLevel2 NtSetContextThread NtSetDebugFilterState NtSetDefaultHardErrorPort NtSetDefaultLocale NtSetDefaultUILanguage NtSetDriverEntryOrder NtSetEaFile NtSetEvent NtSetEventBoostPriority NtSetHighEventPair NtSetHighWaitLowEventPair NtSetIRTimer NtSetInformationDebugObject NtSetInformationEnlistment NtSetInformationFile NtSetInformationJobObject NtSetInformationKey NtSetInformationObject NtSetInformationProcess NtSetInformationResourceManager NtSetInformationSymbolicLink NtSetInformationThread NtSetInformationToken NtSetInformationTransaction NtSetInformationTransactionManager NtSetInformationVirtualMemory NtSetInformationWorkerFactory NtSetIntervalProfile NtSetIoCompletion NtSetIoCompletionEx NtSetLdtEntries NtSetLowEventPair NtSetLowWaitHighEventPair NtSetQuotaInformationFile NtSetSecurityObject NtSetSystemEnvironmentValue NtSetSystemEnvironmentValueEx NtSetSystemInformation NtSetSystemPowerState NtSetSystemTime NtSetThreadExecutionState NtSetTimer NtSetTimer2 NtSetTimerEx NtSetTimerResolution NtSetUuidSeed NtSetValueKey NtSetVolumeInformationFile NtSetWnfProcessNotificationEvent NtShutdownSystem NtShutdownWorkerFactory NtSignalAndWaitForSingleObject NtSinglePhaseReject NtStartProfile NtStopProfile NtSubscribeWnfStateChange NtSuspendProcess NtSuspendThread NtSystemDebugControl NtTerminateEnclave NtTerminateJobObject NtTerminateProcess NtTerminateThread NtTestAlert NtThawRegistry NtThawTransactions NtTraceControl NtTraceEvent NtTranslateFilePath NtUmsThreadYield NtUnloadDriver NtUnloadKey NtUnloadKey2 NtUnloadKeyEx NtUnlockFile NtUnlockVirtualMemory NtUnmapViewOfSection NtUnmapViewOfSectionEx NtUnsubscribeWnfStateChange NtUpdateWnfStateData NtVdmControl NtWaitForAlertByThreadId NtWaitForDebugEvent NtWaitForKeyedEvent NtWaitForMultipleObjects NtWaitForMultipleObjects32 NtWaitForSingleObject NtWaitForWorkViaWorkerFactory NtWaitHighEventPair NtWaitLowEventPair NtWorkerFactoryWorkerReady NtWriteFile NtWriteFileGather NtWriteRequestData " \ +"NtWriteVirtualMemory NtYieldExecution NtdllDefWindowProc_A NtdllDefWindowProc_W NtdllDialogWndProc_A NtdllDialogWndProc_W PfxFindPrefix PfxInitialize PfxInsertPrefix PfxRemovePrefix PssNtCaptureSnapshot PssNtDuplicateSnapshot PssNtFreeRemoteSnapshot PssNtFreeSnapshot PssNtFreeWalkMarker PssNtQuerySnapshot PssNtValidateDescriptor PssNtWalkSnapshot RtlAbortRXact RtlAbsoluteToSelfRelativeSD RtlAcquirePebLock RtlAcquirePrivilege RtlAcquireReleaseSRWLockExclusive RtlAcquireResourceExclusive RtlAcquireResourceShared RtlAcquireSRWLockExclusive RtlAcquireSRWLockShared RtlActivateActivationContext RtlActivateActivationContextEx RtlActivateActivationContextUnsafeFast RtlAddAccessAllowedAce RtlAddAccessAllowedAceEx RtlAddAccessAllowedObjectAce RtlAddAccessDeniedAce RtlAddAccessDeniedAceEx RtlAddAccessDeniedObjectAce RtlAddAccessFilterAce RtlAddAce RtlAddActionToRXact RtlAddAtomToAtomTable RtlAddAttributeActionToRXact RtlAddAuditAccessAce RtlAddAuditAccessAceEx RtlAddAuditAccessObjectAce RtlAddCompoundAce RtlAddFunctionTable RtlAddGrowableFunctionTable RtlAddIntegrityLabelToBoundaryDescriptor RtlAddMandatoryAce RtlAddProcessTrustLabelAce RtlAddRefActivationContext RtlAddRefMemoryStream RtlAddResourceAttributeAce RtlAddSIDToBoundaryDescriptor RtlAddScopedPolicyIDAce RtlAddVectoredContinueHandler RtlAddVectoredExceptionHandler RtlAddressInSectionTable RtlAdjustPrivilege RtlAllocateActivationContextStack RtlAllocateAndInitializeSid RtlAllocateAndInitializeSidEx RtlAllocateHandle RtlAllocateHeap RtlAllocateMemoryBlockLookaside RtlAllocateMemoryZone RtlAllocateWnfSerializationGroup RtlAnsiCharToUnicodeChar RtlAnsiStringToUnicodeSize RtlAnsiStringToUnicodeString RtlAppendAsciizToString RtlAppendPathElement RtlAppendStringToString RtlAppendUnicodeStringToString RtlAppendUnicodeToString RtlApplicationVerifierStop RtlApplyRXact RtlApplyRXactNoFlush RtlAppxIsFileOwnedByTrustedInstaller RtlAreAllAccessesGranted RtlAreAnyAccessesGranted RtlAreBitsClear RtlAreBitsSet RtlAreLongPathsEnabled RtlAssert " \ +"RtlAvlInsertNodeEx RtlAvlRemoveNode RtlBarrier RtlBarrierForDelete RtlCallEnclaveReturn RtlCancelTimer RtlCanonicalizeDomainName RtlCapabilityCheck RtlCapabilityCheckForSingleSessionSku RtlCaptureContext RtlCaptureStackBackTrace RtlCharToInteger RtlCheckBootStatusIntegrity RtlCheckForOrphanedCriticalSections RtlCheckPortableOperatingSystem RtlCheckRegistryKey RtlCheckSandboxedToken RtlCheckSystemBootStatusIntegrity RtlCheckTokenCapability RtlCheckTokenMembership RtlCheckTokenMembershipEx RtlCleanUpTEBLangLists RtlClearAllBits RtlClearBit RtlClearBits RtlClearThreadWorkOnBehalfTicket RtlCloneMemoryStream RtlCloneUserProcess RtlCmDecodeMemIoResource RtlCmEncodeMemIoResource RtlCommitDebugInfo RtlCommitMemoryStream RtlCompactHeap RtlCompareAltitudes RtlCompareMemory RtlCompareMemoryUlong RtlCompareString RtlCompareUnicodeString RtlCompareUnicodeStrings RtlCompleteProcessCloning RtlCompressBuffer RtlComputeCrc32 RtlComputeImportTableHash RtlComputePrivatizedDllName_U RtlConnectToSm RtlConsoleMultiByteToUnicodeN RtlContractHashTable RtlConvertDeviceFamilyInfoToString RtlConvertExclusiveToShared RtlConvertLCIDToString RtlConvertSRWLockExclusiveToShared RtlConvertSharedToExclusive RtlConvertSidToUnicodeString RtlConvertToAutoInheritSecurityObject RtlCopyBitMap RtlCopyContext RtlCopyExtendedContext RtlCopyLuid RtlCopyLuidAndAttributesArray RtlCopyMappedMemory RtlCopyMemory RtlCopyMemoryNonTemporal RtlCopyMemoryStreamTo RtlCopyOutOfProcessMemoryStreamTo RtlCopySecurityDescriptor RtlCopySid RtlCopySidAndAttributesArray RtlCopyString RtlCopyUnicodeString RtlCrc32 RtlCrc64 RtlCreateAcl RtlCreateActivationContext RtlCreateAndSetSD RtlCreateAtomTable RtlCreateBootStatusDataFile RtlCreateBoundaryDescriptor RtlCreateEnvironment RtlCreateEnvironmentEx RtlCreateHashTable RtlCreateHashTableEx RtlCreateHeap RtlCreateMemoryBlockLookaside RtlCreateMemoryZone RtlCreateProcessParameters RtlCreateProcessParametersEx RtlCreateProcessReflection RtlCreateQueryDebugBuffer RtlCreateRegistryKey RtlCreateSecurityDescriptor " \ +"RtlCreateServiceSid RtlCreateSystemVolumeInformationFolder RtlCreateTagHeap RtlCreateTimer RtlCreateTimerQueue RtlCreateUmsCompletionList RtlCreateUmsThreadContext RtlCreateUnicodeString RtlCreateUnicodeStringFromAsciiz RtlCreateUserProcess RtlCreateUserProcessEx RtlCreateUserSecurityObject RtlCreateUserStack RtlCreateUserThread RtlCreateVirtualAccountSid RtlCultureNameToLCID RtlCustomCPToUnicodeN RtlCutoverTimeToSystemTime RtlDeCommitDebugInfo RtlDeNormalizeProcessParams RtlDeactivateActivationContext RtlDeactivateActivationContextUnsafeFast RtlDebugPrintTimes RtlDecodePointer RtlDecodeRemotePointer RtlDecodeSystemPointer RtlDecompressBuffer RtlDecompressBufferEx RtlDecompressFragment RtlDefaultNpAcl RtlDelete RtlDeleteAce RtlDeleteAtomFromAtomTable RtlDeleteBarrier RtlDeleteBoundaryDescriptor RtlDeleteCriticalSection RtlDeleteElementGenericTable RtlDeleteElementGenericTableAvl RtlDeleteElementGenericTableAvlEx RtlDeleteFunctionTable RtlDeleteGrowableFunctionTable RtlDeleteHashTable RtlDeleteNoSplay RtlDeleteRegistryValue RtlDeleteResource RtlDeleteSecurityObject RtlDeleteTimer RtlDeleteTimerQueue RtlDeleteTimerQueueEx RtlDeleteUmsCompletionList RtlDeleteUmsThreadContext RtlDequeueUmsCompletionListItems RtlDeregisterSecureMemoryCacheCallback RtlDeregisterWait RtlDeregisterWaitEx RtlDeriveCapabilitySidsFromName RtlDestroyAtomTable RtlDestroyEnvironment RtlDestroyHandleTable RtlDestroyHeap RtlDestroyMemoryBlockLookaside RtlDestroyMemoryZone RtlDestroyProcessParameters RtlDestroyQueryDebugBuffer RtlDetectHeapLeaks RtlDetermineDosPathNameType_U RtlDisableThreadProfiling RtlDllShutdownInProgress RtlDnsHostNameToComputerName RtlDoesFileExists_U RtlDosApplyFileIsolationRedirection_Ustr RtlDosLongPathNameToNtPathName_U_WithStatus RtlDosLongPathNameToRelativeNtPathName_U_WithStatus RtlDosPathNameToNtPathName_U RtlDosPathNameToNtPathName_U_WithStatus RtlDosPathNameToRelativeNtPathName_U RtlDosPathNameToRelativeNtPathName_U_WithStatus RtlDosSearchPath_U RtlDosSearchPath_Ustr RtlDowncaseUnicodeChar " \ +"RtlDowncaseUnicodeString RtlDrainNonVolatileFlush RtlDumpResource RtlDuplicateUnicodeString RtlEmptyAtomTable RtlEnableEarlyCriticalSectionEventCreation RtlEnableThreadProfiling RtlEnclaveCallDispatch RtlEnclaveCallDispatchReturn RtlEncodePointer RtlEncodeRemotePointer RtlEncodeSystemPointer RtlEndEnumerationHashTable RtlEndStrongEnumerationHashTable RtlEndWeakEnumerationHashTable RtlEnterCriticalSection RtlEnterUmsSchedulingMode RtlEnumProcessHeaps RtlEnumerateEntryHashTable RtlEnumerateGenericTable RtlEnumerateGenericTableAvl RtlEnumerateGenericTableLikeADirectory RtlEnumerateGenericTableWithoutSplaying RtlEnumerateGenericTableWithoutSplayingAvl RtlEqualComputerName RtlEqualDomainName RtlEqualLuid RtlEqualPrefixSid RtlEqualSid RtlEqualString RtlEqualUnicodeString RtlEqualWnfChangeStamps RtlEraseUnicodeString RtlEthernetAddressToStringA RtlEthernetAddressToStringW RtlEthernetStringToAddressA RtlEthernetStringToAddressW RtlExecuteUmsThread RtlExitUserProcess RtlExitUserThread RtlExpandEnvironmentStrings RtlExpandEnvironmentStrings_U RtlExpandHashTable RtlExtendCorrelationVector RtlExtendMemoryBlockLookaside RtlExtendMemoryZone RtlExtractBitMap RtlFillMemory RtlFinalReleaseOutOfProcessMemoryStream RtlFindAceByType RtlFindActivationContextSectionGuid RtlFindActivationContextSectionString RtlFindCharInUnicodeString RtlFindClearBits RtlFindClearBitsAndSet RtlFindClearRuns RtlFindClosestEncodableLength RtlFindExportedRoutineByName RtlFindLastBackwardRunClear RtlFindLeastSignificantBit RtlFindLongestRunClear RtlFindMessage RtlFindMostSignificantBit RtlFindNextForwardRunClear RtlFindSetBits RtlFindSetBitsAndClear RtlFindUnicodeSubstring RtlFirstEntrySList RtlFirstFreeAce RtlFlsAlloc RtlFlsFree RtlFlushHeaps RtlFlushNonVolatileMemory RtlFlushNonVolatileMemoryRanges RtlFlushSecureMemoryCache RtlFormatCurrentUserKeyPath RtlFormatMessage RtlFormatMessageEx RtlFreeActivationContextStack RtlFreeAnsiString RtlFreeHandle RtlFreeHeap RtlFreeMemoryBlockLookaside RtlFreeNonVolatileToken " \ +"RtlFreeOemString RtlFreeSid RtlFreeThreadActivationContextStack RtlFreeUnicodeString RtlFreeUserStack RtlGUIDFromString RtlGenerate8dot3Name RtlGetAce RtlGetActiveActivationContext RtlGetActiveConsoleId RtlGetAppContainerNamedObjectPath RtlGetAppContainerParent RtlGetAppContainerSidType RtlGetCallersAddress RtlGetCompressionWorkSpaceSize RtlGetConsoleSessionForegroundProcessId RtlGetControlSecurityDescriptor RtlGetCriticalSectionRecursionCount RtlGetCurrentDirectory_U RtlGetCurrentPeb RtlGetCurrentProcessorNumber RtlGetCurrentProcessorNumberEx RtlGetCurrentServiceSessionId RtlGetCurrentTransaction RtlGetCurrentUmsThread RtlGetDaclSecurityDescriptor RtlGetDeviceFamilyInfoEnum RtlGetElementGenericTable RtlGetElementGenericTableAvl RtlGetEnabledExtendedFeatures RtlGetExePath RtlGetExtendedContextLength RtlGetExtendedFeaturesMask RtlGetFileMUIPath RtlGetFrame RtlGetFullPathName_U RtlGetFullPathName_UEx RtlGetFullPathName_UstrEx RtlGetFunctionTableListHead RtlGetGroupSecurityDescriptor RtlGetIntegerAtom RtlGetInterruptTimePrecise RtlGetLastNtStatus RtlGetLastWin32Error RtlGetLengthWithoutLastFullDosOrNtPathElement RtlGetLengthWithoutTrailingPathSeperators RtlGetLocaleFileMappingAddress RtlGetLongestNtPathLength RtlGetNativeSystemInformation RtlGetNextEntryHashTable RtlGetNextUmsListItem RtlGetNonVolatileToken RtlGetNtGlobalFlags RtlGetNtProductType RtlGetNtSystemRoot RtlGetNtVersionNumbers RtlGetOwnerSecurityDescriptor RtlGetParentLocaleName RtlGetPersistedStateLocation RtlGetProcessHeaps RtlGetProcessPreferredUILanguages RtlGetProductInfo RtlGetSaclSecurityDescriptor RtlGetSearchPath RtlGetSecurityDescriptorRMControl RtlGetSessionProperties RtlGetSetBootStatusData RtlGetSuiteMask RtlGetSystemBootStatus RtlGetSystemBootStatusEx RtlGetSystemPreferredUILanguages RtlGetSystemTimePrecise RtlGetThreadErrorMode RtlGetThreadLangIdByIndex RtlGetThreadPreferredUILanguages RtlGetThreadWorkOnBehalfTicket RtlGetTokenNamedObjectPath RtlGetUILanguageInfo RtlGetUmsCompletionListEvent RtlGetUnloadEventTrace " \ +"RtlGetUnloadEventTraceEx RtlGetUserInfoHeap RtlGetUserPreferredUILanguages RtlGetVersion RtlGrowFunctionTable RtlGuardCheckLongJumpTarget RtlHashUnicodeString RtlHeapTrkInitialize RtlIdentifierAuthoritySid RtlIdnToAscii RtlIdnToNameprepUnicode RtlIdnToUnicode RtlImageDirectoryEntryToData RtlImageNtHeader RtlImageNtHeaderEx RtlImageRvaToSection RtlImageRvaToVa RtlImpersonateSelf RtlImpersonateSelfEx RtlIncrementCorrelationVector RtlInitAnsiString RtlInitAnsiStringEx RtlInitBarrier RtlInitCodePageTable RtlInitEnumerationHashTable RtlInitMemoryStream RtlInitNlsTables RtlInitOutOfProcessMemoryStream RtlInitString RtlInitStringEx RtlInitStrongEnumerationHashTable RtlInitUnicodeString RtlInitUnicodeStringEx RtlInitWeakEnumerationHashTable RtlInitializeAtomPackage RtlInitializeBitMap RtlInitializeBitMapEx RtlInitializeConditionVariable RtlInitializeContext RtlInitializeCorrelationVector RtlInitializeCriticalSection RtlInitializeCriticalSectionAndSpinCount RtlInitializeCriticalSectionEx RtlInitializeExtendedContext RtlInitializeGenericTable RtlInitializeGenericTableAvl RtlInitializeHandleTable RtlInitializeNtUserPfn RtlInitializeRXact RtlInitializeResource RtlInitializeSListHead RtlInitializeSRWLock RtlInitializeSid RtlInitializeSidEx RtlInsertElementGenericTable RtlInsertElementGenericTableAvl RtlInsertElementGenericTableFull RtlInsertElementGenericTableFullAvl RtlInsertEntryHashTable RtlInstallFunctionTableCallback RtlInt64ToUnicodeString RtlIntegerToChar RtlIntegerToUnicodeString RtlInterlockedClearBitRun RtlInterlockedFlushSList RtlInterlockedPopEntrySList RtlInterlockedPushEntrySList RtlInterlockedPushListSList RtlInterlockedPushListSListEx RtlInterlockedSetBitRun RtlIoDecodeMemIoResource RtlIoEncodeMemIoResource RtlIpv4AddressToStringA RtlIpv4AddressToStringExA RtlIpv4AddressToStringExW RtlIpv4AddressToStringW RtlIpv4StringToAddressA RtlIpv4StringToAddressExA RtlIpv4StringToAddressExW RtlIpv4StringToAddressW RtlIpv6AddressToStringA RtlIpv6AddressToStringExA RtlIpv6AddressToStringExW " \ +"RtlIpv6AddressToStringW RtlIpv6StringToAddressA RtlIpv6StringToAddressExA RtlIpv6StringToAddressExW RtlIpv6StringToAddressW RtlIsActivationContextActive RtlIsCapabilitySid RtlIsCloudFilesPlaceholder RtlIsCriticalSectionLocked RtlIsCriticalSectionLockedByThread RtlIsCurrentProcess RtlIsCurrentThread RtlIsCurrentThreadAttachExempt RtlIsDosDeviceName_U RtlIsElevatedRid RtlIsGenericTableEmpty RtlIsGenericTableEmptyAvl RtlIsMultiSessionSku RtlIsMultiUsersInSessionSku RtlIsNameInExpression RtlIsNameInUnUpcasedExpression RtlIsNameLegalDOS8Dot3 RtlIsNonEmptyDirectoryReparsePointAllowed RtlIsNormalizedString RtlIsPackageSid RtlIsParentOfChildAppContainer RtlIsPartialPlaceholder RtlIsPartialPlaceholderFileHandle RtlIsPartialPlaceholderFileInfo RtlIsProcessorFeaturePresent RtlIsStateSeparationEnabled RtlIsTextUnicode RtlIsThreadWithinLoaderCallout RtlIsUntrustedObject RtlIsValidHandle RtlIsValidIndexHandle RtlIsValidLocaleName RtlIsValidProcessTrustLabelSid RtlKnownExceptionFilter RtlLCIDToCultureName RtlLargeIntegerToChar RtlLcidToLocaleName RtlLeaveCriticalSection RtlLengthRequiredSid RtlLengthSecurityDescriptor RtlLengthSid RtlLengthSidAsUnicodeString RtlLoadString RtlLocalTimeToSystemTime RtlLocaleNameToLcid RtlLocateExtendedFeature RtlLocateExtendedFeature2 RtlLocateLegacyContext RtlLockBootStatusData RtlLockCurrentThread RtlLockHeap RtlLockMemoryBlockLookaside RtlLockMemoryStreamRegion RtlLockMemoryZone RtlLockModuleSection RtlLogStackBackTrace RtlLookupAtomInAtomTable RtlLookupElementGenericTable RtlLookupElementGenericTableAvl RtlLookupElementGenericTableFull RtlLookupElementGenericTableFullAvl RtlLookupEntryHashTable RtlLookupFirstMatchingElementGenericTableAvl RtlLookupFunctionEntry RtlLookupFunctionTable RtlMakeSelfRelativeSD RtlMapGenericMask RtlMapSecurityErrorToNtStatus RtlMoveMemory RtlMultiAppendUnicodeStringBuffer RtlMultiByteToUnicodeN RtlMultiByteToUnicodeSize RtlMultipleAllocateHeap RtlMultipleFreeHeap RtlNewInstanceSecurityObject RtlNewSecurityGrantedAccess " \ +"RtlNewSecurityObject RtlNewSecurityObjectEx RtlNewSecurityObjectWithMultipleInheritance RtlNormalizeProcessParams RtlNormalizeString RtlNtPathNameToDosPathName RtlNtStatusToDosError RtlNtStatusToDosErrorNoTeb RtlNtdllName RtlNumberGenericTableElements RtlNumberGenericTableElementsAvl RtlNumberOfClearBits RtlNumberOfClearBitsInRange RtlNumberOfSetBits RtlNumberOfSetBitsInRange RtlNumberOfSetBitsUlongPtr RtlOemStringToUnicodeSize RtlOemStringToUnicodeString RtlOemToUnicodeN RtlOpenCurrentUser RtlOsDeploymentState RtlOwnerAcesPresent RtlPcToFileHeader RtlPinAtomInAtomTable RtlPopFrame RtlPrefixString RtlPrefixUnicodeString RtlPrepareForProcessCloning RtlProcessFlsData RtlProtectHeap RtlPublishWnfStateData RtlPushFrame RtlQueryActivationContextApplicationSettings RtlQueryAtomInAtomTable RtlQueryCriticalSectionOwner RtlQueryDepthSList RtlQueryDynamicTimeZoneInformation RtlQueryElevationFlags RtlQueryEnvironmentVariable RtlQueryEnvironmentVariable_U RtlQueryHeapInformation RtlQueryImageMitigationPolicy RtlQueryInformationAcl RtlQueryInformationActivationContext RtlQueryInformationActiveActivationContext RtlQueryInterfaceMemoryStream RtlQueryModuleInformation RtlQueryPackageClaims RtlQueryPackageIdentity RtlQueryPackageIdentityEx RtlQueryPerformanceCounter RtlQueryPerformanceFrequency RtlQueryProcessBackTraceInformation RtlQueryProcessDebugInformation RtlQueryProcessHeapInformation RtlQueryProcessLockInformation RtlQueryProcessPlaceholderCompatibilityMode RtlQueryProtectedPolicy RtlQueryRegistryValueWithFallback RtlQueryRegistryValues RtlQueryRegistryValuesEx RtlQueryResourcePolicy RtlQuerySecurityObject RtlQueryTagHeap RtlQueryThreadPlaceholderCompatibilityMode RtlQueryThreadProfiling RtlQueryTimeZoneInformation RtlQueryTokenHostIdAsUlong64 RtlQueryUmsThreadInformation RtlQueryUnbiasedInterruptTime RtlQueryValidationRunlevel RtlQueryWnfMetaNotification RtlQueryWnfStateData RtlQueryWnfStateDataWithExplicitScope RtlQueueApcWow64Thread RtlQueueWorkItem RtlRaiseCustomSystemEventTrigger " \ +"RtlRaiseException RtlRaiseStatus RtlRandom RtlRandomEx RtlRbInsertNodeEx RtlRbRemoveNode RtlReAllocateHeap RtlReadMemoryStream RtlReadOutOfProcessMemoryStream RtlReadThreadProfilingData RtlRealPredecessor RtlRealSuccessor RtlRegisterForWnfMetaNotification RtlRegisterSecureMemoryCacheCallback RtlRegisterThreadWithCsrss RtlRegisterWait RtlReleaseActivationContext RtlReleaseMemoryStream RtlReleasePath RtlReleasePebLock RtlReleasePrivilege RtlReleaseRelativeName RtlReleaseResource RtlReleaseSRWLockExclusive RtlReleaseSRWLockShared RtlRemoteCall RtlRemoveEntryHashTable RtlRemovePrivileges RtlRemoveVectoredContinueHandler RtlRemoveVectoredExceptionHandler RtlReplaceSidInSd RtlReplaceSystemDirectoryInPath RtlReportException RtlReportExceptionEx RtlReportSilentProcessExit RtlReportSqmEscalation RtlResetMemoryBlockLookaside RtlResetMemoryZone RtlResetNtUserPfn RtlResetRtlTranslations RtlRestoreBootStatusDefaults RtlRestoreContext RtlRestoreLastWin32Error RtlRestoreSystemBootStatusDefaults RtlRetrieveNtUserPfn RtlRevertMemoryStream RtlRunDecodeUnicodeString RtlRunEncodeUnicodeString RtlRunOnceBeginInitialize RtlRunOnceComplete RtlRunOnceExecuteOnce RtlRunOnceInitialize RtlSecondsSince1970ToTime RtlSecondsSince1980ToTime RtlSeekMemoryStream RtlSelfRelativeToAbsoluteSD RtlSelfRelativeToAbsoluteSD2 RtlSendMsgToSm RtlSetAllBits RtlSetAttributesSecurityDescriptor RtlSetBit RtlSetBits RtlSetControlSecurityDescriptor RtlSetCriticalSectionSpinCount RtlSetCurrentDirectory_U RtlSetCurrentEnvironment RtlSetCurrentTransaction RtlSetDaclSecurityDescriptor RtlSetDynamicTimeZoneInformation RtlSetEnvironmentStrings RtlSetEnvironmentVar RtlSetEnvironmentVariable RtlSetExtendedFeaturesMask RtlSetGroupSecurityDescriptor RtlSetHeapInformation RtlSetImageMitigationPolicy RtlSetInformationAcl RtlSetIoCompletionCallback RtlSetLastWin32Error RtlSetLastWin32ErrorAndNtStatusFromNtStatus RtlSetMemoryStreamSize RtlSetOwnerSecurityDescriptor RtlSetPortableOperatingSystem RtlSetProcessDebugInformation RtlSetProcessIsCritical " \ +"RtlSetProcessPlaceholderCompatibilityMode RtlSetProcessPreferredUILanguages RtlSetProtectedPolicy RtlSetProxiedProcessId RtlSetSaclSecurityDescriptor RtlSetSearchPathMode RtlSetSecurityDescriptorRMControl RtlSetSecurityObject RtlSetSecurityObjectEx RtlSetSystemBootStatus RtlSetSystemBootStatusEx RtlSetThreadErrorMode RtlSetThreadIsCritical RtlSetThreadPlaceholderCompatibilityMode RtlSetThreadPoolStartFunc RtlSetThreadPreferredUILanguages RtlSetThreadSubProcessTag RtlSetThreadWorkOnBehalfTicket RtlSetTimeZoneInformation RtlSetTimer RtlSetUmsThreadInformation RtlSetUnhandledExceptionFilter RtlSetUserFlagsHeap RtlSetUserValueHeap RtlSidDominates RtlSidDominatesForTrust RtlSidEqualLevel RtlSidHashInitialize RtlSidHashLookup RtlSidIsHigherLevel RtlSizeHeap RtlSleepConditionVariableCS RtlSleepConditionVariableSRW RtlSplay RtlStartRXact RtlStatMemoryStream RtlStringFromGUID RtlStringFromGUIDEx RtlStronglyEnumerateEntryHashTable RtlSubAuthorityCountSid RtlSubAuthoritySid RtlSubscribeWnfStateChangeNotification RtlSubtreePredecessor RtlSubtreeSuccessor RtlSwitchedVVI RtlSystemTimeToLocalTime RtlTestAndPublishWnfStateData RtlTestBit RtlTestBitEx RtlTestProtectedAccess RtlTimeFieldsToTime RtlTimeToElapsedTimeFields RtlTimeToSecondsSince1970 RtlTimeToSecondsSince1980 RtlTimeToTimeFields RtlTraceDatabaseAdd RtlTraceDatabaseCreate RtlTraceDatabaseDestroy RtlTraceDatabaseEnumerate RtlTraceDatabaseFind RtlTraceDatabaseLock RtlTraceDatabaseUnlock RtlTraceDatabaseValidate RtlTryAcquirePebLock RtlTryAcquireSRWLockExclusive RtlTryAcquireSRWLockShared RtlTryConvertSRWLockSharedToExclusiveOrRelease RtlTryEnterCriticalSection RtlUTF8ToUnicodeN RtlUmsThreadYield RtlUnhandledExceptionFilter RtlUnhandledExceptionFilter2 RtlUnicodeStringToAnsiSize RtlUnicodeStringToAnsiString RtlUnicodeStringToCountedOemString RtlUnicodeStringToInteger RtlUnicodeStringToOemSize RtlUnicodeStringToOemString RtlUnicodeToCustomCPN RtlUnicodeToMultiByteN RtlUnicodeToMultiByteSize RtlUnicodeToOemN RtlUnicodeToUTF8N RtlUniform " \ +"RtlUnlockBootStatusData RtlUnlockCurrentThread RtlUnlockHeap RtlUnlockMemoryBlockLookaside RtlUnlockMemoryStreamRegion RtlUnlockMemoryZone RtlUnlockModuleSection RtlUnsubscribeWnfNotificationWaitForCompletion RtlUnsubscribeWnfNotificationWithCompletionCallback RtlUnsubscribeWnfStateChangeNotification RtlUnwind RtlUnwindEx RtlUpcaseUnicodeChar RtlUpcaseUnicodeString RtlUpcaseUnicodeStringToAnsiString RtlUpcaseUnicodeStringToCountedOemString RtlUpcaseUnicodeStringToOemString RtlUpcaseUnicodeToCustomCPN RtlUpcaseUnicodeToMultiByteN RtlUpcaseUnicodeToOemN RtlUpdateClonedCriticalSection RtlUpdateClonedSRWLock RtlUpdateTimer RtlUpperChar RtlUpperString RtlUserThreadStart RtlValidAcl RtlValidProcessProtection RtlValidRelativeSecurityDescriptor RtlValidSecurityDescriptor RtlValidSid RtlValidateCorrelationVector RtlValidateHeap RtlValidateProcessHeaps RtlValidateUnicodeString RtlVerifyVersionInfo RtlVirtualUnwind RtlWaitForWnfMetaNotification RtlWaitOnAddress RtlWakeAddressAll RtlWakeAddressAllNoFence RtlWakeAddressSingle RtlWakeAddressSingleNoFence RtlWakeAllConditionVariable RtlWakeConditionVariable RtlWalkFrameChain RtlWalkHeap RtlWeaklyEnumerateEntryHashTable RtlWerpReportException RtlWnfCompareChangeStamp RtlWnfDllUnloadCallback RtlWow64CallFunction64 RtlWow64EnableFsRedirection RtlWow64EnableFsRedirectionEx RtlWow64GetCpuAreaInfo RtlWow64GetCurrentCpuArea RtlWow64GetCurrentMachine RtlWow64GetEquivalentMachineCHPE RtlWow64GetProcessMachines RtlWow64GetSharedInfoProcess RtlWow64GetThreadContext RtlWow64GetThreadSelectorEntry RtlWow64IsWowGuestMachineSupported RtlWow64LogMessageInEventLogger RtlWow64PopAllCrossProcessWork RtlWow64PopCrossProcessWork RtlWow64PushCrossProcessWork RtlWow64SetThreadContext RtlWow64SuspendThread RtlWriteMemoryStream RtlWriteNonVolatileMemory RtlWriteRegistryValue RtlZeroHeap RtlZeroMemory RtlZombifyActivationContext RtlpApplyLengthFunction RtlpCheckDynamicTimeZoneInformation RtlpCleanupRegistryKeys RtlpConvertAbsoluteToRelativeSecurityAttribute " \ +"RtlpConvertCultureNamesToLCIDs RtlpConvertLCIDsToCultureNames RtlpConvertRelativeToAbsoluteSecurityAttribute RtlpCreateProcessRegistryInfo RtlpEnsureBufferSize RtlpExecuteUmsThread RtlpFreezeTimeBias RtlpGetDeviceFamilyInfoEnum RtlpGetLCIDFromLangInfoNode RtlpGetNameFromLangInfoNode RtlpGetSystemDefaultUILanguage RtlpGetUserOrMachineUILanguage4NLS RtlpInitializeLangRegistryInfo RtlpIsQualifiedLanguage RtlpLoadMachineUIByPolicy RtlpLoadUserUIByPolicy RtlpMergeSecurityAttributeInformation RtlpMuiFreeLangRegistryInfo RtlpMuiRegCreateRegistryInfo RtlpMuiRegFreeRegistryInfo RtlpMuiRegLoadRegistryInfo RtlpNotOwnerCriticalSection RtlpNtCreateKey RtlpNtEnumerateSubKey RtlpNtMakeTemporaryKey RtlpNtOpenKey RtlpNtQueryValueKey RtlpNtSetValueKey RtlpQueryDefaultUILanguage RtlpQueryProcessDebugInformationFromWow64 RtlpQueryProcessDebugInformationRemote RtlpRefreshCachedUILanguage RtlpSetInstallLanguage RtlpSetPreferredUILanguages RtlpSetUserPreferredUILanguages RtlpUmsExecuteYieldThreadEnd RtlpUmsThreadYield RtlpUnWaitCriticalSection RtlpVerifyAndCommitUILanguageSettings RtlpWaitForCriticalSection RtlxAnsiStringToUnicodeSize RtlxOemStringToUnicodeSize RtlxUnicodeStringToAnsiSize RtlxUnicodeStringToOemSize SbExecuteProcedure SbSelectProcedure ShipAssert ShipAssertGetBufferInfo ShipAssertMsgA ShipAssertMsgW TpAllocAlpcCompletion TpAllocAlpcCompletionEx TpAllocCleanupGroup TpAllocIoCompletion TpAllocJobNotification TpAllocPool TpAllocTimer TpAllocWait TpAllocWork TpAlpcRegisterCompletionList TpAlpcUnregisterCompletionList TpCallbackDetectedUnrecoverableError TpCallbackIndependent TpCallbackLeaveCriticalSectionOnCompletion TpCallbackMayRunLong TpCallbackReleaseMutexOnCompletion TpCallbackReleaseSemaphoreOnCompletion TpCallbackSendAlpcMessageOnCompletion TpCallbackSendPendingAlpcMessage TpCallbackSetEventOnCompletion TpCallbackUnloadDllOnCompletion TpCancelAsyncIoOperation TpCaptureCaller TpCheckTerminateWorker TpDbgDumpHeapUsage TpDbgSetLogRoutine TpDisablePoolCallbackChecks TpDisassociateCallback " \ +"TpIsTimerSet TpPostWork TpQueryPoolStackInformation TpReleaseAlpcCompletion TpReleaseCleanupGroup TpReleaseCleanupGroupMembers TpReleaseIoCompletion TpReleaseJobNotification TpReleasePool TpReleaseTimer TpReleaseWait TpReleaseWork TpSetDefaultPoolMaxThreads TpSetDefaultPoolStackInformation TpSetPoolMaxThreads TpSetPoolMaxThreadsSoftLimit TpSetPoolMinThreads TpSetPoolStackInformation TpSetPoolThreadBasePriority TpSetPoolWorkerThreadIdleTimeout TpSetTimer TpSetTimerEx TpSetWait TpSetWaitEx TpSimpleTryPost TpStartAsyncIoOperation TpTimerOutstandingCallbackCount TpTrimPools TpWaitForAlpcCompletion TpWaitForIoCompletion TpWaitForJobNotification TpWaitForTimer TpWaitForWait TpWaitForWork VerSetConditionMask WerReportExceptionWorker WerReportSQMEvent WinSqmAddToAverageDWORD WinSqmAddToStream WinSqmAddToStreamEx WinSqmCheckEscalationAddToStreamEx WinSqmCheckEscalationSetDWORD WinSqmCheckEscalationSetDWORD64 WinSqmCheckEscalationSetString WinSqmCommonDatapointDelete WinSqmCommonDatapointSetDWORD WinSqmCommonDatapointSetDWORD64 WinSqmCommonDatapointSetStreamEx WinSqmCommonDatapointSetString WinSqmEndSession WinSqmEventEnabled WinSqmEventWrite WinSqmGetEscalationRuleStatus WinSqmGetInstrumentationProperty WinSqmIncrementDWORD WinSqmIsOptedIn WinSqmIsOptedInEx WinSqmIsSessionDisabled WinSqmSetDWORD WinSqmSetDWORD64 WinSqmSetEscalationInfo WinSqmSetIfMaxDWORD WinSqmSetIfMinDWORD WinSqmSetString WinSqmStartSession WinSqmStartSessionForPartner WinSqmStartSqmOptinListener ZwAcceptConnectPort ZwAccessCheck ZwAccessCheckAndAuditAlarm ZwAccessCheckByType ZwAccessCheckByTypeAndAuditAlarm ZwAccessCheckByTypeResultList ZwAccessCheckByTypeResultListAndAuditAlarm ZwAccessCheckByTypeResultListAndAuditAlarmByHandle ZwAcquireProcessActivityReference ZwAddAtom ZwAddAtomEx ZwAddBootEntry ZwAddDriverEntry ZwAdjustGroupsToken ZwAdjustPrivilegesToken ZwAdjustTokenClaimsAndDeviceGroups ZwAlertResumeThread ZwAlertThread ZwAlertThreadByThreadId ZwAllocateLocallyUniqueId ZwAllocateReserveObject ZwAllocateUserPhysicalPages " \ +"ZwAllocateUuids ZwAllocateVirtualMemory ZwAllocateVirtualMemoryEx ZwAlpcAcceptConnectPort ZwAlpcCancelMessage ZwAlpcConnectPort ZwAlpcConnectPortEx ZwAlpcCreatePort ZwAlpcCreatePortSection ZwAlpcCreateResourceReserve ZwAlpcCreateSectionView ZwAlpcCreateSecurityContext ZwAlpcDeletePortSection ZwAlpcDeleteResourceReserve ZwAlpcDeleteSectionView ZwAlpcDeleteSecurityContext ZwAlpcDisconnectPort ZwAlpcImpersonateClientContainerOfPort ZwAlpcImpersonateClientOfPort ZwAlpcOpenSenderProcess ZwAlpcOpenSenderThread ZwAlpcQueryInformation ZwAlpcQueryInformationMessage ZwAlpcRevokeSecurityContext ZwAlpcSendWaitReceivePort ZwAlpcSetInformation ZwApphelpCacheControl ZwAreMappedFilesTheSame ZwAssignProcessToJobObject ZwAssociateWaitCompletionPacket ZwCallEnclave ZwCallbackReturn ZwCancelIoFile ZwCancelIoFileEx ZwCancelSynchronousIoFile ZwCancelTimer ZwCancelTimer2 ZwCancelWaitCompletionPacket ZwClearEvent ZwClose ZwCloseObjectAuditAlarm ZwCommitComplete ZwCommitEnlistment ZwCommitRegistryTransaction ZwCommitTransaction ZwCompactKeys ZwCompareObjects ZwCompareSigningLevels ZwCompareTokens ZwCompleteConnectPort ZwCompressKey ZwConnectPort ZwContinue ZwConvertBetweenAuxiliaryCounterAndPerformanceCounter ZwCreateDebugObject ZwCreateDirectoryObject ZwCreateDirectoryObjectEx ZwCreateEnclave ZwCreateEnlistment ZwCreateEvent ZwCreateEventPair ZwCreateFile ZwCreateIRTimer ZwCreateIoCompletion ZwCreateJobObject ZwCreateJobSet ZwCreateKey ZwCreateKeyTransacted ZwCreateKeyedEvent ZwCreateLowBoxToken ZwCreateMailslotFile ZwCreateMutant ZwCreateNamedPipeFile ZwCreatePagingFile ZwCreatePartition ZwCreatePort ZwCreatePrivateNamespace ZwCreateProcess ZwCreateProcessEx ZwCreateProfile ZwCreateProfileEx ZwCreateRegistryTransaction ZwCreateResourceManager ZwCreateSection ZwCreateSemaphore ZwCreateSymbolicLinkObject ZwCreateThread ZwCreateThreadEx ZwCreateTimer ZwCreateTimer2 ZwCreateToken ZwCreateTokenEx ZwCreateTransaction ZwCreateTransactionManager ZwCreateUserProcess ZwCreateWaitCompletionPacket ZwCreateWaitablePort " \ +"ZwCreateWnfStateName ZwCreateWorkerFactory ZwDebugActiveProcess ZwDebugContinue ZwDelayExecution ZwDeleteAtom ZwDeleteBootEntry ZwDeleteDriverEntry ZwDeleteFile ZwDeleteKey ZwDeleteObjectAuditAlarm ZwDeletePrivateNamespace ZwDeleteValueKey ZwDeleteWnfStateData ZwDeleteWnfStateName ZwDeviceIoControlFile ZwDisableLastKnownGood ZwDisplayString ZwDrawText ZwDuplicateObject ZwDuplicateToken ZwEnableLastKnownGood ZwEnumerateBootEntries ZwEnumerateDriverEntries ZwEnumerateKey ZwEnumerateSystemEnvironmentValuesEx ZwEnumerateTransactionObject ZwEnumerateValueKey ZwExtendSection ZwFilterBootOption ZwFilterToken ZwFilterTokenEx ZwFindAtom ZwFlushBuffersFile ZwFlushBuffersFileEx ZwFlushInstallUILanguage ZwFlushInstructionCache ZwFlushKey ZwFlushProcessWriteBuffers ZwFlushVirtualMemory ZwFlushWriteBuffer ZwFreeUserPhysicalPages ZwFreeVirtualMemory ZwFreezeRegistry ZwFreezeTransactions ZwFsControlFile ZwGetCachedSigningLevel ZwGetCompleteWnfStateSubscription ZwGetContextThread ZwGetCurrentProcessorNumber ZwGetCurrentProcessorNumberEx ZwGetDevicePowerState ZwGetMUIRegistryInfo ZwGetNextProcess ZwGetNextThread ZwGetNlsSectionPtr ZwGetNotificationResourceManager ZwGetWriteWatch ZwImpersonateAnonymousToken ZwImpersonateClientOfPort ZwImpersonateThread ZwInitializeEnclave ZwInitializeNlsFiles ZwInitializeRegistry ZwInitiatePowerAction ZwIsProcessInJob ZwIsSystemResumeAutomatic ZwIsUILanguageComitted ZwListenPort ZwLoadDriver ZwLoadEnclaveData ZwLoadHotPatch ZwLoadKey ZwLoadKey2 ZwLoadKeyEx ZwLockFile ZwLockProductActivationKeys ZwLockRegistryKey ZwLockVirtualMemory ZwMakePermanentObject ZwMakeTemporaryObject ZwManagePartition ZwMapCMFModule ZwMapUserPhysicalPages ZwMapUserPhysicalPagesScatter ZwMapViewOfSection ZwMapViewOfSectionEx ZwModifyBootEntry ZwModifyDriverEntry ZwNotifyChangeDirectoryFile ZwNotifyChangeDirectoryFileEx ZwNotifyChangeKey ZwNotifyChangeMultipleKeys ZwNotifyChangeSession ZwOpenDirectoryObject ZwOpenEnlistment ZwOpenEvent ZwOpenEventPair ZwOpenFile ZwOpenIoCompletion " \ +"ZwOpenJobObject ZwOpenKey ZwOpenKeyEx ZwOpenKeyTransacted ZwOpenKeyTransactedEx ZwOpenKeyedEvent ZwOpenMutant ZwOpenObjectAuditAlarm ZwOpenPartition ZwOpenPrivateNamespace ZwOpenProcess ZwOpenProcessToken ZwOpenProcessTokenEx ZwOpenRegistryTransaction ZwOpenResourceManager ZwOpenSection ZwOpenSemaphore ZwOpenSession ZwOpenSymbolicLinkObject ZwOpenThread ZwOpenThreadToken ZwOpenThreadTokenEx ZwOpenTimer ZwOpenTransaction ZwOpenTransactionManager ZwPlugPlayControl ZwPowerInformation ZwPrePrepareComplete ZwPrePrepareEnlistment ZwPrepareComplete ZwPrepareEnlistment ZwPrivilegeCheck ZwPrivilegeObjectAuditAlarm ZwPrivilegedServiceAuditAlarm ZwPropagationComplete ZwPropagationFailed ZwProtectVirtualMemory ZwPulseEvent ZwQueryAttributesFile ZwQueryAuxiliaryCounterFrequency ZwQueryBootEntryOrder ZwQueryBootOptions ZwQueryDebugFilterState ZwQueryDefaultLocale ZwQueryDefaultUILanguage ZwQueryDirectoryFile ZwQueryDirectoryFileEx ZwQueryDirectoryObject ZwQueryDriverEntryOrder ZwQueryEaFile ZwQueryEvent ZwQueryFullAttributesFile ZwQueryInformationAtom ZwQueryInformationByName ZwQueryInformationEnlistment ZwQueryInformationFile ZwQueryInformationJobObject ZwQueryInformationPort ZwQueryInformationProcess ZwQueryInformationResourceManager ZwQueryInformationThread ZwQueryInformationToken ZwQueryInformationTransaction ZwQueryInformationTransactionManager ZwQueryInformationWorkerFactory ZwQueryInstallUILanguage ZwQueryIntervalProfile ZwQueryIoCompletion ZwQueryKey ZwQueryLicenseValue ZwQueryMultipleValueKey ZwQueryMutant ZwQueryObject ZwQueryOpenSubKeys ZwQueryOpenSubKeysEx ZwQueryPerformanceCounter ZwQueryPortInformationProcess ZwQueryQuotaInformationFile ZwQuerySection ZwQuerySecurityAttributesToken ZwQuerySecurityObject ZwQuerySecurityPolicy ZwQuerySemaphore ZwQuerySymbolicLinkObject ZwQuerySystemEnvironmentValue ZwQuerySystemEnvironmentValueEx ZwQuerySystemInformation ZwQuerySystemInformationEx ZwQuerySystemTime ZwQueryTimer ZwQueryTimerResolution ZwQueryValueKey ZwQueryVirtualMemory " \ +"ZwQueryVolumeInformationFile ZwQueryWnfStateData ZwQueryWnfStateNameInformation ZwQueueApcThread ZwQueueApcThreadEx ZwRaiseException ZwRaiseHardError ZwReadFile ZwReadFileScatter ZwReadOnlyEnlistment ZwReadRequestData ZwReadVirtualMemory ZwRecoverEnlistment ZwRecoverResourceManager ZwRecoverTransactionManager ZwRegisterProtocolAddressInformation ZwRegisterThreadTerminatePort ZwReleaseKeyedEvent ZwReleaseMutant ZwReleaseSemaphore ZwReleaseWorkerFactoryWorker ZwRemoveIoCompletion ZwRemoveIoCompletionEx ZwRemoveProcessDebug ZwRenameKey ZwRenameTransactionManager ZwReplaceKey ZwReplacePartitionUnit ZwReplyPort ZwReplyWaitReceivePort ZwReplyWaitReceivePortEx ZwReplyWaitReplyPort ZwRequestPort ZwRequestWaitReplyPort ZwResetEvent ZwResetWriteWatch ZwRestoreKey ZwResumeProcess ZwResumeThread ZwRevertContainerImpersonation ZwRollbackComplete ZwRollbackEnlistment ZwRollbackRegistryTransaction ZwRollbackTransaction ZwRollforwardTransactionManager ZwSaveKey ZwSaveKeyEx ZwSaveMergedKeys ZwSecureConnectPort ZwSerializeBoot ZwSetBootEntryOrder ZwSetBootOptions ZwSetCachedSigningLevel ZwSetCachedSigningLevel2 ZwSetContextThread ZwSetDebugFilterState ZwSetDefaultHardErrorPort ZwSetDefaultLocale ZwSetDefaultUILanguage ZwSetDriverEntryOrder ZwSetEaFile ZwSetEvent ZwSetEventBoostPriority ZwSetHighEventPair ZwSetHighWaitLowEventPair ZwSetIRTimer ZwSetInformationDebugObject ZwSetInformationEnlistment ZwSetInformationFile ZwSetInformationJobObject ZwSetInformationKey ZwSetInformationObject ZwSetInformationProcess ZwSetInformationResourceManager ZwSetInformationSymbolicLink ZwSetInformationThread ZwSetInformationToken ZwSetInformationTransaction ZwSetInformationTransactionManager ZwSetInformationVirtualMemory ZwSetInformationWorkerFactory ZwSetIntervalProfile ZwSetIoCompletion ZwSetIoCompletionEx ZwSetLdtEntries ZwSetLowEventPair ZwSetLowWaitHighEventPair ZwSetQuotaInformationFile ZwSetSecurityObject ZwSetSystemEnvironmentValue ZwSetSystemEnvironmentValueEx ZwSetSystemInformation ZwSetSystemPowerState " \ +"ZwSetSystemTime ZwSetThreadExecutionState ZwSetTimer ZwSetTimer2 ZwSetTimerEx ZwSetTimerResolution ZwSetUuidSeed ZwSetValueKey ZwSetVolumeInformationFile ZwSetWnfProcessNotificationEvent ZwShutdownSystem ZwShutdownWorkerFactory ZwSignalAndWaitForSingleObject ZwSinglePhaseReject ZwStartProfile ZwStopProfile ZwSubscribeWnfStateChange ZwSuspendProcess ZwSuspendThread ZwSystemDebugControl ZwTerminateEnclave ZwTerminateJobObject ZwTerminateProcess ZwTerminateThread ZwTestAlert ZwThawRegistry ZwThawTransactions ZwTraceControl ZwTraceEvent ZwTranslateFilePath ZwUmsThreadYield ZwUnloadDriver ZwUnloadKey ZwUnloadKey2 ZwUnloadKeyEx ZwUnlockFile ZwUnlockVirtualMemory ZwUnmapViewOfSection ZwUnmapViewOfSectionEx ZwUnsubscribeWnfStateChange ZwUpdateWnfStateData ZwVdmControl ZwWaitForAlertByThreadId ZwWaitForDebugEvent ZwWaitForKeyedEvent ZwWaitForMultipleObjects ZwWaitForMultipleObjects32 ZwWaitForSingleObject ZwWaitForWorkViaWorkerFactory ZwWaitHighEventPair ZwWaitLowEventPair ZwWorkerFactoryWorkerReady ZwWriteFile ZwWriteFileGather ZwWriteRequestData ZwWriteVirtualMemory ZwYieldExecution __C_specific_handler __chkstk __isascii __iscsym __iscsymf __misaligned_access __toascii _atoi64 _errno _fltused _i64toa _i64toa_s _i64tow _i64tow_s _itoa _itoa_s _itow _itow_s _lfind _local_unwind _ltoa _ltoa_s _ltow _ltow_s _makepath_s _memccpy _memicmp _setjmp _setjmpex _snprintf _snprintf_s _snscanf_s _snwprintf _snwprintf_s _snwscanf_s _splitpath _splitpath_s _strcmpi _stricmp _strlwr _strlwr_s _strnicmp _strnset_s _strset_s _strupr _strupr_s _swprintf _ui64toa _ui64toa_s _ui64tow _ui64tow_s _ultoa _ultoa_s _ultow _ultow_s _vscprintf _vscwprintf _vsnprintf _vsnprintf_s _vsnwprintf _vsnwprintf_s _vswprintf _wcsicmp _wcslwr _wcslwr_s _wcsnicmp _wcsnset_s _wcsset_s _wcstoi64 _wcstoui64 _wcsupr _wcsupr_s _wmakepath_s _wsplitpath_s _wtoi _wtoi64 _wtol abs atan atan2 atoi atol bsearch bsearch_s ceil cos fabs floor isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper iswalnum " \ +"iswalpha iswascii iswctype iswdigit iswgraph iswlower iswprint iswspace iswxdigit isxdigit labs log longjmp mbstowcs memchr memcmp memcpy memcpy_s memmove memmove_s memset pow qsort qsort_s sin sprintf sprintf_s sqrt sscanf sscanf_s strcat strcat_s strchr strcmp strcpy strcpy_s strcspn strlen strncat strncat_s strncmp strncpy strncpy_s strnlen strpbrk strrchr strspn strstr strtok_s strtol strtoul swprintf swprintf_s swscanf_s tan tolower toupper towlower towupper vDbgPrintEx vDbgPrintExWithPrefix vsprintf vsprintf_s vswprintf_s wcscat wcscat_s wcschr wcscmp wcscpy wcscpy_s wcscspn wcslen wcsncat wcsncat_s wcsncmp wcsncpy wcsncpy_s wcsnlen wcspbrk wcsrchr wcsspn wcsstr wcstok_s wcstol wcstombs wcstoul"; + +char apis_user32[] = "ActivateKeyboardLayout AddClipboardFormatListener AdjustWindowRect AdjustWindowRectEx AdjustWindowRectExForDpi AlignRects AllowForegroundActivation AllowSetForegroundWindow AnimateWindow AnyPopup AppendMenuA AppendMenuW AreDpiAwarenessContextsEqual ArrangeIconicWindows AttachThreadInput BeginDeferWindowPos BeginPaint BlockInput BringWindowToTop BroadcastSystemMessage BroadcastSystemMessageA BroadcastSystemMessageExA BroadcastSystemMessageExW BroadcastSystemMessageW BuildReasonArray CalcMenuBar CalculatePopupWindowPosition CallMsgFilter CallMsgFilterA CallMsgFilterW CallNextHookEx CallWindowProcA CallWindowProcW CancelShutdown CascadeChildWindows CascadeWindows ChangeClipboardChain ChangeDisplaySettingsA ChangeDisplaySettingsExA ChangeDisplaySettingsExW ChangeDisplaySettingsW ChangeMenuA ChangeMenuW ChangeWindowMessageFilter ChangeWindowMessageFilterEx CharLowerA CharLowerBuffA CharLowerBuffW CharLowerW CharNextA CharNextExA CharNextW CharPrevA CharPrevExA CharPrevW CharToOemA CharToOemBuffA CharToOemBuffW CharToOemW CharUpperA CharUpperBuffA CharUpperBuffW CharUpperW CheckDBCSEnabledExt CheckDlgButton CheckMenuItem CheckMenuRadioItem CheckProcessForClipboardAccess CheckProcessSession CheckRadioButton CheckWindowThreadDesktop ChildWindowFromPoint ChildWindowFromPointEx CliImmSetHotKey ClientThreadSetup ClientToScreen ClipCursor CloseClipboard CloseDesktop CloseGestureInfoHandle CloseTouchInputHandle CloseWindow CloseWindowStation ConsoleControl ControlMagnification CopyAcceleratorTableA CopyAcceleratorTableW CopyIcon CopyImage CopyRect CountClipboardFormats CreateAcceleratorTableA CreateAcceleratorTableW CreateCaret CreateCursor CreateDCompositionHwndTarget CreateDesktopA CreateDesktopExA CreateDesktopExW CreateDesktopW CreateDialogIndirectParamA CreateDialogIndirectParamAorW CreateDialogIndirectParamW CreateDialogParamA CreateDialogParamW CreateIcon CreateIconFromResource CreateIconFromResourceEx CreateIconIndirect CreateMDIWindowA CreateMDIWindowW " \ +"CreateMenu CreatePalmRejectionDelayZone CreatePopupMenu CreateSystemThreads CreateWindowExA CreateWindowExW CreateWindowInBand CreateWindowInBandEx CreateWindowIndirect CreateWindowStationA CreateWindowStationW CsrBroadcastSystemMessageExW CtxInitUser32 DWMBindCursorToOutputConfig DWMCommitInputSystemOutputConfig DWMSetCursorOrientation DWMSetInputSystemOutputConfig DdeAbandonTransaction DdeAccessData DdeAddData DdeClientTransaction DdeCmpStringHandles DdeConnect DdeConnectList DdeCreateDataHandle DdeCreateStringHandleA DdeCreateStringHandleW DdeDisconnect DdeDisconnectList DdeEnableCallback DdeFreeDataHandle DdeFreeStringHandle DdeGetData DdeGetLastError DdeGetQualityOfService DdeImpersonateClient DdeInitializeA DdeInitializeW DdeKeepStringHandle DdeNameService DdePostAdvise DdeQueryConvInfo DdeQueryNextServer DdeQueryStringA DdeQueryStringW DdeReconnect DdeSetQualityOfService DdeSetUserHandle DdeUnaccessData DdeUninitialize DefFrameProcA DefFrameProcW DefMDIChildProcA DefMDIChildProcW DefRawInputProc DeferWindowPos DeferWindowPosAndBand DelegateInput DeleteMenu DeregisterShellHookWindow DestroyAcceleratorTable DestroyCaret DestroyCursor DestroyDCompositionHwndTarget DestroyIcon DestroyMenu DestroyPalmRejectionDelayZone DestroyReasons DestroyWindow DialogBoxIndirectParamA DialogBoxIndirectParamAorW DialogBoxIndirectParamW DialogBoxParamA DialogBoxParamW DisableProcessWindowsGhosting DispatchMessageA DispatchMessageW DisplayConfigGetDeviceInfo DisplayConfigSetDeviceInfo DisplayExitWindowsWarnings DlgDirListA DlgDirListComboBoxA DlgDirListComboBoxW DlgDirListW DlgDirSelectComboBoxExA DlgDirSelectComboBoxExW DlgDirSelectExA DlgDirSelectExW DoSoundConnect DoSoundDisconnect DragDetect DragObject DrawAnimatedRects DrawCaption DrawCaptionTempA DrawCaptionTempW DrawEdge DrawFocusRect DrawFrame DrawFrameControl DrawIcon DrawIconEx DrawMenuBar DrawMenuBarTemp DrawStateA DrawStateW DrawTextA DrawTextExA DrawTextExW DrawTextW " \ +"DwmGetDxRgn DwmGetDxSharedSurface DwmGetRemoteSessionOcclusionEvent DwmGetRemoteSessionOcclusionState DwmKernelShutdown DwmKernelStartup DwmLockScreenUpdates DwmValidateWindow EditWndProc EmptyClipboard EnableMenuItem EnableMouseInPointer EnableNonClientDpiScaling EnableOneCoreTransformMode EnableScrollBar EnableSessionForMMCSS EnableWindow EndDeferWindowPos EndDeferWindowPosEx EndDialog EndMenu EndPaint EndTask EnterReaderModeHelper EnumChildWindows EnumClipboardFormats EnumDesktopWindows EnumDesktopsA EnumDesktopsW EnumDisplayDevicesA EnumDisplayDevicesW EnumDisplayMonitors EnumDisplaySettingsA EnumDisplaySettingsExA EnumDisplaySettingsExW EnumDisplaySettingsW EnumPropsA EnumPropsExA EnumPropsExW EnumPropsW EnumThreadWindows EnumWindowStationsA EnumWindowStationsW EnumWindows EqualRect EvaluateProximityToPolygon EvaluateProximityToRect ExcludeUpdateRgn ExitWindowsEx FillRect FindWindowA FindWindowExA FindWindowExW FindWindowW FlashWindow FlashWindowEx FrameRect FreeDDElParam FrostCrashedWindow GetActiveWindow GetAltTabInfo GetAltTabInfoA GetAltTabInfoW GetAncestor GetAppCompatFlags GetAppCompatFlags2 GetAsyncKeyState GetAutoRotationState GetAwarenessFromDpiAwarenessContext GetCIMSSM GetCapture GetCaretBlinkTime GetCaretPos GetClassInfoA GetClassInfoExA GetClassInfoExW GetClassInfoW GetClassLongA GetClassLongPtrA GetClassLongPtrW GetClassLongW GetClassNameA GetClassNameW GetClassWord GetClientRect GetClipCursor GetClipboardAccessToken GetClipboardData GetClipboardFormatNameA GetClipboardFormatNameW GetClipboardOwner GetClipboardSequenceNumber GetClipboardViewer GetComboBoxInfo GetCurrentInputMessageSource GetCursor GetCursorFrameInfo GetCursorInfo GetCursorPos GetDC GetDCEx GetDesktopID GetDesktopWindow GetDialogBaseUnits GetDialogControlDpiChangeBehavior GetDialogDpiChangeBehavior GetDisplayAutoRotationPreferences GetDisplayConfigBufferSizes GetDlgCtrlID GetDlgItem GetDlgItemInt GetDlgItemTextA GetDlgItemTextW GetDoubleClickTime GetDpiForMonitorInternal GetDpiForSystem " \ +"GetDpiForWindow GetDpiFromDpiAwarenessContext GetFocus GetForegroundWindow GetGUIThreadInfo GetGestureConfig GetGestureExtraArgs GetGestureInfo GetGuiResources GetIconInfo GetIconInfoExA GetIconInfoExW GetInputDesktop GetInputLocaleInfo GetInputState GetInternalWindowPos GetKBCodePage GetKeyNameTextA GetKeyNameTextW GetKeyState GetKeyboardLayout GetKeyboardLayoutList GetKeyboardLayoutNameA GetKeyboardLayoutNameW GetKeyboardState GetKeyboardType GetLastActivePopup GetLastInputInfo GetLayeredWindowAttributes GetListBoxInfo GetMagnificationDesktopColorEffect GetMagnificationDesktopMagnification GetMagnificationDesktopSamplingMode GetMagnificationLensCtxInformation GetMenu GetMenuBarInfo GetMenuCheckMarkDimensions GetMenuContextHelpId GetMenuDefaultItem GetMenuInfo GetMenuItemCount GetMenuItemID GetMenuItemInfoA GetMenuItemInfoW GetMenuItemRect GetMenuState GetMenuStringA GetMenuStringW GetMessageA GetMessageExtraInfo GetMessagePos GetMessageTime GetMessageW GetMonitorInfoA GetMonitorInfoW GetMouseMovePointsEx GetNextDlgGroupItem GetNextDlgTabItem GetOpenClipboardWindow GetParent GetPhysicalCursorPos GetPointerCursorId GetPointerDevice GetPointerDeviceCursors GetPointerDeviceProperties GetPointerDeviceRects GetPointerDevices GetPointerFrameArrivalTimes GetPointerFrameInfo GetPointerFrameInfoHistory GetPointerFramePenInfo GetPointerFramePenInfoHistory GetPointerFrameTouchInfo GetPointerFrameTouchInfoHistory GetPointerInfo GetPointerInfoHistory GetPointerInputTransform GetPointerPenInfo GetPointerPenInfoHistory GetPointerTouchInfo GetPointerTouchInfoHistory GetPointerType GetPriorityClipboardFormat GetProcessDefaultLayout GetProcessDpiAwarenessInternal GetProcessUIContextInformation GetProcessWindowStation GetProgmanWindow GetPropA GetPropW GetQueueStatus GetRawInputBuffer GetRawInputData GetRawInputDeviceInfoA GetRawInputDeviceInfoW GetRawInputDeviceList GetRawPointerDeviceData GetReasonTitleFromReasonCode GetRegisteredRawInputDevices GetScrollBarInfo GetScrollInfo GetScrollPos " \ +"GetScrollRange GetSendMessageReceiver GetShellWindow GetSubMenu GetSysColor GetSysColorBrush GetSystemDpiForProcess GetSystemMenu GetSystemMetrics GetSystemMetricsForDpi GetTabbedTextExtentA GetTabbedTextExtentW GetTaskmanWindow GetThreadDesktop GetThreadDpiAwarenessContext GetThreadDpiHostingBehavior GetTitleBarInfo GetTopLevelWindow GetTopWindow GetTouchInputInfo GetUnpredictedMessagePos GetUpdateRect GetUpdateRgn GetUpdatedClipboardFormats GetUserObjectInformationA GetUserObjectInformationW GetUserObjectSecurity GetWinStationInfo GetWindow GetWindowBand GetWindowCompositionAttribute GetWindowCompositionInfo GetWindowContextHelpId GetWindowDC GetWindowDisplayAffinity GetWindowDpiAwarenessContext GetWindowDpiHostingBehavior GetWindowFeedbackSetting GetWindowInfo GetWindowLongA GetWindowLongPtrA GetWindowLongPtrW GetWindowLongW GetWindowMinimizeRect GetWindowModuleFileName GetWindowModuleFileNameA GetWindowModuleFileNameW GetWindowPlacement GetWindowProcessHandle GetWindowRect GetWindowRgn GetWindowRgnBox GetWindowRgnEx GetWindowTextA GetWindowTextLengthA GetWindowTextLengthW GetWindowTextW GetWindowThreadProcessId GetWindowWord GhostWindowFromHungWindow GrayStringA GrayStringW HandleDelegatedInput HideCaret HiliteMenuItem HungWindowFromGhostWindow IMPGetIMEA IMPGetIMEW IMPQueryIMEA IMPQueryIMEW IMPSetIMEA IMPSetIMEW ImpersonateDdeClientWindow InSendMessage InSendMessageEx InflateRect InheritWindowMonitor InitDManipHook InitializeGenericHidInjection InitializeInputDeviceInjection InitializeLpkHooks InitializePointerDeviceInjection InitializePointerDeviceInjectionEx InitializeTouchInjection InjectDeviceInput InjectGenericHidInput InjectKeyboardInput InjectMouseInput InjectPointerInput InjectTouchInput InsertMenuA InsertMenuItemA InsertMenuItemW InsertMenuW InternalGetWindowIcon InternalGetWindowText IntersectRect InvalidateRect InvalidateRgn InvertRect IsCharAlphaA IsCharAlphaNumericA IsCharAlphaNumericW IsCharAlphaW IsCharLowerA IsCharLowerW IsCharUpperA IsCharUpperW " \ +"IsChild IsClipboardFormatAvailable IsDialogMessage IsDialogMessageA IsDialogMessageW IsDlgButtonChecked IsGUIThread IsHungAppWindow IsIconic IsImmersiveProcess IsInDesktopWindowBand IsMenu IsMouseInPointerEnabled IsOneCoreTransformMode IsProcessDPIAware IsQueueAttached IsRectEmpty IsSETEnabled IsServerSideWindow IsThreadDesktopComposited IsThreadMessageQueueAttached IsThreadTSFEventAware IsTopLevelWindow IsTouchWindow IsValidDpiAwarenessContext IsWinEventHookInstalled IsWindow IsWindowArranged IsWindowEnabled IsWindowInDestroy IsWindowRedirectedForPrint IsWindowUnicode IsWindowVisible IsWow64Message IsZoomed KillTimer LoadAcceleratorsA LoadAcceleratorsW LoadBitmapA LoadBitmapW LoadCursorA LoadCursorFromFileA LoadCursorFromFileW LoadCursorW LoadIconA LoadIconW LoadImageA LoadImageW LoadKeyboardLayoutA LoadKeyboardLayoutEx LoadKeyboardLayoutW LoadLocalFonts LoadMenuA LoadMenuIndirectA LoadMenuIndirectW LoadMenuW LoadRemoteFonts LoadStringA LoadStringW LockSetForegroundWindow LockWindowStation LockWindowUpdate LockWorkStation LogicalToPhysicalPoint LogicalToPhysicalPointForPerMonitorDPI LookupIconIdFromDirectory LookupIconIdFromDirectoryEx MBToWCSEx MBToWCSExt MB_GetString MITActivateInputProcessing MITBindInputTypeToMonitors MITCoreMsgKGetConnectionHandle MITCoreMsgKOpenConnectionTo MITCoreMsgKSend MITDeactivateInputProcessing MITDisableMouseIntercept MITDispatchCompletion MITEnableMouseIntercept MITGetCursorUpdateHandle MITInjectLegacyISMTouchFrame MITRegisterManipulationThread MITSetForegroundRoutingInfo MITSetInputCallbacks MITSetInputDelegationMode MITSetLastInputRecipient MITSetManipulationInputTarget MITStopAndEndInertia MITSynthesizeMouseInput MITSynthesizeMouseWheel MITSynthesizeTouchInput MITUpdateInputGlobals MITWaitForMultipleObjectsEx MakeThreadTSFEventAware MapDialogRect MapVirtualKeyA MapVirtualKeyExA MapVirtualKeyExW MapVirtualKeyW MapVisualRelativePoints MapWindowPoints MenuItemFromPoint MenuWindowProcA MenuWindowProcW MessageBeep MessageBoxA MessageBoxExA " \ +"MessageBoxExW MessageBoxIndirectA MessageBoxIndirectW MessageBoxTimeoutA MessageBoxTimeoutW MessageBoxW ModifyMenuA ModifyMenuW MonitorFromPoint MonitorFromRect MonitorFromWindow MoveWindow MsgWaitForMultipleObjects MsgWaitForMultipleObjectsEx NotifyOverlayWindow NotifyWinEvent OemKeyScan OemToCharA OemToCharBuffA OemToCharBuffW OemToCharW OffsetRect OpenClipboard OpenDesktopA OpenDesktopW OpenIcon OpenInputDesktop OpenThreadDesktop OpenWindowStationA OpenWindowStationW PackDDElParam PackTouchHitTestingProximityEvaluation PaintDesktop PaintMenuBar PaintMonitor PeekMessageA PeekMessageW PhysicalToLogicalPoint PhysicalToLogicalPointForPerMonitorDPI PostMessageA PostMessageW PostQuitMessage PostThreadMessageA PostThreadMessageW PrintWindow PrivateExtractIconExA PrivateExtractIconExW PrivateExtractIconsA PrivateExtractIconsW PrivateRegisterICSProc PtInRect QueryBSDRWindow QueryDisplayConfig QuerySendMessage RIMAddInputObserver RIMAreSiblingDevices RIMDeviceIoControl RIMEnableMonitorMappingForDevice RIMFreeInputBuffer RIMGetDevicePreparsedData RIMGetDevicePreparsedDataLockfree RIMGetDeviceProperties RIMGetDevicePropertiesLockfree RIMGetPhysicalDeviceRect RIMGetSourceProcessId RIMObserveNextInput RIMOnPnpNotification RIMOnTimerNotification RIMReadInput RIMRegisterForInput RIMRemoveInputObserver RIMSetTestModeStatus RIMUnregisterForInput RIMUpdateInputObserverRegistration RealChildWindowFromPoint RealGetWindowClass RealGetWindowClassA RealGetWindowClassW ReasonCodeNeedsBugID ReasonCodeNeedsComment RecordShutdownReason RedrawWindow RegisterBSDRWindow RegisterClassA RegisterClassExA RegisterClassExW RegisterClassW RegisterClipboardFormatA RegisterClipboardFormatW RegisterDManipHook RegisterDeviceNotificationA RegisterDeviceNotificationW RegisterErrorReportingDialog RegisterFrostWindow RegisterGhostWindow RegisterHotKey RegisterLogonProcess RegisterMessagePumpHook RegisterPointerDeviceNotifications RegisterPointerInputTarget RegisterPointerInputTargetEx RegisterPowerSettingNotification " \ +"RegisterRawInputDevices RegisterServicesProcess RegisterSessionPort RegisterShellHookWindow RegisterSuspendResumeNotification RegisterSystemThread RegisterTasklist RegisterTouchHitTestingWindow RegisterTouchWindow RegisterUserApiHook RegisterWindowMessageA RegisterWindowMessageW ReleaseCapture ReleaseDC ReleaseDwmHitTestWaiters RemoveClipboardFormatListener RemoveInjectionDevice RemoveMenu RemovePropA RemovePropW RemoveThreadTSFEventAwareness ReplyMessage ReportInertia ResolveDesktopForWOW ReuseDDElParam ScreenToClient ScrollChildren ScrollDC ScrollWindow ScrollWindowEx SendDlgItemMessageA SendDlgItemMessageW SendIMEMessageExA SendIMEMessageExW SendInput SendMessageA SendMessageCallbackA SendMessageCallbackW SendMessageTimeoutA SendMessageTimeoutW SendMessageW SendNotifyMessageA SendNotifyMessageW SetActiveWindow SetCapture SetCaretBlinkTime SetCaretPos SetClassLongA SetClassLongPtrA SetClassLongPtrW SetClassLongW SetClassWord SetClipboardData SetClipboardViewer SetCoalescableTimer SetCoreWindow SetCursor SetCursorContents SetCursorPos SetDebugErrorLevel SetDeskWallpaper SetDesktopColorTransform SetDialogControlDpiChangeBehavior SetDialogDpiChangeBehavior SetDisplayAutoRotationPreferences SetDisplayConfig SetDlgItemInt SetDlgItemTextA SetDlgItemTextW SetDoubleClickTime SetFeatureReportResponse SetFocus SetForegroundWindow SetGestureConfig SetInternalWindowPos SetKeyboardState SetLastErrorEx SetLayeredWindowAttributes SetMagnificationDesktopColorEffect SetMagnificationDesktopMagnification SetMagnificationDesktopSamplingMode SetMagnificationLensCtxInformation SetMenu SetMenuContextHelpId SetMenuDefaultItem SetMenuInfo SetMenuItemBitmaps SetMenuItemInfoA SetMenuItemInfoW SetMessageExtraInfo SetMessageQueue SetMirrorRendering SetParent SetPhysicalCursorPos SetProcessDPIAware SetProcessDefaultLayout SetProcessDpiAwarenessContext SetProcessDpiAwarenessInternal SetProcessRestrictionExemption SetProcessWindowStation SetProgmanWindow SetPropA SetPropW SetRect SetRectEmpty SetScrollInfo " \ +"SetScrollPos SetScrollRange SetShellWindow SetShellWindowEx SetSysColors SetSysColorsTemp SetSystemCursor SetSystemMenu SetTaskmanWindow SetThreadDesktop SetThreadDpiAwarenessContext SetThreadDpiHostingBehavior SetThreadInputBlocked SetTimer SetUserObjectInformationA SetUserObjectInformationW SetUserObjectSecurity SetWinEventHook SetWindowBand SetWindowCompositionAttribute SetWindowCompositionTransition SetWindowContextHelpId SetWindowDisplayAffinity SetWindowFeedbackSetting SetWindowLongA SetWindowLongPtrA SetWindowLongPtrW SetWindowLongW SetWindowPlacement SetWindowPos SetWindowRgn SetWindowRgnEx SetWindowStationUser SetWindowTextA SetWindowTextW SetWindowWord SetWindowsHookA SetWindowsHookExA SetWindowsHookExW SetWindowsHookW ShowCaret ShowCursor ShowOwnedPopups ShowScrollBar ShowStartGlass ShowSystemCursor ShowWindow ShowWindowAsync ShutdownBlockReasonCreate ShutdownBlockReasonDestroy ShutdownBlockReasonQuery SignalRedirectionStartComplete SkipPointerFrameMessages SoftModalMessageBox SoundSentry SubtractRect SwapMouseButton SwitchDesktop SwitchDesktopWithFade SwitchToThisWindow SystemParametersInfoA SystemParametersInfoForDpi SystemParametersInfoW TabbedTextOutA TabbedTextOutW TileChildWindows TileWindows ToAscii ToAsciiEx ToUnicode ToUnicodeEx TrackMouseEvent TrackPopupMenu TrackPopupMenuEx TranslateAccelerator TranslateAcceleratorA TranslateAcceleratorW TranslateMDISysAccel TranslateMessage TranslateMessageEx UndelegateInput UnhookWinEvent UnhookWindowsHook UnhookWindowsHookEx UnionRect UnloadKeyboardLayout UnlockWindowStation UnpackDDElParam UnregisterClassA UnregisterClassW UnregisterDeviceNotification UnregisterHotKey UnregisterMessagePumpHook UnregisterPointerInputTarget UnregisterPointerInputTargetEx UnregisterPowerSettingNotification UnregisterSessionPort UnregisterSuspendResumeNotification UnregisterTouchWindow UnregisterUserApiHook UpdateDefaultDesktopThumbnail UpdateLayeredWindow UpdateLayeredWindowIndirect UpdatePerUserSystemParameters UpdateWindow UpdateWindowInputSinkHints " \ +"User32InitializeImmEntryTable UserClientDllInitialize UserHandleGrantAccess UserLpkPSMTextOut UserLpkTabbedTextOut UserRealizePalette UserRegisterWowHandlers VRipOutput VTagOutput ValidateRect ValidateRgn VkKeyScanA VkKeyScanExA VkKeyScanExW VkKeyScanW WCSToMBEx WINNLSEnableIME WINNLSGetEnableStatus WINNLSGetIMEHotkey WaitForInputIdle WaitForRedirectionStartComplete WaitMessage WinHelpA WinHelpW WindowFromDC WindowFromPhysicalPoint WindowFromPoint _UserTestTokenForInteractive gSharedInfo gapfnScSendMessage keybd_event mouse_event wsprintfA wsprintfW wvsprintfA wvsprintfW"; + +bool ModuleBoundsHookCheckSingle(HMODULE dll, char* apiList) +{ + MODULEINFO moduleInfo; + if (GetModuleInformation(GetCurrentProcess(), dll, &moduleInfo, sizeof(MODULEINFO)) == FALSE) + { + // todo: error condition + return FALSE; + } + + PVOID moduleBottom = moduleInfo.lpBaseOfDll; + PVOID moduleTop = reinterpret_cast((reinterpret_cast(moduleBottom) + moduleInfo.SizeOfImage)); + + char* currentAPI = NULL; + char* nextAPI = NULL; + currentAPI = strtok_s(apiList, " ", &nextAPI); + + bool foundHook = false; + + while (currentAPI != NULL) + { + PVOID procAddr = GetProcAddress(dll, currentAPI); + if (procAddr != NULL) + { + if (procAddr < moduleBottom || procAddr >= moduleTop) + { + foundHook = true; + //printf("Caught hook on API '%s'\n", currentAPI); + } + } + + currentAPI = strtok_s(NULL, " ", &nextAPI); + } + + return foundHook; +} + +BOOL ModuleBoundsHookCheck() +{ + bool foundHook = ModuleBoundsHookCheckSingle(LoadLibrary(_T("kernel32.dll")), apis_kernel32) && + ModuleBoundsHookCheckSingle(LoadLibrary(_T("ntdll.dll")), apis_ntdll) && + ModuleBoundsHookCheckSingle(LoadLibrary(_T("user32.dll")), apis_user32); + + return foundHook ? TRUE : FALSE; +} \ No newline at end of file diff --git a/byp/sbexecution/AntiDebug/ModuleBoundsHookCheck.h b/byp/sbexecution/AntiDebug/ModuleBoundsHookCheck.h new file mode 100644 index 00000000..764ad29a --- /dev/null +++ b/byp/sbexecution/AntiDebug/ModuleBoundsHookCheck.h @@ -0,0 +1,3 @@ +#pragma once + +BOOL ModuleBoundsHookCheck(); \ No newline at end of file diff --git a/byp/sbexecution/AntiDebug/NtGlobalFlag.cpp b/byp/sbexecution/AntiDebug/NtGlobalFlag.cpp new file mode 100644 index 00000000..2b7d7f4f --- /dev/null +++ b/byp/sbexecution/AntiDebug/NtGlobalFlag.cpp @@ -0,0 +1,63 @@ +#include "pch.h" +#include "NtGlobalFlag.h" + + +BOOL +NtGlobalFlag ( + VOID + ) +/*++ + +Routine Description: + + NtGlobalFlag is a DWORD value inside the process PEB. This value + contains many flags set by the OS that affects the way the process + runs. When a process is being debugged, the flags: + - FLG_HEAP_ENABLE_TAIL_CHECK (0x10) + - FLG_HEAP_ENABLE_FREE_CHECK (0x20) + - FLG_HEAP_VALIDATE_PARAMETERS(0x40) are set for the process + + If the 32-bit executable is being run on a 64-bit system, both the + 32-bit and 64-bit PEBs are checked. The WoW64 PEB address is + fetched via the WoW64 Thread Environment Block (TEB) at FS:[0x18]-0x2000. + +Arguments: + + None + +Return Value: + + TRUE - if debugger was detected + FALSE - otherwise +--*/ +{ + PDWORD pNtGlobalFlag = NULL, pNtGlobalFlagWoW64 = NULL; + +#if defined (ENV64BIT) + pNtGlobalFlag = (PDWORD)(__readgsqword(0x60) + 0xBC); + +#elif defined(ENV32BIT) + /* NtGlobalFlags for real 32-bits OS */ + BYTE* _teb32 = (BYTE*)__readfsdword(0x18); + DWORD _peb32 = *(DWORD*)(_teb32 + 0x30); + pNtGlobalFlag = (PDWORD)(_peb32 + 0x68); + + if (IsWoW64()) + { + /* In Wow64, there is a separate PEB for the 32-bit portion and the 64-bit portion + which we can double-check */ + + BYTE* _teb64 = (BYTE*)__readfsdword(0x18) - 0x2000; + DWORD64 _peb64 = *(DWORD64*)(_teb64 + 0x60); + pNtGlobalFlagWoW64 = (PDWORD)(_peb64 + 0xBC); + } +#endif + + BOOL normalDetected = pNtGlobalFlag && *pNtGlobalFlag & 0x00000070; + BOOL wow64Detected = pNtGlobalFlagWoW64 && *pNtGlobalFlagWoW64 & 0x00000070; + + if(normalDetected || wow64Detected) + return TRUE; + else + return FALSE; +} diff --git a/byp/sbexecution/AntiDebug/NtGlobalFlag.h b/byp/sbexecution/AntiDebug/NtGlobalFlag.h new file mode 100644 index 00000000..13bdf364 --- /dev/null +++ b/byp/sbexecution/AntiDebug/NtGlobalFlag.h @@ -0,0 +1,3 @@ +#pragma once + +BOOL NtGlobalFlag(); \ No newline at end of file diff --git a/byp/sbexecution/AntiDebug/NtQueryInformationProcess_ProcessDebugFlags.cpp b/byp/sbexecution/AntiDebug/NtQueryInformationProcess_ProcessDebugFlags.cpp new file mode 100644 index 00000000..5f40267b --- /dev/null +++ b/byp/sbexecution/AntiDebug/NtQueryInformationProcess_ProcessDebugFlags.cpp @@ -0,0 +1,26 @@ +#include "pch.h" + +#include "NtQueryInformationProcess_ProcessDebugFlags.h" + +/* +When NtQueryProcessInformation is called with the ProcessDebugFlags class, the function will return the inverse of EPROCESS->NoDebugInherit, +which means that if a debugger is present, then this function will return FALSE if the process is being debugged. + */ + +BOOL NtQueryInformationProcess_ProcessDebugFlags() +{ + // ProcessDebugFlags + const int ProcessDebugFlags = 0x1f; + + auto NtQueryInfoProcess = static_cast(API::GetAPI(API_IDENTIFIER::API_NtQueryInformationProcess)); + + // Other Vars + NTSTATUS Status; + DWORD NoDebugInherit = 0; + + Status = NtQueryInfoProcess(GetCurrentProcess(), ProcessDebugFlags, &NoDebugInherit, sizeof(DWORD), NULL); + if (Status == 0x00000000 && NoDebugInherit == 0) + return TRUE; + else + return FALSE; +} diff --git a/byp/sbexecution/AntiDebug/NtQueryInformationProcess_ProcessDebugFlags.h b/byp/sbexecution/AntiDebug/NtQueryInformationProcess_ProcessDebugFlags.h new file mode 100644 index 00000000..919a9a5a --- /dev/null +++ b/byp/sbexecution/AntiDebug/NtQueryInformationProcess_ProcessDebugFlags.h @@ -0,0 +1,3 @@ +#pragma once + +BOOL NtQueryInformationProcess_ProcessDebugFlags(); \ No newline at end of file diff --git a/byp/sbexecution/AntiDebug/NtQueryInformationProcess_ProcessDebugObject.cpp b/byp/sbexecution/AntiDebug/NtQueryInformationProcess_ProcessDebugObject.cpp new file mode 100644 index 00000000..5fb10e37 --- /dev/null +++ b/byp/sbexecution/AntiDebug/NtQueryInformationProcess_ProcessDebugObject.cpp @@ -0,0 +1,49 @@ +#include "pch.h" + +#include "NtQueryInformationProcess_ProcessDebugObject.h" + +/* +This function uses NtQuerySystemInformation to try to retrieve a handle to the current process's debug object handle. +If the function is successful it'll return true which means we're being debugged or it'll return false if it fails +the process isn't being debugged +*/ + +BOOL NtQueryInformationProcess_ProcessDebugObject() +{ + // ProcessDebugObjectHandle + const int ProcessDebugObjectHandle = 0x1e; + + auto NtQueryInfoProcess = static_cast(API::GetAPI(API_IDENTIFIER::API_NtQueryInformationProcess)); + + // Other Vars + NTSTATUS Status; + HANDLE hDebugObject = NULL; + +#if defined (ENV64BIT) + DWORD dProcessInformationLength = sizeof(ULONG) * 2; + DWORD64 IsRemotePresent = 0; + +#elif defined(ENV32BIT) + DWORD dProcessInformationLength = sizeof(ULONG); + DWORD32 IsRemotePresent = 0; +#endif + + // Regular check + Status = NtQueryInfoProcess(GetCurrentProcess(), ProcessDebugObjectHandle, &hDebugObject, dProcessInformationLength, NULL); + + if (Status != STATUS_PORT_NOT_SET) + return TRUE; + if (hDebugObject != NULL) + return TRUE; + + // Check with overlapping return length and debug object handle buffers to find anti-anti-debuggers + Status = NtQueryInfoProcess(GetCurrentProcess(), ProcessDebugObjectHandle, &hDebugObject, dProcessInformationLength, (PULONG)&hDebugObject); + if (Status != STATUS_PORT_NOT_SET) + return TRUE; + if (hDebugObject == NULL) + return TRUE; // Handle incorrectly zeroed + if ((ULONG)(ULONG_PTR)hDebugObject != dProcessInformationLength) + return TRUE; // Return length incorrectly overwritten + + return FALSE; +} diff --git a/byp/sbexecution/AntiDebug/NtQueryInformationProcess_ProcessDebugObject.h b/byp/sbexecution/AntiDebug/NtQueryInformationProcess_ProcessDebugObject.h new file mode 100644 index 00000000..9f609ab7 --- /dev/null +++ b/byp/sbexecution/AntiDebug/NtQueryInformationProcess_ProcessDebugObject.h @@ -0,0 +1,5 @@ +#pragma once + +BOOL NtQueryInformationProcess_ProcessDebugObject(); + +#define STATUS_PORT_NOT_SET ((NTSTATUS)0xC0000353L) diff --git a/byp/sbexecution/AntiDebug/NtQueryInformationProcess_ProcessDebugPort.cpp b/byp/sbexecution/AntiDebug/NtQueryInformationProcess_ProcessDebugPort.cpp new file mode 100644 index 00000000..eca5a836 --- /dev/null +++ b/byp/sbexecution/AntiDebug/NtQueryInformationProcess_ProcessDebugPort.cpp @@ -0,0 +1,35 @@ +#include "pch.h" + +#include "NtQueryInformationProcess_ProcessDebugPort.h" + +/* +Instead of calling CheckRemoteDebuggerPresent an individual could also make directly the call to +NtQueryInformationProcess process theirself. +*/ + +BOOL NtQueryInformationProcess_ProcessDebugPort () +{ + auto NtQueryInfoProcess = static_cast(API::GetAPI(API_IDENTIFIER::API_NtQueryInformationProcess)); + + // ProcessDebugPort + const int ProcessDbgPort = 7; + + // Other Vars + NTSTATUS Status; + +#if defined (ENV64BIT) + DWORD dProcessInformationLength = sizeof(ULONG) * 2; + DWORD64 IsRemotePresent = 0; + +#elif defined(ENV32BIT) + DWORD dProcessInformationLength = sizeof(ULONG); + DWORD32 IsRemotePresent = 0; +#endif + + Status = NtQueryInfoProcess(GetCurrentProcess(), ProcessDbgPort, &IsRemotePresent, dProcessInformationLength, NULL); + if(Status == 0x00000000 && IsRemotePresent != 0) + return TRUE; + else + return FALSE; +} + diff --git a/byp/sbexecution/AntiDebug/NtQueryInformationProcess_ProcessDebugPort.h b/byp/sbexecution/AntiDebug/NtQueryInformationProcess_ProcessDebugPort.h new file mode 100644 index 00000000..796d2a5f --- /dev/null +++ b/byp/sbexecution/AntiDebug/NtQueryInformationProcess_ProcessDebugPort.h @@ -0,0 +1,3 @@ +#pragma once + +BOOL NtQueryInformationProcess_ProcessDebugPort(); \ No newline at end of file diff --git a/byp/sbexecution/AntiDebug/NtQueryObject_AllTypesInformation.cpp b/byp/sbexecution/AntiDebug/NtQueryObject_AllTypesInformation.cpp new file mode 100644 index 00000000..4103171b --- /dev/null +++ b/byp/sbexecution/AntiDebug/NtQueryObject_AllTypesInformation.cpp @@ -0,0 +1,87 @@ +#include "pch.h" + +#include "NtQueryObject_ObjectInformation.h" + +/* +Windows XP introduced a "debug object". When a debugging session begins, a debug object is created, +and a handle is associated with it. Using the ntdll NtQueryObject() function with class: ObjectAllTypesInformation. +ObjectAllTypesInformation (3) will return a list with all existing object type, we should iterate over objects to +locate "DebugObject". Todo: Support for Win10 +*/ + + +BOOL NtQueryObject_ObjectAllTypesInformation() +{ + //NOTE this check is unreliable, a debugger present on the system doesn't mean it's attached to you + + auto NtQueryObject = static_cast(API::GetAPI(API_IDENTIFIER::API_NtQueryObject)); + + // Some vars + ULONG size; + PVOID pMemory = NULL; + POBJECT_ALL_INFORMATION pObjectAllInfo = NULL; + NTSTATUS Status; + + // Get the size of the information needed + Status = NtQueryObject(NULL, 3, &size, sizeof(ULONG), &size); + + // Alocate memory for the list + pMemory = VirtualAlloc(NULL, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); + if (pMemory == NULL) + return FALSE; + + // Now we can actually retrieve the list + Status = NtQueryObject((HANDLE)-1, 3, pMemory, size, NULL); + + // Status != STATUS_SUCCESS + if (Status != 0x00000000) + { + VirtualFree(pMemory, 0, MEM_RELEASE); + return FALSE; + } + + // We have the information we need + pObjectAllInfo = (POBJECT_ALL_INFORMATION)pMemory; + UCHAR *pObjInfoLocation = (UCHAR*)pObjectAllInfo->ObjectTypeInformation; + ULONG NumObjects = pObjectAllInfo->NumberOfObjects; + + for (UINT i = 0; i < NumObjects; i++) + { + + POBJECT_TYPE_INFORMATION pObjectTypeInfo = (POBJECT_TYPE_INFORMATION)pObjInfoLocation; + + // The debug object will always be present + if (StrCmp(_T("DebugObject"), pObjectTypeInfo->TypeName.Buffer) == 0) + { + // Are there any objects? + if (pObjectTypeInfo->TotalNumberOfObjects > 0) + { + VirtualFree(pMemory, 0, MEM_RELEASE); + return TRUE; + } + else + { + VirtualFree(pMemory, 0, MEM_RELEASE); + return FALSE; + } + } + + // Get the address of the current entries + // string so we can find the end + pObjInfoLocation = (unsigned char*)pObjectTypeInfo->TypeName.Buffer; + + // Add the size + pObjInfoLocation += pObjectTypeInfo->TypeName.MaximumLength; + + // Skip the trailing null and alignment bytes + ULONG_PTR tmp = ((ULONG_PTR)pObjInfoLocation) & -(int)sizeof(void*); + + // Not pretty but it works + if ((ULONG_PTR)tmp != (ULONG_PTR)pObjInfoLocation) + tmp += sizeof(void*); + pObjInfoLocation = ((unsigned char*)tmp); + } + + VirtualFree(pMemory, 0, MEM_RELEASE); + return FALSE; +} diff --git a/byp/sbexecution/AntiDebug/NtQueryObject_ObjectInformation.h b/byp/sbexecution/AntiDebug/NtQueryObject_ObjectInformation.h new file mode 100644 index 00000000..af8624d5 --- /dev/null +++ b/byp/sbexecution/AntiDebug/NtQueryObject_ObjectInformation.h @@ -0,0 +1,24 @@ +#pragma once + +BOOL NtQueryObject_ObjectAllTypesInformation(); +BOOL NtQueryObject_ObjectTypeInformation(); + + +#define DEBUG_READ_EVENT 0x0001 +#define DEBUG_PROCESS_ASSIGN 0x0002 +#define DEBUG_SET_INFORMATION 0x0004 +#define DEBUG_QUERY_INFORMATION 0x0008 +#define DEBUG_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | \ + DEBUG_READ_EVENT | DEBUG_PROCESS_ASSIGN | DEBUG_SET_INFORMATION | \ + DEBUG_QUERY_INFORMATION) + +typedef struct _OBJECT_TYPE_INFORMATION { + UNICODE_STRING TypeName; + ULONG TotalNumberOfHandles; + ULONG TotalNumberOfObjects; +}OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION; + +typedef struct _OBJECT_ALL_INFORMATION { + ULONG NumberOfObjects; + OBJECT_TYPE_INFORMATION ObjectTypeInformation[1]; +}OBJECT_ALL_INFORMATION, *POBJECT_ALL_INFORMATION; \ No newline at end of file diff --git a/byp/sbexecution/AntiDebug/NtQueryObject_ObjectTypeInformation.cpp b/byp/sbexecution/AntiDebug/NtQueryObject_ObjectTypeInformation.cpp new file mode 100644 index 00000000..0c0ba17e --- /dev/null +++ b/byp/sbexecution/AntiDebug/NtQueryObject_ObjectTypeInformation.cpp @@ -0,0 +1,54 @@ +#include "pch.h" + +#include "NtQueryObject_ObjectInformation.h" + +/* +Windows XP introduced a "debug object". When a debugging session begins, a debug object is created, +and a handle is associated with it. Using the ntdll NtQueryObject() function with class: ObjectTypeInformation. +ObjectTypeInformation will return the type information of the supplied handle. +*/ + + +BOOL NtQueryObject_ObjectTypeInformation() +{ + //NOTE this check now only detects if NtQueryObject is hooked to set ObjectInformation->TotalNumberOfObjects = 0 + + // We have to import the function + auto NtQueryObject = static_cast(API::GetAPI(API_IDENTIFIER::API_NtQueryObject)); + auto NtCreateDebugObject = static_cast(API::GetAPI(API_IDENTIFIER::API_NtCreateDebugObject)); + + // Some vars + HANDLE DebugObjectHandle; + OBJECT_ATTRIBUTES ObjectAttributes; + InitializeObjectAttributes(&ObjectAttributes, 0, 0, 0, 0); + BYTE memory[0x1000] = { 0 }; + POBJECT_TYPE_INFORMATION ObjectInformation = (POBJECT_TYPE_INFORMATION)memory; + NTSTATUS Status; + + NtCreateDebugObject(&DebugObjectHandle, DEBUG_ALL_ACCESS, &ObjectAttributes, FALSE); + + if (API::IsAvailable(API_IDENTIFIER::API_NtQueryObject)) + { + Status = NtQueryObject(DebugObjectHandle, ObjectTypeInformation, ObjectInformation, sizeof(memory), 0); + + // Make sure to not screw up later checks + CloseHandle(DebugObjectHandle); + + + if (Status >= 0) + { + if (ObjectInformation->TotalNumberOfObjects == 0) + return TRUE; //There should be at least one object (we just created it). + else + return FALSE; + } + else + { + //NOTE: this should actually never happen on a valid handle (so this check can be bypassed by failing NtQueryObject) + return FALSE; + } + } + else + return FALSE; + +} diff --git a/byp/sbexecution/AntiDebug/NtQuerySystemInformation_SystemKernelDebuggerInformation.cpp b/byp/sbexecution/AntiDebug/NtQuerySystemInformation_SystemKernelDebuggerInformation.cpp new file mode 100644 index 00000000..aa03fd23 --- /dev/null +++ b/byp/sbexecution/AntiDebug/NtQuerySystemInformation_SystemKernelDebuggerInformation.cpp @@ -0,0 +1,30 @@ +#include "pch.h" + +#include "NtQuerySystemInformation_SystemKernelDebuggerInformation.h" + +/* +When NtQuerySystemInformation is called with the SystemKernelDebuggerInformation class, the function will return +a SYSTEM_KERNEL_DEBUGGER_INFORMATION struct which will reveal the presence of a kernel debugger. +*/ + +BOOL NtQuerySystemInformation_SystemKernelDebuggerInformation() +{ + // SystemKernelDebuggerInformation + const int SystemKernelDebuggerInformation = 0x23; + + // The debugger information struct + SYSTEM_KERNEL_DEBUGGER_INFORMATION KdDebuggerInfo; + + auto NtQuerySystemInformation = static_cast(API::GetAPI(API_IDENTIFIER::API_NtQuerySystemInformation)); + + // Call NtQuerySystemInformation + NTSTATUS Status = NtQuerySystemInformation(SystemKernelDebuggerInformation, &KdDebuggerInfo, sizeof(SYSTEM_KERNEL_DEBUGGER_INFORMATION), NULL); + if (Status >= 0) + { + // KernelDebuggerEnabled almost always implies !KernelDebuggerNotPresent. KernelDebuggerNotPresent can sometimes + // change if the debugger is temporarily disconnected, but either of these means a debugger is enabled. + if (KdDebuggerInfo.KernelDebuggerEnabled || !KdDebuggerInfo.KernelDebuggerNotPresent) + return TRUE; + } + return FALSE; +} diff --git a/byp/sbexecution/AntiDebug/NtQuerySystemInformation_SystemKernelDebuggerInformation.h b/byp/sbexecution/AntiDebug/NtQuerySystemInformation_SystemKernelDebuggerInformation.h new file mode 100644 index 00000000..746867fc --- /dev/null +++ b/byp/sbexecution/AntiDebug/NtQuerySystemInformation_SystemKernelDebuggerInformation.h @@ -0,0 +1,9 @@ +#pragma once + +BOOL NtQuerySystemInformation_SystemKernelDebuggerInformation(); + +typedef struct _SYSTEM_KERNEL_DEBUGGER_INFORMATION +{ + BOOLEAN KernelDebuggerEnabled; + BOOLEAN KernelDebuggerNotPresent; +} SYSTEM_KERNEL_DEBUGGER_INFORMATION, *PSYSTEM_KERNEL_DEBUGGER_INFORMATION; \ No newline at end of file diff --git a/byp/sbexecution/AntiDebug/NtSetInformationThread_ThreadHideFromDebugger.cpp b/byp/sbexecution/AntiDebug/NtSetInformationThread_ThreadHideFromDebugger.cpp new file mode 100644 index 00000000..ff7b1afc --- /dev/null +++ b/byp/sbexecution/AntiDebug/NtSetInformationThread_ThreadHideFromDebugger.cpp @@ -0,0 +1,133 @@ +#include "pch.h" + +#include "NtSetInformationThread_ThreadHideFromDebugger.h" + +/* +Calling NtSetInformationThread will attempt with ThreadInformationClass set to x11 (ThreadHideFromDebugger) +to hide a thread from the debugger, Passing NULL for hThread will cause the function to hide the thread the +function is running in. Also, the function returns false on failure and true on success. When the function +is called, the thread will continue to run but a debugger will no longer receive any events related to that thread. + +These checks also look for hooks on the NtSetInformationThread API that try to block ThreadHideFromDebugger. +*/ + +#ifndef STATUS_INFO_LENGTH_MISMATCH +#define STATUS_INFO_LENGTH_MISMATCH ((DWORD)0xC0000004L) +#endif +#ifndef STATUS_DATATYPE_MISALIGNMENT +#define STATUS_DATATYPE_MISALIGNMENT ((DWORD)0x80000002L) +#endif + + +BOOL NtSetInformationThread_ThreadHideFromDebugger() +{ + // this is needed because the bool data type can be at unaligned memory locations, whereas the NtQueryInformationThread API expects 32-bit aligned pointers. + struct AlignedBool + { + alignas(4) bool Value; + }; + + // ThreadHideFromDebugger + const int ThreadHideFromDebugger = 0x11; + + auto NtSetInformationThread = static_cast(API::GetAPI(API_IDENTIFIER::API_NtSetInformationThread)); + auto NtQueryInformationThread = static_cast(API::GetAPI(API_IDENTIFIER::API_NtQueryInformationThread)); + + NTSTATUS Status; + bool doQITcheck = false; + + // only do the QueryInformationThread check if we're on Vista and the API is available. + // this is because the ThreadHideFromDebugger class can only be queried from Vista onwards. + if (API::IsAvailable(API_IDENTIFIER::API_NtQueryInformationThread)) + { + doQITcheck = IsWindowsVistaOrGreater(); + } + + AlignedBool isThreadHidden; + isThreadHidden.Value = false; + + // First issue a bogus call with an incorrect length parameter. If it succeeds, we know NtSetInformationThread was hooked. + Status = NtSetInformationThread(GetCurrentThread(), ThreadHideFromDebugger, &isThreadHidden, 12345); + if (Status == 0) + return TRUE; + + // Next try again but give it a bogus thread handle. If it succeeds, again we know NtSetInformationThread was hooked. + Status = NtSetInformationThread((HANDLE)0xFFFF, ThreadHideFromDebugger, NULL, 0); + if (Status == 0) + return TRUE; + + // Now try a legitimate call. + Status = NtSetInformationThread(GetCurrentThread(), ThreadHideFromDebugger, NULL, 0); + + if (Status == 0) + { + if (doQITcheck) + { + // note: the ThreadHideFromDebugger query expects a bool (1 byte), not a BOOL (4 bytes) + // if a BOOL is used, the kernel returns 0xC0000004 (STATUS_INFO_LENGTH_MISMATCH) because BOOL is typedef int. + + // first do a legitimate call. this should succeed or return an error such as access denied. + Status = NtQueryInformationThread(GetCurrentThread(), ThreadHideFromDebugger, &isThreadHidden.Value, sizeof(bool), NULL); + + // this shouldn't happen, because we used the correct length. this will only happen if a buggy hook mistakenly expects a BOOL rather than a bool. + if (Status == STATUS_INFO_LENGTH_MISMATCH) + { + // we found a buggy hook that expects some size other than 1 + return TRUE; + } + + // if the legitimate call succeeded, continue with additional bogus API call checks + if (Status == 0) + { + AlignedBool bogusIsThreadHidden; + bogusIsThreadHidden.Value = false; + + // now do a bogus call with the wrong size. this will catch buggy hooks that accept BOOL (4 bytes) or just don't have any size checks + Status = NtQueryInformationThread(GetCurrentThread(), ThreadHideFromDebugger, &bogusIsThreadHidden.Value, sizeof(BOOL), NULL); + if (Status != STATUS_INFO_LENGTH_MISMATCH) + { + // we found a buggy hook that allows for incorrect size values + return TRUE; + } + + // NtQueryInformationThread explicitly requires the ThreadInformation pointer to be aligned. as such, it should reject unaligned pointers. + // hooks are almost certainly guaranteed to not retain this behaviour, so it's a very nice way to catch them out. + const size_t UnalignedCheckCount = 8; + bool bogusUnalignedValues[UnalignedCheckCount]; + int alignmentErrorCount = 0; +#if _WIN64 + // on 64-bit, up to two elements in the array should be aligned. + const size_t MaxAlignmentCheckSuccessCount = 2; +#else + // on 32-bit, there should be either two or four aligned elements (unsure how WoW64 affects this, so I'm just gonna assume 2 or 4 are ok) + const size_t MaxAlignmentCheckSuccessCount = 4; +#endif + for (size_t i = 0; i < UnalignedCheckCount; i++) + { + Status = NtQueryInformationThread(GetCurrentThread(), ThreadHideFromDebugger, &(bogusUnalignedValues[i]), sizeof(BOOL), NULL); + if (Status == STATUS_DATATYPE_MISALIGNMENT) + { + alignmentErrorCount++; + } + } + // if there weren't enough alignment errors, we know that the API must be hooked and not checking alignment properly! + if (UnalignedCheckCount - MaxAlignmentCheckSuccessCount > alignmentErrorCount) + { + return TRUE; + } + + // the legitimate call was successful, and the bogus call was unsuccessful, so return false (no detection) if the HideFromDebugger flag was properly set. + // if the HideFromDebugger flag was not set, i.e. the NtSetInformationThread call lied to us about being successful, then return true (debugger/hook detected) + return isThreadHidden.Value ? FALSE : TRUE; + } + } + } + else + { + // call failed, should've succeeded + return TRUE; + } + + // we didn't find any hooks. + return FALSE; +} diff --git a/byp/sbexecution/AntiDebug/NtSetInformationThread_ThreadHideFromDebugger.h b/byp/sbexecution/AntiDebug/NtSetInformationThread_ThreadHideFromDebugger.h new file mode 100644 index 00000000..6fc8469d --- /dev/null +++ b/byp/sbexecution/AntiDebug/NtSetInformationThread_ThreadHideFromDebugger.h @@ -0,0 +1,3 @@ +#pragma once + +BOOL NtSetInformationThread_ThreadHideFromDebugger(); \ No newline at end of file diff --git a/byp/sbexecution/AntiDebug/NtSystemDebugControl.cpp b/byp/sbexecution/AntiDebug/NtSystemDebugControl.cpp new file mode 100644 index 00000000..ce7a5b37 --- /dev/null +++ b/byp/sbexecution/AntiDebug/NtSystemDebugControl.cpp @@ -0,0 +1,19 @@ +#include "pch.h" + +BOOL NtSystemDebugControl_Command() { + auto NtSystemDebugControl_ = static_cast(API::GetAPI(API_IDENTIFIER::API_NtSystemDebugControl)); + + auto status = NtSystemDebugControl_(SYSDBG_COMMAND::SysDbgCheckLowMemory, 0, 0, 0, 0, 0); + + const auto STATUS_DEBUGGER_INACTIVE = 0xC0000354L; + const auto STATUS_ACCESS_DENIED = 0xC0000022L; + if (status == STATUS_DEBUGGER_INACTIVE) { + return FALSE; + } else { + // kernel debugger found + if (status != STATUS_ACCESS_DENIED) { + // usermode debugger too + } + return TRUE; + } +} \ No newline at end of file diff --git a/byp/sbexecution/AntiDebug/NtSystemDebugControl.h b/byp/sbexecution/AntiDebug/NtSystemDebugControl.h new file mode 100644 index 00000000..d0c482aa --- /dev/null +++ b/byp/sbexecution/AntiDebug/NtSystemDebugControl.h @@ -0,0 +1 @@ +BOOL NtSystemDebugControl_Command(); \ No newline at end of file diff --git a/byp/sbexecution/AntiDebug/NtYieldExecution.cpp b/byp/sbexecution/AntiDebug/NtYieldExecution.cpp new file mode 100644 index 00000000..2e6d546b --- /dev/null +++ b/byp/sbexecution/AntiDebug/NtYieldExecution.cpp @@ -0,0 +1,38 @@ +#include "pch.h" +#include "NtYieldExecution.h" + +/* +The ntdll function NtYieldExecution or its kernel32 equivalent SwitchToThread function allows the current +thread to offer to give up the rest of its time slice, and allow the next scheduled thread to +execute. If no threads are scheduled to execute (or when the system is busy in particular ways and will +not allow a switch to occur), then the ntdll NtYieldExecution() function returns the +STATUS_NO_YIELD_PERFORMED (0x40000024) status, which causes the kernel32 SwitchToThread() function to +return a zero. When an application is being debugged, the act of single-stepping through the +code causes debug events and often results in no yield being allowed. However, this is a hopelessly +unreliable method for detecting a debugger because it will also detect the presence of a thread that is running with high priority. +*/ + + +BOOL NtYieldExecutionAPI() +{ + //NOTE: this check is unreliable, don't actually use this in a real environment + + auto NtYieldExecution = static_cast(API::GetAPI(API_IDENTIFIER::API_NtYieldExecution)); + + INT iDebugged = 0; + + for (int i = 0; i < 0x20; i++) + { + Sleep(0xf); + + if (NtYieldExecution() != STATUS_NO_YIELD_PERFORMED) + iDebugged++; + } + + if (iDebugged <= 3) + return FALSE; + else + return TRUE; + + +} diff --git a/byp/sbexecution/AntiDebug/NtYieldExecution.h b/byp/sbexecution/AntiDebug/NtYieldExecution.h new file mode 100644 index 00000000..7d4a2b20 --- /dev/null +++ b/byp/sbexecution/AntiDebug/NtYieldExecution.h @@ -0,0 +1,5 @@ +#pragma once + +#define STATUS_NO_YIELD_PERFORMED 0x40000024 + +BOOL NtYieldExecutionAPI(); \ No newline at end of file diff --git a/byp/sbexecution/AntiDebug/OutputDebugStringAPI.cpp b/byp/sbexecution/AntiDebug/OutputDebugStringAPI.cpp new file mode 100644 index 00000000..adf2a7f2 --- /dev/null +++ b/byp/sbexecution/AntiDebug/OutputDebugStringAPI.cpp @@ -0,0 +1,34 @@ +#include "pch.h" + +#include "OutputDebugStringAPI.h" + +/* +OutputDebugString() is typically used to output a string value to the debugging data stream. +This string is then displayed in the debugger. Due to this fact, the function OutputDebugString() +acts differently based on the existence of a debugger on the running process. If a debugger is +attached to the process, the function will execute normally and no error state will be registered; +however if there is no debugger attached, LastError will be set by the process letting us know that +we are debugger free. To execute this method we set LastError to an arbitrary value of our choosing +and then call OutputDebugString(). We then check GetLastError() and if our error code remains, +we know we are debugger free. This Works only in Windows XP/2000 +*/ + +BOOL OutputDebugStringAPI() +{ + + BOOL IsDbgPresent = FALSE; + DWORD Val = 0x29A; + + // This is working only in Windows XP/2000 + if (IsWindowsXPOr2k()) + { + SetLastError(Val); + OutputDebugString(_T("random")); + + if (GetLastError() == Val) + IsDbgPresent = TRUE; + } + + return IsDbgPresent; +} + diff --git a/byp/sbexecution/AntiDebug/OutputDebugStringAPI.h b/byp/sbexecution/AntiDebug/OutputDebugStringAPI.h new file mode 100644 index 00000000..600134ff --- /dev/null +++ b/byp/sbexecution/AntiDebug/OutputDebugStringAPI.h @@ -0,0 +1,3 @@ +#pragma once + +BOOL OutputDebugStringAPI(); diff --git a/byp/sbexecution/AntiDebug/PageExceptionBreakpointCheck.cpp b/byp/sbexecution/AntiDebug/PageExceptionBreakpointCheck.cpp new file mode 100644 index 00000000..16cd329d --- /dev/null +++ b/byp/sbexecution/AntiDebug/PageExceptionBreakpointCheck.cpp @@ -0,0 +1,139 @@ +#include "pch.h" + +#ifdef _DEBUG +#define OutputDebugStringDbgOnly(S) OutputDebugString(S) +#else +#define OutputDebugStringDbgOnly(S) do {} while(0); +#endif + +std::vector executablePages = {}; + +void PageExceptionInitialEnum() +{ + SYSTEM_INFO sysInfo; + GetSystemInfo(&sysInfo); + size_t pageSize = sysInfo.dwPageSize; + + HMODULE hMainModule; + MODULEINFO moduleInfo; + + MEMORY_BASIC_INFORMATION memInfo = { 0 }; + + // Get the main module handle from an address stored within it (pointer to this method) + if (GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCWSTR)PageExceptionBreakpointCheck, &hMainModule)) + { + // Get information about the main module (we want to know the size of it) + if (GetModuleInformation(GetCurrentProcess(), hMainModule, &moduleInfo, sizeof(MODULEINFO))) + { + // cast the module to a pointer + unsigned char* module = static_cast(moduleInfo.lpBaseOfDll); + for (size_t ofs = 0; ofs < moduleInfo.SizeOfImage; ofs += pageSize) + { + if (VirtualQuery(module + ofs, &memInfo, sizeof(MEMORY_BASIC_INFORMATION)) >= sizeof(MEMORY_BASIC_INFORMATION)) + { + if ((memInfo.Protect & PAGE_EXECUTE) == PAGE_EXECUTE || + (memInfo.Protect & PAGE_EXECUTE_READ) == PAGE_EXECUTE_READ || + (memInfo.Protect & PAGE_EXECUTE_WRITECOPY) == PAGE_EXECUTE_WRITECOPY || + (memInfo.Protect & PAGE_EXECUTE_READWRITE) == PAGE_EXECUTE_READWRITE) + { + executablePages.push_back(module + ofs); + } + } + } + } + } +} + +BOOL PageExceptionBreakpointCheck() +{ + SYSTEM_INFO sysInfo; + GetSystemInfo(&sysInfo); + size_t pageSize = sysInfo.dwPageSize; + + HMODULE hMainModule; + MODULEINFO moduleInfo; + + MEMORY_BASIC_INFORMATION memInfo = { 0 }; + + wchar_t buffer[512]; + + // first we check if any of the pages are executable+guard or noaccess + + // Get the main module handle from an address stored within it (pointer to this method) + if (GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCWSTR)PageExceptionBreakpointCheck, &hMainModule)) + { + // Get information about the main module (we want to know the size of it) + if (GetModuleInformation(GetCurrentProcess(), hMainModule, &moduleInfo, sizeof(MODULEINFO))) + { + // cast the module to a pointer + unsigned char* module = static_cast(moduleInfo.lpBaseOfDll); + for (size_t ofs = 0; ofs < moduleInfo.SizeOfImage; ofs += pageSize) + { + SecureZeroMemory(buffer, 512); + wsprintf(buffer, L"Scanning %p... ", module + ofs); + OutputDebugStringDbgOnly(buffer); + if (VirtualQuery(module + ofs, &memInfo, sizeof(MEMORY_BASIC_INFORMATION)) >= sizeof(MEMORY_BASIC_INFORMATION)) + { + if (memInfo.AllocationProtect == 0) + OutputDebugStringDbgOnly(L"^ AllocationProtect is zero. Potential shenanigans."); + if (memInfo.Protect == 0) + OutputDebugStringDbgOnly(L"^ Protect is zero. Potential shenanigans."); + + if ((memInfo.Protect & PAGE_EXECUTE) == PAGE_EXECUTE || + (memInfo.Protect & PAGE_EXECUTE_READ) == PAGE_EXECUTE_READ || + (memInfo.Protect & PAGE_EXECUTE_WRITECOPY) == PAGE_EXECUTE_WRITECOPY || + (memInfo.Protect & PAGE_EXECUTE_READWRITE) == PAGE_EXECUTE_READWRITE) + { + // this is an executable page + OutputDebugStringDbgOnly(L"^ is executable."); + + if ((memInfo.Protect & PAGE_GUARD) == PAGE_GUARD || + (memInfo.AllocationProtect & PAGE_GUARD) == PAGE_GUARD) + { + // this is an executable guard page, page exception debugging detected + OutputDebugStringDbgOnly(L"^ is guard page !!!!!!"); + return TRUE; + } + } + + if ((memInfo.Protect & PAGE_NOACCESS) == PAGE_NOACCESS) + { + // this is a NOACCESS page, which shouldn't exist here (alternative way to set page exception BPs) + OutputDebugStringDbgOnly(L"^ is NOACCESS !!!!!!!"); + return TRUE; + } + } + else OutputDebugStringDbgOnly(L"^ FAILED!"); + } + } + + OutputDebugStringDbgOnly(L"Moving on to delta check..."); + + for (PVOID page : executablePages) + { + SecureZeroMemory(buffer, 512); + wsprintf(buffer, L"Scanning delta for %p... ", page); + OutputDebugStringDbgOnly(buffer); + + if (VirtualQuery(page, &memInfo, sizeof(MEMORY_BASIC_INFORMATION)) >= sizeof(MEMORY_BASIC_INFORMATION)) + { + if (memInfo.AllocationProtect == 0) + OutputDebugStringDbgOnly(L"^ AllocationProtect is zero. Potential shenanigans."); + if (memInfo.Protect == 0) + OutputDebugStringDbgOnly(L"^ Protect is zero. Potential shenanigans."); + + if (!((memInfo.Protect & PAGE_EXECUTE) == PAGE_EXECUTE || + (memInfo.Protect & PAGE_EXECUTE_READ) == PAGE_EXECUTE_READ || + (memInfo.Protect & PAGE_EXECUTE_WRITECOPY) == PAGE_EXECUTE_WRITECOPY || + (memInfo.Protect & PAGE_EXECUTE_READWRITE) == PAGE_EXECUTE_READWRITE)) + { + // page was executable, now isn't! + OutputDebugStringDbgOnly(L"^ was executable, now isn't !!!!!!"); + return TRUE; + } + } + } + } + + return FALSE; +} \ No newline at end of file diff --git a/byp/sbexecution/AntiDebug/PageExceptionBreakpointCheck.h b/byp/sbexecution/AntiDebug/PageExceptionBreakpointCheck.h new file mode 100644 index 00000000..08302c9b --- /dev/null +++ b/byp/sbexecution/AntiDebug/PageExceptionBreakpointCheck.h @@ -0,0 +1,4 @@ +#pragma once + +void PageExceptionInitialEnum(); +BOOL PageExceptionBreakpointCheck(); diff --git a/byp/sbexecution/AntiDebug/ParentProcess.cpp b/byp/sbexecution/AntiDebug/ParentProcess.cpp new file mode 100644 index 00000000..87f21b31 --- /dev/null +++ b/byp/sbexecution/AntiDebug/ParentProcess.cpp @@ -0,0 +1,85 @@ +#include "pch.h" +#include "ParentProcess.h" + +#define _SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING +#include + +DWORD GetExplorerPIDbyShellWindow() +{ + DWORD dwProcessId = 0; + + // Get the PID of explorer by its windows handle + GetWindowThreadProcessId(GetShellWindow(), &dwProcessId); + + return dwProcessId; +} + +DWORD GetParentProcessId() +{ + auto NtQueryInfoProcess = static_cast(API::GetAPI(API_IDENTIFIER::API_NtQueryInformationProcess)); + + NTSTATUS Status = 0; + ALK_PROCESS_BASIC_INFORMATION pbi; + SecureZeroMemory(&pbi, sizeof(ALK_PROCESS_BASIC_INFORMATION)); + + const UINT ProcessBasicInformation = 0; + + Status = NtQueryInfoProcess(GetCurrentProcess(), ProcessBasicInformation, (PVOID)&pbi, sizeof(ALK_PROCESS_BASIC_INFORMATION), 0); + + if (Status != 0) + { + return 0; + } + else + { + return (DWORD)pbi.ParentProcessId; + } +} + +BOOL IsParentExplorerExe() +{ + // this check will throw a false positive if you're running an alternative shell. + + DWORD parentPid = GetParentProcessId(); + + bool parentPidEqualsExplorerPid = false; + + if (parentPid > 0) + { + // first check + HANDLE hParent = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, parentPid); + if (hParent != INVALID_HANDLE_VALUE) + { + WCHAR winDir[MAX_PATH]; + WCHAR parentProcessPath[MAX_PATH]; + if (GetModuleFileNameExW(hParent, NULL, parentProcessPath, MAX_PATH) && GetWindowsDirectory(winDir, MAX_PATH)) + { + CloseHandle(hParent); + + // get path to X:\Windows\explorer.exe + auto expectedPath = std::experimental::filesystem::path(winDir); + expectedPath = expectedPath.append("explorer.exe"); + + // get path to parent process + auto actualPath = std::experimental::filesystem::path(parentProcessPath); + + // if the paths are equivalent, no detection. + return std::experimental::filesystem::equivalent(expectedPath, actualPath) ? FALSE : TRUE; + } + CloseHandle(hParent); + } + + // if the first check couldn't be completed, fall back to the shell window approach. + // this check is less ideal because it throws false positives if you have explorer process isolation enabled (i.e. one process per explorer window) + DWORD explorerPid = GetExplorerPIDbyShellWindow(); + if (explorerPid > 0) + { + if (parentPid != explorerPid) + { + return TRUE; + } + } + } + + return FALSE; +} diff --git a/byp/sbexecution/AntiDebug/ParentProcess.h b/byp/sbexecution/AntiDebug/ParentProcess.h new file mode 100644 index 00000000..6e4a32b2 --- /dev/null +++ b/byp/sbexecution/AntiDebug/ParentProcess.h @@ -0,0 +1,11 @@ +#pragma once + +typedef struct _ALK_PROCESS_BASIC_INFORMATION { + PVOID Reserved1; + void* PebBaseAddress; + PVOID Reserved2[2]; + ULONG_PTR UniqueProcessId; + ULONG_PTR ParentProcessId; +} ALK_PROCESS_BASIC_INFORMATION; + +BOOL IsParentExplorerExe(); \ No newline at end of file diff --git a/byp/sbexecution/AntiDebug/ProcessHeap_Flags.cpp b/byp/sbexecution/AntiDebug/ProcessHeap_Flags.cpp new file mode 100644 index 00000000..22887fa7 --- /dev/null +++ b/byp/sbexecution/AntiDebug/ProcessHeap_Flags.cpp @@ -0,0 +1,66 @@ +#include "pch.h" + +#include "ProcessHeap_Flags.h" + +/* +When a program is run under a debugger, and is created using the debug process creation flags, the heap flags are changed. +These Flags exit at a different location depending upon the version of the operating system. +On Windows XP, these flags exist at 0x0C offset from heap base in 32bit system and offset 0x14 in 64bits +On Windows 7, these flags exist at 0x40 offset from heap base in 32bit system and offset 0x70 in 64bits. +*/ + +#if defined (ENV64BIT) +PUINT32 GetHeapFlags_x64() +{ + PINT64 pProcessHeap = NULL; + PUINT32 pHeapFlags = NULL; + if (IsWindowsVistaOrGreater()){ + pProcessHeap = (PINT64)(__readgsqword(0x60) + 0x30); + pHeapFlags = (PUINT32)(*pProcessHeap + 0x70); + } + + else { + pProcessHeap = (PINT64)(__readgsqword(0x60) + 0x30); + pHeapFlags = (PUINT32)(*pProcessHeap + 0x14); + } + + return pHeapFlags; +} + +#elif defined(ENV32BIT) +PUINT32 GetHeapFlags_x86() +{ + PUINT32 pProcessHeap, pHeapFlags = NULL; + + if (IsWindowsVistaOrGreater()){ + pProcessHeap = (PUINT32)(__readfsdword(0x30) + 0x18); + pHeapFlags = (PUINT32)(*pProcessHeap + 0x40); + } + + else { + pProcessHeap = (PUINT32)(__readfsdword(0x30) + 0x18); + pHeapFlags = (PUINT32)(*pProcessHeap + 0x0C); + } + + return pHeapFlags; +} +#endif + + +BOOL HeapFlags() +{ + PUINT32 pHeapFlags = NULL; + +#if defined (ENV64BIT) + pHeapFlags = GetHeapFlags_x64(); + +#elif defined(ENV32BIT) + pHeapFlags = GetHeapFlags_x86(); + +#endif + + if (*pHeapFlags > 2) + return TRUE; + else + return FALSE; +} diff --git a/byp/sbexecution/AntiDebug/ProcessHeap_Flags.h b/byp/sbexecution/AntiDebug/ProcessHeap_Flags.h new file mode 100644 index 00000000..0c0bb895 --- /dev/null +++ b/byp/sbexecution/AntiDebug/ProcessHeap_Flags.h @@ -0,0 +1,3 @@ +#pragma once + +BOOL HeapFlags(); \ No newline at end of file diff --git a/byp/sbexecution/AntiDebug/ProcessHeap_ForceFlags.cpp b/byp/sbexecution/AntiDebug/ProcessHeap_ForceFlags.cpp new file mode 100644 index 00000000..485274f4 --- /dev/null +++ b/byp/sbexecution/AntiDebug/ProcessHeap_ForceFlags.cpp @@ -0,0 +1,68 @@ +#include "pch.h" + +#include "ProcessHeap_ForceFlags.h" + +/* +When a program is run under a debugger, and is created using the debug process creation flags. The heap flags are changed. +These Flags exit at a different location depending upon the version of the operating system. +On Windows XP, these flags exist at 0x10 offset from heap base in 32bit system and offset 0x18 in bits. +On Windows 7, these flags exist at 0x44 offset from heap base in 32bit system and offset 0x74 in 64bits. +*/ + + +#if defined (ENV64BIT) +PUINT32 GetForceFlags_x64() +{ + PINT64 pProcessHeap = NULL; + PUINT32 pHeapForceFlags = NULL; + if (IsWindowsVistaOrGreater()){ + pProcessHeap = (PINT64)(__readgsqword(0x60) + 0x30); + pHeapForceFlags = (PUINT32)(*pProcessHeap + 0x74); + } + + else { + pProcessHeap = (PINT64)(__readgsqword(0x60) + 0x30); + pHeapForceFlags = (PUINT32)(*pProcessHeap + 0x18); + } + + return pHeapForceFlags; +} + +#elif defined(ENV32BIT) +PUINT32 GetForceFlags_x86() +{ + PUINT32 pProcessHeap, pHeapForceFlags = NULL; + if (IsWindowsVistaOrGreater()) + { + pProcessHeap = (PUINT32)(__readfsdword(0x30) + 0x18); + pHeapForceFlags = (PUINT32)(*pProcessHeap + 0x44); + + } + + else { + pProcessHeap = (PUINT32)(__readfsdword(0x30) + 0x18); + pHeapForceFlags = (PUINT32)(*pProcessHeap + 0x10); + } + + return pHeapForceFlags; +} +#endif + +BOOL HeapForceFlags() +{ + PUINT32 pHeapForceFlags = NULL; + +#if defined (ENV64BIT) + pHeapForceFlags = GetForceFlags_x64(); + +#elif defined(ENV32BIT) + pHeapForceFlags = GetForceFlags_x86(); + +#endif + + if (*pHeapForceFlags > 0) + return TRUE; + else + return FALSE; + +} diff --git a/byp/sbexecution/AntiDebug/ProcessHeap_ForceFlags.h b/byp/sbexecution/AntiDebug/ProcessHeap_ForceFlags.h new file mode 100644 index 00000000..99c4181b --- /dev/null +++ b/byp/sbexecution/AntiDebug/ProcessHeap_ForceFlags.h @@ -0,0 +1,3 @@ +#pragma once + +BOOL HeapForceFlags(); \ No newline at end of file diff --git a/byp/sbexecution/AntiDebug/ProcessJob.cpp b/byp/sbexecution/AntiDebug/ProcessJob.cpp new file mode 100644 index 00000000..26513f4f --- /dev/null +++ b/byp/sbexecution/AntiDebug/ProcessJob.cpp @@ -0,0 +1,78 @@ +#include "pch.h" + +#include "ProcessJob.h" + +/* + * ProcessJob - Contributed by Graham Sutherland (https://github.com/gsuberland) + * + * Checks whether the process is part of a job object and, if so, any non-whitelisted processes are part of that job. + * + * Debuggers and other analysis applications usually place processes inside a job so that child processes will exit + * when the parent process exits. + * You can observe this with Visual Studio by running al-khaser with Debug -> Start Without Debugging. + * + */ + +BOOL ProcessJob() +{ + BOOL foundProblem = FALSE; + + DWORD jobProcessStructSize = sizeof(JOBOBJECT_BASIC_PROCESS_ID_LIST) + sizeof(ULONG_PTR) * 1024; + JOBOBJECT_BASIC_PROCESS_ID_LIST* jobProcessIdList = static_cast(malloc(jobProcessStructSize)); + + if (jobProcessIdList) { + + SecureZeroMemory(jobProcessIdList, jobProcessStructSize); + + jobProcessIdList->NumberOfProcessIdsInList = 1024; + + if (QueryInformationJobObject(NULL, JobObjectBasicProcessIdList, jobProcessIdList, jobProcessStructSize, NULL)) + { + int ok_processes = 0; + for (DWORD i = 0; i < jobProcessIdList->NumberOfAssignedProcesses; i++) + { + ULONG_PTR processId = jobProcessIdList->ProcessIdList[i]; + + // is this the current process? if so that's ok + if (processId == (ULONG_PTR)GetCurrentProcessId()) + { + ok_processes++; + } + else + { + + // find the process name for this job process + HANDLE hJobProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, (DWORD)processId); + if (hJobProcess != NULL) + { + const int processNameBufferSize = 4096; + LPTSTR processName = static_cast(malloc(sizeof(TCHAR) * processNameBufferSize)); + if (processName) { + SecureZeroMemory(processName, sizeof(TCHAR) * processNameBufferSize); + + if (GetProcessImageFileName(hJobProcess, processName, processNameBufferSize) > 0) + { + String pnStr(processName); + + // ignore conhost.exe (this hosts the al-khaser executable in a console) + if (pnStr.find(String(L"\\Windows\\System32\\conhost.exe")) != std::string::npos) + { + ok_processes++; + } + } + + free(processName); + } + CloseHandle(hJobProcess); + } + } + } + + // if we found other processes in the job other than the current process and conhost, report a problem + foundProblem = ok_processes != jobProcessIdList->NumberOfAssignedProcesses; + } + + free(jobProcessIdList); + } + return foundProblem; +} diff --git a/byp/sbexecution/AntiDebug/ProcessJob.h b/byp/sbexecution/AntiDebug/ProcessJob.h new file mode 100644 index 00000000..de03ba29 --- /dev/null +++ b/byp/sbexecution/AntiDebug/ProcessJob.h @@ -0,0 +1,9 @@ +#pragma once + +#ifndef UNICODE +typedef std::string String; +#else +typedef std::wstring String; +#endif + +BOOL ProcessJob(); \ No newline at end of file diff --git a/byp/sbexecution/AntiDebug/ScanForModules.cpp b/byp/sbexecution/AntiDebug/ScanForModules.cpp new file mode 100644 index 00000000..898eee13 --- /dev/null +++ b/byp/sbexecution/AntiDebug/ScanForModules.cpp @@ -0,0 +1,711 @@ +#include "pch.h" + +#define NUMCHARS(a) (sizeof(a)/sizeof(*a)) + +static HRESULT NormalizeNTPathOld(wchar_t* pszPath, size_t nMax) +// Normalizes the path returned by GetProcessImageFileName +{ + wchar_t* pszSlash = wcschr(&pszPath[1], '\\'); + if (pszSlash) pszSlash = wcschr(pszSlash + 1, '\\'); + if (!pszSlash) + return E_FAIL; + wchar_t cSave = *pszSlash; + *pszSlash = 0; + + wchar_t szNTPath[_MAX_PATH]; + wchar_t szDrive[_MAX_PATH] = L"A:"; + // We'll need to query the NT device names for the drives to find a match with pszPath + for (wchar_t cDrive = 'A'; cDrive < 'Z'; ++cDrive) + { + szDrive[0] = cDrive; + szNTPath[0] = 0; + if (0 != QueryDosDevice(szDrive, szNTPath, NUMCHARS(szNTPath)) && + 0 == _wcsicmp(szNTPath, pszPath)) + { + // Match + wcscat_s(szDrive, NUMCHARS(szDrive), L"\\"); + wcscat_s(szDrive, NUMCHARS(szDrive), pszSlash + 1); + wcscpy_s(pszPath, nMax, szDrive); + return S_OK; + } + } + *pszSlash = cSave; + return E_FAIL; +} + +static HRESULT NormalizeNTPath(TCHAR* pszPath, size_t nMax) +// Normalizes the path returned by GetProcessImageFileName +{ + TCHAR* pszSlash = StrChr(&pszPath[1], '\\'); + if (pszSlash) pszSlash = StrChr(pszSlash + 1, '\\'); + if (!pszSlash) + return E_FAIL; + TCHAR cSave = *pszSlash; + *pszSlash = 0; + + TCHAR szNTPath[_MAX_PATH]; + TCHAR szDrive[_MAX_PATH] = L"A:"; + // We'll need to query the NT device names for the drives to find a match with pszPath + for (TCHAR cDrive = 'A'; cDrive < 'Z'; ++cDrive) + { + szDrive[0] = cDrive; + szNTPath[0] = 0; + if (0 != QueryDosDevice(szDrive, szNTPath, NUMCHARS(szNTPath)) && + 0 == StrCmpI(szNTPath, pszPath)) + { + // Match + StringCbCat(szDrive, NUMCHARS(szDrive), _T("\\")); + StringCbCat(szDrive, NUMCHARS(szDrive), pszSlash + 1); + StringCbCopy(pszPath, nMax, szDrive); + return S_OK; + } + } + *pszSlash = cSave; + return E_FAIL; +} + +bool IsGlobalizationNls(TCHAR* filename) +{ + // exclude this nls + // consider removing this hack with proper implementation of memory scan + PCTSTR ret = StrStrI(filename, _T("\\Windows\\Globalization\\Sorting\\SortDefault.nls")); + return (ret != NULL); +} + +bool IsBadLibrary(TCHAR* filename, DWORD filenameLength) +{ + TCHAR systemDrive[MAX_PATH]; + TCHAR systemDriveDevice[MAX_PATH]; + TCHAR systemRootPath[MAX_PATH]; + TCHAR exePath[MAX_PATH]; + TCHAR normalisedPath[MAX_PATH]; + + if (IsGlobalizationNls(filename)) + return false; + + StringCbCopy(normalisedPath, MAX_PATH, filename); + NormalizeNTPath(normalisedPath, MAX_PATH); + size_t normalisedPathLength = 0; + StringCbLength(normalisedPath, MAX_PATH, &normalisedPathLength); + + if (filenameLength == INVALID_FILE_SIZE) + { + size_t filenameActualLength = 0; + StringCbLength(filename, MAX_PATH, &filenameActualLength); + filenameLength = (DWORD)filenameActualLength; + } + + GetSystemDirectory(systemRootPath, MAX_PATH); + +#ifdef _X86_ + TCHAR syswow64Path[MAX_PATH]; + SHGetFolderPath (NULL, CSIDL_SYSTEMX86, NULL, 0, syswow64Path); + StringCbCat(syswow64Path, MAX_PATH, _T("\\")); + size_t syswow64PathLength = 0; + StringCbLength(syswow64Path, MAX_PATH, &syswow64PathLength); +#endif + + size_t exePathLength = GetProcessImageFileName(GetCurrentProcess(), exePath, MAX_PATH); + NormalizeNTPath(exePath, MAX_PATH); + StringCbLength(exePath, MAX_PATH, &exePathLength); + + + if (GetEnvironmentVariable(_T("SystemDrive"), systemDrive, MAX_PATH) > 0) + { + if (QueryDosDeviceW(systemDrive, systemDriveDevice, MAX_PATH) > 0) + { + StringCbCat(systemDriveDevice, MAX_PATH, _T("\\Windows\\System32\\")); + size_t systemDriveDevicelength = 0; + StringCbLength(systemDriveDevice, MAX_PATH, &systemDriveDevicelength); + + //printf("systemDriveDevice: %S (%d)\n", systemDriveDevice, systemDriveDevicelength); + + if (StrNCmpI(systemDriveDevice, filename, (int)(min(systemDriveDevicelength, filenameLength) / sizeof(TCHAR)) ) == 0) + { + // path matched the NT file path + return false; + } + + StringCbCat(systemRootPath, MAX_PATH, _T("\\")); + size_t systemRootPathLength = 0; + StringCbLength(systemRootPath, MAX_PATH, &systemRootPathLength); + + //printf("systemRootPath: %S (%d)\n", systemRootPath, systemRootPathLength); + + if (StrNCmpI(systemRootPath, normalisedPath, (int)(min(systemRootPathLength, normalisedPathLength) / sizeof(TCHAR)) ) == 0) + { + // path matched the regular system path + return false; + } + +#ifdef _X86_ + if (IsWoW64() && StrNCmpI(syswow64Path, normalisedPath, (int)(min(syswow64PathLength, normalisedPathLength) / sizeof(TCHAR)) ) == 0) + { + // path matched the wow64 system path + return false; + } +#endif + + if (StrCmpI(exePath, normalisedPath) == 0) + { + // path matched the executable path + return false; + } + } + } + return true; +} + +BOOL ScanForModules_EnumProcessModulesEx_Internal(DWORD moduleFlag) +{ + //printf("EnumProcessModulesEx()\n"); + HMODULE* moduleList; + HMODULE* tmp; + DWORD currentSize = 1024 * sizeof(HMODULE); + DWORD requiredSize = 0; + bool anyBadLibs = false; + + // the EnumProcessModulesEx API was moved from psapi.dll into kernel32.dll for Windows 7, then back out afterwards. + // check for availability of either. + if (!API::IsAvailable(API_EnumProcessModulesEx_PSAPI) && !API::IsAvailable(API_EnumProcessModulesEx_Kernel)) + { + // neither available + return FALSE; + } + + // API is available in one of the two libraries, use whichever is available. + pEnumProcessModulesEx fnEnumProcessModulesEx; + if (API::IsAvailable(API_EnumProcessModulesEx_PSAPI)) + { + fnEnumProcessModulesEx = static_cast(API::GetAPI(API_IDENTIFIER::API_EnumProcessModulesEx_PSAPI)); + } + else + { + fnEnumProcessModulesEx = static_cast(API::GetAPI(API_IDENTIFIER::API_EnumProcessModulesEx_Kernel)); + } + + moduleList = static_cast(calloc(1024, sizeof(HMODULE))); + if (moduleList) { + + if (fnEnumProcessModulesEx(GetCurrentProcess(), moduleList, currentSize, &requiredSize, moduleFlag)) + { + bool success = true; + if (requiredSize > currentSize) + { + currentSize = requiredSize; + tmp = static_cast(realloc(moduleList, currentSize)); + if (tmp) { + moduleList = tmp; + if (fnEnumProcessModulesEx(GetCurrentProcess(), moduleList, currentSize, &requiredSize, moduleFlag) == FALSE) + { + success = false; + } + } + else { + success = false; //realloc failed + } + } + if (success) + { + DWORD count = requiredSize / sizeof(HMODULE); + TCHAR moduleName[MAX_PATH]; + for (DWORD i = 0; i < count; i++) + { + DWORD len; + if ((len = GetModuleFileNameEx(GetCurrentProcess(), moduleList[i], moduleName, MAX_PATH)) > 0) + { + bool isBad = IsBadLibrary(moduleName, len); + if (isBad) + printf(" [!] Injected library: %S\n", moduleName); + anyBadLibs |= isBad; + } + } + } + } + + free(moduleList); + } + return anyBadLibs ? TRUE : FALSE; +} + +BOOL ScanForModules_EnumProcessModulesEx_32bit() +{ + return ScanForModules_EnumProcessModulesEx_Internal(LIST_MODULES_32BIT); +} + +BOOL ScanForModules_EnumProcessModulesEx_64bit() +{ + + return ScanForModules_EnumProcessModulesEx_Internal(LIST_MODULES_64BIT); +} + +BOOL ScanForModules_EnumProcessModulesEx_All() +{ + return ScanForModules_EnumProcessModulesEx_Internal(LIST_MODULES_ALL); +} + +BOOL ScanForModules_MemoryWalk_GMI() +{ + // TODO: Convert this to the new enumerate_memory() API for speed! + + MEMORY_BASIC_INFORMATION memInfo = { 0 }; + HMODULE moduleHandle = 0; + TCHAR moduleName[MAX_PATH]; + MODULEINFO moduleInfo = { 0 }; + + auto memoryRegions = enumerate_memory(); + + bool anyBadLibs = false; + + for (PMEMORY_BASIC_INFORMATION region : *memoryRegions) + { + if (region->State == MEM_FREE) + { + delete region; + continue; + } + + PBYTE addr = static_cast(region->BaseAddress); + PBYTE regionEnd = addr + region->RegionSize; + + //printf("Scanning %p - %p ...\n", addr, regionEnd); + + while(addr < regionEnd) + { + bool skippedForward = false; + if (VirtualQuery(addr, &memInfo, sizeof(MEMORY_BASIC_INFORMATION)) >= sizeof(MEMORY_BASIC_INFORMATION)) + { + if (memInfo.State != MEM_FREE) + { + if (GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (TCHAR*)addr, &moduleHandle)) + { + SecureZeroMemory(moduleName, MAX_PATH * sizeof(TCHAR)); + DWORD len = GetModuleFileName(moduleHandle, moduleName, MAX_PATH); + //printf(" [!] %p: %S\n", addr, moduleName); + bool isBad = IsBadLibrary(moduleName, len); + if (isBad) + printf(" [!] Injected library: %S\n", moduleName); + anyBadLibs |= isBad; + + if (GetModuleInformation(GetCurrentProcess(), moduleHandle, &moduleInfo, sizeof(MODULEINFO))) + { + size_t moduleSizeRoundedUp = (moduleInfo.SizeOfImage + 1); + moduleSizeRoundedUp += 4096 - (moduleSizeRoundedUp % 4096); + PBYTE nextPos = static_cast(moduleInfo.lpBaseOfDll) + moduleSizeRoundedUp; + if (nextPos > addr) + { + //printf(" -> Moving from %x to %x\n", addr, nextPos); + addr = nextPos; + skippedForward = true; + } + } + } + } + } + if (!skippedForward) + addr += 4096; + } + delete region; + } + delete memoryRegions; + + return anyBadLibs ? TRUE : FALSE; +} + +BOOL ScanForModules_MemoryWalk_Hidden() +{ + HMODULE moduleHandle = 0; + TCHAR moduleName[MAX_PATH]; + + auto memoryRegions = enumerate_memory(); + + bool anyBadLibs = false; + + bool firstPrint = true; + for (PMEMORY_BASIC_INFORMATION region : *memoryRegions) + { + if (region->State == MEM_FREE) + { + delete region; + continue; + } + + PBYTE addr = static_cast(region->BaseAddress); + PBYTE regionEnd = addr + region->RegionSize; + + //printf("Scanning %p - %p ...\n", addr, regionEnd); + + while (addr < regionEnd) + { + bool skippedForward = false; + + if (GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (TCHAR*)addr, &moduleHandle) == FALSE) + { + // not a known module + if ((region->State & MEM_COMMIT) == MEM_COMMIT && + ((region->Protect == PAGE_READONLY) || + (region->Protect == PAGE_READWRITE) || + (region->Protect == PAGE_EXECUTE_READ) || + (region->Protect == PAGE_EXECUTE_READWRITE) || + (region->Protect == PAGE_EXECUTE_WRITECOPY))) + { + auto moduleData = static_cast(region->BaseAddress); + if (moduleData[0] == 'M' && moduleData[1] == 'Z') + { + if (firstPrint) + { + firstPrint = false; + printf("\n\n"); + + if (IsWoW64()) + { + printf(" [!] Running on WoW64, there will be false positives due to wow64 DLLs.\n"); + } + } + + printf(" [!] Executable at %p\n", region->BaseAddress); + anyBadLibs = true; + } + } + } + else + { + MODULEINFO modInfo = { 0 }; + if (GetModuleInformation(GetCurrentProcess(), moduleHandle, &modInfo, sizeof(MODULEINFO))) + { + size_t moduleSizeRoundedUp = (modInfo.SizeOfImage + 1); + moduleSizeRoundedUp += 4096 - (moduleSizeRoundedUp % 4096); + PBYTE nextPos = static_cast(modInfo.lpBaseOfDll) + moduleSizeRoundedUp; + if (nextPos > addr) + { + //printf(" -> Moving from %x to %x\n", addr, nextPos); + addr = nextPos; + skippedForward = true; + } + } + } + + SecureZeroMemory(moduleName, sizeof(TCHAR)*MAX_PATH); + DWORD len; + if ((len = GetMappedFileName(GetCurrentProcess(), region->AllocationBase, moduleName, MAX_PATH)) > 0) + { + bool isBad = IsBadLibrary(moduleName, len); + if (isBad) + printf(" [!] Injected library: %S\n", moduleName); + anyBadLibs |= isBad; + + // mapped files take up a whole region, so just skip to the end of the region + addr = regionEnd; + skippedForward = true; + } + + if (!skippedForward) + addr += 4096; + } + + delete region; + } + delete memoryRegions; + + return anyBadLibs ? TRUE : FALSE; +} + +BOOL ScanForModules_DotNetModuleStructures() +{ + HMODULE moduleHandle = 0; + TCHAR moduleName[MAX_PATH]; + + auto memoryRegions = enumerate_memory(); + + bool anyBadLibs = false; + + /* + This works because the .NET runtime loads structures into memory that describe modules. This happens even if the module is loaded dynamically, from memory. + If al-khaser were a .NET application we'd need to apply some additional checks on the results, but since it isn't then we can just report every .NET module we find. + This check is quite effective because it catches pretty much any kind of .NET injection, even if the injector uses tricks like messing with PE headers or patching EWT. + */ + + bool firstPrint = true; + for (PMEMORY_BASIC_INFORMATION region : *memoryRegions) + { + if (region->State == MEM_FREE || region->Type == MEM_MAPPED || region->Type == MEM_IMAGE) + { + //printf("region %p skipped for being free, mapped, or image.\n", region->BaseAddress); + delete region; + continue; + } + + if ((region->State & MEM_COMMIT) == MEM_COMMIT && + region->Protect == PAGE_READWRITE && + region->AllocationProtect == PAGE_READWRITE) + { + uint64_t* addr = static_cast(region->BaseAddress); + uint64_t* regionEnd = addr + (region->RegionSize / sizeof(uint64_t)); + + // check first qword at region base address. should be zero. + if (*addr == 0) + { + // find the pattern of QWORDs we want (0, 0, 0, 0, 0, 0, pointer, length, 1, 2, 0, 2, 0, 2, 0) + while (addr < regionEnd - 32) + { + uint64_t* ptr = addr; + bool sixZeroes = true; + for (int i = 0; i < 6; i++) + { + sixZeroes &= *(ptr++) == 0; + } + if (sixZeroes) + { + //printf("got six zeroes at %p\n", ptr); + uint64_t stringPtrVal = *ptr; + PCWSTR stringPtr = reinterpret_cast(*ptr); + ptr++; + uint64_t stringLen = *ptr; + ptr++; + if (*ptr++ == 1 && *ptr++ == 2 && *ptr++ == 0 && *ptr++ == 2 && *ptr++ == 0 && *ptr++ == 2 && *ptr++ == 0) + { + // pattern matches, check string addr + if ((stringPtrVal & 0xFFFFFFFF00000000ULL) == ((uint64_t)ptr & 0xFFFFFFFF00000000ULL)) + { + // check string length is sane + if (stringLen < MAX_PATH * sizeof(wchar_t)) + { + // ok, we're sure it's the right structure. report it. + + if (firstPrint) + { + printf("\n\n"); + } + printf(" [!] Found module: %S (structure address %p)\n", stringPtr, stringPtr); + anyBadLibs = true; + } + } + } + } + addr++; + } + } + } + + delete region; + } + delete memoryRegions; + + return anyBadLibs ? TRUE : FALSE; +} + +std::vector* WalkLDR(PPEB_LDR_DATA ldrData) +{ + auto entryList = new std::vector(); + + LIST_ENTRY* head = ldrData->InMemoryOrderModuleList.Flink; + LIST_ENTRY* node = head; + + do + { + LDR_DATA_TABLE_ENTRY ldrEntry = { 0 }; + LDR_DATA_TABLE_ENTRY* pLdrEntry = CONTAINING_RECORD(node, LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks); + + if (attempt_to_read_memory(pLdrEntry, &ldrEntry, sizeof(ldrEntry))) + { + entryList->push_back(new LDR_DATA_TABLE_ENTRY(ldrEntry)); + + node = ldrEntry.InMemoryOrderLinks.Flink; + } + else + { + printf(" [!] Error reading entry.\n"); + break; + } + } + while (node != head); + + entryList->pop_back(); + + return entryList; +} + +std::vector* WalkLDR(PPEB_LDR_DATA64 ldrData) +{ + auto entryList = new std::vector(); + + LIST_ENTRY64 head; + if (!attempt_to_read_memory_wow64(&head, sizeof(LIST_ENTRY64), ldrData->InMemoryOrderModuleList.Flink)) + { + printf(" [!] Error reading list head.\n"); + } + ULONGLONG nodeAddr = ldrData->InMemoryOrderModuleList.Flink; + LIST_ENTRY64 node = head; + LDR_DATA_TABLE_ENTRY64 ldrEntry = { 0 }; + + do + { + if (attempt_to_read_memory_wow64(&ldrEntry, sizeof(LDR_DATA_TABLE_ENTRY64), nodeAddr - sizeof(LIST_ENTRY64))) + { + entryList->push_back(new LDR_DATA_TABLE_ENTRY64(ldrEntry)); + + if (!attempt_to_read_memory_wow64(&node, sizeof(LIST_ENTRY64), ldrEntry.InMemoryOrderLinks.Flink)) + { + break; + } + + nodeAddr = ldrEntry.InMemoryOrderLinks.Flink; + } + else + { + break; + } + } while (nodeAddr != ldrData->InMemoryOrderModuleList.Flink); + + entryList->pop_back(); + + return entryList; +} + +BOOL ScanForModules_LDR_Direct() +{ + PROCESS_BASIC_INFORMATION pbi = { 0 }; + THREAD_BASIC_INFORMATION tbi = { 0 }; + + //printf("MemoryWalk_LDR()\n"); + + bool anyBadLibs = false; + + auto NtQueryInformationProcess = static_cast(API::GetAPI(API_IDENTIFIER::API_NtQueryInformationProcess)); + NTSTATUS status = NtQueryInformationProcess(GetCurrentProcess(), ProcessBasicInformation, &pbi, sizeof(pbi), nullptr); + if (status != 0) + { + printf("Failed to get process information. Status: %d\n", status); + } + else + { + if (pbi.PebBaseAddress != nullptr) + { + PPEB peb = pbi.PebBaseAddress; + if (peb->Ldr != nullptr) + { + PPEB_LDR_DATA ldrData = peb->Ldr; + + auto ldrEntries = WalkLDR(ldrData); + for (LDR_DATA_TABLE_ENTRY* ldrEntry : *ldrEntries) + { + //printf(" -> %S\n", ldrEntry->FullDllName.Buffer); + bool isBad = IsBadLibrary(ldrEntry->FullDllName.Buffer, ldrEntry->FullDllName.Length); + if (isBad) + printf(" [!] Injected library: %S\n", ldrEntry->FullDllName.Buffer); + anyBadLibs |= isBad; + delete ldrEntry; + } + delete ldrEntries; + } + + if (IsWoW64()) + { + PPEB64 peb64 = reinterpret_cast(GetPeb64()); + PEB_LDR_DATA64 ldrData = { 0 }; + + if (peb64 && attempt_to_read_memory_wow64(&ldrData, sizeof(PEB_LDR_DATA64), peb64->Ldr)) + { + auto ldrEntries = WalkLDR(&ldrData); + for (LDR_DATA_TABLE_ENTRY64* ldrEntry : *ldrEntries) + { + WCHAR* dllNameBuffer = new WCHAR[ldrEntry->FullDllName.Length + 1]; + SecureZeroMemory(dllNameBuffer, (ldrEntry->FullDllName.Length + 1) * sizeof(WCHAR)); + if (attempt_to_read_memory_wow64(dllNameBuffer, ldrEntry->FullDllName.Length * sizeof(WCHAR), ldrEntry->FullDllName.Buffer)) + { + //printf(" -> %S\n", dllNameBuffer); + bool isBad = IsBadLibrary(dllNameBuffer, ldrEntry->FullDllName.Length); + if (isBad) + printf(" [!] Injected library (WOW64): %S\n", dllNameBuffer); + anyBadLibs |= isBad; + } + else + { + printf(" [!] Failed to read module name at %llx.\n", reinterpret_cast(ldrEntry->FullDllName.Buffer)); + } + delete [] dllNameBuffer; + delete ldrEntry; + } + delete ldrEntries; + } + } + } + } + + return anyBadLibs ? TRUE : FALSE; +} + +VOID NTAPI LdrEnumCallback(_In_ PLDR_DATA_TABLE_ENTRY ModuleInformation, _In_ PVOID Parameter, _Out_ BOOLEAN *Stop) +{ + // add ldr entry to table from param + auto ldtEntries = static_cast*>(Parameter); + + ldtEntries->push_back(LDR_DATA_TABLE_ENTRY(*ModuleInformation)); + + Stop = FALSE; +} + +BOOL ScanForModules_LdrEnumerateLoadedModules() +{ + if (!API::IsAvailable(API_IDENTIFIER::API_LdrEnumerateLoadedModules)) + return FALSE; + + auto LdrEnumerateLoadedModules = static_cast(API::GetAPI(API_IDENTIFIER::API_LdrEnumerateLoadedModules)); + + auto ldrEntries = new std::vector(); + + NTSTATUS status; + if ((status = LdrEnumerateLoadedModules(FALSE, &LdrEnumCallback, ldrEntries)) != 0) + { + printf("LdrEnumerateLoadedModules failed. Status: %x\n", status); + delete ldrEntries; + return FALSE; + } + + bool anyBadEntries = false; + for (LDR_DATA_TABLE_ENTRY ldrEntry : *ldrEntries) + { + bool isBad = IsBadLibrary(ldrEntry.FullDllName.Buffer, ldrEntry.FullDllName.Length); + anyBadEntries |= isBad; + } + + delete ldrEntries; + return anyBadEntries ? TRUE : FALSE; +} + +BOOL ScanForModules_ToolHelp32() +{ + bool anyBadLibs = false; + + HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, GetCurrentProcessId()); + //printf("Snapshot: %p\n", snapshot); + if (snapshot == INVALID_HANDLE_VALUE) + { + printf("Failed to get snapshot. Last error: %u\n", GetLastError()); + } + else + { + MODULEENTRY32 module = { 0 }; + module.dwSize = sizeof(MODULEENTRY32); + if (Module32First(snapshot, &module) != FALSE) + { + do + { + bool isBad = IsBadLibrary(module.szExePath, INVALID_FILE_SIZE); + if (isBad) + printf(" [!] Injected library: %S\n", module.szExePath); + anyBadLibs |= isBad; + //printf(" [!] %S\n", module.szModule); + + } while (Module32Next(snapshot, &module) != FALSE); + } + else + { + printf("Failed to get first module. Last error: %u\n", GetLastError()); + } + + CloseHandle(snapshot); + } + + return anyBadLibs ? TRUE : FALSE; +} diff --git a/byp/sbexecution/AntiDebug/ScanForModules.h b/byp/sbexecution/AntiDebug/ScanForModules.h new file mode 100644 index 00000000..8baede0d --- /dev/null +++ b/byp/sbexecution/AntiDebug/ScanForModules.h @@ -0,0 +1,11 @@ +#pragma once + +BOOL ScanForModules_EnumProcessModulesEx_32bit(); +BOOL ScanForModules_EnumProcessModulesEx_64bit(); +BOOL ScanForModules_EnumProcessModulesEx_All(); +BOOL ScanForModules_ToolHelp32(); +BOOL ScanForModules_LDR_Direct(); +BOOL ScanForModules_LdrEnumerateLoadedModules(); +BOOL ScanForModules_MemoryWalk_GMI(); +BOOL ScanForModules_MemoryWalk_Hidden(); +BOOL ScanForModules_DotNetModuleStructures(); diff --git a/byp/sbexecution/AntiDebug/SeDebugPrivilege.cpp b/byp/sbexecution/AntiDebug/SeDebugPrivilege.cpp new file mode 100644 index 00000000..0239ebfc --- /dev/null +++ b/byp/sbexecution/AntiDebug/SeDebugPrivilege.cpp @@ -0,0 +1,36 @@ +#include "pch.h" + +#include "SeDebugPrivilege.h" + +/* +If we're being debugged and the process has SeDebugPrivileges privileges then OpenProcess call will be successful. +This requires administrator privilege ! +In Windows XP, Vista and 7, calling OpenProcess with PROCESS_ALL_ACCESS will fait even with SeDebugPrivilege enabled, +That's why I used PROCESS_QUERY_LIMITED_INFORMATION +*/ + + +DWORD GetCsrssProcessId() +{ + if (API::IsAvailable(API_IDENTIFIER::API_CsrGetProcessId)) + { + auto CsrGetProcessId = static_cast(API::GetAPI(API_IDENTIFIER::API_CsrGetProcessId)); + + return CsrGetProcessId(); + } + else + return GetProcessIdFromName(_T("csrss.exe")); +} + + +BOOL CanOpenCsrss() +{ + HANDLE hCsrss = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, GetCsrssProcessId()); + if (hCsrss != NULL) + { + CloseHandle(hCsrss); + return TRUE; + } + else + return FALSE; +} diff --git a/byp/sbexecution/AntiDebug/SeDebugPrivilege.h b/byp/sbexecution/AntiDebug/SeDebugPrivilege.h new file mode 100644 index 00000000..282f1ee4 --- /dev/null +++ b/byp/sbexecution/AntiDebug/SeDebugPrivilege.h @@ -0,0 +1,3 @@ +#pragma once + +BOOL CanOpenCsrss(); diff --git a/byp/sbexecution/AntiDebug/SetHandleInformation_API.cpp b/byp/sbexecution/AntiDebug/SetHandleInformation_API.cpp new file mode 100644 index 00000000..1efcbd55 --- /dev/null +++ b/byp/sbexecution/AntiDebug/SetHandleInformation_API.cpp @@ -0,0 +1,33 @@ +#include "pch.h" + +#include "SetHandleInformation_API.h" + + +BOOL SetHandleInformatiom_ProtectedHandle() +{ + /* some vars */ + HANDLE hMutex; + + /* Create a mutex so we can get a handle */ + hMutex = CreateMutex(NULL, FALSE, _T("Random name")); + + if (hMutex) { + + /* Protect our handle */ + SetHandleInformation(hMutex, HANDLE_FLAG_PROTECT_FROM_CLOSE, HANDLE_FLAG_PROTECT_FROM_CLOSE); + + + __try { + /* Then, let's try close it */ + CloseHandle(hMutex); + } + + __except (EXCEPTION_EXECUTE_HANDLER) { + return TRUE; + } + + } + + return FALSE; + +} diff --git a/byp/sbexecution/AntiDebug/SetHandleInformation_API.h b/byp/sbexecution/AntiDebug/SetHandleInformation_API.h new file mode 100644 index 00000000..5b2671b0 --- /dev/null +++ b/byp/sbexecution/AntiDebug/SetHandleInformation_API.h @@ -0,0 +1,3 @@ +#pragma once + +BOOL SetHandleInformatiom_ProtectedHandle(); \ No newline at end of file diff --git a/byp/sbexecution/AntiDebug/SharedUserData_KernelDebugger.cpp b/byp/sbexecution/AntiDebug/SharedUserData_KernelDebugger.cpp new file mode 100644 index 00000000..0b310e53 --- /dev/null +++ b/byp/sbexecution/AntiDebug/SharedUserData_KernelDebugger.cpp @@ -0,0 +1,32 @@ +#include "pch.h" + +#include "SharedUserData_KernelDebugger.h" + +/* +NtQuerySystemInformation can be used to detect the presence of a kernel debugger. However, the +same information can be obtained from user mode with no system calls at all. This is done by +reading from the KUSER_SHARED_DATA struct, which is has a fixed user mode address of 0x7FFE0000 in all versions +of Windows in both 32 and 64 bit. In kernel mode it is located at 0xFFDF0000 (32 bit) or 0xFFFFF78000000000 (64 bit). +Detailed information about KUSER_SHARED_DATA can be found here: http://www.geoffchappell.com/studies/windows/km/ntoskrnl/structs/kuser_shared_data.htm +*/ + +BOOL SharedUserData_KernelDebugger() +{ + // The fixed user mode address of KUSER_SHARED_DATA + const ULONG_PTR UserSharedData = 0x7FFE0000; + + // UserSharedData->KdDebuggerEnabled is a BOOLEAN according to ntddk.h, which gives the false impression that it is + // either true or false. However, this field is actually a set of bit flags, and is only zero if no debugger is present. + const UCHAR KdDebuggerEnabledByte = *(UCHAR*)(UserSharedData + 0x2D4); // 0x2D4 = the offset of the field + + // Extract the flags. + // The meaning of these is the same as in NtQuerySystemInformation(SystemKernelDebuggerInformation). + // Normally if a debugger is attached, KdDebuggerEnabled is true, KdDebuggerNotPresent is false and the byte is 0x3. + const BOOLEAN KdDebuggerEnabled = (KdDebuggerEnabledByte & 0x1) == 0x1; + const BOOLEAN KdDebuggerNotPresent = (KdDebuggerEnabledByte & 0x2) == 0; + + if (KdDebuggerEnabled || !KdDebuggerNotPresent) + return TRUE; + + return FALSE; +} diff --git a/byp/sbexecution/AntiDebug/SharedUserData_KernelDebugger.h b/byp/sbexecution/AntiDebug/SharedUserData_KernelDebugger.h new file mode 100644 index 00000000..991ed19a --- /dev/null +++ b/byp/sbexecution/AntiDebug/SharedUserData_KernelDebugger.h @@ -0,0 +1,3 @@ +#pragma once + +BOOL SharedUserData_KernelDebugger(); \ No newline at end of file diff --git a/byp/sbexecution/AntiDebug/SoftwareBreakpoints.cpp b/byp/sbexecution/AntiDebug/SoftwareBreakpoints.cpp new file mode 100644 index 00000000..83f5d32c --- /dev/null +++ b/byp/sbexecution/AntiDebug/SoftwareBreakpoints.cpp @@ -0,0 +1,44 @@ +#include "pch.h" + +#include "SoftwareBreakpoints.h" + + +/* +Software breakpoints aka INT 3 represented in the IA-32 instruction set with the opcode CC (0xCC). +Given a memory addresse and size, it is relatively simple to scan for the byte 0xCC -> if(pTmp[i] == 0xCC) +An obfuscated method would be to check if our memory byte xored with 0x55 is equal 0x99 for example ... +*/ + +VOID My_Critical_Function() +{ + int a = 1; + int b = 2; + int c = a + b; + _tprintf(_T("I am critical function, you should protect against int3 bps %d"), c); +} + + +VOID Myfunction_Adresss_Next() +{ + My_Critical_Function(); + /* + There is no guaranteed way of determining the size of a function at run time(and little reason to do so) + however if you assume that the linker located functions that are adjacent in the source code sequentially in memory, + then the following may give an indication of the size of a function Critical_Function by using : + int Critical_Function_length = (int)Myfunction_Adresss_Next - (int)Critical_Function + Works only if you compile the file in Release mode. + */ +}; + +BOOL SoftwareBreakpoints() +{ + //NOTE this check might not work on x64 because of alignment 0xCC bytes + size_t sSizeToCheck = (size_t)(Myfunction_Adresss_Next)-(size_t)(My_Critical_Function); + PUCHAR Critical_Function = (PUCHAR)My_Critical_Function; + + for (size_t i = 0; i < sSizeToCheck; i++) { + if (Critical_Function[i] == 0xCC) // Adding another level of indirection : 0xCC xor 0x55 = 0x99 + return TRUE; + } + return FALSE; +} diff --git a/byp/sbexecution/AntiDebug/SoftwareBreakpoints.h b/byp/sbexecution/AntiDebug/SoftwareBreakpoints.h new file mode 100644 index 00000000..3a12214f --- /dev/null +++ b/byp/sbexecution/AntiDebug/SoftwareBreakpoints.h @@ -0,0 +1,3 @@ +#pragma once + +BOOL SoftwareBreakpoints(); diff --git a/byp/sbexecution/AntiDebug/TLS_callbacks.cpp b/byp/sbexecution/AntiDebug/TLS_callbacks.cpp new file mode 100644 index 00000000..73121bfc --- /dev/null +++ b/byp/sbexecution/AntiDebug/TLS_callbacks.cpp @@ -0,0 +1,136 @@ +#include "pch.h" + +#include "TLS_callbacks.h" + +// The Thread Local Storage (TLS) callback is called before the execution of the EntryPoint of the application +// Malware takes advantages to perform anti-debug and anti-vm checks. +// There could be more than one callback, and sometimes, inside one call back, one can create one in the fly. + + +volatile bool has_run = false; + +VOID WINAPI tls_callback(PVOID hModule, DWORD dwReason, PVOID pContext) +{ + if (!has_run) + { + has_run = true; + tls_callback_thread_event = CreateEvent(NULL, FALSE, FALSE, NULL); + tls_callback_process_event = CreateEvent(NULL, FALSE, FALSE, NULL); + } + + if (dwReason == DLL_THREAD_ATTACH) + { + OutputDebugString(L"TLS callback: thread attach"); + tls_callback_thread_data = 0xDEADBEEF; + SetEvent(tls_callback_thread_event); + } + + if (dwReason == DLL_PROCESS_ATTACH) + { + OutputDebugString(L"TLS callback: process attach"); + tls_callback_process_data = 0xDEADBEEF; + SetEvent(tls_callback_process_event); + } +} + +DWORD WINAPI TLSCallbackDummyThread( + _In_ LPVOID lpParameter +) +{ + OutputDebugString(L"TLS callback: dummy thread launched"); + return 0; +} + +BOOL TLSCallbackThread() +{ + const int BLOWN = 1000; + + if (CreateThread(NULL, 0, &TLSCallbackDummyThread, NULL, 0, NULL) == NULL) + { + OutputDebugString(L"TLS callback: couldn't start dummy thread"); + } + + int fuse = 0; + while (tls_callback_thread_event == NULL && ++fuse != BLOWN) { SwitchToThread(); } + if (fuse >= BLOWN) + { + OutputDebugString(L"TLSCallbackThread timeout on event creation."); + return TRUE; + } + + DWORD waitStatus = WaitForSingleObject(tls_callback_thread_event, 5000); + if (waitStatus != WAIT_OBJECT_0) + { + if (waitStatus == WAIT_FAILED) + OutputDebugString(L"TLSCallbackThread wait failed."); + else if (waitStatus == WAIT_ABANDONED) + OutputDebugString(L"TLSCallbackThread wait abandoned."); + else + OutputDebugString(L"TLSCallbackThread timeout on event wait."); + return TRUE; + } + + if (tls_callback_thread_data != 0xDEADBEEF) + OutputDebugString(L"TLSCallbackThread data did not match."); + else + OutputDebugString(L"All seems fine for TLSCallbackThread."); + + return tls_callback_thread_data == 0xDEADBEEF ? FALSE : TRUE; +} + +BOOL TLSCallbackProcess() +{ + const int BLOWN = 1000; + + int fuse = 0; + while (tls_callback_process_event == NULL && ++fuse != BLOWN) { SwitchToThread(); } + if (fuse >= BLOWN) + { + OutputDebugString(L"TLSCallbackProcess timeout on event creation."); + return TRUE; + } + + DWORD waitStatus = WaitForSingleObject(tls_callback_process_event, 5000); + if (waitStatus != WAIT_OBJECT_0) + { + if (waitStatus == WAIT_FAILED) + OutputDebugString(L"TLSCallbackProcess wait failed."); + else if (waitStatus == WAIT_ABANDONED) + OutputDebugString(L"TLSCallbackProcess wait abandoned."); + else + OutputDebugString(L"TLSCallbackProcess timeout on event wait."); + return TRUE; + } + + if (tls_callback_process_data != 0xDEADBEEF) + OutputDebugString(L"TLSCallbackProcess data did not match."); + else + OutputDebugString(L"All seems fine for TLSCallbackProcess."); + + return tls_callback_process_data == 0xDEADBEEF ? FALSE : TRUE; +} + +#ifdef _WIN64 + #pragma comment (linker, "/INCLUDE:_tls_used") + #pragma comment (linker, "/INCLUDE:tls_callback_func") +#else + #pragma comment (linker, "/INCLUDE:__tls_used") + #pragma comment (linker, "/INCLUDE:_tls_callback_func") +#endif + + +#ifdef _WIN64 + #pragma const_seg(".CRT$XLF") + EXTERN_C const +#else + #pragma data_seg(".CRT$XLF") + EXTERN_C +#endif + +PIMAGE_TLS_CALLBACK tls_callback_func = tls_callback; + +#ifdef _WIN64 + #pragma const_seg() +#else + #pragma data_seg() +#endif //_WIN64 diff --git a/byp/sbexecution/AntiDebug/TLS_callbacks.h b/byp/sbexecution/AntiDebug/TLS_callbacks.h new file mode 100644 index 00000000..0575d201 --- /dev/null +++ b/byp/sbexecution/AntiDebug/TLS_callbacks.h @@ -0,0 +1,10 @@ +#pragma once + +static volatile HANDLE tls_callback_thread_event = 0; +static volatile HANDLE tls_callback_process_event = 0; +static volatile UINT32 tls_callback_thread_data = 0; +static volatile UINT32 tls_callback_process_data = 0; + +VOID WINAPI tls_callback(PVOID hModule, DWORD dwReason, PVOID pContext); +BOOL TLSCallbackThread(); +BOOL TLSCallbackProcess(); diff --git a/byp/sbexecution/AntiDebug/TrapFlag.cpp b/byp/sbexecution/AntiDebug/TrapFlag.cpp new file mode 100644 index 00000000..6eddf650 --- /dev/null +++ b/byp/sbexecution/AntiDebug/TrapFlag.cpp @@ -0,0 +1,51 @@ +#include "pch.h" + +#include "TrapFlag.h" + +/* + This technique is similar to exceptions based debugger detections. + You enable the trap flag in the current process and check whether + an exception is raised or not. If an exception is not raised, you + can assume that a debugger has “swallowed” the exception for us, + and that the program is being traced. The beauty of this approach + is that it detects every debugger, user mode or kernel mode, + because they all use the trap flag for tracing a program. + + Vectored Exception Handling is used here because SEH is an + anti-debug trick in itself. +*/ + +static BOOL SwallowedException = TRUE; + +static LONG CALLBACK VectoredHandler( + _In_ PEXCEPTION_POINTERS ExceptionInfo +) +{ + SwallowedException = FALSE; + + if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_SINGLE_STEP) + return EXCEPTION_CONTINUE_EXECUTION; + + return EXCEPTION_CONTINUE_SEARCH; +} + + + +BOOL TrapFlag() +{ + PVOID Handle = AddVectoredExceptionHandler(1, VectoredHandler); + SwallowedException = TRUE; + +#ifdef _WIN64 + UINT64 eflags = __readeflags(); +#else + UINT eflags = __readeflags(); +#endif + + // Set the trap flag + eflags |= 0x100; + __writeeflags(eflags); + + RemoveVectoredExceptionHandler(Handle); + return SwallowedException; +} diff --git a/byp/sbexecution/AntiDebug/TrapFlag.h b/byp/sbexecution/AntiDebug/TrapFlag.h new file mode 100644 index 00000000..d36c23aa --- /dev/null +++ b/byp/sbexecution/AntiDebug/TrapFlag.h @@ -0,0 +1,3 @@ +#pragma once + +BOOL TrapFlag(); \ No newline at end of file diff --git a/byp/sbexecution/AntiDebug/UnhandledExceptionFilter_Handler.cpp b/byp/sbexecution/AntiDebug/UnhandledExceptionFilter_Handler.cpp new file mode 100644 index 00000000..bbcee11a --- /dev/null +++ b/byp/sbexecution/AntiDebug/UnhandledExceptionFilter_Handler.cpp @@ -0,0 +1,27 @@ +#include "pch.h" +#include "UnhandledExceptionFilter_Handler.h" + + +/* +When an exception occurs, and no registered Exception Handlers exist (neither Structured nor +Vectored), or if none of the registered handlers handles the exception, then the kernel32 +UnhandledExceptionFilter() function will be called as a last resort. +*/ + +BOOL bIsBeinDbg = TRUE; + +LONG WINAPI UnhandledExcepFilter(PEXCEPTION_POINTERS pExcepPointers) +{ + // If a debugger is present, then this function will not be reached. + bIsBeinDbg = FALSE; + return EXCEPTION_CONTINUE_EXECUTION; +} + + +BOOL UnhandledExcepFilterTest () +{ + LPTOP_LEVEL_EXCEPTION_FILTER Top = SetUnhandledExceptionFilter(UnhandledExcepFilter); + RaiseException(EXCEPTION_FLT_DIVIDE_BY_ZERO, 0, 0, NULL); + SetUnhandledExceptionFilter(Top); + return bIsBeinDbg; +} diff --git a/byp/sbexecution/AntiDebug/UnhandledExceptionFilter_Handler.h b/byp/sbexecution/AntiDebug/UnhandledExceptionFilter_Handler.h new file mode 100644 index 00000000..97a76d7a --- /dev/null +++ b/byp/sbexecution/AntiDebug/UnhandledExceptionFilter_Handler.h @@ -0,0 +1,3 @@ +#pragma once + +BOOL UnhandledExcepFilterTest(); \ No newline at end of file diff --git a/byp/sbexecution/AntiDebug/WUDF_IsDebuggerPresent.cpp b/byp/sbexecution/AntiDebug/WUDF_IsDebuggerPresent.cpp new file mode 100644 index 00000000..3a8e24b1 --- /dev/null +++ b/byp/sbexecution/AntiDebug/WUDF_IsDebuggerPresent.cpp @@ -0,0 +1,35 @@ +#include "pch.h" +#include "WUDF_IsDebuggerPresent.h" + +BOOL WUDF_IsAnyDebuggerPresent() +{ + if (API::IsAvailable(API_IDENTIFIER::API_WudfIsAnyDebuggerPresent)) + { + auto WudfIsAnyDebuggerPresent = static_cast(API::GetAPI(API_IDENTIFIER::API_WudfIsAnyDebuggerPresent)); + return WudfIsAnyDebuggerPresent() == 0 ? FALSE : TRUE; + } + else + return FALSE; +} + +BOOL WUDF_IsKernelDebuggerPresent() +{ + if (API::IsAvailable(API_IDENTIFIER::API_WudfIsKernelDebuggerPresent)) + { + auto WudfIsKernelDebuggerPresent = static_cast(API::GetAPI(API_IDENTIFIER::API_WudfIsKernelDebuggerPresent)); + return WudfIsKernelDebuggerPresent() == 0 ? FALSE : TRUE; + } + else + return FALSE; +} + +BOOL WUDF_IsUserDebuggerPresent() +{ + if (API::IsAvailable(API_IDENTIFIER::API_WudfIsUserDebuggerPresent)) + { + auto WudfIsUserDebuggerPresent = static_cast(API::GetAPI(API_IDENTIFIER::API_WudfIsUserDebuggerPresent)); + return WudfIsUserDebuggerPresent() == 0 ? FALSE : TRUE; + } + else + return FALSE; +} diff --git a/byp/sbexecution/AntiDebug/WUDF_IsDebuggerPresent.h b/byp/sbexecution/AntiDebug/WUDF_IsDebuggerPresent.h new file mode 100644 index 00000000..8f6e96e9 --- /dev/null +++ b/byp/sbexecution/AntiDebug/WUDF_IsDebuggerPresent.h @@ -0,0 +1,3 @@ +BOOL WUDF_IsAnyDebuggerPresent(); +BOOL WUDF_IsKernelDebuggerPresent(); +BOOL WUDF_IsUserDebuggerPresent(); diff --git a/byp/sbexecution/AntiDebug/WriteWatch.cpp b/byp/sbexecution/AntiDebug/WriteWatch.cpp new file mode 100644 index 00000000..0a12d52d --- /dev/null +++ b/byp/sbexecution/AntiDebug/WriteWatch.cpp @@ -0,0 +1,296 @@ +#include "pch.h" +#include "WriteWatch.h" + +/* + * This check uses the MEM_WRITE_WATCH feature of VirtualAlloc to test for additional memory writes by debuggers, sandboxing, etc. + * There are a few ways that we can exploit this: + * (1) Allocate a buffer, write it once, get the count, see if it's >1 + * (2) Allocate a buffer, pass it to an API where we know the buffer isn't touched (e.g. call with invalid parameter) and see if the count is >0 + * (3) Allocate a buffer, use it to store a result of a call we care about (e.g. IsDebuggerPresent) and see if the memory was hit exactly once + * (4) Allocate an executable buffer, copy a debug check routine to it, run the check, see if any writes were performed after ours. + * + * Reference: https://msdn.microsoft.com/en-us/library/windows/desktop/aa366887.aspx + * GetWriteWatch: https://msdn.microsoft.com/en-us/library/windows/desktop/aa366573.aspx + * + */ + +BOOL VirtualAlloc_WriteWatch_BufferOnly() +{ + ULONG_PTR hitCount; + DWORD granularity; + BOOL result = FALSE; + + PVOID* addresses = static_cast(VirtualAlloc(NULL, 4096 * sizeof(PVOID), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE)); + if (addresses == NULL) { + printf("VirtualAlloc failed. Last error: %u\n", GetLastError()); + return result; + } + + int* buffer = static_cast(VirtualAlloc(NULL, 4096 * 4096, MEM_RESERVE | MEM_COMMIT | MEM_WRITE_WATCH, PAGE_READWRITE)); + if (buffer == NULL) { + VirtualFree(addresses, 0, MEM_RELEASE); + printf("VirtualAlloc failed. Last error: %u\n", GetLastError()); + return result; + } + + // read the buffer once + buffer[0] = 1234; + + hitCount = 4096; + if (GetWriteWatch(0, buffer, 4096, addresses, &hitCount, &granularity) != 0) + { + printf("GetWriteWatch failed. Last error: %u\n", GetLastError()); + result = FALSE; + } + else + { + // should only have one read here + result = hitCount != 1; + } + + VirtualFree(addresses, 0, MEM_RELEASE); + VirtualFree(buffer, 0, MEM_RELEASE); + + return result; +} + +BOOL VirtualAlloc_WriteWatch_APICalls() +{ + ULONG_PTR hitCount; + DWORD granularity; + BOOL result = FALSE, error = FALSE; + + PVOID* addresses = static_cast(VirtualAlloc(NULL, 4096 * sizeof(PVOID), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE)); + if (addresses == NULL) { + printf("VirtualAlloc failed. Last error: %u\n", GetLastError()); + return result; + } + + int* buffer = static_cast(VirtualAlloc(NULL, 4096 * 4096, MEM_RESERVE | MEM_COMMIT | MEM_WRITE_WATCH, PAGE_READWRITE)); + if (buffer == NULL) { + VirtualFree(addresses, 0, MEM_RELEASE); + printf("VirtualAlloc failed. Last error: %u\n", GetLastError()); + return result; + } + + // make a bunch of calls where buffer *can* be written to, but isn't actually touched due to invalid parameters. + // this can catch out API hooks whose return-by-parameter behaviour is different to that of regular APIs + + if (GlobalGetAtomName(INVALID_ATOM, (LPTSTR)buffer, 1) != FALSE) + { + printf("GlobalGetAtomName succeeded when it should've failed... not sure what happened!\n"); + result = FALSE; + error = TRUE; + } + if (GetEnvironmentVariable(L"%ThisIsAnInvalidEnvironmentVariableName?[]<>@\\;*!-{}#:/~%", (LPWSTR)buffer, 4096*4096) != FALSE) + { + printf("GetEnvironmentVariable succeeded when it should've failed... not sure what happened!\n"); + result = FALSE; + error = TRUE; + } + if (GetBinaryType(L"%ThisIsAnInvalidFileName?[]<>@\\;*!-{}#:/~%", (LPDWORD)buffer) != FALSE) + { + printf("GetBinaryType succeeded when it should've failed... not sure what happened!\n"); + result = FALSE; + error = TRUE; + } + if (HeapQueryInformation(0, (HEAP_INFORMATION_CLASS)69, buffer, 4096, NULL) != FALSE) + { + printf("HeapQueryInformation succeeded when it should've failed... not sure what happened!\n"); + result = FALSE; + error = TRUE; + } + if (ReadProcessMemory(INVALID_HANDLE_VALUE, (LPCVOID)0x69696969, buffer, 4096, NULL) != FALSE) + { + printf("ReadProcessMemory succeeded when it should've failed... not sure what happened!\n"); + result = FALSE; + error = TRUE; + } + if (GetThreadContext(INVALID_HANDLE_VALUE, (LPCONTEXT)buffer) != FALSE) + { + printf("GetThreadContext succeeded when it should've failed... not sure what happened!\n"); + result = FALSE; + error = TRUE; + } + if (GetWriteWatch(0, &VirtualAlloc_WriteWatch_APICalls, 0, NULL, NULL, (PULONG)buffer) == 0) + { + printf("GetWriteWatch succeeded when it should've failed... not sure what happened!\n"); + result = FALSE; + error = TRUE; + } + + if (error == FALSE) + { + // APIs failed as they should have! :) + + hitCount = 4096; + if (GetWriteWatch(0, buffer, 4096, addresses, &hitCount, &granularity) != 0) + { + printf("GetWriteWatch failed. Last error: %u\n", GetLastError()); + result = FALSE; + } + else + { + // should have zero reads here because GlobalGetAtomName doesn't probe the buffer until other checks have succeeded + // if there's an API hook or debugger in here it'll probably try to probe the buffer, which will be caught here + result = hitCount != 0; + } + } + else + { + printf("Write watch API check skipped, ignore the result as it is inconclusive.\n"); + } + + VirtualFree(addresses, 0, MEM_RELEASE); + VirtualFree(buffer, 0, MEM_RELEASE); + + return result; +} + +BOOL VirtualAlloc_WriteWatch_IsDebuggerPresent() +{ + ULONG_PTR hitCount; + DWORD granularity; + BOOL result = FALSE; + + PVOID* addresses = static_cast(VirtualAlloc(NULL, 4096 * sizeof(PVOID), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE)); + if (addresses == NULL) { + printf("VirtualAlloc failed. Last error: %u\n", GetLastError()); + return result; + } + + int* buffer = static_cast(VirtualAlloc(NULL, 4096 * 4096, MEM_RESERVE | MEM_COMMIT | MEM_WRITE_WATCH, PAGE_READWRITE)); + if (buffer == NULL) { + VirtualFree(addresses, 0, MEM_RELEASE); + printf("VirtualAlloc failed. Last error: %u\n", GetLastError()); + return result; + } + + buffer[0] = IsDebuggerPresent(); + + hitCount = 4096; + if (GetWriteWatch(0, buffer, 4096, addresses, &hitCount, &granularity) != 0) + { + printf("GetWriteWatch failed. Last error: %u\n", GetLastError()); + result = FALSE; + } + else + { + // should only have one write here + result = (hitCount != 1) | (buffer[0] == TRUE); + } + + VirtualFree(addresses, 0, MEM_RELEASE); + VirtualFree(buffer, 0, MEM_RELEASE); + + return result; +} + +BOOL VirtualAlloc_WriteWatch_CodeWrite() +{ + ULONG_PTR hitCount; + DWORD granularity; + BOOL result = FALSE; + + PVOID* addresses = static_cast(VirtualAlloc(NULL, 4096 * sizeof(PVOID), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE)); + if (addresses == NULL) { + printf("VirtualAlloc failed. Last error: %u\n", GetLastError()); + return result; + } + + byte* buffer = static_cast(VirtualAlloc(NULL, 4096 * 4096, MEM_RESERVE | MEM_COMMIT | MEM_WRITE_WATCH, PAGE_EXECUTE_READWRITE)); + if (buffer == NULL) { + VirtualFree(addresses, 0, MEM_RELEASE); + printf("VirtualAlloc failed. Last error: %u\n", GetLastError()); + return result; + } + + // construct a call to isDebuggerPresent in assembly + ULONG_PTR isDebuggerPresentAddr = (ULONG_PTR)&IsDebuggerPresent; + +#ifndef _WIN32 +#ifndef _WIN64 +#error Architecture must be WIN32 or WIN64 +#endif +#endif + + +#if _WIN64 + /* + * 64-bit + * + 0: 51 push rcx + 1: 48 b9 ef cd ab 90 78 56 34 12 movabs rcx, 0x1234567890abcdef + b: ff d1 call rcx + d: 59 pop rcx + e: c3 ret + */ + int pos = 0; + buffer[pos++] = 0x51; // push rcx + buffer[pos++] = 0x48; // movabs rcx, ... + buffer[pos++] = 0xB9; // ^ ... + int offset = 0; + for (int n = 0; n < 8; n++) + { + buffer[pos++] = (isDebuggerPresentAddr >> offset) & 0xFF; + offset += 8; + } + buffer[pos++] = 0xFF; // call rcx + buffer[pos++] = 0xD1; // ^ + buffer[pos++] = 0x59; // pop rcx + buffer[pos ] = 0xC3; // ret + +#else + /* + * 32-bit + * + 0: 51 push ecx + 1: b9 78 56 34 12 mov ecx, 0x12345678 + 6: ff d1 call ecx + 8: 59 pop ecx + 9: c3 ret + */ + int pos = 0; + buffer[pos++] = 0x51; // push ecx + buffer[pos++] = 0xB9; // mov ecx, ... + int offset = 0; + for (int n = 0; n < 4; n++) + { + buffer[pos++] = (isDebuggerPresentAddr >> offset) & 0xFF; + offset += 8; + } + buffer[pos++] = 0xFF; // call ecx + buffer[pos++] = 0xD1; // ^ + buffer[pos++] = 0x59; // pop ecx + buffer[pos] = 0xC3; // ret + +#endif + + ResetWriteWatch(buffer, 4096 * 4096); + + // cool, now exec the code + BOOL(*foo)(VOID) = (BOOL(*)(VOID))buffer; + if (foo() == TRUE) + { + result = TRUE; + } + + if (result == FALSE) + { + hitCount = 4096; + if (GetWriteWatch(0, buffer, 4096, addresses, &hitCount, &granularity) != 0) + { + printf("GetWriteWatch failed. Last error: %u\n", GetLastError()); + result = FALSE; + } + else + { + result = hitCount != 0; + } + } + + VirtualFree(addresses, 0, MEM_RELEASE); + VirtualFree(buffer, 0, MEM_RELEASE); + + return result; +} diff --git a/byp/sbexecution/AntiDebug/WriteWatch.h b/byp/sbexecution/AntiDebug/WriteWatch.h new file mode 100644 index 00000000..28f4a93c --- /dev/null +++ b/byp/sbexecution/AntiDebug/WriteWatch.h @@ -0,0 +1,6 @@ +#pragma once + +BOOL VirtualAlloc_WriteWatch_BufferOnly(); +BOOL VirtualAlloc_WriteWatch_APICalls(); +BOOL VirtualAlloc_WriteWatch_IsDebuggerPresent(); +BOOL VirtualAlloc_WriteWatch_CodeWrite(); \ No newline at end of file diff --git a/byp/sbexecution/AntiDebug/int2d_x64.asm b/byp/sbexecution/AntiDebug/int2d_x64.asm new file mode 100644 index 00000000..daf13773 --- /dev/null +++ b/byp/sbexecution/AntiDebug/int2d_x64.asm @@ -0,0 +1,10 @@ +.code + +__int2d proc + mov rax, 0 + int 2dh + nop + ret +__int2d endp + +end diff --git a/byp/sbexecution/AntiDebug/int2d_x86.asm b/byp/sbexecution/AntiDebug/int2d_x86.asm new file mode 100644 index 00000000..bed0cd0c --- /dev/null +++ b/byp/sbexecution/AntiDebug/int2d_x86.asm @@ -0,0 +1,11 @@ +.model flat +.code + +___int2d proc + mov eax, 0 + int 2dh + nop + ret +___int2d endp + +end diff --git a/byp/sbexecution/AntiDebug/pch.h b/byp/sbexecution/AntiDebug/pch.h new file mode 100644 index 00000000..e7df92d7 --- /dev/null +++ b/byp/sbexecution/AntiDebug/pch.h @@ -0,0 +1 @@ +#include "../pch.h" \ No newline at end of file diff --git a/byp/sbexecution/AntiDisassm/AntiDisassm.cpp b/byp/sbexecution/AntiDisassm/AntiDisassm.cpp new file mode 100644 index 00000000..ffd88846 --- /dev/null +++ b/byp/sbexecution/AntiDisassm/AntiDisassm.cpp @@ -0,0 +1,74 @@ +#include "pch.h" + +#include "AntiDisassm.h" + + +extern "C" void __AsmConstantCondition(); +extern "C" void __AsmJmpSameTarget(); +extern "C" void __AsmImpossibleDisassm(); +extern "C" void __AsmFunctionPointer(DWORD); +extern "C" void __AsmReturnPointerAbuse(DWORD64); +#ifndef _WIN64 +extern "C" void __AsmSEHMisuse(); +#endif + +/* + This technique is composed of a single conditional jump instruction placed where the condition + will always be the same. +*/ +VOID AntiDisassmConstantCondition() +{ + __AsmConstantCondition(); +} + +/* + The most common anti-disassembly technique seen in the wild is two back-to back + conditional jump instructions that both point to the same target. For example, + if a jz XYZ is followed by jnz XYZ, the location XYZ will always be jumped to +*/ +VOID AntiDisassmAsmJmpSameTarget() +{ + __AsmJmpSameTarget(); +} + + +/* + By using a data byte placed strategically after a conditional jump instruction + with the idea that disassembly starting at this byte will prevent the real instruction + that follows from being disassembled because the byte that inserted is the opcode for + a multibyte instruction. + +*/ +VOID AntiDisassmImpossibleDiasassm() +{ + __AsmImpossibleDisassm(); +} + + +/* + If function pointers are used in handwritten assembly or crafted in a nonstandard way + in source code, the results can be difficult to reverse engineer without dynamic analysis. +*/ +VOID AntiDisassmFunctionPointer() +{ + + DWORD Number = 2; + __AsmFunctionPointer(Number); +} + + +/* + The most obvious result of this technique is that the disassembler doesn�t show any + code cross - reference to the target being jumped to. +*/ +VOID AntiDisassmReturnPointerAbuse() +{ + __AsmReturnPointerAbuse(666); +} + +#ifndef _WIN64 +VOID AntiDisassmSEHMisuse() +{ + __AsmSEHMisuse(); +} +#endif \ No newline at end of file diff --git a/byp/sbexecution/AntiDisassm/AntiDisassm.h b/byp/sbexecution/AntiDisassm/AntiDisassm.h new file mode 100644 index 00000000..99f02d14 --- /dev/null +++ b/byp/sbexecution/AntiDisassm/AntiDisassm.h @@ -0,0 +1,8 @@ +#pragma once + +VOID AntiDisassmConstantCondition(); +VOID AntiDisassmAsmJmpSameTarget(); +VOID AntiDisassmImpossibleDiasassm(); +VOID AntiDisassmFunctionPointer(); +VOID AntiDisassmReturnPointerAbuse(); +VOID AntiDisassmSEHMisuse(); \ No newline at end of file diff --git a/byp/sbexecution/AntiDisassm/AntiDisassm_x64.asm b/byp/sbexecution/AntiDisassm/AntiDisassm_x64.asm new file mode 100644 index 00000000..4d20ecd3 --- /dev/null +++ b/byp/sbexecution/AntiDisassm/AntiDisassm_x64.asm @@ -0,0 +1,75 @@ + +.code + +__AsmConstantCondition proc + xor rax, rax + jz L_END + db 0e8h +L_END: + nop + ret +__AsmConstantCondition endp + + +__AsmJmpSameTarget proc + jz L_END + jnz L_END + db 0e8h +L_END: + nop + ret +__AsmJmpSameTarget endp + + +__AsmImpossibleDisassm proc + push rax + + mov ax, 05EBh ; db 066h, 0B8h, 0EBh, 005h + xor eax, eax ; db 033h, 0C0h + db 074h, 0fah + db 0e8h ; call + + pop rax + ret +__AsmImpossibleDisassm endp + +; a dummy function +func2 proc + mov rax, r8 + shl rax, 2 + ret + func2 endp + + +__AsmFunctionPointer proc + push rax + push rcx + push rsi + mov rcx, offset func2 + mov r8, 02h + call rcx + mov rsi, rax + mov r8, 03h + call rcx + lea rax, [rsi+rax+1] + pop rsi + pop rcx + pop rax + ret +__AsmFunctionPointer endp + + +__AsmReturnPointerAbuse proc + call $+5 + add qword ptr[rsp], 6 + ret + + push rax + mov rax, rcx + imul rax, 40h + pop rax + ret +__AsmReturnPointerAbuse endp + + +end diff --git a/byp/sbexecution/AntiDisassm/AntiDisassm_x86.asm b/byp/sbexecution/AntiDisassm/AntiDisassm_x86.asm new file mode 100644 index 00000000..327f1820 --- /dev/null +++ b/byp/sbexecution/AntiDisassm/AntiDisassm_x86.asm @@ -0,0 +1,111 @@ +.model flat, c + +.code + +__AsmConstantCondition proc + xor eax, eax + jz L_END + db 0e8h +L_END: + nop + ret +__AsmConstantCondition endp + + +__AsmJmpSameTarget proc + jz L_END + jnz L_END + db 0e8h +L_END: + nop + ret +__AsmJmpSameTarget endp + + +__AsmImpossibleDisassm proc + push eax + + mov ax, 05EBh ; db 066h, 0B8h, 0EBh, 005h + xor eax, eax ; db 033h, 0C0h + db 074h, 0fah + db 0e8h ; call + + pop eax + ret +__AsmImpossibleDisassm endp + +; a dummy function +func2 proc arg_0:DWORD + mov eax, [arg_0] + shl eax, 2 + pop ebp + retn + func2 endp + + +__AsmFunctionPointer proc arg_0:DWORD + + LOCAL var_4:DWORD + + push ecx + push esi + mov [var_4], offset func2 + push 03h + call [var_4] + add esp, 4 + mov esi, eax + mov eax, [arg_0] + push eax + call [var_4] + add esp, 4 + lea eax, [esi+eax+1] + pop esi + mov esp, ebp + pop ebp + retn +__AsmFunctionPointer endp + +__AsmReturnPointerAbuse proc + + call $+5 + add dword ptr[esp], 5 + retn + + push eax + mov eax, [ebp+8] + imul eax, 40h + pop eax + retn +__AsmReturnPointerAbuse endp + +; another dummy function +func3 proc + mov esp, [esp+8] + ASSUME FS:NOTHING + mov eax, dword ptr fs:[0] + ASSUME FS:ERROR + mov eax, [eax] + mov eax, [eax] + ASSUME FS:NOTHING + mov dword ptr fs:[0], eax + ASSUME FS:ERROR + add esp, 8 + pop ebp + retn + func3 endp + +__AsmSEHMisuse proc + push ebp + mov eax, offset func3 + push eax + ASSUME FS:NOTHING + push dword ptr fs:[0] + mov dword ptr fs:[0], esp + ASSUME FS:ERROR + xor ecx, ecx + div ecx + call func2 + retn +__AsmSEHMisuse endp + +end diff --git a/byp/sbexecution/AntiDisassm/pch.h b/byp/sbexecution/AntiDisassm/pch.h new file mode 100644 index 00000000..e7df92d7 --- /dev/null +++ b/byp/sbexecution/AntiDisassm/pch.h @@ -0,0 +1 @@ +#include "../pch.h" \ No newline at end of file diff --git a/byp/sbexecution/AntiDump/ErasePEHeaderFromMemory.cpp b/byp/sbexecution/AntiDump/ErasePEHeaderFromMemory.cpp new file mode 100644 index 00000000..bbdd1ddd --- /dev/null +++ b/byp/sbexecution/AntiDump/ErasePEHeaderFromMemory.cpp @@ -0,0 +1,25 @@ +#include "pch.h" + +#include "ErasePEHeaderFromMemory.h" + +/* This function will erase the current images PE header from memory preventing a successful image if dumped */ + + +VOID ErasePEHeaderFromMemory() +{ + _tprintf(_T("[*] Erasing PE header from memory\n")); + DWORD OldProtect = 0; + + // Get base address of module + char *pBaseAddr = (char*)GetModuleHandle(NULL); + + // Change memory protection + VirtualProtect(pBaseAddr, 4096, // Assume x86 page size + PAGE_READWRITE, &OldProtect); + + // Erase the header + SecureZeroMemory(pBaseAddr, 4096); +} + + + diff --git a/byp/sbexecution/AntiDump/ErasePEHeaderFromMemory.h b/byp/sbexecution/AntiDump/ErasePEHeaderFromMemory.h new file mode 100644 index 00000000..4f9af23e --- /dev/null +++ b/byp/sbexecution/AntiDump/ErasePEHeaderFromMemory.h @@ -0,0 +1,3 @@ +#pragma once + +VOID ErasePEHeaderFromMemory(); \ No newline at end of file diff --git a/byp/sbexecution/AntiDump/SizeOfImage.cpp b/byp/sbexecution/AntiDump/SizeOfImage.cpp new file mode 100644 index 00000000..3881b8ac --- /dev/null +++ b/byp/sbexecution/AntiDump/SizeOfImage.cpp @@ -0,0 +1,23 @@ +#include "pch.h" + +#include "SizeOfImage.h" + +// Any unreasonably large value will work say for example 0x100000 or 100,000h + +VOID SizeOfImage() +{ + +#if defined (ENV64BIT) + PPEB pPeb = (PPEB)__readgsqword(0x60); +#elif defined(ENV32BIT) + PPEB pPeb = (PPEB)__readfsdword(0x30); +#endif + + _tprintf(_T("[*] Increasing SizeOfImage in PE Header to: 0x100000\n")); + + // The following pointer hackery is because winternl.h defines incomplete PEB types + PLIST_ENTRY InLoadOrderModuleList = (PLIST_ENTRY)pPeb->Ldr->Reserved2[1]; // pPeb->Ldr->InLoadOrderModuleList + PLDR_DATA_TABLE_ENTRY tableEntry = CONTAINING_RECORD(InLoadOrderModuleList, LDR_DATA_TABLE_ENTRY, Reserved1[0] /*InLoadOrderLinks*/); + PULONG pEntrySizeOfImage = (PULONG)&tableEntry->Reserved3[1]; // &tableEntry->SizeOfImage + *pEntrySizeOfImage = (ULONG)((INT_PTR)tableEntry->DllBase + 0x100000); +} diff --git a/byp/sbexecution/AntiDump/SizeOfImage.h b/byp/sbexecution/AntiDump/SizeOfImage.h new file mode 100644 index 00000000..336bdb1f --- /dev/null +++ b/byp/sbexecution/AntiDump/SizeOfImage.h @@ -0,0 +1,3 @@ +#pragma once + +VOID SizeOfImage(); \ No newline at end of file diff --git a/byp/sbexecution/AntiDump/pch.h b/byp/sbexecution/AntiDump/pch.h new file mode 100644 index 00000000..e7df92d7 --- /dev/null +++ b/byp/sbexecution/AntiDump/pch.h @@ -0,0 +1 @@ +#include "../pch.h" \ No newline at end of file diff --git a/byp/sbexecution/AntiVM/Generic.cpp b/byp/sbexecution/AntiVM/Generic.cpp new file mode 100644 index 00000000..fb9937d4 --- /dev/null +++ b/byp/sbexecution/AntiVM/Generic.cpp @@ -0,0 +1,2046 @@ +#include "pch.h" + +#include "Generic.h" + +/* +Check if the DLL is loaded in the context of the process +*/ +VOID loaded_dlls() +{ + /* Some vars */ + HMODULE hDll; + + /* Array of strings of blacklisted dlls */ + CONST TCHAR* szDlls[] = { + _T("avghookx.dll"), // AVG + _T("avghooka.dll"), // AVG + _T("snxhk.dll"), // Avast + _T("sbiedll.dll"), // Sandboxie + _T("dbghelp.dll"), // WindBG + _T("api_log.dll"), // iDefense Lab + _T("dir_watch.dll"), // iDefense Lab + _T("pstorec.dll"), // SunBelt Sandbox + _T("vmcheck.dll"), // Virtual PC + _T("wpespy.dll"), // WPE Pro + _T("cmdvrt64.dll"), // Comodo Container + _T("cmdvrt32.dll"), // Comodo Container + + }; + + WORD dwlength = sizeof(szDlls) / sizeof(szDlls[0]); + for (int i = 0; i < dwlength; i++) + { + TCHAR msg[256] = _T(""); + _stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking if process loaded modules contains: %s "), szDlls[i]); + + /* Check if process loaded modules contains the blacklisted dll */ + hDll = GetModuleHandle(szDlls[i]); + if (hDll == NULL) + print_results(FALSE, msg); + else + print_results(TRUE, msg); + } +} + +/* +Check if the file name contains any of the following strings. +This is likely an automated malware sandbox. +*/ +VOID known_file_names() { + + /* Array of strings of filenames seen in sandboxes */ + CONST TCHAR* szFilenames[] = { + _T("sample.exe"), + _T("bot.exe"), + _T("sandbox.exe"), + _T("malware.exe"), + _T("test.exe"), + _T("klavme.exe"), + _T("myapp.exe"), + _T("testapp.exe"), + + }; + +#if defined (ENV64BIT) + PPEB pPeb = (PPEB)__readgsqword(0x60); + +#elif defined(ENV32BIT) + PPEB pPeb = (PPEB)__readfsdword(0x30); +#endif + + if (!pPeb->ProcessParameters->ImagePathName.Buffer) { + return; + } + + // Get the file name from path/ + WCHAR* szFileName = PathFindFileNameW(pPeb->ProcessParameters->ImagePathName.Buffer); + + TCHAR msg[256] = _T(""); + WORD dwlength = sizeof(szFilenames) / sizeof(szFilenames[0]); + for (int i = 0; i < dwlength; i++) + { + _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) + print_results(FALSE, msg); + else + print_results(TRUE, msg); + } + + // 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)) + print_results(TRUE, msg); + else + print_results(FALSE, msg); +} + +static TCHAR * get_username() { + TCHAR *username; + DWORD nSize = (UNLEN + 1); + + username = (TCHAR *) malloc(nSize * sizeof(TCHAR)); + if (!username) { + return NULL; + } + if (0 == GetUserName(username, &nSize)) { + free(username); + return NULL; + } + return username; +} + +/* +Check for usernames associated with sandboxes +*/ +VOID known_usernames() { + + /* Array of strings of usernames seen in sandboxes */ + CONST TCHAR* szUsernames[] = { + /* Checked for by Gootkit + * https://www.sentinelone.com/blog/gootkit-banking-trojan-deep-dive-anti-analysis-features/ */ + _T("CurrentUser"), + _T("Sandbox"), + + /* Checked for by ostap + * https://www.bromium.com/deobfuscating-ostap-trickbots-javascript-downloader/ */ + _T("Emily"), + _T("HAPUBWS"), + _T("Hong Lee"), + _T("IT-ADMIN"), + _T("Johnson"), /* Lastline Sandbox */ + _T("Miller"), /* Lastline Sandbox */ + _T("milozs"), + _T("Peter Wilson"), + _T("timmy"), + _T("user"), + + /* Checked for by Betabot (not including ones from above) + * https://www.bromium.com/deobfuscating-ostap-trickbots-javascript-downloader/ */ + _T("sand box"), + _T("malware"), + _T("maltest"), + _T("test user"), + + /* Checked for by Satan (not including ones from above) + * https://cofense.com/satan/ */ + _T("virus"), + + /* Checked for by Emotet (not including ones from above) + * https://blog.trendmicro.com/trendlabs-security-intelligence/new-emotet-hijacks-windows-api-evades-sandbox-analysis/ */ + _T("John Doe"), /* VirusTotal Cuckoofork Sandbox */ + }; + TCHAR *username; + + if (NULL == (username = get_username())) { + return; + } + + TCHAR msg[256]; + WORD dwlength = sizeof(szUsernames) / sizeof(szUsernames[0]); + for (int i = 0; i < dwlength; i++) { + + _stprintf_s(msg, sizeof(msg) / sizeof(msg[0]), _T("Checking if username matches : %s "), szUsernames[i]); + + /* Do a case-insensitive search for all entries in szHostnames */ + BOOL matched = FALSE; + if (0 == _tcsicmp(szUsernames[i], username)) { + matched = TRUE; + } + + print_results(matched, msg); + } + + free(username); +} + +static TCHAR * get_netbios_hostname() { + TCHAR *hostname; + DWORD nSize = (MAX_COMPUTERNAME_LENGTH + 1); + + hostname = (TCHAR *) malloc(nSize * sizeof(TCHAR)); + if (!hostname) { + return NULL; + } + if (0 == GetComputerName(hostname, &nSize)) { + free(hostname); + return NULL; + } + return hostname; +} + +static TCHAR * get_dns_hostname() { + TCHAR *hostname; + DWORD nSize = 0; + + GetComputerNameEx(ComputerNameDnsHostname, NULL, &nSize); + hostname = (TCHAR *) malloc((nSize + 1) * sizeof(TCHAR)); + if (!hostname) { + return NULL; + } + if (0 == GetComputerNameEx(ComputerNameDnsHostname, hostname, &nSize)) { + free(hostname); + return NULL; + } + return hostname; +} + +/* +Check for hostnames associated with sandboxes +*/ +VOID known_hostnames() { + + /* Array of strings of hostnames seen in sandboxes */ + CONST TCHAR* szHostnames[] = { + /* Checked for by Gootkit + * https://www.sentinelone.com/blog/gootkit-banking-trojan-deep-dive-anti-analysis-features/ */ + _T("SANDBOX"), + _T("7SILVIA"), + + /* Checked for by ostap + * https://www.bromium.com/deobfuscating-ostap-trickbots-javascript-downloader/ */ + _T("HANSPETER-PC"), + _T("JOHN-PC"), + _T("MUELLER-PC"), + _T("WIN7-TRAPS"), + + /* Checked for by Shifu (not including ones from above) + * https://www.mcafee.com/blogs/other-blogs/mcafee-labs/japanese-banking-trojan-shifu-combines-malware-tools */ + _T("FORTINET"), + + /* Checked for by Emotet (not including ones from above) + * https://blog.trendmicro.com/trendlabs-security-intelligence/new-emotet-hijacks-windows-api-evades-sandbox-analysis/ */ + _T("TEQUILABOOMBOOM"), /* VirusTotal Cuckoofork Sandbox */ + }; + TCHAR *NetBIOSHostName; + TCHAR *DNSHostName; + + if (NULL == (NetBIOSHostName = get_netbios_hostname())) { + return; + } + + if (NULL == (DNSHostName = get_dns_hostname())) { + free(NetBIOSHostName); + return; + } + + TCHAR msg[256]; + WORD dwlength = sizeof(szHostnames) / sizeof(szHostnames[0]); + for (int i = 0; i < dwlength; i++) { + + _stprintf_s(msg, sizeof(msg) / sizeof(msg[0]), _T("Checking if hostname matches : %s "), szHostnames[i]); + + /* Do a case-insensitive search for all entries in szHostnames */ + BOOL matched = FALSE; + if (0 == _tcsicmp(szHostnames[i], NetBIOSHostName)) { + matched = TRUE; + } + else if (0 == _tcsicmp(szHostnames[i], DNSHostName)) { + matched = TRUE; + } + + print_results(matched, msg); + } + + free(NetBIOSHostName); + free(DNSHostName); +} + +/* +Check for a combination of environmental conditions, replicating what malware +could/has used to detect that it's running in a sandbox. */ +VOID other_known_sandbox_environment_checks() { + TCHAR *NetBIOSHostName; + TCHAR *DNSHostName; + TCHAR *username; + BOOL matched; + + if (NULL == (username = get_username())) { + return; + } + if (NULL == (NetBIOSHostName = get_netbios_hostname())) { + free(username); + return; + } + + if (NULL == (DNSHostName = get_dns_hostname())) { + free(username); + free(NetBIOSHostName); + return; + } + /* From Emotet + * https://blog.trendmicro.com/trendlabs-security-intelligence/new-emotet-hijacks-windows-api-evades-sandbox-analysis/ */ + + matched = FALSE; + if ((0 == StrCmp(username, _T("Wilber"))) && + ((0 == StrCmpNI(NetBIOSHostName, _T("SC"), 2)) || + (0 == StrCmpNI(NetBIOSHostName, _T("SW"), 2)))) { + matched = TRUE; + } + print_results(matched, (TCHAR *)_T("Checking whether username is 'Wilber' and NetBIOS name starts with 'SC' or 'SW' ")); + + 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' ")); + + 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' ")); + + matched = FALSE; + if ((0 == StrCmp(username, _T("John"))) && + (is_FileExists((TCHAR *)_T("C:\\take_screenshot.ps1"))) && + (is_FileExists((TCHAR *)_T("C:\\loaddll.exe")))) { + matched = TRUE; + } + print_results(matched, (TCHAR *)_T("Checking whether username is 'John' and two sandbox files exist ")); + + matched = FALSE; + if ((is_FileExists((TCHAR *)_T("C:\\email.doc"))) && + (is_FileExists((TCHAR *)_T("C:\\email.htm"))) && + (is_FileExists((TCHAR *)_T("C:\\123\\email.doc"))) && + (is_FileExists((TCHAR *)_T("C:\\123\\email.docx")))) { + matched = TRUE; + } + print_results(matched, (TCHAR *)_T("Checking whether four known sandbox 'email' file paths exist ")); + + matched = FALSE; + if ((is_FileExists((TCHAR *)_T("C:\\a\\foobar.bmp"))) && + (is_FileExists((TCHAR *)_T("C:\\a\\foobar.doc"))) && + (is_FileExists((TCHAR *)_T("C:\\a\\foobar.gif")))) { + matched = TRUE; + } + print_results(matched, (TCHAR *)_T("Checking whether three known sandbox 'foobar' files exist ")); + + free(username); + free(NetBIOSHostName); + free(DNSHostName); +} + +/* +Detect Hybrid Analysis with mac vendor +*/ +BOOL hybridanalysismacdetect() +{ + return check_mac_addr(_T("\x0A\x00\x27")); +} + +/* +Number of Processors in VM +*/ + +BOOL NumberOfProcessors() +{ +#if defined (ENV64BIT) + PULONG ulNumberProcessors = (PULONG)(__readgsqword(0x60) + 0xB8); + +#elif defined(ENV32BIT) + PULONG ulNumberProcessors = (PULONG)(__readfsdword(0x30) + 0x64); + +#endif + + if (*ulNumberProcessors < 2) + return TRUE; + else + return FALSE; +} + + +/* +This trick involves looking at pointers to critical operating system tables +that are typically relocated on a virtual machine. One such table is the +Interrupt Descriptor Table (IDT), which tells the system where various operating +system interrupt handlers are located in memory. On real machines, the IDT is +located lower in memory than it is on guest (i.e., virtual) machines +PS: Does not seem to work on newer version of VMWare Workstation (Tested on v12) +*/ +BOOL idt_trick() +{ + UINT idt_base = get_idt_base(); + if ((idt_base >> 24) == 0xff) + return TRUE; + + else + return FALSE; +} + +/* +Same for Local Descriptor Table (LDT) +*/ +BOOL ldt_trick() +{ + UINT ldt_base = get_ldt_base(); + + if (ldt_base == 0xdead0000) + return FALSE; + else + return TRUE; // VMWare detected +} + + +/* +Same for Global Descriptor Table (GDT) +*/ +BOOL gdt_trick() +{ + UINT gdt_base = get_gdt_base(); + + if ((gdt_base >> 24) == 0xff) + return TRUE; // VMWare detected + + else + return FALSE; +} + + +/* +The instruction STR (Store Task Register) stores the selector segment of the TR +register (Task Register) in the specified operand (memory or other general purpose register). +All x86 processors can manage tasks in the same way as an operating system would do it. +That is, keeping the task state and recovering it when that task is executed again. All +the states of a task are kept in its TSS; there is one TSS per task. How can we know which +is the TSS associated to the execution task? Using STR instruction, due to the fact that +the selector segment that was brought back points into the TSS of the present task. +In all the tests that were done, the value brought back by STR from within a virtual machine +was different to the obtained from a native system, so apparently, it can be used as a another +mechanism of a unique instruction in assembler to detect virtual machines. +*/ +BOOL str_trick() +{ + UCHAR mem[4] = { 0, 0, 0, 0 }; + +#if defined (ENV32BIT) + __asm str mem; +#endif + + if ((mem[0] == 0x00) && (mem[1] == 0x40)) + return TRUE; // VMWare detected + else + return FALSE; +} + + +/* +Check number of cores using WMI +*/ +BOOL number_cores_wmi() +{ + IWbemServices *pSvc = NULL; + IWbemLocator *pLoc = NULL; + IEnumWbemClassObject* pEnumerator = NULL; + BOOL bStatus = FALSE; + HRESULT hRes; + BOOL bFound = FALSE; + + // Init WMI + bStatus = InitWMI(&pSvc, &pLoc, _T("ROOT\\CIMV2")); + if (bStatus) + { + // If success, execute the desired query + bStatus = ExecWMIQuery(&pSvc, &pLoc, &pEnumerator, _T("SELECT * FROM Win32_Processor")); + if (bStatus) + { + // Get the data from the query + IWbemClassObject *pclsObj = NULL; + ULONG uReturn = 0; + VARIANT vtProp; + + // Iterate over our enumator + while (pEnumerator) + { + hRes = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn); + if (0 == uReturn) + break; + + // Get the value of the Name property + hRes = pclsObj->Get(_T("NumberOfCores"), 0, &vtProp, 0, 0); + if (SUCCEEDED(hRes)) { + if (V_VT(&vtProp) != VT_NULL) { + + // Do our comparaison + if (vtProp.uintVal < 2) { + bFound = TRUE; + } + + // release the current result object + VariantClear(&vtProp); + } + } + + // release class object + pclsObj->Release(); + + // break from while + if (bFound) + break; + } + + // Cleanup + pEnumerator->Release(); + pSvc->Release(); + pLoc->Release(); + CoUninitialize(); + } + } + + return bFound; +} + +/* +Filter for removable disk, CD-ROM, network drive or RAM disk +*/ +BOOL checkDriveType(IWbemClassObject* pclsObj) +{ + if (!pclsObj) + return FALSE; + + BOOL res = FALSE; + VARIANT vtDriveType; + HRESULT hResDriveType; + + hResDriveType = pclsObj->Get(_T("DriveType"), 0, &vtDriveType, NULL, 0); + if (SUCCEEDED(hResDriveType) && V_VT(&vtDriveType) != VT_NULL) + { + if (vtDriveType.uintVal == 2 // removable disk (USB) + || vtDriveType.uintVal == 4 // network drive + || vtDriveType.uintVal == 5 // CD-ROM + || vtDriveType.uintVal == 6 // RAM disk + ) + { + res = TRUE; + } + VariantClear(&vtDriveType); + } + return res; +} + +/* +Check hard disk size using WMI +*/ +BOOL disk_size_wmi() +{ + IWbemServices *pSvc = NULL; + IWbemLocator *pLoc = NULL; + IEnumWbemClassObject* pEnumerator = NULL; + BOOL bStatus = FALSE; + HRESULT hRes; + BOOL bFound = FALSE; + UINT64 minHardDiskSize = (80ULL * (1024ULL * (1024ULL * (1024ULL)))); + + // Init WMI + bStatus = InitWMI(&pSvc, &pLoc, _T("ROOT\\CIMV2")); + if (bStatus) + { + // If success, execute the desired query + bStatus = ExecWMIQuery(&pSvc, &pLoc, &pEnumerator, _T("SELECT * FROM Win32_LogicalDisk")); + if (bStatus) + { + // Get the data from the query + IWbemClassObject *pclsObj = NULL; + ULONG uReturn = 0; + VARIANT vtProp; + + // Iterate over our enumator + while (pEnumerator) + { + hRes = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn); + if (0 == uReturn) + break; + + // Don`t check removable disk, network drive CD-ROM and RAM disk + if (checkDriveType(pclsObj)) { + pclsObj->Release(); + continue; + } + + // Get the value of the Name property + hRes = pclsObj->Get(_T("Size"), 0, &vtProp, NULL, 0); + if (SUCCEEDED(hRes)) { + if (V_VT(&vtProp) != VT_NULL) + { + // convert disk size string to bytes + errno = 0; + unsigned long long diskSizeBytes = _tcstoui64_l(vtProp.bstrVal, NULL, 10, _get_current_locale()); + // do the check only if we successfuly got the disk size + if (errno == 0) + { + // Do our comparison + if (diskSizeBytes < minHardDiskSize) { // Less than 80GB + bFound = TRUE; + } + } + // release the current result object + VariantClear(&vtProp); + } + } + + // release class object + pclsObj->Release(); + + // break from while + if (bFound) + break; + } + + // Cleanup + pEnumerator->Release(); + pSvc->Release(); + pLoc->Release(); + CoUninitialize(); + } + } + + return bFound; +} + + +/* +DeviceIoControl works with disks directly rather than partitions (GetDiskFreeSpaceEx) +We can send IOCTL_DISK_GET_LENGTH_INFO code to get the raw byte size of the physical disk +*/ +BOOL dizk_size_deviceiocontrol() +{ + HANDLE hDevice = INVALID_HANDLE_VALUE; + BOOL bResult = FALSE; + GET_LENGTH_INFORMATION size = { 0 }; + DWORD lpBytesReturned = 0; + LONGLONG minHardDiskSize = (80LL * (1024LL * (1024LL * (1024LL)))); + LARGE_INTEGER totalDiskSize; + totalDiskSize.QuadPart = 0LL; + + // This technique requires admin priviliege starting from Windows Vista + if (!IsElevated() && IsWindowsVistaOrGreater()) + return FALSE; + + // This code tries to get the physical disk(s) associated with the drive that Windows is on. + // This is not always C:\ or PhysicalDrive0 so we need to do some work to account for multi-disk volumes. + // By default we fall back to PhysicalDrive0 if any of this fails. + + bool defaultToDrive0 = true; + + // get the Windows system directory + wchar_t winDirBuffer[MAX_PATH]; + SecureZeroMemory(winDirBuffer, MAX_PATH); + UINT winDirLen = GetSystemWindowsDirectory(winDirBuffer, MAX_PATH); + + if (winDirLen) + { + // get the drive number (0-25 for A-Z) associated with the directory + int driveNumber = PathGetDriveNumber(winDirBuffer); + if (driveNumber >= 0) + { + // convert the drive number to a root path (e.g. C:\) + wchar_t driveRootPathBuffer[MAX_PATH]; + SecureZeroMemory(driveRootPathBuffer, MAX_PATH); + + wnsprintf(driveRootPathBuffer, MAX_PATH, _T("\\\\.\\%C:"), _T('A') + driveNumber); + + // open a handle to the volume + HANDLE hVolume = CreateFile( + driveRootPathBuffer, + GENERIC_READ, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS, + NULL); + + if (hVolume != INVALID_HANDLE_VALUE) + { + DWORD extentSize = 8192; //256 VOLUME_DISK_EXTENTS entries + PVOLUME_DISK_EXTENTS diskExtents = NULL; + + diskExtents = static_cast(LocalAlloc(LPTR, extentSize)); + if (diskExtents) { + + DWORD dummy = 0; + BOOL extentsIoctlOK = DeviceIoControl(hVolume, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, NULL, 0, diskExtents, extentSize, &dummy, NULL); + + if (extentsIoctlOK && diskExtents->NumberOfDiskExtents > 0) + { + // loop through disks associated with this drive + // we want to sum the disk + wchar_t physicalPathBuffer[MAX_PATH]; + + for (DWORD i = 0; i < diskExtents->NumberOfDiskExtents; i++) + { + if (wnsprintf(physicalPathBuffer, MAX_PATH, _T("\\\\.\\PhysicalDrive%u"), diskExtents->Extents[i].DiskNumber) > 0) + { + // open the physical disk + hDevice = CreateFile( + physicalPathBuffer, + GENERIC_READ, + FILE_SHARE_READ, + NULL, + OPEN_EXISTING, + 0, + NULL); + + if (hDevice != INVALID_HANDLE_VALUE) + { + // fetch the size info + bResult = DeviceIoControl( + hDevice, // device to be queried + IOCTL_DISK_GET_LENGTH_INFO, // operation to perform + NULL, 0, // no input buffer + &size, sizeof(GET_LENGTH_INFORMATION), + &lpBytesReturned, // bytes returned + (LPOVERLAPPED)NULL); // synchronous I/O + + if (bResult) + { + // add size :) + totalDiskSize.QuadPart += size.Length.QuadPart; + // we've been successful so far, so let's say it's fine + defaultToDrive0 = false; + } + else + { + // failed IOCTL call + defaultToDrive0 = true; + } + + CloseHandle(hDevice); + + if (!bResult) + break; + } + else + { + // failed to open the drive + defaultToDrive0 = true; + break; + } + } + else + { + // failed to construct the path string for some reason + defaultToDrive0 = true; + break; + } + } + } + + LocalFree(diskExtents); + } + + CloseHandle(hVolume); + } + } + } + + // for some reason we couldn't enumerate the disks associated with the system drive + // so we'll just check PhysicalDrive0 as a backup + if (defaultToDrive0) + { + hDevice = CreateFile(_T("\\\\.\\PhysicalDrive0"), + GENERIC_READ, // no access to the drive + FILE_SHARE_READ, // share mode + NULL, // default security attributes + OPEN_EXISTING, // disposition + 0, // file attributes + NULL); // do not copy file attributes + + if (hDevice != INVALID_HANDLE_VALUE) { + + if (DeviceIoControl( + hDevice, // device to be queried + IOCTL_DISK_GET_LENGTH_INFO, // operation to perform + NULL, 0, // no input buffer + &size, sizeof(GET_LENGTH_INFORMATION), + &lpBytesReturned, // bytes returned + (LPOVERLAPPED)NULL)) // synchronous I/O + { + totalDiskSize.QuadPart = size.Length.QuadPart; + } + CloseHandle(hDevice); + } + } + + if (totalDiskSize.QuadPart < minHardDiskSize) // 80GB + bResult = TRUE; + else + bResult = FALSE; + + return bResult; +} + + +BOOL setupdi_diskdrive() +{ + HDEVINFO hDevInfo; + SP_DEVINFO_DATA DeviceInfoData; + DWORD i; + BOOL bFound = FALSE; + + // Create a HDEVINFO with all present devices. + hDevInfo = SetupDiGetClassDevs((LPGUID)&GUID_DEVCLASS_DISKDRIVE, + 0, // Enumerator + 0, + DIGCF_PRESENT); + + if (hDevInfo == INVALID_HANDLE_VALUE) + return FALSE; + + // Enumerate through all devices in Set. + DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); + + /* Init some vars */ + DWORD dwPropertyRegDataType; + LPTSTR buffer = NULL; + DWORD dwSize = 0; + + for (i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData); i++) + { + while (!SetupDiGetDeviceRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_HARDWAREID, + &dwPropertyRegDataType, (PBYTE)buffer, dwSize, &dwSize)) + { + if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { + // Change the buffer size. + if (buffer)LocalFree(buffer); + // Double the size to avoid problems on + // W2k MBCS systems per KB 888609. + buffer = (LPTSTR)LocalAlloc(LPTR, dwSize * 2); + if (buffer == NULL) + break; + } + else + break; + + } + + if (buffer) { + // Do our comparison + if ((StrStrI(buffer, _T("vbox")) != NULL) || + (StrStrI(buffer, _T("vmware")) != NULL) || + (StrStrI(buffer, _T("qemu")) != NULL) || + (StrStrI(buffer, _T("virtual")) != NULL)) + { + bFound = TRUE; + break; + } + } + } + + if (buffer) + LocalFree(buffer); + + // Cleanup + SetupDiDestroyDeviceInfoList(hDevInfo); + + if (GetLastError() != NO_ERROR && GetLastError() != ERROR_NO_MORE_ITEMS) + return FALSE; + + return bFound; +} + + +/* +Check if there is any mouse movement in the sandbox. +*/ +BOOL mouse_movement() { + + POINT positionA = {}; + POINT positionB = {}; + + /* Retrieve the position of the mouse cursor, in screen coordinates */ + GetCursorPos(&positionA); + + /* Wait a moment */ + Sleep(5000); + + /* Retrieve the poition gain */ + GetCursorPos(&positionB); + + if ((positionA.x == positionB.x) && (positionA.y == positionB.y)) + /* Probably a sandbox, because mouse position did not change. */ + return TRUE; + + else + return FALSE; +} + + +/* +Check for the lack of user input. +This version is slightly different from the original: +https://www.lastline.com/labsblog/malware-evasion-techniques/ +It does not run inside an infinite loop (preventing al-khaser to get stuck) +*/ +BOOL lack_user_input() { + int correct_idle_time_counter = 0; + DWORD current_tick_count = 0, idle_time = 0; + LASTINPUTINFO last_input_info; // Contains the time of the last input + last_input_info.cbSize = sizeof(LASTINPUTINFO); + + for (int i = 0; i < 128; ++i) { + Sleep(0xb); + // Retrieves the time of the last input event + if (GetLastInputInfo(&last_input_info)) { + current_tick_count = GetTickCount(); + if (current_tick_count < last_input_info.dwTime) + // impossible case unless GetTickCount is manipulated + return TRUE; + if (current_tick_count - last_input_info.dwTime < 100) { + correct_idle_time_counter++; + if (correct_idle_time_counter >= 10) + return FALSE; + } + } + else // GetLastInputInfo must not fail + return TRUE; + } + return TRUE; +} + + +/* +Check if the machine have enough memory space, usually VM get a small ammount, +one reason if because several VMs are running on the same servers so they can run +more tasks at the same time. +*/ +BOOL memory_space() +{ + DWORDLONG ullMinRam = (1024LL * (1024LL * (1024LL * 1LL))); // 1GB + MEMORYSTATUSEX statex = { 0 }; + + statex.dwLength = sizeof(statex); + GlobalMemoryStatusEx(&statex); + + return (statex.ullTotalPhys < ullMinRam) ? TRUE : FALSE; +} + +/* +This trick consists of getting information about total amount of space. +This can be used to expose a sandbox. +*/ +BOOL disk_size_getdiskfreespace() +{ + ULONGLONG minHardDiskSize = (80ULL * (1024ULL * (1024ULL * (1024ULL)))); + LPCWSTR pszDrive = NULL; + BOOL bStatus = FALSE; + + // 64 bits integer, low and high bytes + ULARGE_INTEGER totalNumberOfBytes; + + // If the function succeeds, the return value is nonzero. If the function fails, the return value is 0 (zero). + bStatus = GetDiskFreeSpaceEx(pszDrive, NULL, &totalNumberOfBytes, NULL); + if (bStatus) { + if (totalNumberOfBytes.QuadPart < minHardDiskSize) // 80GB + return TRUE; + } + + return FALSE;; +} + +/* +Sleep and check if time have been accelerated +*/ +BOOL accelerated_sleep() +{ + DWORD dwStart = 0, dwEnd = 0, dwDiff = 0; + DWORD dwMillisecondsToSleep = 60 * 1000; + + /* Retrieves the number of milliseconds that have elapsed since the system was started */ + dwStart = GetTickCount(); + + /* Let's sleep 1 minute so Sandbox is interested to patch that */ + Sleep(dwMillisecondsToSleep); + + /* Do it again */ + dwEnd = GetTickCount(); + + /* If the Sleep function was patched*/ + dwDiff = dwEnd - dwStart; + if (dwDiff > dwMillisecondsToSleep - 1000) // substracted 1s just to be sure + return FALSE; + else + return TRUE; +} + +/* +The CPUID instruction is a processor supplementary instruction (its name derived from +CPU IDentification) for the x86 architecture allowing software to discover details of +the processor. By calling CPUID with EAX =1, The 31bit of ECX register if set will +reveal the precense of a hypervisor. +*/ +BOOL cpuid_is_hypervisor() +{ + INT CPUInfo[4] = { -1 }; + + /* Query hypervisor precense using CPUID (EAX=1), BIT 31 in ECX */ + __cpuid(CPUInfo, 1); + if ((CPUInfo[2] >> 31) & 1) + return TRUE; + else + return FALSE; +} + + +/* +If HV presence confirmed then it is good to know which type of hypervisor we have +When CPUID is called with EAX=0x40000000, cpuid return the hypervisor signature. +*/ +BOOL cpuid_hypervisor_vendor() +{ + INT CPUInfo[4] = { -1 }; + CHAR szHypervisorVendor[0x40]; + WCHAR *pwszConverted; + + BOOL bResult = FALSE; + + const TCHAR* szBlacklistedHypervisors[] = { + _T("KVMKVMKVM\0\0\0"), /* KVM */ + _T("Microsoft Hv"), /* Microsoft Hyper-V or Windows Virtual PC */ + _T("VMwareVMware"), /* VMware */ + _T("XenVMMXenVMM"), /* Xen */ + _T("prl hyperv "), /* Parallels */ + _T("VBoxVBoxVBox"), /* VirtualBox */ + }; + WORD dwlength = sizeof(szBlacklistedHypervisors) / sizeof(szBlacklistedHypervisors[0]); + + // __cpuid with an InfoType argument of 0 returns the number of + // valid Ids in CPUInfo[0] and the CPU identification string in + // the other three array elements. The CPU identification string is + // not in linear order. The code below arranges the information + // in a human readable form. + __cpuid(CPUInfo, 0x40000000); + memset(szHypervisorVendor, 0, sizeof(szHypervisorVendor)); + memcpy(szHypervisorVendor, CPUInfo + 1, 12); + + for (int i = 0; i < dwlength; i++) + { + pwszConverted = ascii_to_wide_str(szHypervisorVendor); + if (pwszConverted) { + + bResult = (_tcscmp(pwszConverted, szBlacklistedHypervisors[i]) == 0); + + free(pwszConverted); + + if (bResult) + return TRUE; + } + } + + return FALSE; +} + + +/* +Check SerialNumber devices using WMI +*/ +BOOL serial_number_bios_wmi() +{ + IWbemServices *pSvc = NULL; + IWbemLocator *pLoc = NULL; + IEnumWbemClassObject* pEnumerator = NULL; + BOOL bStatus = FALSE; + HRESULT hRes; + BOOL bFound = FALSE; + + // Init WMI + bStatus = InitWMI(&pSvc, &pLoc, _T("ROOT\\CIMV2")); + + if (bStatus) + { + // If success, execute the desired query + bStatus = ExecWMIQuery(&pSvc, &pLoc, &pEnumerator, _T("SELECT * FROM Win32_BIOS")); + if (bStatus) + { + // Get the data from the query + IWbemClassObject *pclsObj = NULL; + ULONG uReturn = 0; + VARIANT vtProp; + + while (pEnumerator) + { + hRes = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn); + if (0 == uReturn) + break; + + // Get the value of the Name property + hRes = pclsObj->Get(_T("SerialNumber"), 0, &vtProp, 0, 0); + if (SUCCEEDED(hRes)) { + if (vtProp.vt == VT_BSTR) { + + // Do our comparison + if ( + (StrStrI(vtProp.bstrVal, _T("VMWare")) != 0) || + (wcscmp(vtProp.bstrVal, _T("0")) == 0) || // VBox (serial is just "0") + (StrStrI(vtProp.bstrVal, _T("Xen")) != 0) || + (StrStrI(vtProp.bstrVal, _T("Virtual")) != 0) || + (StrStrI(vtProp.bstrVal, _T("A M I")) != 0) + ) + { + VariantClear(&vtProp); + pclsObj->Release(); + bFound = TRUE; + break; + } + } + VariantClear(&vtProp); + } + + // release the current result object + pclsObj->Release(); + } + + // Cleanup + pSvc->Release(); + pLoc->Release(); + pEnumerator->Release(); + CoUninitialize(); + } + } + + return bFound; +} + + +/* +Check Model from ComputerSystem using WMI +*/ +BOOL model_computer_system_wmi() +{ + IWbemServices *pSvc = NULL; + IWbemLocator *pLoc = NULL; + IEnumWbemClassObject* pEnumerator = NULL; + BOOL bStatus = FALSE; + HRESULT hRes; + BOOL bFound = FALSE; + + // Init WMI + bStatus = InitWMI(&pSvc, &pLoc, _T("ROOT\\CIMV2")); + + if (bStatus) + { + // If success, execute the desired query + bStatus = ExecWMIQuery(&pSvc, &pLoc, &pEnumerator, _T("SELECT * FROM Win32_ComputerSystem")); + if (bStatus) + { + // Get the data from the query + IWbemClassObject *pclsObj = NULL; + ULONG uReturn = 0; + VARIANT vtProp; + + while (pEnumerator) + { + hRes = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn); + if (0 == uReturn) + break; + + // Get the value of the Name property + hRes = pclsObj->Get(_T("Model"), 0, &vtProp, 0, 0); + if (SUCCEEDED(hRes)) { + if (vtProp.vt == VT_BSTR) { + + // Do our comparison + if ( + (StrStrI(vtProp.bstrVal, _T("VirtualBox")) != 0) || + (StrStrI(vtProp.bstrVal, _T("HVM domU")) != 0) || //Xen + (StrStrI(vtProp.bstrVal, _T("VMWare")) != 0) + ) + { + VariantClear(&vtProp); + pclsObj->Release(); + bFound = TRUE; + break; + } + } + VariantClear(&vtProp); + } + + // release the current result object + pclsObj->Release(); + } + + // Cleanup + pSvc->Release(); + pLoc->Release(); + pEnumerator->Release(); + CoUninitialize(); + } + } + + return bFound; +} + + +/* +Check Manufacturer from ComputerSystem using WMI +*/ +BOOL manufacturer_computer_system_wmi() +{ + IWbemServices *pSvc = NULL; + IWbemLocator *pLoc = NULL; + IEnumWbemClassObject* pEnumerator = NULL; + BOOL bStatus = FALSE; + HRESULT hRes; + BOOL bFound = FALSE; + + // Init WMI + bStatus = InitWMI(&pSvc, &pLoc, _T("ROOT\\CIMV2")); + + if (bStatus) + { + // If success, execute the desired query + bStatus = ExecWMIQuery(&pSvc, &pLoc, &pEnumerator, _T("SELECT * FROM Win32_ComputerSystem")); + if (bStatus) + { + // Get the data from the query + IWbemClassObject *pclsObj = NULL; + ULONG uReturn = 0; + VARIANT vtProp; + + while (pEnumerator) + { + hRes = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn); + if (0 == uReturn) + break; + + // Get the value of the Name property + hRes = pclsObj->Get(_T("Manufacturer"), 0, &vtProp, 0, 0); + if (SUCCEEDED(hRes)) { + if (vtProp.vt == VT_BSTR) { + + // Do our comparison + if ( + (StrStrI(vtProp.bstrVal, _T("VMWare")) != 0) || + (StrStrI(vtProp.bstrVal, _T("Xen")) != 0) || + (StrStrI(vtProp.bstrVal, _T("innotek GmbH")) != 0) || // Vbox + (StrStrI(vtProp.bstrVal, _T("QEMU")) != 0) + ) + { + VariantClear(&vtProp); + pclsObj->Release(); + bFound = TRUE; + break; + } + } + VariantClear(&vtProp); + } + // release the current result object + pclsObj->Release(); + } + + // Cleanup + pSvc->Release(); + pLoc->Release(); + pEnumerator->Release(); + CoUninitialize(); + } + } + + return bFound; +} + + +/* +Check Current Temperature using WMI, this requires admin privileges +In my tests, it works against vbox, vmware, kvm and xen. +*/ +BOOL current_temperature_acpi_wmi() +{ + IWbemServices *pSvc = NULL; + IWbemLocator *pLoc = NULL; + IEnumWbemClassObject* pEnumerator = NULL; + BOOL bStatus = FALSE; + HRESULT hRes; + BOOL bFound = FALSE; + + // This technique required admin priviliege + if (!IsElevated()) + return FALSE; + + // Init WMI + bStatus = InitWMI(&pSvc, &pLoc, _T("root\\WMI")); + + if (bStatus) + { + // If success, execute the desired query + bStatus = ExecWMIQuery(&pSvc, &pLoc, &pEnumerator, _T("SELECT * FROM MSAcpi_ThermalZoneTemperature")); + if (bStatus) + { + // Get the data from the query + IWbemClassObject *pclsObj = NULL; + ULONG uReturn = 0; + VARIANT vtProp; + + while (pEnumerator) + { + hRes = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn); + if (0 == uReturn) { + bFound = TRUE; + break; + } + + // Get the value of the Name property + hRes = pclsObj->Get(_T("CurrentTemperature"), 0, &vtProp, 0, 0); + if (SUCCEEDED(hRes)) { + VariantClear(&vtProp); + pclsObj->Release(); + break; + } + + // release the current result object + VariantClear(&vtProp); + pclsObj->Release(); + } + + // Cleanup + pSvc->Release(); + pLoc->Release(); + pEnumerator->Release(); + CoUninitialize(); + } + } + + return bFound; +} + +/* +Check ProcessId from Win32_Processor using WMI +KVM, XEN anv VMWare seems to return something, VBOX return NULL +*/ +BOOL process_id_processor_wmi() +{ + IWbemServices *pSvc = NULL; + IWbemLocator *pLoc = NULL; + IEnumWbemClassObject* pEnumerator = NULL; + BOOL bStatus = FALSE; + HRESULT hRes; + BOOL bFound = FALSE; + + // Init WMI + bStatus = InitWMI(&pSvc, &pLoc, _T("ROOT\\CIMV2")); + + if (bStatus) + { + // If success, execute the desired query + bStatus = ExecWMIQuery(&pSvc, &pLoc, &pEnumerator, _T("SELECT * FROM Win32_Processor")); + if (bStatus) + { + // Get the data from the query + IWbemClassObject *pclsObj = NULL; + ULONG uReturn = 0; + VARIANT vtProp; + + while (pEnumerator) + { + hRes = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn); + if (0 == uReturn) + break; + + // Get the value of the Name property + hRes = pclsObj->Get(_T("ProcessorId"), 0, &vtProp, 0, 0); + if (SUCCEEDED(hRes)) { + + // Do our comparison + if (vtProp.bstrVal == NULL) + { + bFound = TRUE; + } + } + // release the current result object + VariantClear(&vtProp); + pclsObj->Release(); + + // break from while + if (bFound) + break; + } + + // Cleanup + pSvc->Release(); + pLoc->Release(); + pEnumerator->Release(); + CoUninitialize(); + } + } + + return bFound; +} + +/* +Check what power states are enabled. +Most VMs don't support S1-S4 power states whereas most hardware does, and thermal control is usually not found either. +This has been tested on VirtualBox and Hyper-V, as well as a physical desktop and laptop. +*/ +BOOL power_capabilities() +{ + SYSTEM_POWER_CAPABILITIES powerCaps; + BOOL bFound = FALSE; + if (GetPwrCapabilities(&powerCaps) == TRUE) + { + if ((powerCaps.SystemS1 | powerCaps.SystemS2 | powerCaps.SystemS3 | powerCaps.SystemS4) == FALSE) + { + bFound = (powerCaps.ThermalControl == FALSE); + } + } + + return bFound; +} + + +/* +According to MSDN, this query should return a class that provides statistics on the CPU fan. +Win32/OilRig checks to see if the result of this query returned a class with more than 0 elements, +which would most likely be true in a non-virtual environment. +*/ +BOOL cpu_fan_wmi() +{ + IWbemServices *pSvc = NULL; + IWbemLocator *pLoc = NULL; + IEnumWbemClassObject* pEnumerator = NULL; + BOOL bStatus = FALSE; + HRESULT hRes; + BOOL bFound = FALSE; + ULONG uObjCount = 0; + + // Init WMI + bStatus = InitWMI(&pSvc, &pLoc, _T("ROOT\\CIMV2")); + if (bStatus) + { + // If success, execute the desired query + bStatus = ExecWMIQuery(&pSvc, &pLoc, &pEnumerator, _T("SELECT * FROM Win32_Fan")); + if (bStatus) + { + // Get the data from the query + IWbemClassObject *pclsObj = NULL; + ULONG uReturn = 0; + + while (pEnumerator) + { + hRes = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn); + if (0 == uReturn) { + break; + } + else { + uObjCount++; + pclsObj->Release(); + } + } + + // Cleanup + pSvc->Release(); + pLoc->Release(); + pEnumerator->Release(); + CoUninitialize(); + } + } + + if (uObjCount == 0) + bFound = TRUE; + return bFound; +} + + +/* +Check Caption from VideoController using WMI +*/ +BOOL caption_video_controller_wmi() +{ + IWbemServices *pSvc = NULL; + IWbemLocator *pLoc = NULL; + IEnumWbemClassObject* pEnumerator = NULL; + BOOL bStatus = FALSE; + HRESULT hRes; + BOOL bFound = FALSE; + + // Init WMI + bStatus = InitWMI(&pSvc, &pLoc, _T("ROOT\\CIMV2")); + + if (bStatus) + { + // If success, execute the desired query + bStatus = ExecWMIQuery(&pSvc, &pLoc, &pEnumerator, _T("SELECT * FROM Win32_VideoController")); + if (bStatus) + { + // Get the data from the query + IWbemClassObject *pclsObj = NULL; + ULONG uReturn = 0; + VARIANT vtProp; + + while (pEnumerator) + { + hRes = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn); + if (0 == uReturn) + break; + + // Get the value of the Name property + hRes = pclsObj->Get(_T("Caption"), 0, &vtProp, 0, 0); + if (SUCCEEDED(hRes)) { + if (vtProp.vt == VT_BSTR) { + + // Do our comparison + if ( + (StrStrI(vtProp.bstrVal, _T("Hyper-V")) != 0) || + (StrStrI(vtProp.bstrVal, _T("VMWare")) != 0) + ) + { + VariantClear(&vtProp); + pclsObj->Release(); + bFound = TRUE; + break; + } + } + VariantClear(&vtProp); + } + + // release the current result object + pclsObj->Release(); + } + + // Cleanup + pSvc->Release(); + pLoc->Release(); + pEnumerator->Release(); + CoUninitialize(); + } + } + + return bFound; +} + +/* +Detect Virtual machine by calling NtQueryLicenseValue with Kernel-VMDetection-Private as license value. +This detection works on Windows 7 and does not detect Microsoft Hypervisor. +*/ +BOOL query_license_value() +{ + auto RtlInitUnicodeString = static_cast(API::GetAPI(API_IDENTIFIER::API_RtlInitUnicodeString)); + auto NtQueryLicenseValue = static_cast(API::GetAPI(API_IDENTIFIER::API_NtQueryLicenseValue)); + + if (RtlInitUnicodeString == nullptr || NtQueryLicenseValue == nullptr) + return FALSE; + + UNICODE_STRING LicenseValue; + RtlInitUnicodeString(&LicenseValue, L"Kernel-VMDetection-Private"); + + ULONG Result = 0, ReturnLength; + + NTSTATUS Status = NtQueryLicenseValue(&LicenseValue, NULL, reinterpret_cast(&Result), sizeof(ULONG), &ReturnLength); + + if (NT_SUCCESS(Status)) { + return (Result != 0); + } + + return FALSE; +} + +int wmi_query_count(const _TCHAR* query) +{ + IWbemServices *pSvc = NULL; + IWbemLocator *pLoc = NULL; + IEnumWbemClassObject* pEnumerator = NULL; + BOOL bStatus = FALSE; + HRESULT hRes; + + int count = 0; + + // Init WMI + bStatus = InitWMI(&pSvc, &pLoc, _T("ROOT\\CIMV2")); + if (bStatus) + { + // If success, execute the desired query + bStatus = ExecWMIQuery(&pSvc, &pLoc, &pEnumerator, query); + if (bStatus) + { + // Get the data from the query + IWbemClassObject *pclsObj = NULL; + ULONG uReturn = 0; + + // Iterate over our enumator + while (pEnumerator) + { + hRes = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn); + if (0 == uReturn) + break; + + count++; + + pclsObj->Release(); + } + + // Cleanup + pEnumerator->Release(); + pSvc->Release(); + pLoc->Release(); + CoUninitialize(); + } + else + { + pSvc->Release(); + pLoc->Release(); + CoUninitialize(); + } + } + else return -1; + + return count; +} + +/* +Check Win32_CacheMemory for entries +*/ +BOOL cachememory_wmi() +{ + int count = wmi_query_count(_T("SELECT * FROM Win32_CacheMemory")); + if (count == 0) + { + return TRUE; + } + return FALSE; +} + +/* +Check Win32_PhysicalMemory for entries +*/ +BOOL physicalmemory_wmi() +{ + int count = wmi_query_count(_T("SELECT * FROM Win32_PhysicalMemory")); + if (count == 0) + { + return TRUE; + } + return FALSE; +} + +/* +Check Win32_MemoryDevice for entries +*/ +BOOL memorydevice_wmi() +{ + int count = wmi_query_count(_T("SELECT * FROM Win32_MemoryDevice")); + if (count == 0) + { + return TRUE; + } + return FALSE; +} + +/* +Check Win32_MemoryArray for entries +*/ +BOOL memoryarray_wmi() +{ + int count = wmi_query_count(_T("SELECT * FROM Win32_MemoryArray")); + if (count == 0) + { + return TRUE; + } + return FALSE; +} + +/* +Check Win32_VoltageProbe for entries +*/ +BOOL voltageprobe_wmi() +{ + int count = wmi_query_count(_T("SELECT * FROM Win32_VoltageProbe")); + if (count == 0) + { + return TRUE; + } + return FALSE; +} + +/* +Check Win32_PortConnector for entries +*/ +BOOL portconnector_wmi() +{ + int count = wmi_query_count(_T("SELECT * FROM Win32_PortConnector")); + if (count == 0) + { + return TRUE; + } + return FALSE; +} + +/* +Check Win32_SMBIOSMemory for entries +*/ +BOOL smbiosmemory_wmi() +{ + int count = wmi_query_count(_T("SELECT * FROM Win32_SMBIOSMemory")); + if (count == 0) + { + return TRUE; + } + return FALSE; +} + +/* +Check Win32_PerfFormattedData_Counters_ThermalZoneInformation for entries +*/ +BOOL perfctrs_thermalzoneinfo_wmi() +{ + int count = wmi_query_count(_T("SELECT * FROM Win32_PerfFormattedData_Counters_ThermalZoneInformation")); + if (count == 0) + { + return TRUE; + } + return FALSE; +} + +/* +Check CIM_Memory for entries +*/ +BOOL cim_memory_wmi() +{ + int count = wmi_query_count(_T("SELECT * FROM CIM_Memory")); + if (count == 0) + { + return TRUE; + } + return FALSE; +} + +/* +Check CIM_NumericSensor for entries +*/ +BOOL cim_numericsensor_wmi() +{ + int count = wmi_query_count(_T("SELECT * FROM CIM_NumericSensor")); + if (count == 0) + { + return TRUE; + } + return FALSE; +} + +/* +Check CIM_PhysicalConnector for entries +*/ +BOOL cim_physicalconnector_wmi() +{ + int count = wmi_query_count(_T("SELECT * FROM CIM_PhysicalConnector")); + if (count == 0) + { + return TRUE; + } + return FALSE; +} + +/* +Check CIM_Sensor for entries +*/ +BOOL cim_sensor_wmi() +{ + int count = wmi_query_count(_T("SELECT * FROM CIM_Sensor")); + if (count == 0) + { + return TRUE; + } + return FALSE; +} + +/* +Check CIM_Slot for entries +*/ +BOOL cim_slot_wmi() +{ + int count = wmi_query_count(_T("SELECT * FROM CIM_Slot")); + if (count == 0) + { + return TRUE; + } + return FALSE; +} + +/* +Check CIM_TemperatureSensor for entries +*/ +BOOL cim_temperaturesensor_wmi() +{ + int count = wmi_query_count(_T("SELECT * FROM CIM_TemperatureSensor")); + if (count == 0) + { + return TRUE; + } + return FALSE; +} + +/* +Check CIM_VoltageSensor for entries +*/ +BOOL cim_voltagesensor_wmi() +{ + int count = wmi_query_count(_T("SELECT * FROM CIM_VoltageSensor")); + if (count == 0) + { + return TRUE; + } + return FALSE; +} + +/* +Checks whether the specified application is a genuine Windows installation. + +*/ + +#define WINDOWS_SLID \ + { 0x55c92734, \ + 0xd682, \ + 0x4d71, \ + { 0x98, 0x3e, 0xd6, 0xec, 0x3f, 0x16, 0x05, 0x9f } \ + } + +BOOL pirated_windows() +{ + CONST SLID AppId = WINDOWS_SLID; + SL_GENUINE_STATE GenuineState; + HRESULT hResult; + + hResult = SLIsGenuineLocal(&AppId, &GenuineState, NULL); + + if (hResult == S_OK) { + if (GenuineState != SL_GEN_STATE_IS_GENUINE) { + return TRUE; + } + } + return FALSE; +} + +/* Check HKLM\System\CurrentControlSet\Services\Disk\Enum for values related + * to virtual machines. */ +BOOL registry_services_disk_enum() +{ + HKEY hkResult = NULL; + const TCHAR* diskEnumKey = _T("System\\CurrentControlSet\\Services\\Disk\\Enum"); + DWORD diskCount = 0; + DWORD cbData = sizeof(diskCount); + const TCHAR* szChecks[] = { + /* Checked for by Smokeloader + * https://research.checkpoint.com/2019-resurgence-of-smokeloader/*/ + _T("qemu"), + _T("virtio"), + _T("vmware"), + _T("vbox"), + _T("xen"), + + /* Checked for by Kutaki (not including ones from above) + * https://cofense.com/kutaki-malware-bypasses-gateways-steal-users-credentials/ */ + _T("VMW"), + _T("Virtual"), + + }; + WORD dwChecksLength = sizeof(szChecks) / sizeof(szChecks[0]); + BOOL bFound = FALSE; + + /* Each disk has a corresponding value where the value name starts at '0' for + * the first disk and increases by 1 for each subsequent disk. The 'Count' + * value appears to store the total number of disk entries.*/ + + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, diskEnumKey, NULL, KEY_READ, &hkResult) == ERROR_SUCCESS) + { + if (RegQueryValueEx(hkResult, _T("Count"), NULL, NULL, (LPBYTE)&diskCount, &cbData) != ERROR_SUCCESS) + { + RegCloseKey(hkResult); + return bFound; + } + RegCloseKey(hkResult); + } + + for (unsigned int i = 0; i < diskCount; i++) { + TCHAR subkey[11]; + + _stprintf_s(subkey, sizeof(subkey) / sizeof(subkey[0]), _T("%d"), i); + + for (unsigned int j = 0; j < dwChecksLength; j++) { + //_tprintf(_T("Checking %s %s for %s (%d)\n"), diskEnumKey, subkey, szChecks[j], diskCount); + if (Is_RegKeyValueExists(HKEY_LOCAL_MACHINE, diskEnumKey, subkey, szChecks[j])) { + bFound = TRUE; + break; + } + } + if (bFound) { + break; + } + } + return bFound; +} + +BOOL registry_disk_enum() +{ + HKEY hkResult = NULL; + const TCHAR* szEntries[] = { + _T("System\\CurrentControlSet\\Enum\\IDE"), + _T("System\\CurrentControlSet\\Enum\\SCSI"), + }; + const TCHAR* szChecks[] = { + /* Checked for by Smokeloader + * https://research.checkpoint.com/2019-resurgence-of-smokeloader/*/ + _T("qemu"), + _T("virtio"), + _T("vmware"), + _T("vbox"), + _T("xen"), + + /* Checked for by Kutaki (not including ones from above) + * https://cofense.com/kutaki-malware-bypasses-gateways-steal-users-credentials/ */ + _T("VMW"), + _T("Virtual"), + + }; + WORD dwEntriesLength = sizeof(szEntries) / sizeof(szEntries[0]); + WORD dwChecksLength = sizeof(szChecks) / sizeof(szChecks[0]); + BOOL bFound = FALSE; + + for (unsigned int i = 0; i < dwEntriesLength; i++) { + DWORD cSubKeys = 0; + DWORD cbMaxSubKeyLen = 0; + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, szEntries[i], NULL, KEY_READ, &hkResult) != ERROR_SUCCESS) { + continue; + } + + if (RegQueryInfoKey(hkResult, NULL, NULL, NULL, &cSubKeys, &cbMaxSubKeyLen, NULL, NULL, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) { + RegCloseKey(hkResult); + continue; + } + + DWORD subKeyBufferLen = (cbMaxSubKeyLen + 1) * sizeof(TCHAR); + TCHAR* subKeyBuffer = (TCHAR *)malloc(subKeyBufferLen); + if (!subKeyBuffer) { + RegCloseKey(hkResult); + continue; + } + + for (unsigned int j = 0; j < cSubKeys; j++) { + DWORD cchName = subKeyBufferLen; + if (RegEnumKeyEx(hkResult, j, subKeyBuffer, &cchName, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) { + continue; + } + for (unsigned int k = 0; k < dwChecksLength; k++) { + //_tprintf(_T("Checking %s %s for %s (%d)\n"), szEntries[i], subKeyBuffer, szChecks[k], cSubKeys); + if (StrStrI(subKeyBuffer, szChecks[k]) != NULL) { + bFound = TRUE; + break; + } + } + if (bFound) { + break; + } + } + + free(subKeyBuffer); + RegCloseKey(hkResult); + + if (bFound) { + break; + } + } + return bFound; +} + +BOOL handle_one_table(BYTE* currentPosition, UINT& bias, BYTE* smBiosTableBoundary) +{ + struct SmbiosTableHeader + { + BYTE type; // Table type + BYTE length; // Length of the table + WORD handle; // Handle of the table + }; + + SmbiosTableHeader* tableHeader = reinterpret_cast(currentPosition); + SmbiosTableHeader* tableBoundary = reinterpret_cast(smBiosTableBoundary); + + const BYTE lastEntry = 127; + if (tableHeader->type == lastEntry) { + // End of tables reached + return TRUE; + } + + currentPosition += tableHeader->length; + UINT i = 0; + // Find the end of the table + while (!(currentPosition[i] == 0 && currentPosition[i + 1] == 0) + && (currentPosition + i + 1 < smBiosTableBoundary)) + { + i++; + } + //pair of terminal zeros + i += 2; + bias = i + tableHeader->length; + + return FALSE; +} + +BOOL check_tables_number(const PBYTE smbios) +{ + struct RawSMBIOSData + { + BYTE method; // Access method(obsolete) + BYTE mjVer; // Major part of the SMB version(major) + BYTE mnVer; // Minor part of the SMB version(minor) + BYTE dmiRev; // DMI version(obsolete) + DWORD length; // Data table size + BYTE tableData[]; // Table data + }; + + RawSMBIOSData* smBiosData = reinterpret_cast(smbios); + BYTE* smBiosTableBoundary = smBiosData->tableData + smBiosData->length; + BYTE* currentPosition = smBiosData->tableData; + UINT tableNumber = 0; + + while (currentPosition < smBiosTableBoundary) { + UINT biasNewTable = 0; + tableNumber++; + if (handle_one_table(currentPosition, biasNewTable, smBiosTableBoundary)) + { + break; + } + currentPosition += biasNewTable; + } + + const UINT tableMinReal = 40; + if (tableNumber <= tableMinReal) + { + return TRUE; + } + return FALSE; +} + +/* +Check for SMBIOS tables number +*/ +BOOL number_SMBIOS_tables() +{ + BOOL result = FALSE; + + DWORD smbiosSize = 0; + PBYTE smbios = get_system_firmware(static_cast('RSMB'), 0x0000, &smbiosSize); + if (smbios != NULL) + { + result = check_tables_number(smbios); + free(smbios); + } + return result; +} diff --git a/byp/sbexecution/AntiVM/Generic.h b/byp/sbexecution/AntiVM/Generic.h new file mode 100644 index 00000000..3d9c4d94 --- /dev/null +++ b/byp/sbexecution/AntiVM/Generic.h @@ -0,0 +1,52 @@ +#pragma once + +VOID loaded_dlls(); +VOID known_file_names(); +VOID known_usernames(); +VOID known_hostnames(); +VOID other_known_sandbox_environment_checks(); +BOOL NumberOfProcessors(); +BOOL idt_trick(); +BOOL ldt_trick(); +BOOL gdt_trick(); +BOOL str_trick(); +BOOL number_cores_wmi(); +BOOL disk_size_wmi(); +BOOL setupdi_diskdrive(); +BOOL mouse_movement(); +BOOL lack_user_input(); +BOOL memory_space(); +BOOL dizk_size_deviceiocontrol(); +BOOL disk_size_getdiskfreespace(); +BOOL accelerated_sleep(); +BOOL cpuid_is_hypervisor(); +BOOL cpuid_hypervisor_vendor(); +BOOL serial_number_bios_wmi(); +BOOL model_computer_system_wmi(); +BOOL manufacturer_computer_system_wmi(); +BOOL current_temperature_acpi_wmi(); +BOOL process_id_processor_wmi(); +BOOL power_capabilities(); +BOOL hybridanalysismacdetect(); +BOOL cpu_fan_wmi(); +BOOL caption_video_controller_wmi(); +BOOL query_license_value(); +BOOL cachememory_wmi(); +BOOL physicalmemory_wmi(); +BOOL memorydevice_wmi(); +BOOL memoryarray_wmi(); +BOOL voltageprobe_wmi(); +BOOL portconnector_wmi(); +BOOL smbiosmemory_wmi(); +BOOL perfctrs_thermalzoneinfo_wmi(); +BOOL cim_memory_wmi(); +BOOL cim_numericsensor_wmi(); +BOOL cim_physicalconnector_wmi(); +BOOL cim_sensor_wmi(); +BOOL cim_slot_wmi(); +BOOL cim_temperaturesensor_wmi(); +BOOL cim_voltagesensor_wmi(); +BOOL pirated_windows(); +BOOL registry_services_disk_enum(); +BOOL registry_disk_enum(); +BOOL number_SMBIOS_tables(); \ No newline at end of file diff --git a/byp/sbexecution/AntiVM/HyperV.cpp b/byp/sbexecution/AntiVM/HyperV.cpp new file mode 100644 index 00000000..be1b7e34 --- /dev/null +++ b/byp/sbexecution/AntiVM/HyperV.cpp @@ -0,0 +1,70 @@ +#include "pch.h" +#include "HyperV.h" + + +BOOL check_hyperv_driver_objects() +{ + auto driverList = enumerate_object_directory(L"\\Driver"); + if (driverList == nullptr) + { + return FALSE; + } + for (wchar_t* driver : *driverList) + { + if (StrCmpCW(driver, L"VMBusHID") == 0) + { + return TRUE; + } + if (StrCmpCW(driver, L"vmbus") == 0) + { + return TRUE; + } + if (StrCmpCW(driver, L"vmgid") == 0) + { + return TRUE; + } + if (StrCmpCW(driver, L"IndirectKmd") == 0) + { + return TRUE; + } + if (StrCmpCW(driver, L"HyperVideo") == 0) + { + return TRUE; + } + if (StrCmpCW(driver, L"hyperkbd") == 0) + { + return TRUE; + } + } + return FALSE; +} + + +BOOL check_hyperv_global_objects() +{ + auto globalObjs = enumerate_object_directory(L"\\GLOBAL??"); + if (globalObjs == nullptr) + { + return FALSE; + } + for (wchar_t* globalObj : *globalObjs) + { + if (StrStrW(globalObj, L"VMBUS#") != NULL) + { + return TRUE; + } + if (StrCmpCW(globalObj, L"VDRVROOT") == 0) + { + return TRUE; + } + if (StrCmpCW(globalObj, L"VmGenerationCounter") == 0) + { + return TRUE; + } + if (StrCmpCW(globalObj, L"VmGid") == 0) + { + return TRUE; + } + } + return FALSE; +} diff --git a/byp/sbexecution/AntiVM/HyperV.h b/byp/sbexecution/AntiVM/HyperV.h new file mode 100644 index 00000000..d099a707 --- /dev/null +++ b/byp/sbexecution/AntiVM/HyperV.h @@ -0,0 +1,4 @@ +#pragma once + +BOOL check_hyperv_driver_objects(); +BOOL check_hyperv_global_objects(); diff --git a/byp/sbexecution/AntiVM/KVM.cpp b/byp/sbexecution/AntiVM/KVM.cpp new file mode 100644 index 00000000..4ecae99b --- /dev/null +++ b/byp/sbexecution/AntiVM/KVM.cpp @@ -0,0 +1,99 @@ +#include "pch.h" + + +/* +Check against kvm registry keys +*/ +VOID kvm_reg_keys() +{ + /* Array of strings of blacklisted registry keys */ + const TCHAR* szKeys[] = { + _T("SYSTEM\\ControlSet001\\Services\\vioscsi"), + _T("SYSTEM\\ControlSet001\\Services\\viostor"), + _T("SYSTEM\\ControlSet001\\Services\\VirtIO-FS Service"), + _T("SYSTEM\\ControlSet001\\Services\\VirtioSerial"), + _T("SYSTEM\\ControlSet001\\Services\\BALLOON"), + _T("SYSTEM\\ControlSet001\\Services\\BalloonService"), + _T("SYSTEM\\ControlSet001\\Services\\netkvm"), + }; + + WORD dwlength = sizeof(szKeys) / sizeof(szKeys[0]); + + /* Check one by one */ + for (int i = 0; i < dwlength; i++) + { + 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])) + print_results(TRUE, msg); + else + print_results(FALSE, msg); + } +} + +/* +Check against kvm blacklisted files +*/ +VOID kvm_files() +{ + /* Array of strings of blacklisted paths */ + const TCHAR* szPaths[] = { + _T("System32\\drivers\\balloon.sys"), + _T("System32\\drivers\\netkvm.sys"), + _T("System32\\drivers\\pvpanic.sys"), + _T("System32\\drivers\\viofs.sys"), + _T("System32\\drivers\\viogpudo.sys"), + _T("System32\\drivers\\vioinput.sys"), + _T("System32\\drivers\\viorng.sys"), + _T("System32\\drivers\\vioscsi.sys"), + _T("System32\\drivers\\vioser.sys"), + _T("System32\\drivers\\viostor.sys"), + + }; + + /* Getting Windows Directory */ + WORD dwlength = sizeof(szPaths) / sizeof(szPaths[0]); + TCHAR szWinDir[MAX_PATH] = _T(""); + TCHAR szPath[MAX_PATH] = _T(""); + PVOID OldValue = NULL; + + GetWindowsDirectory(szWinDir, MAX_PATH); + + if (IsWoW64()) { + Wow64DisableWow64FsRedirection(&OldValue); + } + + /* Check one by one */ + for (int i = 0; i < dwlength; i++) + { + 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)) + print_results(TRUE, msg); + else + print_results(FALSE, msg); + } + + if (IsWoW64()) { + Wow64RevertWow64FsRedirection(&OldValue); + } +} + +/* +Check against kvm blacklisted directories +*/ +BOOL kvm_dir() +{ + TCHAR szProgramFile[MAX_PATH]; + TCHAR szPath[MAX_PATH] = _T(""); + TCHAR szTarget[MAX_PATH] = _T("Virtio-Win\\"); + + if (IsWoW64()) + ExpandEnvironmentStrings(_T("%ProgramW6432%"), szProgramFile, ARRAYSIZE(szProgramFile)); + else + SHGetSpecialFolderPath(NULL, szProgramFile, CSIDL_PROGRAM_FILES, FALSE); + + PathCombine(szPath, szProgramFile, szTarget); + return is_DirectoryExists(szPath); +} \ No newline at end of file diff --git a/byp/sbexecution/AntiVM/KVM.h b/byp/sbexecution/AntiVM/KVM.h new file mode 100644 index 00000000..b92b0dad --- /dev/null +++ b/byp/sbexecution/AntiVM/KVM.h @@ -0,0 +1,5 @@ +#pragma once + +VOID kvm_reg_keys(); +VOID kvm_files(); +BOOL kvm_dir(); diff --git a/byp/sbexecution/AntiVM/Parallels.cpp b/byp/sbexecution/AntiVM/Parallels.cpp new file mode 100644 index 00000000..9b14b554 --- /dev/null +++ b/byp/sbexecution/AntiVM/Parallels.cpp @@ -0,0 +1,36 @@ +#include "pch.h" + +#include "Parallels.h" + +/* +Check for process list +*/ + +VOID parallels_process() +{ + const TCHAR *szProcesses[] = { + _T("prl_cc.exe"), + _T("prl_tools.exe"), + }; + + WORD iLength = sizeof(szProcesses) / sizeof(szProcesses[0]); + for (int i = 0; i < iLength; i++) + { + TCHAR msg[256] = _T(""); + _stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking Parallels processes: %s"), szProcesses[i]); + if (GetProcessIdFromName(szProcesses[i])) + print_results(TRUE, msg); + else + print_results(FALSE, msg); + } +} + + +/* +Check Parallels NIC MAC address +*/ +BOOL parallels_check_mac() +{ + // Parallels, Inc. + return check_mac_addr(_T("\x00\x1C\x42")); +} diff --git a/byp/sbexecution/AntiVM/Parallels.h b/byp/sbexecution/AntiVM/Parallels.h new file mode 100644 index 00000000..34036c15 --- /dev/null +++ b/byp/sbexecution/AntiVM/Parallels.h @@ -0,0 +1,4 @@ +#pragma once + +VOID parallels_process(); +BOOL parallels_check_mac(); \ No newline at end of file diff --git a/byp/sbexecution/AntiVM/Qemu.cpp b/byp/sbexecution/AntiVM/Qemu.cpp new file mode 100644 index 00000000..143d3921 --- /dev/null +++ b/byp/sbexecution/AntiVM/Qemu.cpp @@ -0,0 +1,167 @@ +#include "pch.h" + +#include "Qemu.h" + +/* +Registry key values +*/ + +VOID qemu_reg_key_value() +{ + /* Array of strings of blacklisted registry key values */ + const TCHAR *szEntries[][3] = { + { _T("HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port 0\\Scsi Bus 0\\Target Id 0\\Logical Unit Id 0"), _T("Identifier"), _T("QEMU") }, + { _T("HARDWARE\\Description\\System"), _T("SystemBiosVersion"), _T("QEMU") }, + }; + + WORD dwLength = sizeof(szEntries) / sizeof(szEntries[0]); + + for (int i = 0; i < dwLength; i++) + { + 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])) + print_results(TRUE, msg); + else + print_results(FALSE, msg); + } +} + + + +/* +Check for process list +*/ + +VOID qemu_processes() +{ + const TCHAR *szProcesses[] = { + _T("qemu-ga.exe"), // QEMU guest agent. + _T("vdagent.exe"), // SPICE guest tools. + _T("vdservice.exe"), // SPICE guest tools. + }; + + WORD iLength = sizeof(szProcesses) / sizeof(szProcesses[0]); + for (int i = 0; i < iLength; i++) + { + TCHAR msg[256] = _T(""); + _stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking qemu processes %s "), szProcesses[i]); + if (GetProcessIdFromName(szProcesses[i])) + print_results(TRUE, msg); + else + print_results(FALSE, msg); + } +} + +/* +Check against blacklisted directories. +*/ +VOID qemu_dir() +{ + TCHAR szProgramFile[MAX_PATH]; + TCHAR szPath[MAX_PATH] = _T(""); + + const TCHAR* szDirectories[] = { + _T("qemu-ga"), // QEMU guest agent. + _T("SPICE Guest Tools"), // SPICE guest tools. + }; + + WORD iLength = sizeof(szDirectories) / sizeof(szDirectories[0]); + for (int i = 0; i < iLength; i++) + { + TCHAR msg[256] = _T(""); + + if (IsWoW64()) + ExpandEnvironmentStrings(_T("%ProgramW6432%"), szProgramFile, ARRAYSIZE(szProgramFile)); + else + SHGetSpecialFolderPath(NULL, szProgramFile, CSIDL_PROGRAM_FILES, FALSE); + + PathCombine(szPath, szProgramFile, szDirectories[i]); + + _stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking QEMU directory %s "), szPath); + if (is_DirectoryExists(szPath)) + print_results(TRUE, msg); + else + print_results(FALSE, msg); + } +} + + +/* +Check for SMBIOS firmware +*/ +BOOL qemu_firmware_SMBIOS() +{ + BOOL result = FALSE; + + DWORD smbiosSize = 0; + PBYTE smbios = get_system_firmware(static_cast('RSMB'), 0x0000, &smbiosSize); + if (smbios != NULL) + { + PBYTE qemuString1 = (PBYTE)"qemu"; + size_t StringLen = 4; + PBYTE qemuString2 = (PBYTE)"QEMU"; + + if (find_str_in_data(qemuString1, StringLen, smbios, smbiosSize) || + find_str_in_data(qemuString2, StringLen, smbios, smbiosSize)) + { + result = TRUE; + } + + free(smbios); + } + + return result; +} + + +/* +Check for ACPI firmware +*/ +BOOL qemu_firmware_ACPI() +{ + BOOL result = FALSE; + + PDWORD tableNames = static_cast(malloc(4096)); + + if (tableNames) { + SecureZeroMemory(tableNames, 4096); + DWORD tableSize = enum_system_firmware_tables(static_cast('ACPI'), tableNames, 4096); + + // API not available + if (tableSize == -1) + return FALSE; + + DWORD tableCount = tableSize / 4; + if (tableSize < 4 || tableCount == 0) + { + result = TRUE; + } + else + { + for (DWORD i = 0; i < tableCount; i++) + { + DWORD tableSize = 0; + PBYTE table = get_system_firmware(static_cast('ACPI'), tableNames[i], &tableSize); + + if (table) { + + PBYTE qemuString1 = (PBYTE)"BOCHS"; + size_t StringLen = 4; + PBYTE qemuString2 = (PBYTE)"BXPC"; + + if (find_str_in_data(qemuString1, StringLen, table, tableSize) || + find_str_in_data(qemuString2, StringLen, table, tableSize)) + { + result = TRUE; + } + + free(table); + } + } + } + + free(tableNames); + } + return result; +} diff --git a/byp/sbexecution/AntiVM/Qemu.h b/byp/sbexecution/AntiVM/Qemu.h new file mode 100644 index 00000000..6a632ddc --- /dev/null +++ b/byp/sbexecution/AntiVM/Qemu.h @@ -0,0 +1,7 @@ +#pragma once + +VOID qemu_reg_key_value(); +VOID qemu_processes(); +VOID qemu_dir(); +BOOL qemu_firmware_ACPI(); +BOOL qemu_firmware_SMBIOS(); diff --git a/byp/sbexecution/AntiVM/Services.cpp b/byp/sbexecution/AntiVM/Services.cpp new file mode 100644 index 00000000..33686e80 --- /dev/null +++ b/byp/sbexecution/AntiVM/Services.cpp @@ -0,0 +1,117 @@ +#include "pch.h" + +#include "Services.h" + +BOOL VMDriverServices() +{ + const int KnownServiceCount = 13; + const TCHAR* KnownVMServices[KnownServiceCount] = { + L"VBoxWddm", + L"VBoxSF", //VirtualBox Shared Folders + L"VBoxMouse", //VirtualBox Guest Mouse + L"VBoxGuest", //VirtualBox Guest Driver + L"vmci", //VMWare VMCI Bus Driver + L"vmhgfs", //VMWare Host Guest Control Redirector + L"vmmouse", + L"vmmemctl", //VMWare Guest Memory Controller Driver + L"vmusb", + L"vmusbmouse", + L"vmx_svga", + L"vmxnet", + L"vmx86" + }; + + SC_HANDLE hSCM = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT | SC_MANAGER_ENUMERATE_SERVICE); + if (hSCM != NULL) + { + ENUM_SERVICE_STATUS_PROCESS* services = NULL; + DWORD serviceCount = 0; + if (get_services(hSCM, SERVICE_DRIVER, &services, &serviceCount)) + { + bool ok = true; + + for (DWORD i = 0; i < serviceCount; i++) + { + for (int s = 0; s < KnownServiceCount; s++) + { + if (StrCmpIW(services[i].lpServiceName, KnownVMServices[s]) == 0) + { + ok = false; + break; + } + } + } + + free(services); + + if (ok) + { + CloseServiceHandle(hSCM); + return FALSE; + } + + } + else + { + printf("Failed to get services list.\n"); + } + CloseServiceHandle(hSCM); + } + else + { + printf("Failed to get SCM handle.\n"); + } + + return TRUE; +} + +BOOL get_services(_In_ SC_HANDLE hServiceManager, _In_ DWORD serviceType, _Out_ ENUM_SERVICE_STATUS_PROCESS** servicesBuffer, _Out_ DWORD* serviceCount) +{ + DWORD serviceBufferSize = 1024 * sizeof(ENUM_SERVICE_STATUS_PROCESS); + ENUM_SERVICE_STATUS_PROCESS* services = static_cast(malloc(serviceBufferSize)); + + if (serviceCount) //assume failure + *serviceCount = 0; + + if (services) { + + SecureZeroMemory(services, serviceBufferSize); + + DWORD remainderBufferSize = 0; + DWORD resumeHandle = 0; + if (EnumServicesStatusEx(hServiceManager, SC_ENUM_PROCESS_INFO, serviceType, SERVICE_STATE_ALL, (LPBYTE)services, serviceBufferSize, &remainderBufferSize, serviceCount, &resumeHandle, NULL) != 0) + { + // success and we enumerated all the services + *servicesBuffer = services; + return TRUE; + } + + DWORD lastError = GetLastError(); + if (lastError == ERROR_MORE_DATA) + { + // we didn't get all the services, so we'll just re-enumerate all to make things easy + serviceBufferSize += remainderBufferSize; + + ENUM_SERVICE_STATUS_PROCESS* tmp; + + tmp = static_cast(realloc(services, serviceBufferSize)); + if (tmp) { + services = tmp; + SecureZeroMemory(services, serviceBufferSize); + if (EnumServicesStatusEx(hServiceManager, SC_ENUM_PROCESS_INFO, serviceType, SERVICE_STATE_ALL, (LPBYTE)services, serviceBufferSize, &remainderBufferSize, serviceCount, NULL, NULL) != 0) + { + *servicesBuffer = services; + return TRUE; + } + } + } + else + { + printf("ERROR: %u\n", lastError); + } + + free(services); + + } + return FALSE; +} diff --git a/byp/sbexecution/AntiVM/Services.h b/byp/sbexecution/AntiVM/Services.h new file mode 100644 index 00000000..d3f42255 --- /dev/null +++ b/byp/sbexecution/AntiVM/Services.h @@ -0,0 +1,4 @@ +#pragma once + +BOOL VMDriverServices(); +BOOL get_services(_In_ SC_HANDLE hServiceManager, _In_ DWORD serviceType, _Out_ ENUM_SERVICE_STATUS_PROCESS** servicesBuffer, _Out_ DWORD* serviceCount); diff --git a/byp/sbexecution/AntiVM/VMWare.cpp b/byp/sbexecution/AntiVM/VMWare.cpp new file mode 100644 index 00000000..e7c3e2b6 --- /dev/null +++ b/byp/sbexecution/AntiVM/VMWare.cpp @@ -0,0 +1,297 @@ +#include "pch.h" + +#include "VMWare.h" + +/* +Check against VMWare registry key values +*/ +VOID vmware_reg_key_value() +{ + /* Array of strings of blacklisted registry key values */ + const TCHAR *szEntries[][3] = { + { _T("HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port 0\\Scsi Bus 0\\Target Id 0\\Logical Unit Id 0"), _T("Identifier"), _T("VMWARE") }, + { _T("HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port 1\\Scsi Bus 0\\Target Id 0\\Logical Unit Id 0"), _T("Identifier"), _T("VMWARE") }, + { _T("HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port 2\\Scsi Bus 0\\Target Id 0\\Logical Unit Id 0"), _T("Identifier"), _T("VMWARE") }, + { _T("SYSTEM\\ControlSet001\\Control\\SystemInformation"), _T("SystemManufacturer"), _T("VMWARE") }, + { _T("SYSTEM\\ControlSet001\\Control\\SystemInformation"), _T("SystemProductName"), _T("VMWARE") }, + }; + + WORD dwLength = sizeof(szEntries) / sizeof(szEntries[0]); + + for (int i = 0; i < dwLength; i++) + { + 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])) + print_results(TRUE, msg); + else + print_results(FALSE, msg); + } +} + + + +/* +Check against VMWare registry keys +*/ +VOID vmware_reg_keys() +{ + /* Array of strings of blacklisted registry keys */ + const TCHAR* szKeys[] = { + _T("SOFTWARE\\VMware, Inc.\\VMware Tools"), + }; + + WORD dwlength = sizeof(szKeys) / sizeof(szKeys[0]); + + /* Check one by one */ + for (int i = 0; i < dwlength; i++) + { + 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])) + print_results(TRUE, msg); + else + print_results(FALSE, msg); + } +} + + +/* +Check against VMWare blacklisted files +*/ +VOID vmware_files() +{ + /* Array of strings of blacklisted paths */ + const TCHAR* szPaths[] = { + _T("System32\\drivers\\vmnet.sys"), + _T("System32\\drivers\\vmmouse.sys"), + _T("System32\\drivers\\vmusb.sys"), + _T("System32\\drivers\\vm3dmp.sys"), + _T("System32\\drivers\\vmci.sys"), + _T("System32\\drivers\\vmhgfs.sys"), + _T("System32\\drivers\\vmmemctl.sys"), + _T("System32\\drivers\\vmx86.sys"), + _T("System32\\drivers\\vmrawdsk.sys"), + _T("System32\\drivers\\vmusbmouse.sys"), + _T("System32\\drivers\\vmkdb.sys"), + _T("System32\\drivers\\vmnetuserif.sys"), + _T("System32\\drivers\\vmnetadapter.sys"), + }; + + /* Getting Windows Directory */ + WORD dwlength = sizeof(szPaths) / sizeof(szPaths[0]); + TCHAR szWinDir[MAX_PATH] = _T(""); + TCHAR szPath[MAX_PATH] = _T(""); + PVOID OldValue = NULL; + + GetWindowsDirectory(szWinDir, MAX_PATH); + + if (IsWoW64()) { + Wow64DisableWow64FsRedirection(&OldValue); + } + + /* Check one by one */ + for (int i = 0; i < dwlength; i++) + { + 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)) + print_results(TRUE, msg); + else + print_results(FALSE, msg); + } + + if (IsWoW64()) { + Wow64RevertWow64FsRedirection(&OldValue); + } + +} + +/* +Check against VMWare blacklisted directories +*/ +BOOL vmware_dir() +{ + TCHAR szProgramFile[MAX_PATH]; + TCHAR szPath[MAX_PATH] = _T(""); + TCHAR szTarget[MAX_PATH] = _T("VMWare\\"); + + if (IsWoW64()) + ExpandEnvironmentStrings(_T("%ProgramW6432%"), szProgramFile, ARRAYSIZE(szProgramFile)); + else + SHGetSpecialFolderPath(NULL, szProgramFile, CSIDL_PROGRAM_FILES, FALSE); + + PathCombine(szPath, szProgramFile, szTarget); + return is_DirectoryExists(szPath); +} + + +/* +Check VMWare NIC MAC addresses +*/ +VOID vmware_mac() +{ + /* VMWre blacklisted mac adr */ + const TCHAR *szMac[][2] = { + { _T("\x00\x05\x69"), _T("00:05:69") }, // VMWare, Inc. + { _T("\x00\x0C\x29"), _T("00:0c:29") }, // VMWare, Inc. + { _T("\x00\x1C\x14"), _T("00:1C:14") }, // VMWare, Inc. + { _T("\x00\x50\x56"), _T("00:50:56") }, // VMWare, Inc. + }; + + WORD dwLength = sizeof(szMac) / sizeof(szMac[0]); + + /* Check one by one */ + for (int i = 0; i < dwLength; i++) + { + 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])) + print_results(TRUE, msg); + else + print_results(FALSE, msg); + } +} + + +/* +Check against VMWare adapter name +*/ +BOOL vmware_adapter_name() +{ + const TCHAR* szAdapterName = _T("VMWare"); + if (check_adapter_name(szAdapterName)) + return TRUE; + else + return FALSE; +} + + +/* +Check against VMWare pseaudo-devices +*/ +VOID vmware_devices() +{ + const TCHAR *devices[] = { + _T("\\\\.\\HGFS"), + _T("\\\\.\\vmci"), + }; + + WORD iLength = sizeof(devices) / sizeof(devices[0]); + for (int i = 0; i < iLength; i++) + { + 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) { + CloseHandle(hFile); + print_results(TRUE, msg); + } + else + print_results(FALSE, msg); + } +} + + +/* +Check for process list +*/ + +VOID vmware_processes() +{ + const TCHAR *szProcesses[] = { + _T("vmtoolsd.exe"), + _T("vmwaretray.exe"), + _T("vmwareuser.exe"), + _T("VGAuthService.exe"), + _T("vmacthlp.exe"), + }; + + WORD iLength = sizeof(szProcesses) / sizeof(szProcesses[0]); + for (int i = 0; i < iLength; i++) + { + TCHAR msg[256] = _T(""); + _stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking VWware process %s "), szProcesses[i]); + if (GetProcessIdFromName(szProcesses[i])) + print_results(TRUE, msg); + else + print_results(FALSE, msg); + } +} + +/* +Check for SMBIOS firmware +*/ +BOOL vmware_firmware_SMBIOS() +{ + BOOL result = FALSE; + const DWORD Signature = static_cast('RSMB'); + + DWORD smbiosSize = 0; + PBYTE smbios = get_system_firmware(static_cast('RSMB'), 0x0000, &smbiosSize); + if (smbios != NULL) + { + PBYTE vmwareString = (PBYTE)"VMware"; + size_t vmwwareStringLen = 6; + + if (find_str_in_data(vmwareString, vmwwareStringLen, smbios, smbiosSize)) + { + result = TRUE; + } + + free(smbios); + } + + return result; +} + +/* +Check for ACPI firmware +*/ +BOOL vmware_firmware_ACPI() +{ + BOOL result = FALSE; + + PDWORD tableNames = static_cast(malloc(4096)); + + if (tableNames == NULL) + return FALSE; + + SecureZeroMemory(tableNames, 4096); + DWORD tableSize = enum_system_firmware_tables(static_cast('ACPI'), tableNames, 4096); + + // API not available + if (tableSize == -1) + return FALSE; + + DWORD tableCount = tableSize / 4; + if (tableSize < 4 || tableCount == 0) + { + result = TRUE; + } + else + { + for (DWORD i = 0; i < tableCount; i++) { + DWORD tableSize = 0; + PBYTE table = get_system_firmware(static_cast('ACPI'), tableNames[i], &tableSize); + + if (table) { + + PBYTE vmwareString = (PBYTE)"VMWARE"; + size_t vmwwareStringLen = 6; + + if (find_str_in_data(vmwareString, vmwwareStringLen, table, tableSize)) { + result = TRUE; + } + + free(table); + } + } + } + + free(tableNames); + return result; +} + diff --git a/byp/sbexecution/AntiVM/VMWare.h b/byp/sbexecution/AntiVM/VMWare.h new file mode 100644 index 00000000..c9205def --- /dev/null +++ b/byp/sbexecution/AntiVM/VMWare.h @@ -0,0 +1,12 @@ +#pragma once + +VOID vmware_reg_key_value(); +VOID vmware_reg_keys(); +VOID vmware_files(); +BOOL vmware_dir(); +VOID vmware_mac(); +BOOL vmware_adapter_name(); +VOID vmware_devices(); +VOID vmware_processes(); +BOOL vmware_firmware_SMBIOS(); +BOOL vmware_firmware_ACPI(); \ No newline at end of file diff --git a/byp/sbexecution/AntiVM/VirtualBox.cpp b/byp/sbexecution/AntiVM/VirtualBox.cpp new file mode 100644 index 00000000..c71fdba1 --- /dev/null +++ b/byp/sbexecution/AntiVM/VirtualBox.cpp @@ -0,0 +1,920 @@ +#include "pch.h" + +#include "VirtualBox.h" + +/* +Registry key values +*/ +VOID vbox_reg_key_value() +{ + /* Array of strings of blacklisted registry key values */ + const TCHAR *szEntries[][3] = { + { _T("HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port 0\\Scsi Bus 0\\Target Id 0\\Logical Unit Id 0"), _T("Identifier"), _T("VBOX") }, + { _T("HARDWARE\\Description\\System"), _T("SystemBiosVersion"), _T("VBOX") }, + { _T("HARDWARE\\Description\\System"), _T("VideoBiosVersion"), _T("VIRTUALBOX") }, + { _T("HARDWARE\\Description\\System"), _T("SystemBiosDate"), _T("06/23/99") }, + }; + + WORD dwLength = sizeof(szEntries) / sizeof(szEntries[0]); + + for (int i = 0; i < dwLength; i++) + { + 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])) + print_results(TRUE, msg); + else + print_results(FALSE, msg); + } +} + + +/* +Check against virtualbox registry keys +*/ +VOID vbox_reg_keys() +{ + /* Array of strings of blacklisted registry keys */ + const TCHAR* szKeys[] = { + _T("HARDWARE\\ACPI\\DSDT\\VBOX__"), + _T("HARDWARE\\ACPI\\FADT\\VBOX__"), + _T("HARDWARE\\ACPI\\RSDT\\VBOX__"), + _T("SOFTWARE\\Oracle\\VirtualBox Guest Additions"), + _T("SYSTEM\\ControlSet001\\Services\\VBoxGuest"), + _T("SYSTEM\\ControlSet001\\Services\\VBoxMouse"), + _T("SYSTEM\\ControlSet001\\Services\\VBoxService"), + _T("SYSTEM\\ControlSet001\\Services\\VBoxSF"), + _T("SYSTEM\\ControlSet001\\Services\\VBoxVideo") + }; + + WORD dwlength = sizeof(szKeys) / sizeof(szKeys[0]); + + /* Check one by one */ + for (int i = 0; i < dwlength; i++) + { + 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])) + print_results(TRUE, msg); + else + print_results(FALSE, msg); + } +} + + +/* +Check against virtualbox blacklisted files +*/ +VOID vbox_files() +{ + /* Array of strings of blacklisted paths */ + const TCHAR* szPaths[] = { + _T("System32\\drivers\\VBoxMouse.sys"), + _T("System32\\drivers\\VBoxGuest.sys"), + _T("System32\\drivers\\VBoxSF.sys"), + _T("System32\\drivers\\VBoxVideo.sys"), + _T("System32\\vboxdisp.dll"), + _T("System32\\vboxhook.dll"), + _T("System32\\vboxmrxnp.dll"), + _T("System32\\vboxogl.dll"), + _T("System32\\vboxoglarrayspu.dll"), + _T("System32\\vboxoglcrutil.dll"), + _T("System32\\vboxoglerrorspu.dll"), + _T("System32\\vboxoglfeedbackspu.dll"), + _T("System32\\vboxoglpackspu.dll"), + _T("System32\\vboxoglpassthroughspu.dll"), + _T("System32\\vboxservice.exe"), + _T("System32\\vboxtray.exe"), + _T("System32\\VBoxControl.exe"), + }; + + /* Getting Windows Directory */ + WORD dwlength = sizeof(szPaths) / sizeof(szPaths[0]); + TCHAR szWinDir[MAX_PATH] = _T(""); + TCHAR szPath[MAX_PATH] = _T(""); + PVOID OldValue = NULL; + + GetWindowsDirectory(szWinDir, MAX_PATH); + + if (IsWoW64()) { + Wow64DisableWow64FsRedirection(&OldValue); + } + + /* Check one by one */ + for (int i = 0; i < dwlength; i++) + { + 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)) + print_results(TRUE, msg); + else + print_results(FALSE, msg); + } + + if (IsWoW64()) { + Wow64RevertWow64FsRedirection(&OldValue); + } +} + + +/* +Check against virtualbox blacklisted directories +*/ +BOOL vbox_dir() +{ + TCHAR szProgramFile[MAX_PATH]; + TCHAR szPath[MAX_PATH] = _T(""); + TCHAR szTarget[MAX_PATH] = _T("oracle\\virtualbox guest additions\\"); + + if (IsWoW64()) + ExpandEnvironmentStrings(_T("%ProgramW6432%"), szProgramFile, ARRAYSIZE(szProgramFile)); + else + SHGetSpecialFolderPath(NULL, szProgramFile, CSIDL_PROGRAM_FILES, FALSE); + + PathCombine(szPath, szProgramFile, szTarget); + return is_DirectoryExists(szPath); +} + + +/* +Check virtualbox NIC MAC address +*/ +BOOL vbox_check_mac() +{ + // PCS Systemtechnik CmbH (VirtualBox) + return check_mac_addr(_T("\x08\x00\x27")); +} + + +/* +Check against pseaudo-devices +*/ +VOID vbox_devices() +{ + const TCHAR *devices[] = { + _T("\\\\.\\VBoxMiniRdrDN"), + _T("\\\\.\\VBoxGuest"), + _T("\\\\.\\pipe\\VBoxMiniRdDN"), + _T("\\\\.\\VBoxTrayIPC"), + _T("\\\\.\\pipe\\VBoxTrayIPC") + }; + + WORD iLength = sizeof(devices) / sizeof(devices[0]); + for (int i = 0; i < iLength; i++) + { + 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) { + CloseHandle(hFile); + print_results(TRUE, msg); + } + else + print_results(FALSE, msg); + } +} + + +/* +Check for Window class +*/ +BOOL vbox_window_class() +{ + HWND hClass = FindWindow(_T("VBoxTrayToolWndClass"), NULL); + HWND hWindow = FindWindow(NULL, _T("VBoxTrayToolWnd")); + + if (hClass || hWindow) + return TRUE; + else + return FALSE; +} + + +/* +Check for shared folders network profider +*/ +BOOL vbox_network_share() +{ + TCHAR szProviderName[MAX_PATH] = _T(""); + DWORD lpBufferSize = MAX_PATH; + + if (WNetGetProviderName(WNNC_NET_RDR2SAMPLE, szProviderName, &lpBufferSize) == NO_ERROR) + { + if (StrCmpI(szProviderName, _T("VirtualBox Shared Folders")) == 0) + return TRUE; + else + return FALSE; + } + return FALSE; +} + + +/* +Check for process list +*/ +VOID vbox_processes() +{ + const TCHAR *szProcesses[] = { + _T("vboxservice.exe"), + _T("vboxtray.exe") + }; + + WORD iLength = sizeof(szProcesses) / sizeof(szProcesses[0]); + for (int i = 0; i < iLength; i++) + { + TCHAR msg[256] = _T(""); + _stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking VirtualBox process %s "), szProcesses[i]); + if (GetProcessIdFromName(szProcesses[i])) + print_results(TRUE, msg); + else + print_results(FALSE, msg); + } +} + + +/* +Check vbox mac @ using WMI +*/ +BOOL vbox_mac_wmi() +{ + IWbemServices *pSvc = NULL; + IWbemLocator *pLoc = NULL; + IEnumWbemClassObject* pEnumerator = NULL; + BOOL bStatus = FALSE; + HRESULT hRes; + BOOL bFound = FALSE; + + // Init WMI + bStatus = InitWMI(&pSvc, &pLoc, _T("ROOT\\CIMV2")); + if (bStatus) + { + // If success, execute the desired query + bStatus = ExecWMIQuery(&pSvc, &pLoc, &pEnumerator, _T("SELECT * FROM Win32_NetworkAdapterConfiguration")); + if (bStatus) + { + // Get the data from the query + IWbemClassObject *pclsObj = NULL; + ULONG uReturn = 0; + VARIANT vtProp; + + // Iterate over our enumator + while (pEnumerator) + { + hRes = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn); + if (0 == uReturn) + break; + + // Get the value of the Name property + hRes = pclsObj->Get(_T("MACAddress"), 0, &vtProp, 0, 0); + if (SUCCEEDED(hRes)) { + + if (V_VT(&vtProp) != VT_NULL) { + + if ((vtProp.vt & VT_BSTR) == VT_BSTR) + { + // Do our comparison + if (_tcsstr(vtProp.bstrVal, _T("08:00:27")) != 0) { + bFound = TRUE; + } + } + + // release the current result object + VariantClear(&vtProp); + } + } + pclsObj->Release(); + + // break from while + if (bFound) + break; + } + + // Cleanup + pEnumerator->Release(); + pSvc->Release(); + pLoc->Release(); + CoUninitialize(); + } + } + + return bFound; +} + + +/* +Check vbox event log using WMI +*/ +BOOL vbox_eventlogfile_wmi() +{ + IWbemServices *pSvc = NULL; + IWbemLocator *pLoc = NULL; + IEnumWbemClassObject* pEnumerator = NULL; + BOOL bStatus = FALSE; + HRESULT hRes; + BOOL bFound = FALSE; + + const TCHAR *szVBoxSources[] = { + _T("vboxvideo"), + _T("VBoxVideoW8"), + _T("VBoxWddm") + }; + + USHORT MaxVBoxSources = _countof(szVBoxSources); + + // Init WMI + bStatus = InitWMI(&pSvc, &pLoc, _T("ROOT\\CIMV2")); + if (bStatus) + { + // If success, execute the desired query + bStatus = ExecWMIQuery(&pSvc, &pLoc, &pEnumerator, _T("SELECT * FROM Win32_NTEventlogFile")); + if (bStatus) + { + // Get the data from the query + IWbemClassObject *pclsObj = NULL; + ULONG uReturn = 0; + VARIANT vtProp; + + // Iterate over our enumator + while (pEnumerator && !bFound) + { + hRes = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn); + if (0 == uReturn) + break; + + // Get the value of the FileName property + hRes = pclsObj->Get(_T("FileName"), 0, &vtProp, 0, 0); + if (SUCCEEDED(hRes) && (V_VT(&vtProp) != VT_NULL)) { + + if ((vtProp.vt & VT_BSTR) == VT_BSTR) + { + // Do our comparaison + if (StrCmpI(vtProp.bstrVal, _T("System")) == 0) { + + // Now, grab the Source property + VariantClear(&vtProp); + hRes = pclsObj->Get(_T("Sources"), 0, &vtProp, 0, 0); + + // Get the number of elements of our SAFEARRAY + SAFEARRAY* saSources = vtProp.parray; + LONG* pVals; + HRESULT hr = SafeArrayAccessData(saSources, (VOID**)&pVals); // direct access to SA memory + if (SUCCEEDED(hr)) { + LONG lowerBound, upperBound; + SafeArrayGetLBound(saSources, 1, &lowerBound); + SafeArrayGetUBound(saSources, 1, &upperBound); + LONG iLength = upperBound - lowerBound + 1; + + // Iteare over our array of BTSR + TCHAR* bstrItem; + for (LONG ix = 0; ix < iLength; ix++) { + SafeArrayGetElement(saSources, &ix, (void *)&bstrItem); + + for (UINT id = 0; id < MaxVBoxSources; id++) { + if (_tcsicmp(bstrItem, szVBoxSources[id]) == 0) + { + bFound = TRUE; + break; + } + } + // break from upper level "for" on detection success + if (bFound) + break; + } + //unlock data + SafeArrayUnaccessData(saSources); + } + } + } + + // release the current result object + VariantClear(&vtProp); + } + pclsObj->Release(); + } + + // Cleanup + pEnumerator->Release(); + pSvc->Release(); + pLoc->Release(); + CoUninitialize(); + + } + } + + return bFound; +} + + +BOOL vbox_firmware_SMBIOS() +{ + BOOL result = FALSE; + + DWORD smbiosSize = 0; + PBYTE smbios = get_system_firmware(static_cast('RSMB'), 0x0000, &smbiosSize); + if (smbios != NULL) + { + PBYTE virtualBoxString = (PBYTE)"VirtualBox"; + size_t virtualBoxStringLen = 10; + PBYTE vboxLowerString = (PBYTE)"vbox"; + size_t vboxLowerStringLen = 4; + PBYTE vboxUpperString = (PBYTE)"VBOX"; + size_t vboxUpperStringLen = 4; + + if (find_str_in_data(virtualBoxString, virtualBoxStringLen, smbios, smbiosSize) || + find_str_in_data(vboxLowerString, vboxLowerStringLen, smbios, smbiosSize) || + find_str_in_data(vboxUpperString, vboxUpperStringLen, smbios, smbiosSize)) + { + result = TRUE; + } + + free(smbios); + } + + return result; +} + + +BOOL vbox_firmware_ACPI() +{ + BOOL result = FALSE; + + PDWORD tableNames = static_cast(malloc(4096)); + + if (tableNames == NULL) + return FALSE; + + SecureZeroMemory(tableNames, 4096); + DWORD tableSize = enum_system_firmware_tables(static_cast('ACPI'), tableNames, 4096); + + // API not available + if (tableSize == -1) + return FALSE; + + DWORD tableCount = tableSize / 4; + + if (tableSize < 4 || tableCount == 0) + { + result = TRUE; + } + else + { + for (DWORD i = 0; i < tableCount; i++) + { + DWORD tableSize = 0; + PBYTE table = get_system_firmware(static_cast('ACPI'), tableNames[i], &tableSize); + + if (table) { + + PBYTE virtualBoxString = (PBYTE)"VirtualBox"; + size_t virtualBoxStringLen = 10; + PBYTE vboxLowerString = (PBYTE)"vbox"; + size_t vboxLowerStringLen = 4; + PBYTE vboxUpperString = (PBYTE)"VBOX"; + size_t vboxUpperStringLen = 4; + + if (find_str_in_data(virtualBoxString, virtualBoxStringLen, table, tableSize) || + find_str_in_data(vboxLowerString, vboxLowerStringLen, table, tableSize) || + find_str_in_data(vboxUpperString, vboxUpperStringLen, table, tableSize)) + { + result = TRUE; + } + + free(table); + } + } + } + + free(tableNames); + return result; +} + + +/* +Check vbox devices using WMI +*/ +BOOL vbox_pnpentity_pcideviceid_wmi() +{ + IWbemServices *pSvc = NULL; + IWbemLocator *pLoc = NULL; + IEnumWbemClassObject* pEnumerator = NULL; + BOOL bStatus = FALSE; + HRESULT hRes; + BOOL bFound = FALSE; + + // Init WMI + bStatus = InitWMI(&pSvc, &pLoc, _T("ROOT\\CIMV2")); + if (bStatus) + { + // If success, execute the desired query + bStatus = ExecWMIQuery(&pSvc, &pLoc, &pEnumerator, _T("SELECT * FROM Win32_PnPEntity")); + if (bStatus) + { + // Get the data from the query + IWbemClassObject *pclsObj = NULL; + ULONG uReturn = 0; + VARIANT vtProp; + + while (pEnumerator) + { + hRes = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn); + if (0 == uReturn) + break; + + // Get the value of the Name property + hRes = pclsObj->Get(_T("DeviceId"), 0, &vtProp, 0, 0); + + if (SUCCEEDED(hRes)) { + if (vtProp.vt == VT_BSTR) { + + // Do our comparaison + if (_tcsstr(vtProp.bstrVal, _T("PCI\\VEN_80EE&DEV_CAFE")) != 0) + { + bFound = TRUE; + } + } + VariantClear(&vtProp); + } + + // release the current result object + pclsObj->Release(); + + if (bFound) + break; + } + + // Cleanup + pSvc->Release(); + pLoc->Release(); + pEnumerator->Release(); + CoUninitialize(); + } + } + + return bFound; +} + + +/* +Check Win32_PnPEntity for known VirtualBox hardware +*/ +BOOL vbox_pnpentity_controllers_wmi() +{ + IWbemServices *pSvc = NULL; + IWbemLocator *pLoc = NULL; + IEnumWbemClassObject* pEnumerator = NULL; + BOOL bStatus = FALSE; + HRESULT hRes; + BOOL bFound = FALSE; + + // Init WMI + bStatus = InitWMI(&pSvc, &pLoc, _T("ROOT\\CIMV2")); + if (bStatus) + { + // If success, execute the desired query + bStatus = ExecWMIQuery(&pSvc, &pLoc, &pEnumerator, _T("SELECT * FROM Win32_PnPEntity")); + if (bStatus) + { + // Get the data from the query + IWbemClassObject *pclsObj = NULL; + ULONG uReturn = 0; + VARIANT vtProp; + + int findCount = 0; + const int findThreshold = 3; + + // Iterate over our enumator + while (pEnumerator) + { + hRes = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn); + if (0 == uReturn) + break; + + // Get the value of the Name property + hRes = pclsObj->Get(_T("Name"), 0, &vtProp, 0, 0); + if (SUCCEEDED(hRes)) { + + if (V_VT(&vtProp) != VT_NULL) { + + if ((vtProp.vt & VT_BSTR) == VT_BSTR) + { + // increment the find counter if this instance matches any of the known VBox hardware + if (_tcsstr(vtProp.bstrVal, _T("82801FB")) != 0) { + findCount++; + } + else if (_tcsstr(vtProp.bstrVal, _T("82441FX")) != 0) { + findCount++; + } + else if (_tcsstr(vtProp.bstrVal, _T("82371SB")) != 0) { + findCount++; + } + else if (_tcsstr(vtProp.bstrVal, _T("OpenHCD")) != 0) { + findCount++; + } + } + + // release the current result object + VariantClear(&vtProp); + } + } + pclsObj->Release(); + } + + if (findCount >= findThreshold) + { + bFound = TRUE; + } + + // Cleanup + pEnumerator->Release(); + pSvc->Release(); + pLoc->Release(); + CoUninitialize(); + } + } + + return bFound; +} + + +/* +Check Win32_Bus to see if only ACPIBus_BUS_0, PCI_BUS_0, PNP_BUS_0 are present +*/ +BOOL vbox_bus_wmi() +{ + IWbemServices *pSvc = NULL; + IWbemLocator *pLoc = NULL; + IEnumWbemClassObject* pEnumerator = NULL; + BOOL bStatus = FALSE; + HRESULT hRes; + BOOL bFound = FALSE; + + // Init WMI + bStatus = InitWMI(&pSvc, &pLoc, _T("ROOT\\CIMV2")); + if (bStatus) + { + // If success, execute the desired query + bStatus = ExecWMIQuery(&pSvc, &pLoc, &pEnumerator, _T("SELECT * FROM Win32_Bus")); + if (bStatus) + { + // Get the data from the query + IWbemClassObject *pclsObj = NULL; + ULONG uReturn = 0; + VARIANT vtProp; + + int count = 0; + int findCount = 0; + const int findThreshold = 3; + + // Iterate over our enumator + while (pEnumerator) + { + hRes = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn); + if (0 == uReturn) + break; + + count++; + + // Get the value of the Name property + hRes = pclsObj->Get(_T("Name"), 0, &vtProp, 0, 0); + if (SUCCEEDED(hRes)) { + + if (V_VT(&vtProp) != VT_NULL) + { + if ((vtProp.vt & VT_BSTR) == VT_BSTR) + { + // increment the find counter if this is + if (_tcsstr(vtProp.bstrVal, _T("ACPIBus_BUS_0")) != 0) { + findCount++; + } + else if (_tcsstr(vtProp.bstrVal, _T("PCI_BUS_0")) != 0) { + findCount++; + } + else if (_tcsstr(vtProp.bstrVal, _T("PNP_BUS_0")) != 0) { + findCount++; + } + } + + // release the current result object + VariantClear(&vtProp); + } + } + pclsObj->Release(); + } + + // check that there are 3 instances and they match the strings above + if (count == findThreshold && + findCount == findThreshold) + { + bFound = TRUE; + } + + // Cleanup + pEnumerator->Release(); + pSvc->Release(); + pLoc->Release(); + CoUninitialize(); + } + } + + return bFound; +} + + +/* +Check Win32_BaseBoard +*/ +BOOL vbox_baseboard_wmi() +{ + IWbemServices *pSvc = NULL; + IWbemLocator *pLoc = NULL; + IEnumWbemClassObject* pEnumerator = NULL; + BOOL bStatus = FALSE; + HRESULT hRes; + BOOL bFound = FALSE; + + // Init WMI + bStatus = InitWMI(&pSvc, &pLoc, _T("ROOT\\CIMV2")); + if (bStatus) + { + // If success, execute the desired query + bStatus = ExecWMIQuery(&pSvc, &pLoc, &pEnumerator, _T("SELECT * FROM Win32_BaseBoard")); + if (bStatus) + { + // Get the data from the query + IWbemClassObject *pclsObj = NULL; + ULONG uReturn = 0; + VARIANT vtProp = { 0 }; + + // Iterate over our enumator + while (pEnumerator) + { + hRes = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn); + if (0 == uReturn) + break; + + // Get the value of the Product property + hRes = pclsObj->Get(_T("Product"), 0, &vtProp, 0, 0); + if (SUCCEEDED(hRes)) { + + if (V_VT(&vtProp) != VT_NULL) { + + if ((vtProp.vt & VT_BSTR) == VT_BSTR) + { + // Do our comparison + if (_tcsstr(vtProp.bstrVal, _T("VirtualBox")) != 0) { + bFound = TRUE; + } + } + + // release the current result object + VariantClear(&vtProp); + } + } + + vtProp = { 0 }; + + // Get the value of the Manufacturer property + hRes = pclsObj->Get(_T("Manufacturer"), 0, &vtProp, 0, 0); + if (SUCCEEDED(hRes)) { + + if (V_VT(&vtProp) != VT_NULL) { + + if ((vtProp.vt & VT_BSTR) == VT_BSTR) + { + // Do our comparison + if (_tcsstr(vtProp.bstrVal, _T("Oracle Corporation")) != 0) { + bFound = TRUE; + } + } + + // release the current result object + VariantClear(&vtProp); + } + } + + pclsObj->Release(); + + // break from while + if (bFound) + break; + } + + // Cleanup + pEnumerator->Release(); + pSvc->Release(); + pLoc->Release(); + CoUninitialize(); + } + } + + return bFound; +} + + +/* +Check Win32_PnPDevice for VBOX entries +*/ +BOOL vbox_pnpentity_vboxname_wmi() +{ + IWbemServices *pSvc = NULL; + IWbemLocator *pLoc = NULL; + IEnumWbemClassObject* pEnumerator = NULL; + BOOL bStatus = FALSE; + HRESULT hRes; + BOOL bFound = FALSE; + + // Init WMI + bStatus = InitWMI(&pSvc, &pLoc, _T("ROOT\\CIMV2")); + if (bStatus) + { + // If success, execute the desired query + bStatus = ExecWMIQuery(&pSvc, &pLoc, &pEnumerator, _T("SELECT * FROM Win32_PnPDevice")); + if (bStatus) + { + // Get the data from the query + IWbemClassObject *pclsObj = NULL; + ULONG uReturn = 0; + VARIANT vtProp; + + // Iterate over our enumator + while (pEnumerator) + { + hRes = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn); + if (0 == uReturn) + break; + + // Get the value of the Name property + hRes = pclsObj->Get(_T("Name"), 0, &vtProp, 0, 0); + if (SUCCEEDED(hRes)) { + + if (V_VT(&vtProp) != VT_NULL) { + + if ((vtProp.vt & VT_BSTR) == VT_BSTR) + { + // Do our comparison + if (_tcsstr(vtProp.bstrVal, _T("VBOX")) != 0) { + bFound = TRUE; + } + } + + // release the current result object + VariantClear(&vtProp); + } + } + + // Get the value of the Caption property + hRes = pclsObj->Get(_T("Caption"), 0, &vtProp, 0, 0); + if (SUCCEEDED(hRes)) { + + if (V_VT(&vtProp) != VT_NULL) { + + if ((vtProp.vt & VT_BSTR) == VT_BSTR) + { + // Do our comparison + if (_tcsstr(vtProp.bstrVal, _T("VBOX")) != 0) { + bFound = TRUE; + } + } + + // release the current result object + VariantClear(&vtProp); + } + } + + // Get the value of the PNPDeviceID property + hRes = pclsObj->Get(_T("PNPDeviceID"), 0, &vtProp, 0, 0); + if (SUCCEEDED(hRes)) { + + if (V_VT(&vtProp) != VT_NULL) { + + if ((vtProp.vt & VT_BSTR) == VT_BSTR) + { + // Do our comparison + if (_tcsstr(vtProp.bstrVal, _T("VEN_VBOX")) != 0) { + bFound = TRUE; + } + } + + // release the current result object + VariantClear(&vtProp); + } + } + + pclsObj->Release(); + + // break from while + if (bFound) + break; + } + + // Cleanup + pEnumerator->Release(); + pSvc->Release(); + pLoc->Release(); + CoUninitialize(); + } + } + + return bFound; +} diff --git a/byp/sbexecution/AntiVM/VirtualBox.h b/byp/sbexecution/AntiVM/VirtualBox.h new file mode 100644 index 00000000..0d34654f --- /dev/null +++ b/byp/sbexecution/AntiVM/VirtualBox.h @@ -0,0 +1,21 @@ +#pragma once + +VOID vbox_reg_key_value(); +VOID vbox_reg_keys(); +VOID vbox_files(); +BOOL vbox_dir(); + +BOOL vbox_check_mac(); +VOID vbox_devices(); +BOOL vbox_window_class(); +BOOL vbox_network_share(); +VOID vbox_processes(); +BOOL vbox_mac_wmi(); +BOOL vbox_eventlogfile_wmi(); +BOOL vbox_firmware_SMBIOS(); +BOOL vbox_firmware_ACPI(); +BOOL vbox_bus_wmi(); +BOOL vbox_baseboard_wmi(); +BOOL vbox_pnpentity_pcideviceid_wmi(); +BOOL vbox_pnpentity_controllers_wmi(); +BOOL vbox_pnpentity_vboxname_wmi(); diff --git a/byp/sbexecution/AntiVM/VirtualPC.cpp b/byp/sbexecution/AntiVM/VirtualPC.cpp new file mode 100644 index 00000000..d77d9dd8 --- /dev/null +++ b/byp/sbexecution/AntiVM/VirtualPC.cpp @@ -0,0 +1,49 @@ +#include "pch.h" + +#include "VirtualPC.h" + +/* +Check for process list +*/ + +VOID virtual_pc_process() +{ + const TCHAR *szProcesses[] = { + _T("VMSrvc.exe"), + _T("VMUSrvc.exe"), + }; + + WORD iLength = sizeof(szProcesses) / sizeof(szProcesses[0]); + for (int i = 0; i < iLength; i++) + { + TCHAR msg[256] = _T(""); + _stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking Virtual PC processes %s "), szProcesses[i]); + if (GetProcessIdFromName(szProcesses[i])) + print_results(TRUE, msg); + else + print_results(FALSE, msg); + } +} + + + +VOID virtual_pc_reg_keys() +{ + /* Array of strings of blacklisted registry keys */ + const TCHAR* szKeys[] = { + _T("SOFTWARE\\Microsoft\\Virtual Machine\\Guest\\Parameters"), + }; + + WORD dwlength = sizeof(szKeys) / sizeof(szKeys[0]); + + /* Check one by one */ + for (int i = 0; i < dwlength; i++) + { + 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])) + print_results(TRUE, msg); + else + print_results(FALSE, msg); + } +} diff --git a/byp/sbexecution/AntiVM/VirtualPC.h b/byp/sbexecution/AntiVM/VirtualPC.h new file mode 100644 index 00000000..53b9d57e --- /dev/null +++ b/byp/sbexecution/AntiVM/VirtualPC.h @@ -0,0 +1,5 @@ +#pragma once + + +VOID virtual_pc_process(); +VOID virtual_pc_reg_keys(); diff --git a/byp/sbexecution/AntiVM/Wine.cpp b/byp/sbexecution/AntiVM/Wine.cpp new file mode 100644 index 00000000..05658a81 --- /dev/null +++ b/byp/sbexecution/AntiVM/Wine.cpp @@ -0,0 +1,49 @@ +#include "pch.h" + +#include "Wine.h" + +/* +Check against Wine export dlls +*/ +BOOL wine_exports() +{ + /* Some vars */ + HMODULE hKernel32; + + /* Get kernel32 module handle */ + hKernel32 = GetModuleHandle(_T("kernel32.dll")); + if (hKernel32 == NULL) { + print_last_error(_T("GetModuleHandle")); + return FALSE; + } + + /* Check if wine_get_unix_file_name is exported by this dll */ + if (GetProcAddress(hKernel32, "wine_get_unix_file_name") == NULL) + return FALSE; + else + return TRUE; +} + +/* +Check against Wine registry keys +*/ +VOID wine_reg_keys() +{ + /* Array of strings of blacklisted registry keys */ + const TCHAR* szKeys[] = { + _T("SOFTWARE\\Wine") + }; + + WORD dwlength = sizeof(szKeys) / sizeof(szKeys[0]); + + /* Check one by one */ + for (int i = 0; i < dwlength; i++) + { + 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])) + print_results(TRUE, msg); + else + print_results(FALSE, msg); + } +} diff --git a/byp/sbexecution/AntiVM/Wine.h b/byp/sbexecution/AntiVM/Wine.h new file mode 100644 index 00000000..832d9c22 --- /dev/null +++ b/byp/sbexecution/AntiVM/Wine.h @@ -0,0 +1,4 @@ +#pragma once + +BOOL wine_exports(); +VOID wine_reg_keys(); \ No newline at end of file diff --git a/byp/sbexecution/AntiVM/Xen.cpp b/byp/sbexecution/AntiVM/Xen.cpp new file mode 100644 index 00000000..baadb436 --- /dev/null +++ b/byp/sbexecution/AntiVM/Xen.cpp @@ -0,0 +1,36 @@ +#include "pch.h" + +#include "Xen.h" + +/* +Check for process list +*/ + +VOID xen_process() +{ + const TCHAR *szProcesses[] = { + _T("xenservice.exe"), + }; + + WORD iLength = sizeof(szProcesses) / sizeof(szProcesses[0]); + for (int i = 0; i < iLength; i++) + { + TCHAR msg[256] = _T(""); + _stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking Citrix Xen process %s"), szProcesses[i]); + if (GetProcessIdFromName(szProcesses[i])) + print_results(TRUE, msg); + else + print_results(FALSE, msg); + } +} + + + +/* +Check Xen NIC MAC address +*/ +BOOL xen_check_mac() +{ + // Xensource, Inc. + return check_mac_addr(_T("\x00\x16\x3E")); +} diff --git a/byp/sbexecution/AntiVM/Xen.h b/byp/sbexecution/AntiVM/Xen.h new file mode 100644 index 00000000..9f1b8d84 --- /dev/null +++ b/byp/sbexecution/AntiVM/Xen.h @@ -0,0 +1,4 @@ +#pragma once + +VOID xen_process(); +BOOL xen_check_mac(); \ No newline at end of file diff --git a/byp/sbexecution/AntiVM/pch.h b/byp/sbexecution/AntiVM/pch.h new file mode 100644 index 00000000..e7df92d7 --- /dev/null +++ b/byp/sbexecution/AntiVM/pch.h @@ -0,0 +1 @@ +#include "../pch.h" \ No newline at end of file diff --git a/byp/sbexecution/CodeInjection/CreateRemoteThread.cpp b/byp/sbexecution/CodeInjection/CreateRemoteThread.cpp new file mode 100644 index 00000000..20a773a0 --- /dev/null +++ b/byp/sbexecution/CodeInjection/CreateRemoteThread.cpp @@ -0,0 +1,97 @@ +#include "pch.h" + +#include "CreateRemoteThread.h" + +BOOL CreateRemoteThread_Injection() +{ + /* Some vars */ + DWORD dwProcessId; + HANDLE hProcess = NULL, hRemoteThread = NULL; + HMODULE hKernel32; + FARPROC LoadLibraryAddress; + LPVOID lpBaseAddress = NULL; + TCHAR lpDllName[] = _T("InjectedDLL.dll"); + TCHAR lpDllPath[MAX_PATH]; + SIZE_T dwSize; + BOOL bStatus = FALSE, bDebugPrivilegeEnabled; + + /* Get Process ID from Process name */ + dwProcessId = GetProcessIdFromName(_T("notepad.exe")); + if (dwProcessId == NULL) + return FALSE; + _tprintf(_T("\t[+] Getting proc id: %u\n"), dwProcessId); + + /* Set Debug privilege */ + bDebugPrivilegeEnabled = SetDebugPrivileges(); + _tprintf(_T("\t[+] Setting Debug Privileges [%d]\n"), bDebugPrivilegeEnabled); + if (!bDebugPrivilegeEnabled) + return FALSE; + + /* Obtain a handle the process */ + hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId); + if (hProcess == NULL) { + print_last_error(_T("OpenProcess")); + goto Cleanup; + } + + /* Obtain a handle to kernel32 */ + hKernel32 = GetModuleHandle(_T("kernel32.dll")); + if (hKernel32 == NULL) { + print_last_error(_T("GetModuleHandle")); + goto Cleanup; + } + + /* Get LoadLibrary address */ + _tprintf(_T("\t[+] Looking for LoadLibrary in kernel32\n")); + LoadLibraryAddress = GetProcAddress(hKernel32, "LoadLibraryW"); + if (LoadLibraryAddress == NULL) { + print_last_error(_T("GetProcAddress")); + goto Cleanup; + } + _tprintf(_T("\t[+] Found at 0x%p\n"), LoadLibraryAddress); + + /* Get the full path of the dll */ + GetFullPathName(lpDllName, MAX_PATH, lpDllPath, NULL); + _tprintf(_T("\t[+] Full DLL Path: %s\n"), lpDllPath); + + /* Calculate the number of bytes needed for the DLL's pathname */ + dwSize = _tcslen(lpDllPath) * sizeof(TCHAR); + + /* Allocate memory into the remote process */ + _tprintf(_T("\t[+] Allocating space for the path of the DLL\n")); + lpBaseAddress = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); + if (lpBaseAddress == NULL) { + print_last_error(_T("VirtualAllocEx")); + goto Cleanup; + } + + /* Write to the remote process */ + printf("\t[+] Writing into the current process space at 0x%p\n", lpBaseAddress); + if (!WriteProcessMemory(hProcess, lpBaseAddress, lpDllPath, dwSize, NULL)) { + print_last_error(_T("WriteProcessMemory")); + goto Cleanup; + } + + /* Create the more thread */ + hRemoteThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)LoadLibraryAddress, lpBaseAddress, NULL, 0); + if (hRemoteThread == NULL) { + print_last_error(_T("CreateRemoteThread")); + } + else { + _tprintf(_T("Remote thread has been created successfully ...\n")); + WaitForSingleObject(hRemoteThread, INFINITE); + CloseHandle(hRemoteThread); + + /* assign function success return result */ + bStatus = TRUE; + } + +Cleanup: + /* If lpBaseAddress initialized then hProcess is initialized too because of upper check. */ + if (lpBaseAddress) { + VirtualFreeEx(hProcess, lpBaseAddress, 0, MEM_RELEASE); + } + if (hProcess) CloseHandle(hProcess); + + return bStatus; +} diff --git a/byp/sbexecution/CodeInjection/CreateRemoteThread.h b/byp/sbexecution/CodeInjection/CreateRemoteThread.h new file mode 100644 index 00000000..6721e5d0 --- /dev/null +++ b/byp/sbexecution/CodeInjection/CreateRemoteThread.h @@ -0,0 +1,3 @@ +#pragma once + +BOOL CreateRemoteThread_Injection(); \ No newline at end of file diff --git a/byp/sbexecution/CodeInjection/GetSetThreadContext.cpp b/byp/sbexecution/CodeInjection/GetSetThreadContext.cpp new file mode 100644 index 00000000..a9fca1a8 --- /dev/null +++ b/byp/sbexecution/CodeInjection/GetSetThreadContext.cpp @@ -0,0 +1,132 @@ +#include "pch.h" + +#include "GetSetThreadContext.h" + +BOOL GetSetThreadContext_Injection() +{ +#ifdef _WIN64 + return TRUE; //TODO implement this on x64 +#else + TCHAR lpApplicationName[] = _T("C:\\Windows\\System32\\svchost.exe"); + TCHAR lpApplicationName2[] = _T("C:\\masm32\\examples\\dialogs_later\\basic\\basicdlg.exe"); + BOOL bResult = FALSE; + + STARTUPINFO StartupInfo; + PROCESS_INFORMATION ProcessInfo; + + PCONTEXT pContext = NULL; + HANDLE hFile = INVALID_HANDLE_VALUE; + + SecureZeroMemory(&StartupInfo, sizeof(STARTUPINFO)); + SecureZeroMemory(&ProcessInfo, sizeof(PPROCESS_INFORMATION)); + + do { /* not a loop */ + + // Create the hollowed process in suspended mode + if (!CreateProcess(lpApplicationName, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &StartupInfo, &ProcessInfo)) { + print_last_error(_T("CreateProcess")); + break; + } + + // Allocate space for context structure + LPVOID pTargetImageBase = NULL; + + pContext = PCONTEXT(VirtualAlloc(NULL, sizeof(CONTEXT), MEM_COMMIT, PAGE_READWRITE)); + if (pContext == NULL) { + print_last_error(_T("VirtualAlloc")); + break; + } + + // Get the thread context of target + pContext->ContextFlags = CONTEXT_FULL; + if (!GetThreadContext(ProcessInfo.hThread, pContext)) { + print_last_error(_T("GetThreadContext")); + break; + } + + // Read the image base address of target + ReadProcessMemory(ProcessInfo.hProcess, LPCVOID(pContext->Ebx + 8), pTargetImageBase, 4, NULL); + + // Opening source image + hFile = CreateFile(lpApplicationName2, GENERIC_READ, NULL, NULL, OPEN_ALWAYS, NULL, NULL); + if (hFile == INVALID_HANDLE_VALUE) + { + print_last_error(_T("CreateFile")); + break; + } + + // Reading the file + DWORD dwSize = GetFileSize(hFile, 0); + DWORD dwBytesRead; + PBYTE pBuffer = static_cast(MALLOC(dwSize)); + + if (pBuffer == NULL) { + print_last_error(_T("HeapAlloc")); + break; + } + else { + + SecureZeroMemory(pBuffer, dwSize); + + ReadFile(hFile, pBuffer, dwSize, &dwBytesRead, 0); + PIMAGE_SECTION_HEADER pImageSectionHeader; + + PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pBuffer; + if (pDosHeader->e_magic == IMAGE_DOS_SIGNATURE) + { + PIMAGE_NT_HEADERS32 pNTHeaders = PIMAGE_NT_HEADERS(DWORD(pBuffer) + pDosHeader->e_lfanew); + if (pNTHeaders->Signature == IMAGE_NT_SIGNATURE) + { + + if (DWORD(pTargetImageBase) == pNTHeaders->OptionalHeader.ImageBase) + { + pNtUnmapViewOfSection NtUnmapViewOfSection; + NtUnmapViewOfSection = (pNtUnmapViewOfSection)(GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtUnmapViewOfSection")); + NtUnmapViewOfSection(ProcessInfo.hProcess, pTargetImageBase); + } + + LPVOID pImageBase; + + pImageBase = VirtualAllocEx(ProcessInfo.hProcess, LPVOID(pNTHeaders->OptionalHeader.ImageBase), + pNTHeaders->OptionalHeader.SizeOfImage, + MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); + + if (pImageBase == NULL) { + print_last_error(_T("VirtualAllocEx")); + break; + } + else { + + WriteProcessMemory(ProcessInfo.hProcess, pImageBase, pBuffer, pNTHeaders->OptionalHeader.SizeOfHeaders, NULL); + for (int Count = 0; Count < pNTHeaders->FileHeader.NumberOfSections; Count++) + { + pImageSectionHeader = PIMAGE_SECTION_HEADER(DWORD(pBuffer) + pDosHeader->e_lfanew + 248 + (Count * 40)); + WriteProcessMemory(ProcessInfo.hProcess, LPVOID(DWORD(pImageBase) + pImageSectionHeader->VirtualAddress), + LPVOID(DWORD(pBuffer) + pImageSectionHeader->PointerToRawData), pImageSectionHeader->SizeOfRawData, NULL); + } + WriteProcessMemory(ProcessInfo.hProcess, LPVOID(pContext->Ebx + 8), LPVOID(&pNTHeaders->OptionalHeader.ImageBase), 4, NULL); + pContext->Eax = DWORD(pImageBase) + pNTHeaders->OptionalHeader.AddressOfEntryPoint; + SetThreadContext(ProcessInfo.hThread, LPCONTEXT(pContext)); + + LONG dwRet; + + dwRet = ResumeThread(ProcessInfo.hThread); + bResult = (dwRet != -1); + } + } + } + + FREE(pBuffer); + } + + } while (FALSE); /* not a loop */ + + /* Cleanup */ + if (ProcessInfo.hThread) CloseHandle(ProcessInfo.hThread); + if (ProcessInfo.hProcess) CloseHandle(ProcessInfo.hProcess); + if (pContext) VirtualFree(pContext, 0, MEM_RELEASE); + if (hFile != INVALID_HANDLE_VALUE) CloseHandle(hFile); + + return bResult; +#endif +} diff --git a/byp/sbexecution/CodeInjection/GetSetThreadContext.h b/byp/sbexecution/CodeInjection/GetSetThreadContext.h new file mode 100644 index 00000000..c83e6963 --- /dev/null +++ b/byp/sbexecution/CodeInjection/GetSetThreadContext.h @@ -0,0 +1,3 @@ +#pragma once + +BOOL GetSetThreadContext_Injection(); diff --git a/byp/sbexecution/CodeInjection/InjectedDLL/InjectedDLL.cpp b/byp/sbexecution/CodeInjection/InjectedDLL/InjectedDLL.cpp new file mode 100644 index 00000000..322e7816 --- /dev/null +++ b/byp/sbexecution/CodeInjection/InjectedDLL/InjectedDLL.cpp @@ -0,0 +1,39 @@ +#include "stdafx.h" +#include "InjectedDLL.h" + +LRESULT CALLBACK MyProc(INT code, WPARAM wParam, LPARAM lParam); + +LRESULT CALLBACK MyProc(INT code, WPARAM wParam, LPARAM lParam) +{ + //here goes our code + TCHAR str[MAX_PATH] = _T(""); + _stprintf(str, _T("[Al-khaser] - Injected from process: %d"), GetCurrentProcessId()); + OutputDebugString(str); + return CallNextHookEx(NULL, code, wParam, lParam); //this is needed to let other applications set other hooks on this target +} + + +BOOL APIENTRY DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpReserved) +{ + switch (dwReason) + { + case DLL_PROCESS_ATTACH: + OutputDebugString(_T("[Al-khaser] - DLL is attached")); + break; + + case DLL_PROCESS_DETACH: + OutputDebugString(_T("[Al-khaser] - DLL is detached")); + break; + + case DLL_THREAD_ATTACH: + OutputDebugString(_T("[Al-khaser] - Thread is atached")); + break; + + case DLL_THREAD_DETACH: + OutputDebugString(_T("[Al-khaser] - Thread is detached")); + break; + } + + /* Returns TRUE on success, FALSE on failure */ + return TRUE; +} diff --git a/byp/sbexecution/CodeInjection/InjectedDLL/InjectedDLL.h b/byp/sbexecution/CodeInjection/InjectedDLL/InjectedDLL.h new file mode 100644 index 00000000..b9c272d2 --- /dev/null +++ b/byp/sbexecution/CodeInjection/InjectedDLL/InjectedDLL.h @@ -0,0 +1,2 @@ +#include +#include \ No newline at end of file diff --git a/byp/sbexecution/CodeInjection/InjectedDLL/InjectedDLL.vcxproj b/byp/sbexecution/CodeInjection/InjectedDLL/InjectedDLL.vcxproj new file mode 100644 index 00000000..ae563462 --- /dev/null +++ b/byp/sbexecution/CodeInjection/InjectedDLL/InjectedDLL.vcxproj @@ -0,0 +1,163 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + {BFB018FC-33D1-4351-B6EA-1CA77336A0E4} + Win32Proj + InjectedDLL + 8.1 + + + + DynamicLibrary + true + v140_xp + Unicode + + + DynamicLibrary + false + v140_xp + true + Unicode + + + DynamicLibrary + true + v140 + Unicode + + + DynamicLibrary + false + v140 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + false + + + + + + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;INJECTEDDLL_EXPORTS;%(PreprocessorDefinitions) + MultiThreaded + false + + + Windows + true + definitions.def + + + + + + + Level3 + Disabled + _DEBUG;_WINDOWS;_USRDLL;INJECTEDDLL_EXPORTS;%(PreprocessorDefinitions) + + + Windows + true + definitions.def + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;INJECTEDDLL_EXPORTS;%(PreprocessorDefinitions) + MultiThreaded + + + Windows + true + true + true + definitions.def + + + + + Level3 + + + MaxSpeed + true + true + NDEBUG;_WINDOWS;_USRDLL;INJECTEDDLL_EXPORTS;%(PreprocessorDefinitions) + + + Windows + true + true + true + definitions.def + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/byp/sbexecution/CodeInjection/InjectedDLL/InjectedDLL.vcxproj.filters b/byp/sbexecution/CodeInjection/InjectedDLL/InjectedDLL.vcxproj.filters new file mode 100644 index 00000000..a5df031e --- /dev/null +++ b/byp/sbexecution/CodeInjection/InjectedDLL/InjectedDLL.vcxproj.filters @@ -0,0 +1,32 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + + + Header Files + + + + + Source Files + + + \ No newline at end of file diff --git a/byp/sbexecution/CodeInjection/InjectedDLL/definitions.def b/byp/sbexecution/CodeInjection/InjectedDLL/definitions.def new file mode 100644 index 00000000..ed7fcca0 --- /dev/null +++ b/byp/sbexecution/CodeInjection/InjectedDLL/definitions.def @@ -0,0 +1,3 @@ +LIBRARY +EXPORTS + MyProc \ No newline at end of file diff --git a/byp/sbexecution/CodeInjection/NtCreateThreadEx.cpp b/byp/sbexecution/CodeInjection/NtCreateThreadEx.cpp new file mode 100644 index 00000000..b466e2e0 --- /dev/null +++ b/byp/sbexecution/CodeInjection/NtCreateThreadEx.cpp @@ -0,0 +1,141 @@ +#include "pch.h" + +#include "NtCreateThreadEx.h" + +BOOL NtCreateThreadEx_Injection() +{ + // some vars + HMODULE hNtdll; + DWORD dwProcessId; + HANDLE hProcess = NULL; + TCHAR lpDllName[] = _T("InjectedDLL.dll"); + TCHAR lpDllPath[MAX_PATH]; + LPVOID lpBaseAddress = NULL; + BOOL bStatus = FALSE; + HMODULE hKernel32; + FARPROC LoadLibraryAddress; + HANDLE hRemoteThread = NULL; + NTSTATUS Status; + SIZE_T dwSize; + CLIENT_ID ClientId; + PS_ATTRIBUTE_LIST PsAttrList; + + // we have to import our function + pNtCreateThreadEx NtCreateThreadEx = NULL; + + /* + GetLastError cannot be used with NtCreateThreadEx because this service does not set Win32 LastError value. + Native status code must be translated to Win32 error code and set manually. + */ + pRtlNtStatusToDosError RtlNtStatusToDosErrorPtr = NULL; + + /* Get Process ID from Process name */ + dwProcessId = GetProcessIdFromName(_T("notepad.exe")); + if (dwProcessId == 0) + return FALSE; + _tprintf(_T("\t[+] Getting proc id: %u\n"), dwProcessId); + + /* Obtain a handle the process */ + hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId); + if (hProcess == NULL) { + print_last_error(_T("OpenProcess")); + goto Cleanup; + } + + /* Get module handle of ntdll */ + hNtdll = GetModuleHandle(_T("ntdll.dll")); + if (hNtdll == NULL) { + print_last_error(_T("GetModuleHandle")); + goto Cleanup; + } + + /* Obtain a handle to kernel32 */ + hKernel32 = GetModuleHandle(_T("kernel32.dll")); + if (hKernel32 == NULL) { + print_last_error(_T("GetModuleHandle")); + goto Cleanup; + } + + /* Get routine pointer, failure is not critical */ + RtlNtStatusToDosErrorPtr = (pRtlNtStatusToDosError)GetProcAddress(hNtdll, "RtlNtStatusToDosError"); + + // Get the address NtCreateThreadEx + _tprintf(_T("\t[+] Looking for NtCreateThreadEx in ntdll\n")); + NtCreateThreadEx = (pNtCreateThreadEx)GetProcAddress(hNtdll, "NtCreateThreadEx"); + if (NtCreateThreadEx == NULL) { + print_last_error(_T("GetProcAddress")); + goto Cleanup; + } + _tprintf(_T("\t[+] Found at 0x%p\n"), NtCreateThreadEx); + + /* Get LoadLibrary address */ + _tprintf(_T("\t[+] Looking for LoadLibrary in kernel32\n")); + LoadLibraryAddress = GetProcAddress(hKernel32, "LoadLibraryW"); + if (LoadLibraryAddress == NULL) { + print_last_error(_T("GetProcAddress")); + goto Cleanup; + } + _tprintf(_T("\t[+] Found at 0x%p\n"), LoadLibraryAddress); + + /* Get the full path of the dll */ + GetFullPathName(lpDllName, MAX_PATH, lpDllPath, NULL); + _tprintf(_T("\t[+] Full DLL Path: %s\n"), lpDllPath); + + /* Calculate the number of bytes needed for the DLL's pathname */ + dwSize = _tcslen(lpDllPath) * sizeof(TCHAR); + + /* Allocate memory into the remote process */ + _tprintf(_T("\t[+] Allocating space for the path of the DLL\n")); + lpBaseAddress = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); + if (lpBaseAddress == NULL) { + print_last_error(_T("VirtualAllocEx")); + goto Cleanup; + } + + /* Write to the remote process */ + printf("\t[+] Writing into the current process space at 0x%p\n", lpBaseAddress); + if (!WriteProcessMemory(hProcess, lpBaseAddress, lpDllPath, dwSize, NULL)) { + print_last_error(_T("WriteProcessMemory")); + goto Cleanup; + } + + /* Create the more thread */ + SecureZeroMemory(&PsAttrList, sizeof(PsAttrList)); + + /* Setup attributes entry */ + PsAttrList.TotalLength = sizeof(PS_ATTRIBUTE_LIST); + PsAttrList.Attributes[0].Attribute = PS_ATTRIBUTE_CLIENT_ID; + PsAttrList.Attributes[0].Size = sizeof(CLIENT_ID); + PsAttrList.Attributes[0].u1.ValuePtr = &ClientId; + + Status = NtCreateThreadEx(&hRemoteThread, THREAD_ALL_ACCESS, NULL, hProcess, + (LPTHREAD_START_ROUTINE)LoadLibraryAddress, lpBaseAddress, 0, 0, 0, 0, &PsAttrList); + + if (!NT_SUCCESS(Status)) { + if (RtlNtStatusToDosErrorPtr) { + SetLastError(RtlNtStatusToDosErrorPtr(Status)); + } + else { + SetLastError(ERROR_INTERNAL_ERROR); + } + print_last_error(_T("NtCreateThreadEx")); + } + + else { + _tprintf(_T("Remote thread has been created successfully ...\n")); + WaitForSingleObject(hRemoteThread, INFINITE); + CloseHandle(hRemoteThread); + + /* assign function success return result */ + bStatus = TRUE; + } + +Cleanup: + /* If lpBaseAddress initialized then hProcess is initialized too because of upper check. */ + if (lpBaseAddress) { + VirtualFreeEx(hProcess, lpBaseAddress, 0, MEM_RELEASE); + } + if (hProcess) CloseHandle(hProcess); + + return bStatus; +} diff --git a/byp/sbexecution/CodeInjection/NtCreateThreadEx.h b/byp/sbexecution/CodeInjection/NtCreateThreadEx.h new file mode 100644 index 00000000..f34038c5 --- /dev/null +++ b/byp/sbexecution/CodeInjection/NtCreateThreadEx.h @@ -0,0 +1,3 @@ +#pragma once + +BOOL NtCreateThreadEx_Injection(); diff --git a/byp/sbexecution/CodeInjection/QueueUserAPC.cpp b/byp/sbexecution/CodeInjection/QueueUserAPC.cpp new file mode 100644 index 00000000..a8a4961e --- /dev/null +++ b/byp/sbexecution/CodeInjection/QueueUserAPC.cpp @@ -0,0 +1,171 @@ +#include "pch.h" + +#include "QueueUserAPC.h" + +// +// Check whatever InjectedDLL.dll was loaded, because this dll +// does not provide any other way of caller notification. +// +BOOL IsDllInjected(DWORD dwProcessId, LPTSTR DllName) +{ + BOOL bFound = FALSE; + HANDLE hSnapshot; + + hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwProcessId); + if (hSnapshot != INVALID_HANDLE_VALUE) { + + MODULEENTRY32 me32; + me32.dwSize = sizeof(MODULEENTRY32); + + if (Module32First(hSnapshot, &me32)) { + + do { + + if (StrCmpI(me32.szModule, DllName) == 0) { + bFound = TRUE; + break; + } + + } while (Module32Next(hSnapshot, &me32)); + + } + + CloseHandle(hSnapshot); + } + + return bFound; +} + +BOOL QueueUserAPC_Injection() +{ + TCHAR lpDllName[] = _T("InjectedDLL.dll"); + TCHAR lpDllPath[MAX_PATH]; + + HANDLE hThreadSnapshot = INVALID_HANDLE_VALUE; + + DWORD dwTargetProcessId, dwCurrentProcessId = GetCurrentProcessId(); + + HANDLE hProcess = NULL; + HANDLE hThread = NULL; + + HMODULE hKernel32; + + FARPROC LoadLibraryAddress; + LPVOID lpBaseAddress = NULL; + BOOL bStatus = FALSE; + + + /* Get Process ID from Process name */ + + // + // calc used because it has multiple threads and some of them maybe alertable. + // + dwTargetProcessId = GetProcessIdFromName(_T("calc.exe")); + if (dwTargetProcessId == 0) + dwTargetProcessId = GetProcessIdFromName(_T("win32calc.exe"));//w10 classic calc + + if (dwTargetProcessId == 0) { + print_last_error(_T("GetProcessIdFromName")); + return FALSE; + } + + /* Obtain a hmodule of kernel32 */ + hKernel32 = GetModuleHandle(_T("kernel32.dll")); + if (hKernel32 == NULL) { + print_last_error(_T("GetModuleHandle")); + return FALSE; + } + + /* Get LoadLibrary address */ + _tprintf(_T("\t[+] Looking for LoadLibrary in kernel32\n")); + LoadLibraryAddress = GetProcAddress(hKernel32, "LoadLibraryW"); + if (LoadLibraryAddress == NULL) { + print_last_error(_T("GetProcAddress")); + return FALSE; + } + _tprintf(_T("\t[+] Found at 0x%p\n"), LoadLibraryAddress); + + _tprintf(_T("\t[+] Getting proc id: %u\n"), dwTargetProcessId); + + /* Obtain a handle the process */ + hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwTargetProcessId); + if (hProcess == NULL) { + print_last_error(_T("OpenProcess")); + return FALSE; + } + + do { // not a loop + + /* Get the full path of the dll */ + GetFullPathName(lpDllName, MAX_PATH, lpDllPath, NULL); + _tprintf(_T("\t[+] Full DLL Path: %s\n"), lpDllPath); + + // The maximum size of the string buffer. + SIZE_T WriteBufferSize = _tcslen(lpDllPath) * sizeof(TCHAR); + + /* Allocate memory into the remote process */ + _tprintf(_T("\t[+] Allocating space for the path of the DLL\n")); + lpBaseAddress = VirtualAllocEx(hProcess, NULL, WriteBufferSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); + if (lpBaseAddress == NULL) { + print_last_error(_T("VirtualAllocEx")); + break; + } + + /* Write to the remote process */ + printf("\t[+] Writing into the current process space at 0x%p\n", lpBaseAddress); + if (!WriteProcessMemory(hProcess, lpBaseAddress, lpDllPath, WriteBufferSize, NULL)) { + print_last_error(_T("WriteProcessMemory")); + break; + } + + hThreadSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); + if (hThreadSnapshot == INVALID_HANDLE_VALUE) + break; + + THREADENTRY32 te32; + te32.dwSize = sizeof(THREADENTRY32); + + // + // Brute force threads to find suitable alertable thread for APC injection (if any). + // + if (Thread32First(hThreadSnapshot, &te32)) { + do { + if (te32.th32OwnerProcessID == dwTargetProcessId) { + + hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, te32.th32ThreadID); + if (hThread) { + + if (QueueUserAPC((PAPCFUNC)LoadLibraryAddress, hThread, (ULONG_PTR)lpBaseAddress)) { + + if (IsDllInjected(dwTargetProcessId, lpDllName)) { + bStatus = TRUE; + } + } + CloseHandle(hThread); + } + } + + // dll injected - leave + if (bStatus) { + _tprintf(_T("\t[+] Dll has been injected successfully ...\n")); + break; + } + + } while (Thread32Next(hThreadSnapshot, &te32)); + } + + } while (FALSE); // not a loop + + // + // Cleanup. + // + if (hThreadSnapshot != INVALID_HANDLE_VALUE) CloseHandle(hThreadSnapshot); + + if (lpBaseAddress) { + VirtualFreeEx(hProcess, lpBaseAddress, 0, MEM_RELEASE); + } + + CloseHandle(hProcess); + + return bStatus; +} diff --git a/byp/sbexecution/CodeInjection/QueueUserAPC.h b/byp/sbexecution/CodeInjection/QueueUserAPC.h new file mode 100644 index 00000000..a4401e9f --- /dev/null +++ b/byp/sbexecution/CodeInjection/QueueUserAPC.h @@ -0,0 +1,4 @@ +#pragma once + +BOOL QueueUserAPC_Injection(); + diff --git a/byp/sbexecution/CodeInjection/RtlCreateUserThread.cpp b/byp/sbexecution/CodeInjection/RtlCreateUserThread.cpp new file mode 100644 index 00000000..6505639c --- /dev/null +++ b/byp/sbexecution/CodeInjection/RtlCreateUserThread.cpp @@ -0,0 +1,127 @@ +#include "pch.h" + +#include "RtlCreateUserThread.h" + +BOOL RtlCreateUserThread_Injection() +{ + // some vars + HMODULE hNtdll; + DWORD dwProcessId; + HANDLE hProcess; + TCHAR lpDllName[] = _T("InjectedDLL.dll"); + TCHAR lpDllPath[MAX_PATH]; + LPVOID lpBaseAddress = NULL; + BOOL bStatus = FALSE; + HMODULE hKernel32; + FARPROC LoadLibraryAddress; + HANDLE hRemoteThread = NULL; + SIZE_T dwSize; + NTSTATUS Status; + + // we have to import our function + pRtlCreateUserThread RtlCreateUserThread = NULL; + + /* + GetLastError cannot be used with RtlCreateUserThread because this routine does not set Win32 LastError value. + Native status code must be translated to Win32 error code and set manually. + */ + pRtlNtStatusToDosError RtlNtStatusToDosErrorPtr = NULL; + + /* Get Process ID from Process name */ + dwProcessId = GetProcessIdFromName(_T("notepad.exe")); + if (dwProcessId == NULL) + return FALSE; + _tprintf(_T("\t[+] Getting proc id: %u\n"), dwProcessId); + + /* Obtain a handle the process */ + hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId); + if (hProcess == NULL) { + print_last_error(_T("OpenProcess")); + return FALSE; + } + + /* Get module handle of ntdll */ + hNtdll = GetModuleHandle(_T("ntdll.dll")); + if (hNtdll == NULL) { + print_last_error(_T("GetModuleHandle")); + goto Cleanup; + } + + /* Get routine pointer, failure is not critical */ + RtlNtStatusToDosErrorPtr = (pRtlNtStatusToDosError)GetProcAddress(hNtdll, "RtlNtStatusToDosError"); + + /* Obtain a handle to kernel32 */ + hKernel32 = GetModuleHandle(_T("kernel32.dll")); + if (hKernel32 == NULL) { + print_last_error(_T("GetModuleHandle")); + goto Cleanup; + } + + // Get the address RtlCreateUserThread + _tprintf(_T("\t[+] Looking for RtlCreateUserThread in ntdll\n")); + RtlCreateUserThread = (pRtlCreateUserThread)GetProcAddress(hNtdll, "RtlCreateUserThread"); + if (RtlCreateUserThread == NULL) { + print_last_error(_T("GetProcAddress")); + goto Cleanup; + } + _tprintf(_T("\t[+] Found at 0x%p\n"), RtlCreateUserThread); + + /* Get LoadLibrary address */ + _tprintf(_T("\t[+] Looking for LoadLibrary in kernel32\n")); + LoadLibraryAddress = GetProcAddress(hKernel32, "LoadLibraryW"); + if (LoadLibraryAddress == NULL) { + print_last_error(_T("GetProcAddress")); + goto Cleanup; + } + _tprintf(_T("\t[+] Found at 0x%p\n"), LoadLibraryAddress); + + /* Get the full path of the dll */ + GetFullPathName(lpDllName, MAX_PATH, lpDllPath, NULL); + _tprintf(_T("\t[+] Full DLL Path: %s\n"), lpDllPath); + + /* Calculate the number of bytes needed for the DLL's pathname */ + dwSize = _tcslen(lpDllPath) * sizeof(TCHAR); + + /* Allocate memory into the remote process */ + _tprintf(_T("\t[+] Allocating space for the path of the DLL\n")); + lpBaseAddress = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); + if (lpBaseAddress == NULL) { + print_last_error(_T("VirtualAllocEx")); + goto Cleanup; + } + + /* Write to the remote process */ + printf("\t[+] Writing into the current process space at 0x%p\n", lpBaseAddress); + if (!WriteProcessMemory(hProcess, lpBaseAddress, lpDllPath, dwSize, NULL)) { + print_last_error(_T("WriteProcessMemory")); + goto Cleanup; + } + + /* Create the more thread */ + Status = RtlCreateUserThread(hProcess, NULL, 0, 0, 0, 0, LoadLibraryAddress, lpBaseAddress, &hRemoteThread, NULL); + if (!NT_SUCCESS(Status)) { + if (RtlNtStatusToDosErrorPtr) { + SetLastError(RtlNtStatusToDosErrorPtr(Status)); + } + else { + SetLastError(ERROR_INTERNAL_ERROR); + } + print_last_error(_T("RtlCreateUserThread")); + } + else { + _tprintf(_T("Remote thread has been created successfully ...\n")); + WaitForSingleObject(hRemoteThread, INFINITE); + CloseHandle(hRemoteThread); + + /* assign function success return result */ + bStatus = TRUE; + } +Cleanup: + /* hProcess is always initialized here. */ + if (lpBaseAddress) { + VirtualFreeEx(hProcess, lpBaseAddress, 0, MEM_RELEASE); + } + CloseHandle(hProcess); + + return bStatus; +} diff --git a/byp/sbexecution/CodeInjection/RtlCreateUserThread.h b/byp/sbexecution/CodeInjection/RtlCreateUserThread.h new file mode 100644 index 00000000..a20fee81 --- /dev/null +++ b/byp/sbexecution/CodeInjection/RtlCreateUserThread.h @@ -0,0 +1,3 @@ +#pragma once + +BOOL RtlCreateUserThread_Injection(); diff --git a/byp/sbexecution/CodeInjection/SetWindowsHooksEx.cpp b/byp/sbexecution/CodeInjection/SetWindowsHooksEx.cpp new file mode 100644 index 00000000..da05a553 --- /dev/null +++ b/byp/sbexecution/CodeInjection/SetWindowsHooksEx.cpp @@ -0,0 +1,61 @@ +#include "pch.h" + +#include "SetWindowsHooksEx.h" + +BOOL SetWindowsHooksEx_Injection() +{ + TCHAR lpDllName[] = _T("InjectedDLL.dll"); + TCHAR lpDllPath[MAX_PATH]; + HOOKPROC myFunctionAddress; + HMODULE hOurDll; + DWORD dwProcessId, dwThreadId; + HHOOK hHook; + + /* Get Process ID from Process name */ + dwProcessId = GetProcessIdFromName(_T("notepad.exe")); + if (dwProcessId == NULL) + return FALSE; + _tprintf(_T("\t[+] Getting proc id: %u\n"), dwProcessId); + + /* Get thread id from process id */ + dwThreadId = GetMainThreadId(dwProcessId); + if (dwThreadId == NULL) + return FALSE; + _tprintf(_T("\t[+] Getting main thread id of proc id: %u\n"), dwThreadId); + + /* Get the full path of the dll to be injected */ + GetFullPathName(lpDllName, MAX_PATH, lpDllPath, NULL); + _tprintf(_T("\t[+] Full DLL Path: %s\n"), lpDllPath); + + /* Obtain a handle to our injected dll */ + hOurDll = LoadLibrary(lpDllPath); + if (hOurDll == NULL) { + print_last_error(_T("LoadLibrary")); + return FALSE; + } + + /* Get 'MyProc' address */ + _tprintf(_T("\t[+] Looking for 'MyProc' in our dll\n")); + myFunctionAddress = (HOOKPROC)GetProcAddress(hOurDll, "MyProc"); + if (myFunctionAddress == NULL) { + print_last_error(_T("GetProcAddress")); + return FALSE; + } + _tprintf(_T("\t[+] Found at 0x%p\n"), myFunctionAddress); + + /* Injection happens here */ + hHook = SetWindowsHookEx(WH_KEYBOARD, myFunctionAddress, hOurDll, dwThreadId); + if (hHook == NULL) { + print_last_error(_T("SetWindowsHookEx")); + return FALSE; + } + + /* Unhook */ + _tprintf(_T("SetWindowsHookEx created successfully ...\n")); + + /* When we want to remove the hook */ + // UnhookWindowsHookEx(hHook); + + return TRUE; + +} diff --git a/byp/sbexecution/CodeInjection/SetWindowsHooksEx.h b/byp/sbexecution/CodeInjection/SetWindowsHooksEx.h new file mode 100644 index 00000000..77158873 --- /dev/null +++ b/byp/sbexecution/CodeInjection/SetWindowsHooksEx.h @@ -0,0 +1,3 @@ +#pragma once + +BOOL SetWindowsHooksEx_Injection(); \ No newline at end of file diff --git a/byp/sbexecution/CodeInjection/pch.h b/byp/sbexecution/CodeInjection/pch.h new file mode 100644 index 00000000..e7df92d7 --- /dev/null +++ b/byp/sbexecution/CodeInjection/pch.h @@ -0,0 +1 @@ +#include "../pch.h" \ No newline at end of file diff --git a/byp/sbexecution/OfficeMacro/al-khaser.docm b/byp/sbexecution/OfficeMacro/al-khaser.docm new file mode 100644 index 0000000000000000000000000000000000000000..ec99985eb4e8b041075cf27cd0767f4b127505c7 GIT binary patch literal 17744 zcmeHvbyOYM(k~X=-QC?KxLbhWF2RDky9al7cL+{!_u%gC7Tn>T;3)R zUaL>9?!D{RTdKNhSJgfrr9r_^fxv+vfq;OBfWQ_*oil)efSAC6fKY%SK{SP}tsIQ3 z9CVdjZH(-->0K->2y?+eD6@e;0QLWS{4XAXIwfhjWdX!?)h&KC_lgrZUc!Ja8z47Y ziF}2xaW|ZcH4LY+AP;xn`}=c)d+Vq$q;J39C4c$s_FyPe-IZMDT+dlSo-0t~k+)id z&cDAtVlPh$GVgN%Z(iL;O8=QcxA4lcQ;Bh@K%+dkJ1}0dVnV3YLtr3gP8_E9t1T61 zF@##~GkZ$91g z(tM8#gZ*XoMuv{bgowG|hzdUYSTGKm|z^L_Q~DkSXff0|ol{H>t*t!EQVUl*j^v76u^Ix^_ku_6+nt zfB!4Z|BFTVFI_K>?K10OgcUgVfAODelV9q>%#&p>m{`VKgn-nP{D88&U^f5y!n3dd zqJ8*Dd}L}mZo2K*ZC<9W^88)07fW^u)9jp?gr+-0 zDX(aI5MJ{bmKU@!e{~WIU366UT8(zE(ox(u<_I&Y8(M4&Mh3F<82xf+>>sU@M{ao? zMSUTGv`{%vAq-C*##+c4ulu2USp4kgMCx_Ao7On#+JaXA-S$uUz(IWCp#zj~fdK*G z0zm>hTiY2j{7Xm-tqmM40SfS^=KDinfC1_cQ2T%PQ69%6*TaYy=uGJs$flO%wl5oHKT-#m7Y1&wa<>=gozhKg3j07iWQ8ijnf-a(A-OwOU-9IebLr#`XAui~oPGVu3*A4iP zK}Fmm?4WkOR~^Ua7f_U*FeBzT)4DVqbf=t@FT8BN!gnvReqJUbYA5u5m;22kLv9i2 zNx%wRJDemmqeeIy0*3$TKeAg!X_y=m;8V;3FtU&UT=a|G{>o_iN;1~VjIeD83*L+l zau%N@F)$rNEf4+h!BIz?@KMzp0wr<@hc23R`5$R+`99{4O6E$m-$_Wewmp>?+HB21 zO;CmGBSC#Lj)v0C-+5{ruVsTuFM6Mc%qlm8;=E&ZbvtUAVc1FCSC4=w)RNCmOIC14 z4kbJwRau-y(?!cU_>%4mO*H;)`x6{H42C>zJ-30c?SAw*$}Gi^1VYiPC}6r$!F9ozuaSE%Z|G+=NA1@(+;#M;_ya?@%z8xU~kT1)p_1)xu^Am(blz1!V?Gw*16gD)*qr4NdgUkaOuWU1ds+ zN1GfsO}+YV#tjw?3!IfJmD=#J+CM5DPm(jDZGMpp8IS0a-D)7kyY5YXf|};GVNC~VXkq>!bngn|OHjJ9hi&+-FrptOb{%$zPntDvlw0U3EBKSON z$vEz=$KRpwdr0ldd<^#EFslPs-|)SDT_mUwbL((3qs1vwAO4s^oE(U%OeJ2!jKCr7 z97Fk|eUqsg-h6i66vdi!BAy*okyR)UwFsgb{*#GgZNTf-%O>+i!XuE(4LF(7w>?*b z7i-72Wr-W$*0*z@C7;n=c0mV<33v;#xtIehJ)Dw}cDw~(iB8#0_!E#bU?>?&JVZbGT4h5lAm9SI`SNYmMjT8F0O>8m0DmF` z5%I;GK!64E@AU8d>_eo7$qCu(i?o5r2px{Jj65ma%P!-9$qDkzZiDKAnGA*x%qQJ? zCNkgy77eD5e?(7`0dDN0P6&z%Aq%8l0iWmNfpm}i5oB0nu_Csr4-Cf#?OMNY{j-rC zoOgr=rprhvHaO0ZZ_omS#g=!#7kigiqD#M;1hw!?yE8d(9nKlsos^tfh)7)5CTBN` zfkccixo@ss_gih}uU%iWs9yt)u|oo%U%u)*ePNKh7HNNM^M0GmdRo$ES8zABH&iSy zqp6a&v&vKgZ6hiPg%eLon09TxJU1ObeLIgCdAF6pX}r%PH=JCNIqgDujyG|Q<}QB3 zRg!sJyq|uf<;;swydODZKXBBv=vJvVK00q-3jSCQwU9=C;tyiM0D&{6FQ+peR~m-u zqYl*#q!q5Fc&bF~sGLr#`;FaiCTr24N>xusKssf8W($=8GgGyJWq3QjEv*_qPWi%; z+Ed#xAbOeZwSU5juBrcX20JyMLV;1!lW1OfTEa+0THVrd!f5u?NG`Q%QqS5ENN2M_ zIoIA|mByCe`*pWfm>ZdvX8f#fos9=R_f33J-PN+z(HaTQc6n~?FZSfK{zo?s*jmZO z)-s|n)~L41IG`aL%mYQ-R0+_PHh7gMpL7R znoQkWEfh{KdW=z~$afu#-Bgr#oU|FVGuyo^;vXOF46AC=uVNFu6g6RRGQ%`@wXMml zjoWVWB+2qB4lk3h+gfACuVGU$;4ZR{wpGeZN%;~NG@AME$0lz$1^Gazv=6n(wB$LNR>p z-ruOmD1vo`zi*yx4aCEjgT887HvoSv_vIgd(8$}0P%o^cNbA43hUJ~hKXA1&!V6Ej zd028Z)M@tpKrZN_$if;)-u}rLh1d<$jy~r>8dBDOaSWw4q(&O)6ngalwqQTJ*^iN_CmRCaWaC97=Ms6-=iT7jHF+1SXG zK2GL5iJZAWiY+D~2&H84gU%X-sQs)(ZYEqYGwRFr{| z?9hW0ZCt`gq)krhR|)tpB$x{f(2k4TM4GuFXl>PThketa0s6*-5%A{0pM1cbf`=?^2cB!pXrvx#lkbq0#znsB>OWSQQJE$#Jv_!Hi0pa+ zc}J6=K(1a9O)C>n2v3d}E8!XI>49!5l^rR*F^Y-Suc{MhwdJo%A)ahiZ1DVD(?3!ef zq5G1diBf^FtY(QL^;c7ZuI*dQ91w~LsrzBh++r9g4_J##I?JRy6jX_la!I69ba4*T zq@(Poq^mR;AA+QXw;b{oE7goOrAl8Gae3i;NLQIh6_oGs`WPh}KTOHQIV{&z+bY1Z z3pd-wT4k_}@_;&@de4Tg{F3tDAvpDF1}*S-glnT2$}`E#m)_R>9vy!O6LB zKMfokTJWKrS*s9hs4}@2(PEbNx?a?I>x4a-!t*$RTasg}@l!_Fx|d_ib;YE&MdyLt zE>@hSjYe{7i|VDscI~C=6%5WnegO(NX4PGreq>N4Oz78%IPI53%du`Vq5MWsC3m=pIWU|TC0UX#-L&1!L!Epey|-Oa{c_>{aT|7<4@c!F!W8%B z)Ial)NO@l@p$O8dP58h-DCD$Es+=K*)wc+C%L8hAL(?Z2H-X$l6A6|telH0$+kt)&Gn zD&L1H#v(N*yE(bPmm8iDAB`6z0IP-xc)SQ;N6CWUWcv0;TIHtQB!L@^(Ka|DrP|-w4NH%oU^@L74|>;Gvy-j_G#VTmIe`(T*ry z{5TP%H|xFG*M8@D@$(MTWk?!>VXAHQWwU;p?Oo+~CRGbIrss>-Q0#JYs|8_m^|jN5 za3F+ffeOyoC7WU^;H8)jm_zo?%GJ7W9Amw{5eo_63h{O-% z*y-et+8RZ?RMjDi9+>j8VH6gI%yI#K9j~8pDp&}{cC_17@n>uB?;aUU)U%vlVYE;L zr?cAiNLV;7cpIfh9vFx}GeyNi4B(zGvQRsOTTAWDjo`_R7Oys zX_H$lMoO*KP@Ielu|SJ4dg3;bGaGzdTOQ=MlBe!1Dq^8>wND^}$C#QeKapz4ZhOe) zf#{P8yzJX%Un-uRYZ0Ig?VRNgK`tQiMRYQj9d>)rq*O0T2)Dz13?o0&fnq4~{z1z+ z2Ud8WniJrehrsJ!RwlY_p0oD-tjMxX@Ld0a{BpHz#GPYDdlkp_YI z1zvw-6#C_*9yVFZVYpWF5A6d{+&a}Am)QMV4&89<;RU#VuBq77) zIAseKF8Fa_Aqu$)lxz-*dUR%2)km3BJv9M^vgA^V{?jBK8fStA#Mho2#(6TT_BT*X zoCtA~{XQ!lkJ;|v^=FiH<+>m3aur+Z0j=0Okzab(|Nbc-Kw1|9FpeMw{1$x8R9t>isv`eulT zlXaG8QZHKMcdXsn`-s%yIZFL5D-Jc9<>ffYKOH`#X1C(7$Jl?R^s0ynwS)sDe@~Xo*ZhAMUfL_sC-SnXYH-jthnC$&K`{Z(R+q{V*2RF~ph|QeoE$J=Y z!Rj08Q-NFoM7xT+q3Ku2t8wIur^SXyaeZHM6{<8!(CmiUa}CImF>*^))xLb7D+km3 zVpbhNI;(+g-n~{hR8=y&lnth9n%?&Oa^MuATZg%Ce~Nwt0~~i*>erEj)!{ZKIIEf0 zuzZm9v~eE#q493kF-7lom;&kbqhsxhefjf&nc$4&R7K>vgt5j#2`(mG)Hoq}g)L?C z!^wBWdOThJmfAN~p$j$V-a|MNaD+a;4EiD(#3NYIT@zEKt0GIbM zaSMVUU7588ccERoRv6Pax52BeM6uIk;t?t3`VFeP7>Rc(hc>IfkxcQi)*VYOcUSEk z#p23RWqO?G=I8W%sEMb{C_Sx=@tj^9hjADv>-Gh=HJ4C95LL+V=2u_Fz!|_O;_|2y zM~6V<0|z&H^zvfzo?o}JdDHJ{=uaypUtSgKsX^9@g(X( zN9LQl^WLWNq%y@8gcKsy0nxXTVb8Zpu#+_T3&wCK(#<3+& z_72OvR{6YmeBt=z4xW?EtO5VS&JJJ8-q#6zfid)+K#zA6z;`=f=0fxdo0L^zqAuZv zD!1RBPBQVMmQRBql^_xB?iN>>oJnz^9!X+~JC@Plu)0#i10GM1yz@tS zFHN7?ihJmM1~hv6#Gxr3>cZ`P##lDX%C;R>hISVV1i8>8Xn&V5vtK>Ru0AoDaJFsi zqer_Za?kFm?P=U|=9%Zzr13Gu`r8}Ee{%4ZDv+&{0K6?>*g!yNf2^1tOpGjz7=HaS z{dDi0sLO=maA3A$JQDP-;CYYU8-#Ey7;u}`rUjgklZm^EWy+UhVM(rOqkxccp+gs# z9_IM2xlvkzLS4tcrdld4pBB$m?vWTxV)jVxNByC0p%lrA%$vwcIa8@Hu zXV|4c)L>moJA^7Maum|~3aO|o!DI0xdZ8#(DpN<;f!H4Tpps9Wj$U9wK;jzHXRLNV z_zZfNY^VzhEC}vlW1&Oi$d)c*WZ7pi+JH$8#B2v#-y>!~LLd$Xo*ZzZ-R#FZGbAO6 ziC9$6o&+6Pe`;ieq+l}|$eo;;aO7>A)P7V2B4)Ss-^*q)p?#qOf(7B4P7jN`aXZyn z*VJSCs8e@;#_@Dh>O22D&+$W>;R(~_-Ei0$xEJTOD$|UB>ttS|wW zm1fUI(+xCAa?T8kY#N=sGmKhoq5gQS+V15{Zi_keA84iJ6_qP|Xv=dNAm@tg@jwY$ zls3@49-;k=(VPUxJo=a?o0N$#*3gQ>M)n0NSSm-C-nX{OlA>T|gvILnGQjI5!}mb= zj67&~`v!-zlZ4hfulIYq_BM|PeTR9vvIP8mp4YW~N7x@oR*!D(be~_Y6@ScMo$K&F z3`g$2f4$4%dpezGI2FhN)%AQiiNYAy@w|G-;^(REY=Mn*xF?cDgy5K9`X+}mJ&*+wKIKue zh&9QpJqy9deDIjN4z!)Tux^N&!gj&p{bm|i+C3rPM^?l>?kxw8zG_e8_3pJtMSjR% zL5p6{BGwPMpiYNMR>SHEI2h!m)W;d}=Yk3Mu_t1|BNFN&6iHvUu&QYiylalfa9_F` z;$e#Uun_{+1VJ?$-`NOsrZIM>;?YY`)C~=fUvFHd;3ae@9gIH{k{7Ydm(X#ZA2zqU(zm$|B5x3jm*)kSr zWg?U=9&sNN)*5C7xtiB&@T5qAQmUL@dQdIxnv!15iP_&kHaL7Wi*Zw;hcs+>3kqOQ zmdv#xnxw@ZC(JQ+qNiO#N3Zz)qJn;89)s5O2K3!)=Eq8UjFxqDHsgq*m9F943QHSZ z@?M>J;$b~Y<$j#0e?Y^^2jnH@@K3>WY2#e;r^-@rZt9fmrmULh#Pcb^<))yLqu88@ z?v-bf9Kh*L>D8@R!}`n#uP%jY(ITb;P`$(xZ=&jj;bD9`w(yGD56>vHh@fB;b`{5_ zgomM;^>g3%Tm*;eX)qY9?`XJq%JgN2jVQG=PmJF zEhr`P9C`|n@0e$t2-G_BH|CkTrFE@>LlrFv3M0pJ(%R!?st`K$Q|Ghz!`Z={C2kK3 z!Vf&cdtn?5rJmcT(h6F&4DVQ}6de)hX$)>|3pAErZ{O)*r9eb1RcTw_VHY^Hanm-v z=#vKlZ=`+700O*W=hK(Rm_0Bs0C1?OIE&d-`z3N^$8XDhz7Go|RU#uyASiGe6wlF*%r;h#!g~d<{A!tK91q^(Tc%tAywo z3PCV!uvzftY4e+u8k(jKq0>_T#LdSCo7JjdDc&4VUPvWLM_a$gA>s%lJ|)Xsl=wk` zc$Pg8i=~NVG<@9i&2P66css+?X-#PH0WSH4?TUaKTvf!VG$SsUS*GiyXiGix?Xl3g zbcU3gMHQwfOLTr1I1+S?mu2lgc3s;%J?P|Tw*g8O@sF+pIxX_a;nPoDnjbH1oyUkc za87gTEYJ=iTwg(rIt5C!e4U^yJeFXPz5(Yo$Ufom#D*wzn?r9Zi*GP){mRng;&C@- zS41kM*d@Htf^P#kKwRK~!RRG4JHta{tmZ;4HusTRtM}oMf;lcW0^yN1z+<0D3Y>Q(0Y61>7301YHBOzT2G)fl*>z+-1BfYoZa>W zKc3i`p1C&CPsECK0>Ogc)1*h$*jI_MOfe`so9SRnW*wKMw$WO`nmkRMX~;;U#7ONN z!hGF^?=iLJ8VxP4!RWOJCioimg;Q!}$E!V^K6lpsIriJ6Cob>Up4`RNF*GZFYg>7* zoL@wmp^|gY(UQf5m6*Lb6)<8UR;-6bZ<-&}fb;&X==9CP4 z5(_mfU9qorWU`(CA*_E2#WwQQE+7E`=neWW!7Y0u2M1HD&-OoAqfTWpa+w{~lVQS} z@med&NOCQ}1%zSS*w0o`WDMdXvJpy;C?S=5dhXkrv=r_l3Y!hiP9OPs6Zd(p^SLhO zDPFab$d4wD)~h!By_7+y_3<`_78&oOn|LuEaU~m`yD>G_^K$up<_4q#w7#E<%;5z*k?VfcI z#l`T}O%K))&m;$*mABCE!Ud>AgA)88^k=vvT+BHi#U{&6xvN$KOq6}^CmM^S$Hm`d z1b>M6<~E8b2+NTsNX$7-1$5Qi+l~i{Pz9C-*tl)PI3pN6C_~P1_mL%HwZhHRox6jA z3W$lsnB+5cmiERk5sy=fW&c1uC)59!8L4k%rWFK~mL-YBVnPOy$^>ObZgd3SmC_ z5AAHE*@t997h{Hulb=I5Havvdx89BOt4N_tm@IEY@Z4vDCgY4`ZHzkaBU>|0q2(V^ zVAV2I=j5*-Qw4hLaLx3~v519&NHYp#&ozAH6A6tQy@Ck0ORncPakfzxV{EeDh0h9{ zh@8D6AfKewn9anl6ZO+W6^WxK#Rl&=6sBMfGp;2+;}|4{<_M!VM3(6`Sq-u9V>}Tl z6hsV=@zy2@JB0K*5}6a6IbEj4t>`wQV1_q7mi?+aZNqaaHn(Yv=Row9c`SqZKvHJ; z<57c_eR)gnP`2>KtvpeUC{fDKO|w=GJcuM=T)G=CQy(+>9$B(<#`nbwjxvaHwbR1R zM}{)YK6jXn{v^dJW~I>$2Yyj9kn8?JIVq(~?Ui0sdG0_mx5kQUfH^!@EY{{lBss5) zS|%O!ONJ%(p-fOV0!tyOyjm^)pmK*~+qdj3$tN zKIo(E*R$xwu?ii_olB zK-0$l*V>FQmlTLHn-Ea*|9zxK|4L&CI`?n)pX7Cnbv#trik~yhp0Dn%tlTCIT7Yg) zWba?|gy(h~$mpdY^5mz!BQPfA*liUXA=E4qh)-BBTW0yz$~MG;NDyGz7p%fm1^Hxl z^RdBeK9tZyplD1G3mNDAoc-v=u~PmGj5iOtN8Ij^@krwk(Y{Q#YY#%J%X_@qEgT7@ zWtV;yOrd0_csDLel4ooRqwOl;&mzGGZlT&m1*P(1Vv7P-taQccd26j{NTp=s=eK1? z&%E@L#zk-DO-IMY)z13Ze7-7VFL@gGXK1rOYv{_y zWuW~T5rZ~8bDSZ$d}8Ref}w?0=Y+D$tYSG+1-wYH1g+Nz3n&ik?(ub!#pZY{W=8l;YHsH-rWAZ#*^CB|a(#($Egk#hR%S!yKB zwxz+67!OXNfTZ%nHBHz7ZW5n6PygC$+=>@*=va!}>Vx7M7 zaTuvcn#zG&3ceXzT=Ij#h?<${di!1>jl%(D$lH^AOIx6*HdAepNp^|ZM@&38K3QbzT)~no1E| zCwxjT9SFxIwvK9=OM|;eF`Q0QSk!U{Zz@dMi2BIGTt!W>A%~_DipcpJh&Y!cDo5u> z1Q7=jJ9fgGxp+Ds7FaSR!i+v!)a|%=-;$F)UzLZ=@&Im=ZziXGU2To}jB}27vw3qz zcTpElClB>6vmXb^X~2sIIi)jf$WXEP654B)#~Ji0x$&`eSwLr~6lnu?N*lV;-c6^v z<%D>Ee$l|PdbwBMx5TAo5#sia!FxXGY>_rw{l0#p0OZa2{5YoDhQ(BcGCD%JwLHgs zy~wn0#kJu(PH{SQlF)Z>Vag{eDzx*Mk!6YMsFY>1_jWo(Yiu^svC5Bqjoypbi38pq%ULLm)$(ZcC4X%%&+1ZjDW=fRbDM~(q-xh zjY{>CyQ|6(@=aZrFszW|)5e@wcwk-p+z)T~eS- zh~OJ78vt)b<03kmdNW~{YP+W zAO&;bLG>kst{OpgW}_ol9yXTLRP=P(`Ct``e#wj1&lXc0ytJ9ws4r9r)RNfO73xW` zIOcs{fiqyKgr^1~F|{XSRnhS}tS&oIj8(gddp|ZfY0aw|kN=>8cGUi1BkkoMJzTlY zEP_Tg^xp7c@=>ua(9Z0|W$S0|fNb1o$N{_71KVM!!~)tr^<(%gsnZ=iJk8os-J$F@u+%x46czmP5?t zwsErtO)H6zYd-o13`Z@TePsYrK;9vvr2lr4KqvnM)Z4-ky!+*P`Fy-2-0Pwhk(wJv zX6-zJIJ1u$X|ZSVVBlr81tG7PQazEegxQPTZL{y-PR{#f#9FRM^nutF$y7ikz3^hu zL_QIaQTit2 z(&F(l%-(8PU3FUJI^<|96L|-#1RXc{Bu=2p(5`B1p{`t7hy+voR#|Ppxb=S1;ZepM zg^KWkfblEV*ml>d$W#i-X|TN^^P|%?=JKu-|)?1<3+#5v*sU`=0r6 zkkz}h%t^Y9fgCXgw#8Tn4A@x*w#fijG{6;%bs+A*B$6U(5?3yjn6n_%Q~iMS$(Lfe zrKu$f>C?*UmjK4IGZFzz=eq!c{#D+NFSgEd`+(=Q&VWaT5&Lt}6$fI=v@{Sc7L`gV zC9&dU-uSWxDaMPX!9kzl-FPS#B|$#$*0Motb=4&=&bP4irm{Y}=%fnKD_oh-;)v)VJ=DG%SrY9+%VZ}tJk3FRC^Mr93=}!yFkYO4rzb6?SC37bO;5Mo$#i;99 z?H}I6YGCS27=&TQsWX6LzE4vh!{(wgZkJ*B;%w1_ZB;g3i)?y_O)AJx5K3TLxOtpJ zHtwi?%bDy@kgp`ilS3jqqBYyJr{T3OH8panJGJYF);%Ys8T|U?aTe{zK_VT*`9y{x zao*(VNJ~5v)?@`?<+*i-*qxc_@COz~)=n7ZL~1ev_Rk=1w{hdIveRAm+F+jECq;7Lu0)1m`EE5TlR|d>nbA@J^vhq+qRUNuTG)h))mZG&-!&aX@sD9uJdq zdnHnXQ(x;)qyO$oM6I|Q*O@*YB+B;05%opRaa~Eo&iEjzv~Hi^RAF9hdNYUtrNO2r z2~tJI(}nRtx~f+5+a`BQVBXTA^iZgf3qub0Rk4$EU*6jKW}j}4qQdT#)D+wXv;?~! z4dEgpwR(ZNVADXN__v-!@wSctDg#%rq8-|Ef+mT<-YQ0FGTLw{aG1QQ&Tff!m|kBZ zL2n;S(cZPyQ*t%_^ylgHgKO)mNe65iPal_5d5lY<8B|8) z(xJpIu>+B)L*lg)QZ{<7u0?BfbQ+Sn%zBGlAk}^*)}~r}yIACP=(C|V3+=EMQaX~6 z0=1}vm8E@WbNZtma&?s7aF^rI2PFV2Fmu;m%6Q7iAx=3`0DFEbM*BjF~IajM4VG|9&|zC&GC+oaGp?FWDYfNvi?T$iAE) zaXi?7%5ylJOIIecZ);JBF5vj++E1`P&hzRL9`=kHp79*N)_zIS411gLhP*cznZj!6 ze%wOQ*=mh3*=9V(PotdGxZb=m^OjSI(`GXajbCpE|ET+IDb?tCd%?Z=g2Zi{+e_pe zYB1`64aK!bUNJUn%H8Uc#7$1Y3(T#-PaJH;;@!4wEm}B2N(CXAVFPv*^bZm@28d_K zI(Z@x%Nbyrcl;nmN{IM|N)m!NXv7m@fq;@t5ZKR3m{Ba$;RsCB`2m<{3jcZzpil}H z_*D%~YuUZWKOCCMBu@xzsTk3hy;Pe4o{>6y01K`E3xGoCuVvIC*%8o4KdTNG6Y>le zNBgn=@n|jzI|v7@e>)s{TNpq>Bo>JJt7(6{=x2L~{@KLSzHVT#zzfd2?t8>MA*o<_ zqIdt(wttcQyv0HbfWZ2n*5}gjr%A`RFP~7{*JiG9-#+O!o4vnT^^9K@#k&@-aNGTS znR~0H;@otb2sslt&QITx^~3fMw8Npq6}?-B<=u~- z_Lzu9nj=u`AkiRb-^5q=b+u@b>|1M_ekMcDe(i-u#tjE!ZB_t2rE_1Afl18 zrDIkr2!p5`{TN!5gN()2>n;c?)+-^R{$S=p*&_u9rB*@&Omou-T7!W?&nEIt8czO` zLQfx_ikU>`zeZOK4^11Oi%0M)AH%!w%AS7J0_3fU8o&P85)>R=Q7doiHgUaCq3a5qOg~0sRDc z?{;Ycdr42k5rtkszp}JWiS4XH(ablq5=Aqu`kf?fRl0h~h_b|`eE6*NmjJ^5YcYV< zQUQU7(4A@XC!{Q(VyrFzVuqZpQo}6n51iIN3V*$1h~aOAOZmUGK(3zEYv~b~yr+R* zqL5#!own%#-fG`BCI1zEYL7VkWkaUsHHQ?%!VQ^?Uvjq9l6ysqv0Ssxx2nV?XE`*@ zTJDl{)&u6~kqQ3^ulOs@t%q{y>7X&BN|sfSgFRK<>&l$b_?TCc@gVo31=%5Po(7vP z1V6j!x3VwI{4DBkCP}aRxotOX<;^mOS(;F<2)cbAI^WkmU&_k-?|VLYJ6H_vI;O%$ zKFNh`u$JaUP-bjk27hMW^sDM56#g9Tk=G_4D=@S=d*iGE?expZWk z_*#$YBI>epfj8(k+7rnv-wUJW*8q?C%hiK~sxZ?9z8*wJFbLVf!)woyGgOAdG2l)Fw z>OTm7UgrRk^_N}MzZ3p_gXv!hZvg@HU(4G6%XZV>k$&Gh_$QVT)W4Dbx|8sC^53_P z{YhQ`SZDug$lp^Jeh2tHlkQJ|c|dO6F93(%^6Gwv_&sgnPY61qzYWIUTk^|^|2x+2 zc?f@EQ4;^zpFgq^ey9FDR{bZn5b3|E{~Edeo&4{?t3Qc>fNTIe^ZtxR{5_QQJIdcf zIDbW{qWT@>S2W{yfWL=9{t8e*{a1kh6cqU#>+jC=zhc$W0s;NQwf;N#?+(sC0dyGt zJ)nPccm7WQyRYm|dPSyx)Bol<`yJtTm(iaHk<5Qg>Hj#8ekcCBp8S&(Am6-y>HWX8 Y=11vw0O9=^bU*^q1$cCq1%BTBA5*L&cmMzZ literal 0 HcmV?d00001 diff --git a/byp/sbexecution/OfficeMacro/macros.vba b/byp/sbexecution/OfficeMacro/macros.vba new file mode 100644 index 00000000..759fc990 --- /dev/null +++ b/byp/sbexecution/OfficeMacro/macros.vba @@ -0,0 +1,29 @@ +Sub Document_Close() + + On Error Resume Next + + ActiveDocument.Range.Text = "Al-khaser 0.69 by Lord Noteworthy" & vbCrLf & vbCrLf & "Public malware techniques used in the wild: Virtual Machine, Emulation, Debuggers, Sandbox detection." & vbCrLf + + checkFileMRU +End Sub + + +Public Sub checkFileMRU() + + printMsg "[*] Checking Application.RecentFiles.Count ..." + + ActiveDocument.Range.Text = ActiveDocument.Range.Text & msg + If Application.RecentFiles.Count < 3 Then + printMsg "BAD" + Else + printMsg "GOOD" + End If + +End Sub + + +Public Function printMsg(msg) + + ActiveDocument.Range.Text = ActiveDocument.Range.Text & msg + +End Function \ No newline at end of file diff --git a/byp/sbexecution/Shared/APIs.cpp b/byp/sbexecution/Shared/APIs.cpp new file mode 100644 index 00000000..cd335819 --- /dev/null +++ b/byp/sbexecution/Shared/APIs.cpp @@ -0,0 +1,181 @@ +#include "pch.h" +#include "APIs.h" + +#define API_COUNT (sizeof(ApiData)/sizeof(*ApiData)) + +API_DATA ApiData[] = { + /* Identifier Library Export Name X86/X64/either Minimum OS Version Removed in OS Version */ + { API_IDENTIFIER::API_CsrGetProcessId, "ntdll.dll", "CsrGetProcessId", API_OS_BITS::ANY, API_OS_VERSION::WIN_XP, API_OS_VERSION::NONE }, + /* the EnumProcessModulesEx API was moved from psapi.dll into kernel32.dll for Windows 7, then back out afterwards, so we need both versions. */ + { API_IDENTIFIER::API_EnumProcessModulesEx_Kernel, "kernel32.dll", "EnumProcessModulesEx", API_OS_BITS::ANY, API_OS_VERSION::WIN_7, API_OS_VERSION::WIN_80 }, + { API_IDENTIFIER::API_EnumProcessModulesEx_PSAPI, "psapi.dll", "EnumProcessModulesEx", API_OS_BITS::ANY, API_OS_VERSION::WIN_VISTA, API_OS_VERSION::NONE }, + { API_IDENTIFIER::API_EnumSystemFirmwareTables, "kernel32.dll", "EnumSystemFirmwareTables", API_OS_BITS::ANY, API_OS_VERSION::WIN_VISTA, API_OS_VERSION::NONE }, + { API_IDENTIFIER::API_GetActiveProcessorCount, "kernel32.dll", "GetActiveProcessorCount", API_OS_BITS::ANY, API_OS_VERSION::WIN_7, API_OS_VERSION::NONE }, + { API_IDENTIFIER::API_GetNativeSystemInfo, "kernel32.dll", "GetNativeSystemInfo", API_OS_BITS::ANY, API_OS_VERSION::WIN_XP, API_OS_VERSION::NONE }, + { API_IDENTIFIER::API_GetProductInfo, "kernel32.dll", "GetProductInfo", API_OS_BITS::ANY, API_OS_VERSION::WIN_XP, API_OS_VERSION::NONE }, + { API_IDENTIFIER::API_GetSystemFirmwareTable, "kernel32.dll", "GetSystemFirmwareTable", API_OS_BITS::ANY, API_OS_VERSION::WIN_VISTA, API_OS_VERSION::NONE }, + { API_IDENTIFIER::API_IsWow64Process, "kernel32.dll", "IsWow64Process", API_OS_BITS::ANY, API_OS_VERSION::WIN_XP_SP2, API_OS_VERSION::NONE }, + { API_IDENTIFIER::API_LdrEnumerateLoadedModules, "ntdll.dll", "LdrEnumerateLoadedModules", API_OS_BITS::ANY, API_OS_VERSION::WIN_XP_SP1, API_OS_VERSION::NONE }, + { API_IDENTIFIER::API_NtClose, "ntdll.dll", "NtClose", API_OS_BITS::ANY, API_OS_VERSION::WIN_XP, API_OS_VERSION::NONE }, + { API_IDENTIFIER::API_NtSystemDebugControl, "ntdll.dll", "NtSystemDebugControl", API_OS_BITS::ANY, API_OS_VERSION::WIN_XP, API_OS_VERSION::NONE }, + { API_IDENTIFIER::API_NtCreateDebugObject, "ntdll.dll", "NtCreateDebugObject", API_OS_BITS::ANY, API_OS_VERSION::WIN_XP, API_OS_VERSION::NONE }, + { API_IDENTIFIER::API_NtDelayExecution, "ntdll.dll", "NtDelayExecution", API_OS_BITS::ANY, API_OS_VERSION::WIN_XP, API_OS_VERSION::NONE }, + { API_IDENTIFIER::API_NtOpenDirectoryObject, "ntdll.dll", "NtOpenDirectoryObject", API_OS_BITS::ANY, API_OS_VERSION::WIN_XP, API_OS_VERSION::NONE }, + { API_IDENTIFIER::API_NtQueryDirectoryObject, "ntdll.dll", "NtQueryDirectoryObject", API_OS_BITS::ANY, API_OS_VERSION::WIN_XP, API_OS_VERSION::NONE }, + { API_IDENTIFIER::API_NtQueryInformationThread, "ntdll.dll", "NtQueryInformationThread", API_OS_BITS::ANY, API_OS_VERSION::WIN_XP, API_OS_VERSION::NONE }, + { API_IDENTIFIER::API_NtQueryInformationProcess, "ntdll.dll", "NtQueryInformationProcess", API_OS_BITS::ANY, API_OS_VERSION::WIN_XP, API_OS_VERSION::NONE }, + { API_IDENTIFIER::API_NtQueryLicenseValue, "ntdll.dll", "NtQueryLicenseValue", API_OS_BITS::ANY, API_OS_VERSION::WIN_VISTA, API_OS_VERSION::NONE }, + { API_IDENTIFIER::API_NtQueryObject, "ntdll.dll", "NtQueryObject", API_OS_BITS::ANY, API_OS_VERSION::WIN_XP, API_OS_VERSION::NONE }, + { API_IDENTIFIER::API_NtQuerySystemInformation, "ntdll.dll", "NtQuerySystemInformation", API_OS_BITS::ANY, API_OS_VERSION::WIN_XP, API_OS_VERSION::NONE }, + { API_IDENTIFIER::API_NtSetInformationThread, "ntdll.dll", "NtSetInformationThread", API_OS_BITS::ANY, API_OS_VERSION::WIN_XP, API_OS_VERSION::NONE }, + { API_IDENTIFIER::API_NtWow64QueryInformationProcess64, "ntdll.dll", "NtWow64QueryInformationProcess64", API_OS_BITS::X86_ONLY, API_OS_VERSION::WIN_XP_SP1, API_OS_VERSION::NONE }, + { API_IDENTIFIER::API_NtWow64ReadVirtualMemory64, "ntdll.dll", "NtWow64ReadVirtualMemory64", API_OS_BITS::X86_ONLY, API_OS_VERSION::WIN_XP_SP1, API_OS_VERSION::NONE }, + { API_IDENTIFIER::API_NtWow64QueryVirtualMemory64, "ntdll.dll", "NtWow64QueryVirtualMemory64", API_OS_BITS::ANY, API_OS_VERSION::WIN_XP_SP1, API_OS_VERSION::WIN_10 }, + { API_IDENTIFIER::API_NtYieldExecution, "ntdll.dll", "NtYieldExecution", API_OS_BITS::ANY, API_OS_VERSION::WIN_XP, API_OS_VERSION::NONE }, + { API_IDENTIFIER::API_RtlInitUnicodeString, "ntdll.dll", "RtlInitUnicodeString", API_OS_BITS::ANY, API_OS_VERSION::WIN_XP, API_OS_VERSION::NONE }, + { API_IDENTIFIER::API_RtlGetVersion, "ntdll.dll", "RtlGetVersion", API_OS_BITS::ANY, API_OS_VERSION::WIN_XP, API_OS_VERSION::NONE }, + { API_IDENTIFIER::API_WudfIsAnyDebuggerPresent, "WUDFPlatform.dll", "WudfIsAnyDebuggerPresent", API_OS_BITS::X64_ONLY, API_OS_VERSION::WIN_VISTA, API_OS_VERSION::NONE }, + { API_IDENTIFIER::API_WudfIsKernelDebuggerPresent, "WUDFPlatform.dll", "WudfIsKernelDebuggerPresent", API_OS_BITS::X64_ONLY, API_OS_VERSION::WIN_VISTA, API_OS_VERSION::NONE }, + { API_IDENTIFIER::API_WudfIsUserDebuggerPresent, "WUDFPlatform.dll", "WudfIsUserDebuggerPresent", API_OS_BITS::X64_ONLY, API_OS_VERSION::WIN_VISTA, API_OS_VERSION::NONE } +}; + +void API::Init() +{ + for (int i = 0; i < API_COUNT; i++) + { + ApiData[i].ExpectedAvailable = ShouldFunctionExistOnCurrentPlatform(ApiData[i].PlatformBits, ApiData[i].MinVersion, ApiData[i].RemovedInVersion); + + HMODULE hLib = LoadLibraryA(ApiData[i].Library); + if (hLib == NULL) + { + ApiData[i].Available = false; + continue; + } + ApiData[i].Pointer = GetProcAddress(hLib, ApiData[i].EntryName); + if (ApiData[i].Pointer == NULL) + { + ApiData[i].Available = false; + continue; + } + else + { + ApiData[i].Available = true; + } + } +} + +bool API::ShouldFunctionExistOnCurrentPlatform(API_OS_BITS bits, API_OS_VERSION minVersion, API_OS_VERSION removedInVersion) +{ + // check if the API should exist on the OS + + // does it meet bitness requirements? + if (bits != API_OS_BITS::ANY) + { +#ifdef ENV64BIT + if (bits != API_OS_BITS::X64_ONLY) + return false; +#endif +#ifdef ENV32BIT + if (bits != API_OS_BITS::X86_ONLY) + return false; +#endif + } + + // does it meet minimum version + bool foundMinVer = false; + bool metMinimumRequirement = false; + + for (int i = 0; i < API_OS_VERSION::VERSION_MAX; i++) + { + if (i == API_OS_VERSION::NONE) + continue; + + if (VersionFunctionMap[i].Version == minVersion) + { + foundMinVer = true; + metMinimumRequirement = VersionFunctionMap[i].Function(); + } + } + if (!foundMinVer) + { + printf("ERROR: Minimum version value was invalid.\n"); + assert(false); + return false; + } + if (!metMinimumRequirement) + return false; + + // if there's no maximum OS restriction, the API should exist + if (removedInVersion == API_OS_VERSION::NONE) + return true; + + // we have an upper restriction. was the API removed in this version? + bool foundRemovedVer = false; + bool metMaximumRequirement = false; + for (int i = 0; i < API_OS_VERSION::VERSION_MAX; i++) + { + if (VersionFunctionMap[i].Version == removedInVersion) + { + foundRemovedVer = true; + metMaximumRequirement = !VersionFunctionMap[i].Function(); + } + } + if (!foundRemovedVer) + { + printf("ERROR: Removed version value was invalid.\n"); + assert(false); + return false; + } + + return metMaximumRequirement; +} + +void API::PrintAvailabilityReport() +{ + int warningCount = 0; + for (int i = 0; i < API_COUNT; i++) + { + if (ApiData[i].ExpectedAvailable && !ApiData[i].Available) + { + printf("[*] Warning: API %s!%s was expected to exist but was not found.\n", ApiData[i].Library, ApiData[i].EntryName); + warningCount += 1; + } + } + if (warningCount == 0) + { + printf("[*] All APIs present and accounted for.\n"); + } +} + +bool API::IsAvailable(API_IDENTIFIER api) +{ + for (int i = 0; i < API_COUNT; i++) + { + if (ApiData[i].Identifier == api) + { + return ApiData[i].Available; + } + } + assert(false); + return false; +} + +void* API::GetAPI(API_IDENTIFIER api) +{ + for (int i = 0; i < API_COUNT; i++) + { + if (ApiData[i].Identifier == api) + { + if (ApiData[i].Available) + { + return ApiData[i].Pointer; + } + else + { + return nullptr; + } + } + } + assert(false); + return nullptr; +} diff --git a/byp/sbexecution/Shared/APIs.h b/byp/sbexecution/Shared/APIs.h new file mode 100644 index 00000000..349a46ff --- /dev/null +++ b/byp/sbexecution/Shared/APIs.h @@ -0,0 +1,130 @@ +#pragma once + +enum API_IDENTIFIER +{ + API_CsrGetProcessId, + API_EnumSystemFirmwareTables, + API_GetActiveProcessorCount, + API_GetSystemFirmwareTable, + API_GetNativeSystemInfo, + API_GetProductInfo, + API_EnumProcessModulesEx_Kernel, + API_EnumProcessModulesEx_PSAPI, + API_IsWow64Process, + API_LdrEnumerateLoadedModules, + API_NtClose, + API_NtSystemDebugControl, + API_NtCreateDebugObject, + API_NtDelayExecution, + API_NtOpenDirectoryObject, + API_NtQueryInformationThread, + API_NtQueryInformationProcess, + API_NtQueryLicenseValue, + API_NtQueryDirectoryObject, + API_NtQueryObject, + API_NtQuerySystemInformation, + API_NtSetInformationThread, + API_NtWow64QueryInformationProcess64, + API_NtWow64QueryVirtualMemory64, + API_NtWow64ReadVirtualMemory64, + API_NtYieldExecution, + API_RtlGetVersion, + API_RtlInitUnicodeString, + API_WudfIsAnyDebuggerPresent, + API_WudfIsKernelDebuggerPresent, + API_WudfIsUserDebuggerPresent, +}; + +enum API_OS_VERSION +{ + NONE, + WIN_XP, + WIN_XP_SP1, + WIN_XP_SP2, + WIN_XP_SP3, + WIN_VISTA, + WIN_VISTA_SP1, + WIN_VISTA_SP2, + WIN_7, + WIN_7_SP1, + WIN_80, + WIN_81, + WIN_10, + VERSION_MAX +}; + +enum API_OS_BITS +{ + ANY, + X86_ONLY, + X64_ONLY, +}; + +struct VERSION_FUNCTION_MAP +{ + API_OS_VERSION Version; + bool(*Function)(); + + VERSION_FUNCTION_MAP(API_OS_VERSION version, bool(*function)()) + { + Version = version; + Function = function; + } + + VERSION_FUNCTION_MAP() + { + } +}; + +struct API_DATA +{ + API_IDENTIFIER Identifier; + const char* Library; + const char* EntryName; + API_OS_BITS PlatformBits; + API_OS_VERSION MinVersion; + API_OS_VERSION RemovedInVersion; + bool Available; + bool ExpectedAvailable; + void* Pointer; + + API_DATA(API_IDENTIFIER identifier, const char* lib, const char* name, API_OS_BITS bits, API_OS_VERSION minVersion, API_OS_VERSION removedInVersion) + { + Identifier = identifier; + Library = lib; + EntryName = name; + PlatformBits = bits; + MinVersion = minVersion; + RemovedInVersion = removedInVersion; + Available = false; + ExpectedAvailable = false; + Pointer = nullptr; + } +}; + +const VERSION_FUNCTION_MAP VersionFunctionMap[] = { + { API_OS_VERSION::NONE, nullptr }, + { API_OS_VERSION::WIN_XP, IsWindowsXPOrGreater }, + { API_OS_VERSION::WIN_XP_SP1, IsWindowsXPSP1OrGreater }, + { API_OS_VERSION::WIN_XP_SP2, IsWindowsXPSP2OrGreater }, + { API_OS_VERSION::WIN_XP_SP3, IsWindowsXPSP3OrGreater }, + { API_OS_VERSION::WIN_VISTA, IsWindowsVistaOrGreater }, + { API_OS_VERSION::WIN_VISTA_SP1, IsWindowsVistaSP1OrGreater }, + { API_OS_VERSION::WIN_VISTA_SP2, IsWindowsVistaSP2OrGreater }, + { API_OS_VERSION::WIN_7, IsWindows7OrGreater }, + { API_OS_VERSION::WIN_7_SP1, IsWindows7SP1OrGreater }, + { API_OS_VERSION::WIN_80, IsWindows8OrGreater }, + { API_OS_VERSION::WIN_81, IsWindows8Point1OrGreater }, + { API_OS_VERSION::WIN_10, IsWindows10OrGreater }, +}; + +class API +{ +private: + static bool ShouldFunctionExistOnCurrentPlatform(API_OS_BITS bits, API_OS_VERSION minVersion, API_OS_VERSION removedInVersion); +public: + static void Init(); + static void PrintAvailabilityReport(); + static bool IsAvailable(API_IDENTIFIER api); + static void* GetAPI(API_IDENTIFIER api); +}; \ No newline at end of file diff --git a/byp/sbexecution/Shared/ApiTypeDefs.cpp b/byp/sbexecution/Shared/ApiTypeDefs.cpp new file mode 100644 index 00000000..1d9f38c5 --- /dev/null +++ b/byp/sbexecution/Shared/ApiTypeDefs.cpp @@ -0,0 +1 @@ +#include "pch.h" diff --git a/byp/sbexecution/Shared/ApiTypeDefs.h b/byp/sbexecution/Shared/ApiTypeDefs.h new file mode 100644 index 00000000..5cd3d6b4 --- /dev/null +++ b/byp/sbexecution/Shared/ApiTypeDefs.h @@ -0,0 +1,136 @@ +#pragma once + +typedef DWORD(NTAPI* pCsrGetId)(VOID); +typedef BOOL(WINAPI* pEnumProcessModulesEx)( + HANDLE hProcess, + HMODULE *lphModule, + DWORD cb, + LPDWORD lpcbNeeded, + DWORD dwFilterFlag); +typedef UINT(WINAPI* pEnumSystemFirmwareTables)(DWORD, PVOID, DWORD); +typedef DWORD(WINAPI* pGetActiveProcessorCount)(WORD); +typedef UINT(WINAPI* pGetSystemFirmwareTable)(DWORD, DWORD, PVOID, DWORD); +typedef void (WINAPI *pGetNativeSystemInfo)(LPSYSTEM_INFO); +typedef BOOL(WINAPI *pGetProductInfo)(DWORD, DWORD, DWORD, DWORD, PDWORD); +typedef BOOL(WINAPI *pIsWow64Process) (HANDLE, PBOOL); +typedef DWORD(WINAPI * pRtlCreateUserThread)( + IN HANDLE ProcessHandle, + IN PSECURITY_DESCRIPTOR SecurityDescriptor, + IN BOOL CreateSuspended, + IN ULONG StackZeroBits, + IN OUT PULONG StackReserved, + IN OUT PULONG StackCommit, + IN LPVOID StartAddress, + IN LPVOID StartParameter, + OUT HANDLE ThreadHandle, + OUT LPVOID ClientID + ); +typedef NTSTATUS(WINAPI* pNtClose)(HANDLE); +typedef enum _SYSDBG_COMMAND { + SysDbgQueryModuleInformation, + SysDbgQueryTraceInformation, + SysDbgSetTracepoint, + SysDbgSetSpecialCall, + SysDbgClearSpecialCalls, + SysDbgQuerySpecialCalls, + SysDbgBreakPoint, + SysDbgQueryVersion, + SysDbgReadVirtual, + SysDbgWriteVirtual, + SysDbgReadPhysical, + SysDbgWritePhysical, + SysDbgReadControlSpace, + SysDbgWriteControlSpace, + SysDbgReadIoSpace, + SysDbgWriteIoSpace, + SysDbgReadMsr, + SysDbgWriteMsr, + SysDbgReadBusData, + SysDbgWriteBusData, + SysDbgCheckLowMemory, + SysDbgEnableKernelDebugger, + SysDbgDisableKernelDebugger, + SysDbgGetAutoKdEnable, + SysDbgSetAutoKdEnable, + SysDbgGetPrintBufferSize, + SysDbgSetPrintBufferSize, + SysDbgGetKdUmExceptionEnable, + SysDbgSetKdUmExceptionEnable, + SysDbgGetTriageDump, + SysDbgGetKdBlockEnable, + SysDbgSetKdBlockEnable, +} SYSDBG_COMMAND, * PSYSDBG_COMMAND; +typedef NTSTATUS(NTAPI* pNtSystemDebugControl)( + IN SYSDBG_COMMAND Command, + IN PVOID InputBuffer, + IN ULONG InputBufferLength, + OUT PVOID OutputBuffer, + IN ULONG OutputBufferLength, + OUT PULONG ReturnLength); +typedef NTSTATUS(WINAPI *pNtCreateDebugObject)(OUT PHANDLE, IN ACCESS_MASK, IN POBJECT_ATTRIBUTES, IN ULONG); +typedef NTSTATUS(WINAPI *pNtCreateThreadEx)( + OUT PHANDLE ThreadHandle, + IN ACCESS_MASK DesiredAccess, + IN OPTIONAL POBJECT_ATTRIBUTES ObjectAttributes, + IN HANDLE ProcessHandle, + IN PVOID StartRoutine, + IN OPTIONAL PVOID Argument, + IN ULONG CreateFlags, //THREAD_CREATE_FLAGS_* + IN OPTIONAL ULONG_PTR ZeroBits, + IN OPTIONAL SIZE_T StackSize, + IN OPTIONAL SIZE_T MaximumStackSize, + IN OPTIONAL PPS_ATTRIBUTE_LIST AttributeList + ); +typedef NTSTATUS(WINAPI *pNtDelayExecution)(IN BOOLEAN, IN PLARGE_INTEGER); +typedef NTSTATUS(WINAPI *pNtQueryInformationProcess)(IN HANDLE, IN UINT, OUT PVOID, IN ULONG, OUT PULONG); +typedef NTSTATUS(WINAPI *pNtQueryInformationThread)(HANDLE, UINT, PVOID, ULONG, PULONG); + +typedef NTSTATUS(NTAPI *pNtQueryLicenseValue)( + IN PUNICODE_STRING ValueName, + OUT OPTIONAL PULONG Type, + OUT PVOID Data, + IN ULONG DataSize, + OUT PULONG ResultDataSize); + +typedef VOID (NTAPI *pRtlInitUnicodeString)( + _Out_ PUNICODE_STRING DestinationString, + _In_opt_ PCWSTR SourceString); + + +typedef NTSTATUS(WINAPI *pNtQueryDirectoryObject)(_In_ HANDLE, _Out_opt_ PVOID, _In_ ULONG, _In_ BOOLEAN, _In_ BOOLEAN, _Inout_ PULONG, _Out_opt_ PULONG); +typedef NTSTATUS(WINAPI *pNtOpenDirectoryObject)(OUT PHANDLE, IN ACCESS_MASK, IN POBJECT_ATTRIBUTES); + +typedef NTSTATUS(WINAPI *pNtQueryObject)(IN HANDLE, IN UINT, OUT PVOID, IN ULONG, OUT PULONG); +typedef NTSTATUS(WINAPI *pNtQuerySystemInformation)(IN UINT, OUT PVOID, IN ULONG, OUT PULONG); +typedef NTSTATUS(WINAPI *pNtSetInformationThread)(HANDLE, UINT, PVOID, ULONG); +typedef NTSTATUS(WINAPI* pNtUnmapViewOfSection)(HANDLE ProcessHandle, PVOID BaseAddress); +typedef NTSTATUS(WINAPI* pNtYieldExecution)(); +typedef NTSTATUS(WINAPI* pRtlGetVersion)(RTL_OSVERSIONINFOEXW*); +typedef ULONG (NTAPI* pRtlNtStatusToDosError)(IN NTSTATUS Status); +typedef NTSTATUS(NTAPI * pNtWow64QueryInformationProcess64)( + IN HANDLE ProcessHandle, + ULONG ProcessInformationClass, + OUT PVOID ProcessInformation, + IN ULONG ProcessInformationLength, + OUT PULONG ReturnLength OPTIONAL); +typedef NTSTATUS(WINAPI *pNtWow64ReadVirtualMemory64)( + HANDLE ProcessHandle, + PVOID64 BaseAddress, + PVOID Buffer, + ULONGLONG BufferSize, + PULONGLONG NumberOfBytesRead +); +typedef NTSTATUS(NTAPI *pNtWow64QueryVirtualMemory64)( + IN HANDLE ProcessHandle, + IN PVOID64 BaseAddress, + IN DWORD MemoryInformationClass, + OUT PMEMORY_BASIC_INFORMATION64 MemoryInformation, + IN ULONG64 Size, + OUT PULONG64 ReturnLength OPTIONAL); +typedef NTSTATUS(NTAPI *pLdrEnumerateLoadedModules)( + IN BOOLEAN ReservedFlag, + IN PLDR_ENUM_CALLBACK EnumProc, + IN PVOID Context); +typedef INT(NTAPI *pWudfIsAnyDebuggerPresent)(); +typedef INT(NTAPI *pWudfIsKernelDebuggerPresent)(); +typedef INT(NTAPI *pWudfIsUserDebuggerPresent)(); diff --git a/byp/sbexecution/Shared/Common.cpp b/byp/sbexecution/Shared/Common.cpp new file mode 100644 index 00000000..e3d855ce --- /dev/null +++ b/byp/sbexecution/Shared/Common.cpp @@ -0,0 +1,199 @@ +#include "pch.h" +#include "Common.h" + +VOID print_detected() +{ + /* Get handle to standard output */ + HANDLE nStdHandle = GetStdHandle(STD_OUTPUT_HANDLE); + CONSOLE_SCREEN_BUFFER_INFO ConsoleScreenBufferInfo; + SecureZeroMemory(&ConsoleScreenBufferInfo, sizeof(CONSOLE_SCREEN_BUFFER_INFO)); + + /* Save the original console color */ + GetConsoleScreenBufferInfo(nStdHandle, &ConsoleScreenBufferInfo); + WORD OriginalColors = *(&ConsoleScreenBufferInfo.wAttributes); + + SetConsoleTextAttribute(nStdHandle, 12); + _tprintf(TEXT("[ BAD ]\n")); + SetConsoleTextAttribute(nStdHandle, OriginalColors); +} + +VOID print_not_detected() +{ + /* Get handle to standard output */ + HANDLE nStdHandle = GetStdHandle(STD_OUTPUT_HANDLE); + CONSOLE_SCREEN_BUFFER_INFO ConsoleScreenBufferInfo; + SecureZeroMemory(&ConsoleScreenBufferInfo, sizeof(CONSOLE_SCREEN_BUFFER_INFO)); + + /* Save the original console color */ + GetConsoleScreenBufferInfo(nStdHandle, &ConsoleScreenBufferInfo); + WORD OriginalColors = *(&ConsoleScreenBufferInfo.wAttributes); + + SetConsoleTextAttribute(nStdHandle, 10); + _tprintf(TEXT("[ GOOD ]\n")); + SetConsoleTextAttribute(nStdHandle, OriginalColors); +} + +VOID print_category(const TCHAR* text) +{ + /* Get handle to standard output */ + HANDLE nStdHandle = GetStdHandle(STD_OUTPUT_HANDLE); + CONSOLE_SCREEN_BUFFER_INFO ConsoleScreenBufferInfo; + SecureZeroMemory(&ConsoleScreenBufferInfo, sizeof(CONSOLE_SCREEN_BUFFER_INFO)); + + /* Save the original console color */ + GetConsoleScreenBufferInfo(nStdHandle, &ConsoleScreenBufferInfo); + WORD OriginalColors = *(&ConsoleScreenBufferInfo.wAttributes); + + SetConsoleTextAttribute(nStdHandle, 13); + _tprintf(TEXT("\n-------------------------[%s]-------------------------\n"), text); + SetConsoleTextAttribute(nStdHandle, OriginalColors); +} + +VOID _print_check_text(const TCHAR* szMsg) +{ + _tprintf(TEXT("[*] %s"), szMsg); + + /* align the result according to the length of the text */ + size_t spaces_to_padd = 95 - _tcslen(szMsg); + while (spaces_to_padd > 0) { + _tprintf(TEXT(" ")); + spaces_to_padd--; + } +} + +VOID _print_check_result(int result, const TCHAR* szMsg) +{ + if (result == TRUE) + print_detected(); + else + print_not_detected(); + + /* log to file*/ + TCHAR buffer[256] = _T(""); + _stprintf_s(buffer, sizeof(buffer) / sizeof(TCHAR), _T("[*] %s -> %d"), szMsg, result); + LOG_PRINT(buffer); +} + +VOID print_results(int result, TCHAR* szMsg) +{ + _print_check_text(szMsg); + _print_check_result(result, szMsg); +} + +// note: templated version of this function is in Common.h +VOID exec_check(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(); + + /* Print / Log the result */ + if (szMsg) + _print_check_result(result, szMsg); +} + +VOID resize_console_window() +{ + // Change the window title: + SetConsoleTitle(_T("Al-Khaser - by Lord Noteworthy")); + + // Get console window handle + HWND wh = GetConsoleWindow(); + + // Move window to required position + MoveWindow(wh, 100, 100, 900, 900, TRUE); +} + + +VOID print_os() +{ + TCHAR szOS[MAX_PATH] = _T(""); + if (GetOSDisplayString(szOS)) + { + //_tcscpy_s(szOS, MAX_PATH, szOS); + _tprintf(_T("\n[*] You are running: %s\n"), szOS); + } +} + +VOID print_last_error(LPCTSTR lpszFunction) +{ + // Retrieve the system error message for the last-error code + + LPVOID lpMsgBuf; + LPVOID lpDisplayBuf; + DWORD dw = GetLastError(); + + if (FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + dw, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR)&lpMsgBuf, + 0, NULL) == 0) + { + //FormatMessage failed, return + return; + } + + // Display the error message and exit the process + + lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, + (lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR)); + + if (lpDisplayBuf) { + + StringCchPrintf((LPTSTR)lpDisplayBuf, + LocalSize(lpDisplayBuf) / sizeof(TCHAR), + TEXT("%s failed with error %u: %s"), + lpszFunction, dw, lpMsgBuf); + + _tprintf((LPCTSTR)lpDisplayBuf); + + LocalFree(lpDisplayBuf); + } + LocalFree(lpMsgBuf); +} + +WCHAR* ascii_to_wide_str(CHAR* lpMultiByteStr) +{ + + /* Get the required size */ + INT iNumChars = MultiByteToWideChar(CP_ACP, 0, lpMultiByteStr, -1, NULL, 0); + + /* Allocate new wide string */ + + SIZE_T Size = (1 + iNumChars) * sizeof(WCHAR); + + WCHAR *lpWideCharStr = reinterpret_cast(malloc(Size)); + + if (lpWideCharStr) { + SecureZeroMemory(lpWideCharStr, Size); + /* Do the conversion */ + iNumChars = MultiByteToWideChar(CP_ACP, 0, lpMultiByteStr, -1, lpWideCharStr, iNumChars); + } + return lpWideCharStr; +} + +CHAR* wide_str_to_multibyte (TCHAR* lpWideStr) +{ + errno_t status; + int *pRetValue = NULL; + CHAR *mbchar = NULL; + size_t sizeInBytes = 0; + + status = wctomb_s(pRetValue, mbchar, sizeInBytes, *lpWideStr); + return mbchar; +} + +BOOL IsHexString(WCHAR* szStr) { + std::wstring s(szStr); + + if (std::find_if(s.begin(), s.end(), [](wchar_t c) {return !std::isxdigit(static_cast(c)); }) == s.end()) + return TRUE; + else + return FALSE; +} diff --git a/byp/sbexecution/Shared/Common.h b/byp/sbexecution/Shared/Common.h new file mode 100644 index 00000000..e207c641 --- /dev/null +++ b/byp/sbexecution/Shared/Common.h @@ -0,0 +1,32 @@ +#pragma once + +VOID print_detected() ; +VOID print_not_detected() ; +VOID print_category(const TCHAR* text); +VOID print_last_error(LPCTSTR lpszFunction); +VOID print_os(); +WCHAR* ascii_to_wide_str(CHAR* lpMultiByteStr); +CHAR* wide_str_to_multibyte(TCHAR* lpWideStr); +BOOL IsHexString(WCHAR* szStr); +VOID resize_console_window(); +VOID print_results(int result, TCHAR* szMsg); +VOID _print_check_text(const TCHAR* szMsg); +VOID _print_check_result(int result, const TCHAR* szMsg); + +VOID exec_check(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 +template +VOID exec_check(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); + + /* Print / Log the result */ + if (szMsg) + _print_check_result(result, szMsg); +} \ No newline at end of file diff --git a/byp/sbexecution/Shared/Utils.cpp b/byp/sbexecution/Shared/Utils.cpp new file mode 100644 index 00000000..5a75757a --- /dev/null +++ b/byp/sbexecution/Shared/Utils.cpp @@ -0,0 +1,1121 @@ +#include "pch.h" +#include "Utils.h" + +BOOL IsWoW64() +{ + BOOL bIsWow64 = FALSE; + + if (API::IsAvailable(API_IDENTIFIER::API_IsWow64Process)) + { + auto fnIsWow64Process = static_cast(API::GetAPI(API_IDENTIFIER::API_IsWow64Process)); + if (!fnIsWow64Process(GetCurrentProcess(), &bIsWow64)) + { + // handle error + } + } + + return bIsWow64; +} + +PVOID64 GetPeb64() +{ + PVOID64 peb64 = NULL; + + if (API::IsAvailable(API_IDENTIFIER::API_NtWow64QueryInformationProcess64)) + { + PROCESS_BASIC_INFORMATION_WOW64 pbi64 = {}; + + auto NtWow64QueryInformationProcess64 = static_cast(API::GetAPI(API_IDENTIFIER::API_NtWow64QueryInformationProcess64)); + NTSTATUS status = NtWow64QueryInformationProcess64(GetCurrentProcess(), ProcessBasicInformation, &pbi64, sizeof(pbi64), nullptr); + if ( NT_SUCCESS ( status ) ) + peb64 = pbi64.PebBaseAddress; + } + + return peb64; +} + +BOOL Is_RegKeyValueExists(HKEY hKey, const TCHAR* lpSubKey, const TCHAR* lpValueName, const TCHAR* search_str) +{ + HKEY hkResult = NULL; + TCHAR lpData[1024] = { 0 }; + DWORD cbData = MAX_PATH; + + if (RegOpenKeyEx(hKey, lpSubKey, NULL, KEY_READ, &hkResult) == ERROR_SUCCESS) + { + if (RegQueryValueEx(hkResult, lpValueName, NULL, NULL, (LPBYTE)lpData, &cbData) == ERROR_SUCCESS) + { + if (StrStrI((PCTSTR)lpData, search_str) != NULL) + { + RegCloseKey(hkResult); + return TRUE; + } + } + RegCloseKey(hkResult); + } + return FALSE; + +} + +BOOL Is_RegKeyExists(HKEY hKey, const TCHAR* lpSubKey) +{ + HKEY hkResult = NULL; + TCHAR lpData[1024] = { 0 }; + DWORD cbData = MAX_PATH; + + if (RegOpenKeyEx(hKey, lpSubKey, NULL, KEY_READ, &hkResult) == ERROR_SUCCESS) + { + RegCloseKey(hkResult); + return TRUE; + } + + return FALSE; +} + +BOOL is_FileExists(TCHAR* szPath) +{ + DWORD dwAttrib = GetFileAttributes(szPath); + return (dwAttrib != INVALID_FILE_ATTRIBUTES) && !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY); +} + +BOOL is_DirectoryExists(TCHAR* szPath) +{ + DWORD dwAttrib = GetFileAttributes(szPath); + return (dwAttrib != INVALID_FILE_ATTRIBUTES) && (dwAttrib & FILE_ATTRIBUTE_DIRECTORY); +} + +BOOL check_mac_addr(const TCHAR* szMac) +{ + BOOL bResult = FALSE; + PIP_ADAPTER_INFO pAdapterInfo, pAdapterInfoPtr; + ULONG ulOutBufLen = sizeof(IP_ADAPTER_INFO); + + pAdapterInfo = (PIP_ADAPTER_INFO)MALLOC(sizeof(IP_ADAPTER_INFO)); + if (pAdapterInfo == NULL) + { + _tprintf(_T("Error allocating memory needed to call GetAdaptersinfo.\n")); + return -1; + } + + DWORD dwResult = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen); + + // Make an initial call to GetAdaptersInfo to get the necessary size into the ulOutBufLen variable + if (dwResult == ERROR_BUFFER_OVERFLOW) + { + FREE(pAdapterInfo); + pAdapterInfo = (PIP_ADAPTER_INFO)MALLOC(ulOutBufLen); + if (pAdapterInfo == NULL) { + printf("Error allocating memory needed to call GetAdaptersinfo\n"); + return 1; + } + + // Now, we can call GetAdaptersInfo + dwResult = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen); + } + + if (dwResult == ERROR_SUCCESS) + { + // Convert the given mac address to an array of multibyte chars so we can compare. + CHAR szMacMultiBytes[4]; + for (int i = 0; i < 4; i++) { + szMacMultiBytes[i] = (CHAR)szMac[i]; + } + + pAdapterInfoPtr = pAdapterInfo; + + while (pAdapterInfoPtr) + { + + if (pAdapterInfoPtr->AddressLength == 6 && !memcmp(szMacMultiBytes, pAdapterInfoPtr->Address, 3)) + { + bResult = TRUE; + break; + } + pAdapterInfoPtr = pAdapterInfoPtr->Next; + } + } + + FREE(pAdapterInfo); + + return bResult; +} + +BOOL check_adapter_name(const TCHAR* szName) +{ + BOOL bResult = FALSE; + PIP_ADAPTER_INFO pAdapterInfo, pAdapterInfoPtr; + ULONG ulOutBufLen = sizeof(IP_ADAPTER_INFO); + + WCHAR *pwszConverted; + + pAdapterInfo = (PIP_ADAPTER_INFO)MALLOC(sizeof(IP_ADAPTER_INFO)); + if (pAdapterInfo == NULL) + { + _tprintf(_T("Error allocating memory needed to call GetAdaptersinfo.\n")); + return -1; + } + + // Make an initial call to GetAdaptersInfo to get the necessary size into the ulOutBufLen variable + + DWORD dwResult = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen); + + if (dwResult == ERROR_BUFFER_OVERFLOW) + { + FREE(pAdapterInfo); + pAdapterInfo = (PIP_ADAPTER_INFO)MALLOC(ulOutBufLen); + if (pAdapterInfo == NULL) { + printf("Error allocating memory needed to call GetAdaptersinfo\n"); + return 1; + } + + dwResult = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen); + } + + if (dwResult == ERROR_SUCCESS) + { + pAdapterInfoPtr = pAdapterInfo; + + while (pAdapterInfoPtr) + { + pwszConverted = ascii_to_wide_str(pAdapterInfoPtr->Description); + if (pwszConverted) { + if (StrStrI(pwszConverted, szName) != NULL) + { + bResult = TRUE; + } + free(pwszConverted); + + if (bResult) + break; + } + pAdapterInfoPtr = pAdapterInfoPtr->Next; + } + } + + FREE(pAdapterInfo); + + return bResult; +} + +BOOL GetOSDisplayString(LPTSTR pszOS) +{ + OSVERSIONINFOEX osvi; + SYSTEM_INFO si; + //PGNSI pGNSI; + //PGPI pGPI; + BOOL bOsVersionInfoEx; + DWORD dwType; + + SecureZeroMemory(&si, sizeof(SYSTEM_INFO)); + SecureZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); + + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); + + if (!API::IsAvailable(API_RtlGetVersion)) + return FALSE; + + auto RtlGetVersion = static_cast(API::GetAPI(API_IDENTIFIER::API_RtlGetVersion)); + + bOsVersionInfoEx = RtlGetVersion((RTL_OSVERSIONINFOEXW*)&osvi); + + if (API::IsAvailable(API_GetNativeSystemInfo)) + { + auto GetNativeSystemInfo = static_cast(API::GetAPI(API_IDENTIFIER::API_GetNativeSystemInfo)); + GetNativeSystemInfo(&si); + } + else + { + GetSystemInfo(&si); + } + + if (VER_PLATFORM_WIN32_NT == osvi.dwPlatformId && osvi.dwMajorVersion > 4) + { + StringCchCopy(pszOS, MAX_PATH, TEXT("Microsoft ")); + + // Test for the specific product. + // todo: Not working in Win10, I should use VersionHelpers + if (osvi.dwMajorVersion == 10) + { + if (osvi.dwMinorVersion == 0) + { + if (osvi.wProductType == VER_NT_WORKSTATION) + StringCchCat(pszOS, MAX_PATH, TEXT("Windows 10 ")); + else { + if (osvi.dwBuildNumber > 17763) { + StringCchCat(pszOS, MAX_PATH, TEXT("Windows Server 20XX ")); + } + else if (osvi.dwBuildNumber > 14393) { + StringCchCat(pszOS, MAX_PATH, TEXT("Windows Server 2019 ")); + } + else { + StringCchCat(pszOS, MAX_PATH, TEXT("Windows Server 2016 ")); + } + } + } + } + + else if (osvi.dwMajorVersion == 6) + { + if (osvi.dwMinorVersion == 0) + { + if (osvi.wProductType == VER_NT_WORKSTATION) + StringCchCat(pszOS, MAX_PATH, TEXT("Windows Vista ")); + else StringCchCat(pszOS, MAX_PATH, TEXT("Windows Server 2008 ")); + } + + if (osvi.dwMinorVersion == 1) + { + if (osvi.wProductType == VER_NT_WORKSTATION) + StringCchCat(pszOS, MAX_PATH, TEXT("Windows 7 ")); + else StringCchCat(pszOS, MAX_PATH, TEXT("Windows Server 2008 R2 ")); + } + + if (osvi.dwMinorVersion == 2) + { + if (osvi.wProductType == VER_NT_WORKSTATION) + StringCchCat(pszOS, MAX_PATH, TEXT("Windows 8 ")); + else + StringCchCat(pszOS, MAX_PATH, TEXT("Windows Server 2012")); + } + + auto GetProductInfo = static_cast(API::GetAPI(API_IDENTIFIER::API_GetProductInfo)); + + GetProductInfo(osvi.dwMajorVersion, osvi.dwMinorVersion, 0, 0, &dwType); + + switch (dwType) + { + case PRODUCT_ULTIMATE: + StringCchCat(pszOS, MAX_PATH, TEXT("Ultimate Edition")); + break; + case PRODUCT_PROFESSIONAL: + StringCchCat(pszOS, MAX_PATH, TEXT("Professional")); + break; + case PRODUCT_HOME_PREMIUM: + StringCchCat(pszOS, MAX_PATH, TEXT("Home Premium Edition")); + break; + case PRODUCT_HOME_BASIC: + StringCchCat(pszOS, MAX_PATH, TEXT("Home Basic Edition")); + break; + case PRODUCT_ENTERPRISE: + StringCchCat(pszOS, MAX_PATH, TEXT("Enterprise Edition")); + break; + case PRODUCT_BUSINESS: + StringCchCat(pszOS, MAX_PATH, TEXT("Business Edition")); + break; + case PRODUCT_STARTER: + StringCchCat(pszOS, MAX_PATH, TEXT("Starter Edition")); + break; + case PRODUCT_CLUSTER_SERVER: + StringCchCat(pszOS, MAX_PATH, TEXT("Cluster Server Edition")); + break; + case PRODUCT_DATACENTER_SERVER: + StringCchCat(pszOS, MAX_PATH, TEXT("Datacenter Edition")); + break; + case PRODUCT_DATACENTER_SERVER_CORE: + StringCchCat(pszOS, MAX_PATH, TEXT("Datacenter Edition (core installation)")); + break; + case PRODUCT_ENTERPRISE_SERVER: + StringCchCat(pszOS, MAX_PATH, TEXT("Enterprise Edition")); + break; + case PRODUCT_ENTERPRISE_SERVER_CORE: + StringCchCat(pszOS, MAX_PATH, TEXT("Enterprise Edition (core installation)")); + break; + case PRODUCT_ENTERPRISE_SERVER_IA64: + StringCchCat(pszOS, MAX_PATH, TEXT("Enterprise Edition for Itanium-based Systems")); + break; + case PRODUCT_SMALLBUSINESS_SERVER: + StringCchCat(pszOS, MAX_PATH, TEXT("Small Business Server")); + break; + case PRODUCT_SMALLBUSINESS_SERVER_PREMIUM: + StringCchCat(pszOS, MAX_PATH, TEXT("Small Business Server Premium Edition")); + break; + case PRODUCT_STANDARD_SERVER: + StringCchCat(pszOS, MAX_PATH, TEXT("Standard Edition")); + break; + case PRODUCT_STANDARD_SERVER_CORE: + StringCchCat(pszOS, MAX_PATH, TEXT("Standard Edition (core installation)")); + break; + case PRODUCT_WEB_SERVER: + StringCchCat(pszOS, MAX_PATH, TEXT("Web Server Edition")); + break; + } + } + + else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2) + { + if (GetSystemMetrics(SM_SERVERR2)) + StringCchCat(pszOS, MAX_PATH, TEXT("Windows Server 2003 R2, ")); + else if (osvi.wSuiteMask & VER_SUITE_STORAGE_SERVER) + StringCchCat(pszOS, MAX_PATH, TEXT("Windows Storage Server 2003")); + else if (osvi.wSuiteMask & VER_SUITE_WH_SERVER) + StringCchCat(pszOS, MAX_PATH, TEXT("Windows Home Server")); + else if (osvi.wProductType == VER_NT_WORKSTATION && + si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) + { + StringCchCat(pszOS, MAX_PATH, TEXT("Windows XP Professional x64 Edition")); + } + else StringCchCat(pszOS, MAX_PATH, TEXT("Windows Server 2003, ")); + + // Test for the server type. + if (osvi.wProductType != VER_NT_WORKSTATION) + { + if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64) + { + if (osvi.wSuiteMask & VER_SUITE_DATACENTER) + StringCchCat(pszOS, MAX_PATH, TEXT("Datacenter Edition for Itanium-based Systems")); + else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE) + StringCchCat(pszOS, MAX_PATH, TEXT("Enterprise Edition for Itanium-based Systems")); + } + + else if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) + { + if (osvi.wSuiteMask & VER_SUITE_DATACENTER) + StringCchCat(pszOS, MAX_PATH, TEXT("Datacenter x64 Edition")); + else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE) + StringCchCat(pszOS, MAX_PATH, TEXT("Enterprise x64 Edition")); + else StringCchCat(pszOS, MAX_PATH, TEXT("Standard x64 Edition")); + } + + else + { + if (osvi.wSuiteMask & VER_SUITE_COMPUTE_SERVER) + StringCchCat(pszOS, MAX_PATH, TEXT("Compute Cluster Edition")); + else if (osvi.wSuiteMask & VER_SUITE_DATACENTER) + StringCchCat(pszOS, MAX_PATH, TEXT("Datacenter Edition")); + else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE) + StringCchCat(pszOS, MAX_PATH, TEXT("Enterprise Edition")); + else if (osvi.wSuiteMask & VER_SUITE_BLADE) + StringCchCat(pszOS, MAX_PATH, TEXT("Web Edition")); + else StringCchCat(pszOS, MAX_PATH, TEXT("Standard Edition")); + } + } + } + + else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1) + { + StringCchCat(pszOS, MAX_PATH, TEXT("Windows XP ")); + if (osvi.wSuiteMask & VER_SUITE_PERSONAL) + StringCchCat(pszOS, MAX_PATH, TEXT("Home Edition")); + else StringCchCat(pszOS, MAX_PATH, TEXT("Professional")); + } + + else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0) + { + StringCchCat(pszOS, MAX_PATH, TEXT("Windows 2000 ")); + + if (osvi.wProductType == VER_NT_WORKSTATION) + { + StringCchCat(pszOS, MAX_PATH, TEXT("Professional")); + } + else + { + if (osvi.wSuiteMask & VER_SUITE_DATACENTER) + StringCchCat(pszOS, MAX_PATH, TEXT("Datacenter Server")); + else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE) + StringCchCat(pszOS, MAX_PATH, TEXT("Advanced Server")); + else StringCchCat(pszOS, MAX_PATH, TEXT("Server")); + } + } + + // Include service pack (if any) and build number. + size_t targetSize; + StringCchLength(osvi.szCSDVersion, MAX_PATH, &targetSize); + if (targetSize > 0) + { + StringCchCat(pszOS, MAX_PATH, TEXT(" ")); + StringCchCat(pszOS, MAX_PATH, osvi.szCSDVersion); + } + + TCHAR buf[80]; + + StringCchPrintf(buf, 80, TEXT(" (build %u)"), osvi.dwBuildNumber); + StringCchCat(pszOS, MAX_PATH, buf); + + if (osvi.dwMajorVersion >= 6) + { + if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) + StringCchCat(pszOS, MAX_PATH, TEXT(" 64-bit")); + else if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL) + StringCchCat(pszOS, MAX_PATH, TEXT(" 32-bit")); + } + + return TRUE; + } + + else + { + return FALSE; + } +} + +BOOL IsWindowsVista() { + OSVERSIONINFOEX osvi; + DWORDLONG dwlConditionMask = 0; + int op = VER_EQUAL; + + // Initialize the OSVERSIONINFOEX structure. + + ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); + osvi.dwMajorVersion = 6; + osvi.dwMinorVersion = 0; + + // Initialize the condition mask. + + VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, op); + VER_SET_CONDITION(dwlConditionMask, VER_MINORVERSION, op); + + // Perform the test. + + return VerifyVersionInfo( + &osvi, + VER_MAJORVERSION | VER_MINORVERSION, + dwlConditionMask); +} + +BOOL IsWindows7() { + OSVERSIONINFOEX osvi; + DWORDLONG dwlConditionMask = 0; + int op = VER_EQUAL; + + // Initialize the OSVERSIONINFOEX structure. + + ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); + osvi.dwMajorVersion = 6; + osvi.dwMinorVersion = 1; + + // Initialize the condition mask. + + VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, op); + VER_SET_CONDITION(dwlConditionMask, VER_MINORVERSION, op); + + // Perform the test. + + return VerifyVersionInfo( + &osvi, + VER_MAJORVERSION | VER_MINORVERSION, + dwlConditionMask); +} + +BOOL IsWindows8or8PointOne() { + OSVERSIONINFOEX osvi; + DWORDLONG dwlConditionMask = 0; + int MajorOp = VER_EQUAL; + int MinorOp = VER_GREATER_EQUAL; + + // Initialize the OSVERSIONINFOEX structure. + + ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); + osvi.dwMajorVersion = 6; + osvi.dwMinorVersion = 2; + + // Initialize the condition mask. + + VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, MajorOp); + VER_SET_CONDITION(dwlConditionMask, VER_MINORVERSION, MinorOp); + + // Perform the test. + + return VerifyVersionInfo( + &osvi, + VER_MAJORVERSION | VER_MINORVERSION, + dwlConditionMask); +} + +DWORD GetProccessIDByName(TCHAR* szProcessNameTarget) +{ + DWORD processIds[1024]; + DWORD dBytesReturned; + BOOL bStatus; + HMODULE hMod; + DWORD cbNeeded; + TCHAR szProcessName[MAX_PATH] = _T(""); + + // Get the list of process identifiers. + bStatus = EnumProcesses(processIds, sizeof(processIds), &dBytesReturned); + if (!bStatus) + { + // Something bad happened + } + + // Calculate how many process identifiers were returned. + int cProcesses = dBytesReturned / sizeof(DWORD); + + for (int i = 0; i < cProcesses; i++) + { + // Get a handle to the process. + HANDLE hProcess = OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, FALSE, processIds[i]); + + // Get the process name. + if (hProcess != NULL) + { + EnumProcessModules(hProcess, &hMod, sizeof(hMod), &cbNeeded); + GetModuleBaseName(hProcess, hMod, szProcessName, sizeof(szProcessName) / sizeof(TCHAR)); + + CloseHandle(hProcess); + + // Make the comparaison + if (StrCmpI(szProcessName, szProcessNameTarget) == 0) + return processIds[i]; + + } + + _tprintf(TEXT("%s (PID: %u)\n"), szProcessName, processIds[i]); + } + + return FALSE; +} + +BOOL SetPrivilege( + HANDLE hToken, // token handle + LPCTSTR Privilege, // Privilege to enable/disable + BOOL bEnablePrivilege // TRUE to enable. FALSE to disable +) +{ + TOKEN_PRIVILEGES tp; + LUID luid; + TOKEN_PRIVILEGES tpPrevious; + DWORD cbPrevious = sizeof(TOKEN_PRIVILEGES); + + if (!LookupPrivilegeValue(NULL, Privilege, &luid)) + return FALSE; + + /* first pass. get current privilege setting */ + tp.PrivilegeCount = 1; + tp.Privileges[0].Luid = luid; + tp.Privileges[0].Attributes = 0; + + AdjustTokenPrivileges( + hToken, + FALSE, + &tp, + sizeof(TOKEN_PRIVILEGES), + &tpPrevious, + &cbPrevious + ); + + if (GetLastError() != ERROR_SUCCESS) return FALSE; + + // + // second pass. set privilege based on previous setting + // + tpPrevious.PrivilegeCount = 1; + tpPrevious.Privileges[0].Luid = luid; + + if (bEnablePrivilege) { + tpPrevious.Privileges[0].Attributes |= (SE_PRIVILEGE_ENABLED); + } + else { + tpPrevious.Privileges[0].Attributes ^= (SE_PRIVILEGE_ENABLED & + tpPrevious.Privileges[0].Attributes); + } + + AdjustTokenPrivileges(hToken, FALSE, &tpPrevious, cbPrevious, NULL, NULL); + + if (GetLastError() != ERROR_SUCCESS) return FALSE; + + return TRUE; +} + + +BOOL SetDebugPrivileges(VOID) { + TOKEN_PRIVILEGES priv = { 0 }; + HANDLE hToken = NULL; + BOOL bResult = FALSE; + + if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) { + print_last_error(_T("OpenProcessToken")); + return bResult; + } + + priv.PrivilegeCount = 1; + priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + + if (LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &priv.Privileges[0].Luid)) { + + bResult = AdjustTokenPrivileges(hToken, FALSE, &priv, 0, NULL, NULL); + if (!bResult) { + print_last_error(_T("AdjustTokenPrivileges")); + } + } + else { + print_last_error(_T("LookupPrivilegeValue")); + } + + CloseHandle(hToken); + return bResult; +} + +DWORD GetProcessIdFromName(LPCTSTR szProcessName) +{ + PROCESSENTRY32 pe32; + HANDLE hSnapshot = NULL; + SecureZeroMemory(&pe32, sizeof(PROCESSENTRY32)); + + // We want a snapshot of processes + hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + + // Check for a valid handle, in this case we need to check for + // INVALID_HANDLE_VALUE instead of NULL + if (hSnapshot == INVALID_HANDLE_VALUE) { + print_last_error(_T("CreateToolhelp32Snapshot")); + return 0; + } + + // Now we can enumerate the running process, also + // we can't forget to set the PROCESSENTRY32.dwSize member + // otherwise the following functions will fail + pe32.dwSize = sizeof(PROCESSENTRY32); + + if (Process32First(hSnapshot, &pe32) == FALSE) + { + // Cleanup the mess + print_last_error(_T("Process32First")); + CloseHandle(hSnapshot); + return 0; + } + + // Do our first comparison + if (StrCmpI(pe32.szExeFile, szProcessName) == 0) + { + // Cleanup the mess + CloseHandle(hSnapshot); + return pe32.th32ProcessID; + } + + // Most likely it won't match on the first try so + // we loop through the rest of the entries until + // we find the matching entry or not one at all + while (Process32Next(hSnapshot, &pe32)) + { + if (StrCmpI(pe32.szExeFile, szProcessName) == 0) + { + // Cleanup the mess + CloseHandle(hSnapshot); + return pe32.th32ProcessID; + } + } + + // If we made it this far there wasn't a match, so we'll return 0 + // _tprintf(_T("\n-> Process %s is not running on this system ..."), szProcessName); + + CloseHandle(hSnapshot); + return 0; +} + +DWORD GetMainThreadId(DWORD pid) +{ + /* Get main thread id from process id */ + HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); + if (h != INVALID_HANDLE_VALUE) { + THREADENTRY32 te; + te.dwSize = sizeof(te); + if (Thread32First(h, &te)) + { + do + { + if (te.dwSize >= FIELD_OFFSET(THREADENTRY32, th32OwnerProcessID) + sizeof(te.th32OwnerProcessID)) { + if (te.th32OwnerProcessID == pid) { + HANDLE hThread = OpenThread(READ_CONTROL, FALSE, te.th32ThreadID); + if (!hThread) + print_last_error(_T("OpenThread")); + else { + CloseHandle(hThread); + CloseHandle(h); + return te.th32ThreadID; + } + } + } + + } while (Thread32Next(h, &te)); + } + CloseHandle(h); + } + + print_last_error(_T("CreateToolhelp32Snapshot")); + return (DWORD)0; +} + +BOOL InitWMI(IWbemServices **pSvc, IWbemLocator **pLoc, const TCHAR* szNetworkResource) +{ + // Initialize COM. + HRESULT hres; + hres = CoInitializeEx(0, COINIT_MULTITHREADED); + if (FAILED(hres)) { + print_last_error(_T("CoInitializeEx")); + return 0; + } + + // Set general COM security levels + hres = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL); + if (FAILED(hres)) { + print_last_error(_T("CoInitializeSecurity")); + CoUninitialize(); + return 0; + } + + // Obtain the initial locator to WMI + hres = CoCreateInstance(CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(pLoc)); + if (FAILED(hres)) { + print_last_error(_T("CoCreateInstance")); + CoUninitialize(); + return 0; + } + + BSTR strNetworkResource = SysAllocString(szNetworkResource); + if (strNetworkResource) { + + // Connect to the root\cimv2 namespace + hres = (*pLoc)->ConnectServer(strNetworkResource, NULL, NULL, NULL, WBEM_FLAG_CONNECT_USE_MAX_WAIT, 0, 0, pSvc); + if (FAILED(hres)) { + SysFreeString(strNetworkResource); + print_last_error(_T("ConnectServer")); + (*pLoc)->Release(); + CoUninitialize(); + return 0; + } + SysFreeString(strNetworkResource); + } + + // Set security levels on the proxy ------------------------- + hres = CoSetProxyBlanket(*pSvc, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE); + if (FAILED(hres)) + { + print_last_error(_T("CoSetProxyBlanket")); + (*pSvc)->Release(); + (*pLoc)->Release(); + CoUninitialize(); + return 0; + } + + return 1; +} + +BOOL ExecWMIQuery(IWbemServices **pSvc, IWbemLocator **pLoc, IEnumWbemClassObject **pEnumerator, const TCHAR* szQuery) +{ + // Execute WMI query + BSTR strQueryLanguage = SysAllocString(OLESTR("WQL")); + BSTR strQuery = SysAllocString(szQuery); + + BOOL bQueryResult = TRUE; + + if (strQueryLanguage && strQuery) { + + HRESULT hres = (*pSvc)->ExecQuery(strQueryLanguage, strQuery, + WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, + NULL, pEnumerator); + + if (FAILED(hres)) { + bQueryResult = FALSE; + print_last_error(_T("ExecQuery")); + (*pSvc)->Release(); + (*pLoc)->Release(); + CoUninitialize(); + } + + } + + if (strQueryLanguage) SysFreeString(strQueryLanguage); + if (strQuery) SysFreeString(strQuery); + + return bQueryResult; +} + + +ULONG get_idt_base() +{ + // Get the base of Interupt Descriptor Table (IDT) + + UCHAR idtr[6]; + ULONG idt = 0; + + // sidt instruction stores the contents of the IDT Register + // (the IDTR which points to the IDT) in a processor register. + +#if defined (ENV32BIT) + _asm sidt idtr +#endif + idt = *((unsigned long *)&idtr[2]); + // printf("IDT base: 0x%x\n", idt); + + return idt; +} + + +ULONG get_ldt_base() +{ + // Get the base of Local Descriptor Table (LDT) + + UCHAR ldtr[5] = "\xef\xbe\xad\xde"; + ULONG ldt = 0; + + // sldt instruction stores the contents of the LDT Register + // (the LDTR which points to the LDT) in a processor register. +#if defined (ENV32BIT) + _asm sldt ldtr +#endif + ldt = *((unsigned long *)&ldtr[0]); + // printf("LDT base: 0x%x\n", ldt); + + return ldt; +} + + +ULONG get_gdt_base() +{ + // Get the base of Global Descriptor Table (GDT) + + UCHAR gdtr[6]; + ULONG gdt = 0; + + // sgdt instruction stores the contents of the GDT Register + // (the GDTR which points to the GDT) in a processor register. +#if defined (ENV32BIT) + _asm sgdt gdtr +#endif + gdt = *((unsigned long *)&gdtr[2]); + // printf("GDT base: 0x%x\n", gdt); + + return gdt; +} + + +/* +Check if a process is running with admin rights +*/ +BOOL IsElevated() +{ + BOOL fRet = FALSE; + HANDLE hToken = NULL; + + if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) { + TOKEN_ELEVATION Elevation; + DWORD cbSize = sizeof(TOKEN_ELEVATION); + if (GetTokenInformation(hToken, TokenElevation, &Elevation, sizeof(Elevation), &cbSize)) { + fRet = Elevation.TokenIsElevated; + } + } + if (hToken) { + CloseHandle(hToken); + } + return fRet; +} + + +BOOL find_str_in_data(PBYTE needle, size_t needleLen, PBYTE haystack, size_t haystackLen) +{ + for (size_t i = 0; i < haystackLen - needleLen; i++) + { + if (memcmp(&haystack[i], needle, needleLen) == 0) + { + return TRUE; + } + } + return FALSE; +} + + +UINT enum_system_firmware_tables(DWORD FirmwareTableProviderSignature, PVOID pFirmwareTableBuffer, DWORD BufferSize) +{ + if (!API::IsAvailable(API_IDENTIFIER::API_EnumSystemFirmwareTables)) + { + return -1; + } + + auto EnumSystemFirmwareTables = static_cast(API::GetAPI(API_IDENTIFIER::API_EnumSystemFirmwareTables)); + return EnumSystemFirmwareTables(FirmwareTableProviderSignature, pFirmwareTableBuffer, BufferSize); +} + +PBYTE get_system_firmware(_In_ DWORD signature, _In_ DWORD table, _Out_ PDWORD pBufferSize) +{ + if (!API::IsAvailable(API_IDENTIFIER::API_GetSystemFirmwareTable)) + { + return NULL; + } + + DWORD bufferSize = 4096; + PBYTE firmwareTable = static_cast(malloc(bufferSize)); + + if (firmwareTable == NULL) + return NULL; + + SecureZeroMemory(firmwareTable, bufferSize); + + auto GetSystemFirmwareTable = static_cast(API::GetAPI(API_IDENTIFIER::API_GetSystemFirmwareTable)); + + DWORD resultBufferSize = GetSystemFirmwareTable(signature, table, firmwareTable, bufferSize); + if (resultBufferSize == 0) + { + printf("First call failed :(\n"); + free(firmwareTable); + return NULL; + } + + // if the buffer was too small, realloc and try again + if (resultBufferSize > bufferSize) + { + PBYTE tmp; + + tmp = static_cast(realloc(firmwareTable, resultBufferSize)); + if (tmp) { + firmwareTable = tmp; + SecureZeroMemory(firmwareTable, resultBufferSize); + if (GetSystemFirmwareTable(signature, table, firmwareTable, resultBufferSize) == 0) + { + printf("Second call failed :(\n"); + free(firmwareTable); + return NULL; + } + } + } + + *pBufferSize = resultBufferSize; + return firmwareTable; +} + +bool attempt_to_read_memory(void* addr, void* buf, int size) +{ + // this is a dumb trick and I love it + BOOL b = ReadProcessMemory(GetCurrentProcess(), addr, buf, size, nullptr); + return b != FALSE; +} + +bool attempt_to_read_memory_wow64(PVOID buffer, DWORD size, PVOID64 address) +{ + auto NtWow64ReadVirtualMemory64 = static_cast(API::GetAPI(API_IDENTIFIER::API_NtWow64ReadVirtualMemory64)); + ULONGLONG bytesRead = 0; + + //printf("dbg: read %llx\n", reinterpret_cast(address)); + + HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId()); + + if (hProcess != NULL) + { + NTSTATUS status = NtWow64ReadVirtualMemory64(hProcess, address, buffer, size, &bytesRead); + /*if (status != 0) + printf("NTSTATUS: %x\n", status);*/ + + CloseHandle(hProcess); + + return status == 0; + } + + printf("attempt_to_read_memory_wow64: Couldn't open process: %u\n", GetLastError()); + return false; +} + +bool attempt_to_read_memory_wow64(PVOID buffer, DWORD size, ULONGLONG address) +{ + return attempt_to_read_memory_wow64(buffer, size, reinterpret_cast(address)); +} + +std::vector* enumerate_memory() +{ + auto regions = new std::vector(); + +#ifdef ENV32BIT + const PBYTE MaxAddress = (PBYTE)0x7FFFFFFF; +#else + const PBYTE MaxAddress = (PBYTE)0x7FFFFFFFFFFFFFFFULL; +#endif + + PBYTE addr = 0; + while (addr < MaxAddress) + { + auto mbi = new MEMORY_BASIC_INFORMATION(); + if (VirtualQuery(addr, mbi, sizeof(MEMORY_BASIC_INFORMATION)) <= 0) + break; + + regions->push_back(mbi); + + addr += mbi->RegionSize; + } + + return regions; +} + +std::vector* enumerate_memory_wow64() +{ + if (IsWoW64() == FALSE) + { + printf("Not WoW64.\n"); + return nullptr; + } + + if (!API::IsAvailable(API_NtWow64QueryVirtualMemory64)) + { + printf("API unavailable.\n"); + return nullptr; + } + + auto NtWow64QueryVirtualMemory64 = static_cast(API::GetAPI(API_IDENTIFIER::API_NtWow64QueryVirtualMemory64)); + + auto regions = new std::vector(); + + const INT64 MaxAddress = 0x7FFFFFFFFFFFFFFFULL; + + INT64 addr = 0; + while (addr < MaxAddress) + { + auto mbi = new MEMORY_BASIC_INFORMATION64(); + ULONG64 returnLength; + NTSTATUS status; + if ((status = NtWow64QueryVirtualMemory64(GetCurrentProcess(), (PVOID64)addr, 0, mbi, sizeof(MEMORY_BASIC_INFORMATION64), &returnLength)) != 0) + { + printf("Failed at %llx with status %d.\n", addr, status); + break; + } + + regions->push_back(mbi); + + addr += mbi->RegionSize; + } + + return regions; +} + + +std::vector* enumerate_object_directory(const wchar_t* path) +{ + if (!API::IsAvailable(API_NtOpenDirectoryObject) || !API::IsAvailable(API_NtQueryDirectoryObject)) + { + return nullptr; + } + + UNICODE_STRING usPath = { 0 }; + usPath.Buffer = const_cast(path); + usPath.Length = lstrlenW(path) * sizeof(wchar_t); + usPath.MaximumLength = usPath.Length; + + OBJECT_ATTRIBUTES objAttr = { 0 }; + InitializeObjectAttributes(&objAttr, &usPath, OBJ_CASE_INSENSITIVE, NULL, NULL); + + auto ntOpenDirectoryObject = static_cast(API::GetAPI(API_NtOpenDirectoryObject)); + auto ntQueryDirectoryObject = static_cast(API::GetAPI(API_NtQueryDirectoryObject)); + + const int DIRECTORY_QUERY = 0x0001; + HANDLE hDirectory = 0; + NTSTATUS status = ntOpenDirectoryObject(&hDirectory, DIRECTORY_QUERY, &objAttr); + if (status != 0) + { + //printf("\nNTODO failed: %x\n", status); + return nullptr; + } + + auto pObjDirInfo = static_cast(calloc(0x800, 1)); + ULONG returnedLength = 0; + ULONG context = 0; + auto results = new std::vector(); + while (ntQueryDirectoryObject(hDirectory, pObjDirInfo, 0x800, TRUE, FALSE, &context, &returnedLength) == 0 && returnedLength > 0) + { + //wprintf(L"\nobject: %s\n", pObjDirInfo->Name.Buffer); + wchar_t* name = static_cast(calloc(pObjDirInfo->Name.Length + 1, sizeof(wchar_t))); + memcpy(name, pObjDirInfo->Name.Buffer, pObjDirInfo->Name.Length * sizeof(wchar_t)); + results->push_back(name); + } + + free(pObjDirInfo); + + return results; +} \ No newline at end of file diff --git a/byp/sbexecution/Shared/Utils.h b/byp/sbexecution/Shared/Utils.h new file mode 100644 index 00000000..42d78f10 --- /dev/null +++ b/byp/sbexecution/Shared/Utils.h @@ -0,0 +1,45 @@ +#pragma once + +BOOL IsWoW64(); +PVOID64 GetPeb64(); +BOOL Is_RegKeyValueExists(HKEY hKey, const TCHAR* lpSubKey, const TCHAR* lpValueName, const TCHAR* search_str); +BOOL Is_RegKeyExists(HKEY hKey, const TCHAR* lpSubKey); +BOOL is_FileExists(TCHAR* szPath); +BOOL is_DirectoryExists(TCHAR* szPath); +BOOL check_mac_addr(const TCHAR* szMac); +BOOL check_adapter_name(const TCHAR* szName); +BOOL GetOSDisplayString(LPTSTR pszOS); +BOOL IsWindowsVista(); +BOOL IsWindows7(); +BOOL IsWindows8or8PointOne(); +DWORD GetProccessIDByName(TCHAR* szProcessNameTarget); +DWORD GetProcessIdFromName(LPCTSTR ProcessName); +BOOL SetPrivilege(HANDLE, LPCTSTR, BOOL); +BOOL SetDebugPrivileges(VOID); +DWORD GetMainThreadId(DWORD pid); +BOOL InitWMI(IWbemServices **pSvc, IWbemLocator **pLoc, const TCHAR* szNetworkResource); +BOOL ExecWMIQuery(IWbemServices **pSvc, IWbemLocator **pLoc, IEnumWbemClassObject **pEnumerator, const TCHAR* szQuery); +ULONG get_idt_base(); +ULONG get_ldt_base(); +ULONG get_gdt_base(); +BOOL IsElevated(); +BOOL find_str_in_data(PBYTE needle, size_t needleLen, PBYTE haystack, size_t haystackLen); +UINT enum_system_firmware_tables(_In_ DWORD FirmwareTableProviderSignature, _Out_ PVOID pFirmwareTableBuffer, _In_ DWORD BufferSize); +PBYTE get_system_firmware(_In_ DWORD signature, _In_ DWORD table, _Out_ PDWORD pBufferSize); +bool attempt_to_read_memory(void* addr, void* buf, int size); +bool attempt_to_read_memory_wow64(PVOID buffer, DWORD size, PVOID64 address); +bool attempt_to_read_memory_wow64(PVOID buffer, DWORD size, ULONGLONG address); +std::vector* enumerate_memory(); +std::vector* enumerate_memory_wow64(); +std::vector* enumerate_object_directory(const wchar_t* path); + +#define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, x) +#define FREE(x) HeapFree(GetProcessHeap(), 0, x) + +#if _WIN32 || _WIN64 +#if _WIN64 +#define ENV64BIT +#else +#define ENV32BIT +#endif +#endif \ No newline at end of file diff --git a/byp/sbexecution/Shared/VersionHelpers.h b/byp/sbexecution/Shared/VersionHelpers.h new file mode 100644 index 00000000..d91a9c43 --- /dev/null +++ b/byp/sbexecution/Shared/VersionHelpers.h @@ -0,0 +1,166 @@ +/****************************************************************** +* * +* VersionHelpers.h -- This module defines helper functions to * +* promote version check with proper * +* comparisons. * +* * +* Copyright (c) Microsoft Corp. All rights reserved. * +* * +******************************************************************/ +#pragma once + +#include "winapifamily.h" + +#ifdef _MSC_VER +#pragma once +#endif // _MSC_VER + +#pragma region Application Family +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) + +#include // for _In_, etc. + +#if !defined(__midl) && !defined(SORTPP_PASS) + +#if (NTDDI_VERSION >= NTDDI_WINXP) + +#ifdef __cplusplus + +#define VERSIONHELPERAPI inline bool + +#else // __cplusplus + +#define VERSIONHELPERAPI FORCEINLINE BOOL + +#endif // __cplusplus + +VERSIONHELPERAPI +IsWindowsVersionOrGreater(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor) +{ + OSVERSIONINFOEXW osvi = { sizeof(osvi), 0, 0, 0, 0, {0}, 0, 0 }; + DWORDLONG const dwlConditionMask = VerSetConditionMask( + VerSetConditionMask( + VerSetConditionMask( + 0, VER_MAJORVERSION, VER_GREATER_EQUAL), + VER_MINORVERSION, VER_GREATER_EQUAL), + VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL); + + osvi.dwMajorVersion = wMajorVersion; + osvi.dwMinorVersion = wMinorVersion; + osvi.wServicePackMajor = wServicePackMajor; + + return VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, dwlConditionMask) != FALSE; +} + +VERSIONHELPERAPI +IsWindowsVersionOrLesser(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor) +{ + OSVERSIONINFOEXW osvi = { sizeof(osvi), 0, 0, 0, 0, { 0 }, 0, 0 }; + DWORDLONG const dwlConditionMask = VerSetConditionMask( + VerSetConditionMask( + 0, VER_MAJORVERSION, VER_EQUAL), + VER_MINORVERSION, VER_LESS_EQUAL); + + osvi.dwMajorVersion = wMajorVersion; + osvi.dwMinorVersion = wMinorVersion; + osvi.wServicePackMajor = wServicePackMajor; + + return VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION, dwlConditionMask) != FALSE; +} + +VERSIONHELPERAPI +IsWindowsXPOrGreater() +{ + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 0); +} + +VERSIONHELPERAPI +IsWindowsXPSP1OrGreater() +{ + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 1); +} + +VERSIONHELPERAPI +IsWindowsXPSP2OrGreater() +{ + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 2); +} + +VERSIONHELPERAPI +IsWindowsXPSP3OrGreater() +{ + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 3); +} + +VERSIONHELPERAPI +IsWindowsVistaOrGreater() +{ + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 0); +} + +VERSIONHELPERAPI +IsWindowsVistaSP1OrGreater() +{ + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 1); +} + +VERSIONHELPERAPI +IsWindowsVistaSP2OrGreater() +{ + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 2); +} + +VERSIONHELPERAPI +IsWindows7OrGreater() +{ + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN7), LOBYTE(_WIN32_WINNT_WIN7), 0); +} + +VERSIONHELPERAPI +IsWindows7SP1OrGreater() +{ + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN7), LOBYTE(_WIN32_WINNT_WIN7), 1); +} + +VERSIONHELPERAPI +IsWindows8OrGreater() +{ + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN8), LOBYTE(_WIN32_WINNT_WIN8), 0); +} + +VERSIONHELPERAPI +IsWindows8Point1OrGreater() +{ + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINBLUE), LOBYTE(_WIN32_WINNT_WINBLUE), 0); +} + +VERSIONHELPERAPI +IsWindows10OrGreater() +{ + return IsWindowsVersionOrGreater(10, 0, 0); +} + +VERSIONHELPERAPI +IsWindowsServer() +{ + OSVERSIONINFOEXW osvi = { sizeof(osvi), 0, 0, 0, 0, {0}, 0, 0, 0, VER_NT_WORKSTATION }; + DWORDLONG const dwlConditionMask = VerSetConditionMask( 0, VER_PRODUCT_TYPE, VER_EQUAL ); + + return !VerifyVersionInfoW(&osvi, VER_PRODUCT_TYPE, dwlConditionMask); +} + + + +VERSIONHELPERAPI +IsWindowsXPOr2k() +{ + return IsWindowsVersionOrLesser(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 0); +} + + +#endif // NTDDI_VERSION + +#endif // defined(__midl) + +#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */ +#pragma endregion diff --git a/byp/sbexecution/Shared/WinStructs.h b/byp/sbexecution/Shared/WinStructs.h new file mode 100644 index 00000000..46fda9ee --- /dev/null +++ b/byp/sbexecution/Shared/WinStructs.h @@ -0,0 +1,133 @@ +#pragma once + +typedef struct _LDR_MODULE { + LIST_ENTRY InLoadOrderModuleList; + LIST_ENTRY InMemoryOrderModuleList; + LIST_ENTRY InInitializationOrderModuleList; + PVOID BaseAddress; + PVOID EntryPoint; + ULONG SizeOfImage; + UNICODE_STRING FullDllName; + UNICODE_STRING BaseDllName; + ULONG Flags; + SHORT LoadCount; + SHORT TlsIndex; + LIST_ENTRY HashTableEntry; + ULONG TimeDateStamp; +} LDR_MODULE, *PLDR_MODULE; + +typedef LONG KPRIORITY; + +typedef struct _THREAD_BASIC_INFORMATION { + NTSTATUS ExitStatus; + PVOID TebBaseAddress; + CLIENT_ID ClientId; + KAFFINITY AffinityMask; + KPRIORITY Priority; + KPRIORITY BasePriority; +} THREAD_BASIC_INFORMATION, *PTHREAD_BASIC_INFORMATION; + +typedef struct _PROCESS_BASIC_INFORMATION_WOW64 { + PVOID Reserved1[2]; + PVOID64 PebBaseAddress; + PVOID Reserved2[4]; + ULONG_PTR UniqueProcessId[2]; + PVOID Reserved3[2]; +} PROCESS_BASIC_INFORMATION_WOW64; + +typedef struct _PEB64 { + BYTE Reserved1[2]; + BYTE BeingDebugged; + BYTE Reserved2[1]; + PVOID64 Reserved3[2]; + PVOID64 Ldr; + PVOID64 ProcessParameters; + BYTE Reserved4[104]; + PVOID64 Reserved5[52]; + PVOID64 PostProcessInitRoutine; + BYTE Reserved6[128]; + PVOID64 Reserved7[1]; + ULONG SessionId; +} PEB64, *PPEB64; + +typedef struct _PEB_LDR_DATA64 { + BYTE Reserved1[8]; + PVOID64 Reserved2[3]; + LIST_ENTRY64 InMemoryOrderModuleList; +} PEB_LDR_DATA64, *PPEB_LDR_DATA64; + +typedef struct _UNICODE_STRING64 { + USHORT Length; + USHORT MaximumLength; + PVOID64 Buffer; +} UNICODE_STRING64; + +typedef struct _LDR_DATA_TABLE_ENTRY64 { + PVOID64 Reserved1[2]; + LIST_ENTRY64 InMemoryOrderLinks; + PVOID64 Reserved2[2]; + PVOID64 DllBase; + PVOID64 Reserved3[2]; + UNICODE_STRING64 FullDllName; + BYTE Reserved4[8]; + PVOID64 Reserved5[3]; + union { + ULONG CheckSum; + PVOID64 Reserved6; + } DUMMYUNIONNAME; + ULONG TimeDateStamp; +} LDR_DATA_TABLE_ENTRY64, *PLDR_DATA_TABLE_ENTRY64; + +/*++ NtCreateThreadEx specific */ + +typedef struct _PS_ATTRIBUTE { + ULONG Attribute; + SIZE_T Size; + union + { + ULONG Value; + PVOID ValuePtr; + } u1; + PSIZE_T ReturnLength; +} PS_ATTRIBUTE, *PPS_ATTRIBUTE; + +typedef struct _PS_ATTRIBUTE_LIST { + SIZE_T TotalLength; + PS_ATTRIBUTE Attributes[1]; +} PS_ATTRIBUTE_LIST, *PPS_ATTRIBUTE_LIST; + +#define PS_ATTRIBUTE_NUMBER_MASK 0x0000ffff +#define PS_ATTRIBUTE_THREAD 0x00010000 +#define PS_ATTRIBUTE_INPUT 0x00020000 +#define PS_ATTRIBUTE_ADDITIVE 0x00040000 + +#define PsAttributeValue(Number, Thread, Input, Additive) \ + (((Number) & PS_ATTRIBUTE_NUMBER_MASK) | \ + ((Thread) ? PS_ATTRIBUTE_THREAD : 0) | \ + ((Input) ? PS_ATTRIBUTE_INPUT : 0) | \ + ((Additive) ? PS_ATTRIBUTE_ADDITIVE : 0)) + +typedef enum _PS_ATTRIBUTE_NUM { + PsAttributeClientId = 3, +} PS_ATTRIBUTE_NUM; + +#define PS_ATTRIBUTE_CLIENT_ID \ + PsAttributeValue(PsAttributeClientId, TRUE, FALSE, FALSE) + +/* NtCreateThreadEx specific --*/ + +typedef struct _SYSTEM_HYPERVISOR_PROCESSOR_COUNT_INFORMATION +{ + ULONG NumberOfLogicalProcessors; + ULONG NumberOfCores; +} SYSTEM_HYPERVISOR_PROCESSOR_COUNT_INFORMATION, *PSYSTEM_HYPERVISOR_PROCESSOR_COUNT_INFORMATION; + + +typedef struct _OBJECT_DIRECTORY_INFORMATION +{ + UNICODE_STRING Name; + UNICODE_STRING TypeName; +} OBJECT_DIRECTORY_INFORMATION, *POBJECT_DIRECTORY_INFORMATION; + +typedef VOID(NTAPI LDR_ENUM_CALLBACK)(_In_ PLDR_DATA_TABLE_ENTRY ModuleInformation, _In_ PVOID Parameter, _Out_ BOOLEAN *Stop); +typedef LDR_ENUM_CALLBACK *PLDR_ENUM_CALLBACK; diff --git a/byp/sbexecution/Shared/log.cpp b/byp/sbexecution/Shared/log.cpp new file mode 100644 index 00000000..1587c646 --- /dev/null +++ b/byp/sbexecution/Shared/log.cpp @@ -0,0 +1,104 @@ +#include "pch.h" +#include "log.h" + +static int SESSION_TRACKER; //Keeps track of session + +TCHAR* print_time() +{ + size_t size = 0; + TCHAR *buf; + errno_t err; + TCHAR timestr[32]; + + /* get current calendar time */ + time_t const sourceTime = time(NULL); + tm tmDest = { 0 }; + err = localtime_s(&tmDest, &sourceTime); + if (err) + { + print_last_error(_T("localtime_s")); + exit(1); + } + + // Converts a time_t time value to a tm structure, and corrects for the local time zone. + err = _tasctime_s(timestr, 32, &tmDest); + if (err) + { + print_last_error(_T("_tasctime_s")); + exit(1); + } + + //Getting rid of \n + timestr[_tcsclen(timestr) - 1] = 0; + + //Additional +2 for square braces + size = (_tcsclen(timestr) + 1 + 2) * sizeof(TCHAR); + buf = (TCHAR*)malloc(size); + if (buf) { + memset(buf, 0x0, size); + _stprintf_s(buf, size / sizeof(TCHAR), _T("[%s]"), timestr); + } + return buf; +} +void log_print(const TCHAR* filename, const TCHAR *fmt, ...) +{ + va_list list; + const TCHAR *p, *r; + int e; + + FILE *fp = NULL; + errno_t error; + + TCHAR *pszTime; + + if (SESSION_TRACKER > 0) + error = _tfopen_s(&fp, _T("log.txt"), _T("a+")); + else + error = _tfopen_s(&fp, _T("log.txt"), _T("w")); + + // file create/open failed + if ((error != 0) || (fp == NULL)) + return; + + pszTime = print_time(); + if (pszTime) { + _ftprintf(fp, _T("%s "), pszTime); + free(pszTime); + } + va_start(list, fmt); + + for (p = fmt; *p; ++p) + { + if (*p != '%')//If simple string + fputc(*p, fp); + + else + { + switch (*++p) + { + /* string */ + case 's': + { + r = va_arg(list, TCHAR *); + _ftprintf(fp, _T("%s"), r); + continue; + } + + /* integer */ + case 'd': + { + e = va_arg(list, int); + _ftprintf(fp, _T("%d"), e); + continue; + } + + default: + fputc(*p, fp); + } + } + } + va_end(list); + fputc('\n', fp); + SESSION_TRACKER++; + fclose(fp); +} diff --git a/byp/sbexecution/Shared/log.h b/byp/sbexecution/Shared/log.h new file mode 100644 index 00000000..3f6db18f --- /dev/null +++ b/byp/sbexecution/Shared/log.h @@ -0,0 +1,19 @@ +#pragma once + +#define WIDEN2(x) L##x +#define WIDEN(x) WIDEN2(x) +#define __WFILE__ WIDEN(__FILE__) + +#ifdef UNICODE +#define __TFILE__ __WFILE__ +#else +#define __TFILE__ __FILE__ +#endif + +void log_print(const TCHAR* filename, const TCHAR *fmt, ...); + +#define LOG_PRINT(...) log_print(__TFILE__, __VA_ARGS__ ) + + + + diff --git a/byp/sbexecution/Shared/pch.h b/byp/sbexecution/Shared/pch.h new file mode 100644 index 00000000..e7df92d7 --- /dev/null +++ b/byp/sbexecution/Shared/pch.h @@ -0,0 +1 @@ +#include "../pch.h" \ No newline at end of file diff --git a/byp/sbexecution/Shared/winapifamily.h b/byp/sbexecution/Shared/winapifamily.h new file mode 100644 index 00000000..dd869f12 --- /dev/null +++ b/byp/sbexecution/Shared/winapifamily.h @@ -0,0 +1,183 @@ +/* + +Copyright (c) Microsoft Corporation. All rights reserved. + +Module Name: + + winapifamily.h + +Abstract: + + Master include file for API family partitioning. + +*/ + +#define _WIN32_WINNT_WIN8 0x0602 +#define _WIN32_WINNT_WINBLUE 0x0603 + +#ifndef _INC_WINAPIFAMILY +#define _INC_WINAPIFAMILY + +#if defined(_MSC_VER) && !defined(MOFCOMP_PASS) +#pragma once +#endif // defined(_MSC_VER) && !defined(MOFCOMP_PASS) + +/* + * When compiling C and C++ code using SDK header files, the development + * environment can specify a target platform by #define-ing the + * pre-processor symbol WINAPI_FAMILY to one of the following values. + * Each FAMILY value denotes an application family for which a different + * subset of the total set of header-file-defined APIs are available. + * Setting the WINAPI_FAMILY value will effectively hide from the + * editing and compilation environments the existence of APIs that + * are not applicable to the family of applications targeting a + * specific platform. + */ + +/* + * The WINAPI_FAMILY values of 0 and 1 are reserved to ensure that + * an error will occur if WINAPI_FAMILY is set to any + * WINAPI_PARTITION value (which must be 0 or 1, see below). + */ +#define WINAPI_FAMILY_PC_APP 2 /* Windows Store Applications */ +#define WINAPI_FAMILY_PHONE_APP 3 /* Windows Phone Applications */ +#define WINAPI_FAMILY_DESKTOP_APP 100 /* Windows Desktop Applications */ +/* The value of WINAPI_FAMILY_DESKTOP_APP may change in future SDKs. */ +/* Additional WINAPI_FAMILY values may be defined in future SDKs. */ + +/* + * For compatibility with Windows 8 header files, the following + * synonym for WINAPI_FAMILY_PC_APP is temporarily #define'd. + * Use of this symbol should be considered deprecated. + */ +#define WINAPI_FAMILY_APP WINAPI_FAMILY_PC_APP + +/* + * If no WINAPI_FAMILY value is specified, then all APIs available to + * Windows desktop applications are exposed. + */ +#ifndef WINAPI_FAMILY +#define WINAPI_FAMILY WINAPI_FAMILY_DESKTOP_APP +#endif + +/* + * API PARTITONs are part of an indirection mechanism for mapping between + * individual APIs and the FAMILYs to which they apply. + * Each PARTITION is a category or subset of named APIs. PARTITIONs + * are permitted to have overlapping membership -- some single API + * might be part of more than one PARTITION. In support of new + * FAMILYs that might be added in future SDKs, any single current + * PARTITION might in that future SDK be split into two or more new PARTITIONs. + * Accordingly, application developers should avoid taking dependencies on + * PARTITION names; developers' only dependency upon the symbols defined + * in this file should be their reliance on the WINAPI_FAMILY names and values. + */ + +/* + * Current PARTITIONS are each #undef'ed below, and then will be #define-ed + * to be either 1 or 0 or depending on the active WINAPI_FAMILY. + */ + +#undef WINAPI_PARTITION_DESKTOP /* usable for PC desktop apps (but not store apps) */ +#undef WINAPI_PARTITION_APP /* usable for most platforms' store apps */ +#undef WINAPI_PARTITION_PC_APP /* specific to PC store apps */ +#undef WINAPI_PARTITION_PHONE_APP /* specific to phone store apps */ + + +/* + * The mapping between families and partitions is summarized here. + * An X indicates that the given partition is active for the given + * platform/family. + * + * +---------------+ + * | *Partition* | + * +---+---+---+---+ + * | | | | P | + * | | | | H | + * | D | | | O | + * | E | | P | N | + * | S | | C | E | + * | K | | _ | _ | + * | T | A | A | A | + * +-------------------------+-+ O | P | P | P | + * | *Platform/Family* \| P | P | P | P | + * +---------------------------+---+---+---+---+ + * | WINAPI_FAMILY_DESKTOP_APP | X | X | X | | + * +---------------------------+---+---+---+---+ + * | WINAPI_FAMILY_PC_APP | | X | X | | + * +---------------------------+---+---+---+---+ + * | WINAPI_FAMILY_PHONE_APP | | X | | X | + * +---------------------------+---+---+---+---+ + * + * The table above is encoded in the following expressions, + * each of which evaluates to 1 or 0. + * + * Whenever a new family is added, all of these expressions + * need to be reconsidered. + */ +#if WINAPI_FAMILY != WINAPI_FAMILY_DESKTOP_APP && WINAPI_FAMILY != WINAPI_FAMILY_PC_APP && WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP +# error Unknown WINAPI_FAMILY value. Was it defined in terms of a WINAPI_PARTITION_* value? +#endif +#define WINAPI_PARTITION_DESKTOP (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP) +#define WINAPI_PARTITION_APP 1 /* active for all current families */ +#define WINAPI_PARTITION_PC_APP (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP || WINAPI_FAMILY == WINAPI_FAMILY_PC_APP) +#define WINAPI_PARTITION_PHONE_APP (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) + +/* + * For compatibility with Windows Phone 8 header files, the following + * synonym for WINAPI_PARTITION_PHONE_APP is temporarily #define'd. + * Use of this symbol should be regarded as deprecated. + */ +#define WINAPI_PARTITION_PHONE WINAPI_PARTITION_PHONE_APP + +/* + * Header files use the WINAPI_FAMILY_PARTITION macro to assign one or + * more declarations to some group of partitions. The macro chooses + * whether the preprocessor will emit or omit a sequence of declarations + * bracketed by an #if/#endif pair. All header file references to the + * WINAPI_PARTITION_* values should be in the form of occurrences of + * WINAPI_FAMILY_PARTITION(...). + * + * For example, the following usage of WINAPI_FAMILY_PARTITION identifies + * a sequence of declarations that are part of both the Windows Desktop + * Partition and the Windows-Phone-Specific Store Partition: + * + * #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_PHONE_APP) + * ... + * #endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_PHONE_APP) + * + * The comment on the closing #endif allow tools as well as people to find the + * matching #ifdef properly. + * + * Usages of WINAPI_FAMILY_PARTITION may be combined, when the partitition definitions are + * related. In particular one might use declarations like + * + * #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) + * + * or + * + * #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) + * + * Direct references to WINAPI_PARTITION_ values (eg #if !WINAPI_FAMILY_PARTITION_...) + * should not be used. + */ +#define WINAPI_FAMILY_PARTITION(Partitions) (Partitions) + +/* + * Macro used to #define or typedef a symbol used for selective deprecation + * of individual methods of a COM interfaces that are otherwise available + * for a given set of partitions. + */ +#define _WINAPI_DEPRECATED_DECLARATION __declspec(deprecated("This API cannot be used in the context of the caller's application type.")) + +/* + * For compatibility with Windows 8 header files, the following + * symbol is temporarily conditionally #define'd. Additional symbols + * like this should be not defined in winapifamily.h, but rather should be + * introduced locally to the header files of the component that needs them. + */ +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) +# define APP_DEPRECATED_HRESULT HRESULT _WINAPI_DEPRECATED_DECLARATION +#endif // WINAPIFAMILY_PARTITION(WINAPI_PARTITION_APP) && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) + +#endif /* !_INC_WINAPIFAMILY */ diff --git a/byp/sbexecution/TimingAttacks/pch.h b/byp/sbexecution/TimingAttacks/pch.h new file mode 100644 index 00000000..e7df92d7 --- /dev/null +++ b/byp/sbexecution/TimingAttacks/pch.h @@ -0,0 +1 @@ +#include "../pch.h" \ No newline at end of file diff --git a/byp/sbexecution/TimingAttacks/timing.cpp b/byp/sbexecution/TimingAttacks/timing.cpp new file mode 100644 index 00000000..63c5ec61 --- /dev/null +++ b/byp/sbexecution/TimingAttacks/timing.cpp @@ -0,0 +1,375 @@ +#include "pch.h" +#include "timing.h" + +/* Timing attacks or sleepy malwares are used to bypass sandboxed in general +Every system which run in a timeout is vulnerable to this types of attacks */ + +BOOL timing_NtDelayexecution(UINT delayInMillis) +{ + // In this example, I will demonstrate NtDelayExecution because it is the lowest user mode + // api to delay execution Sleep -> SleepEx -> NtDelayExecution. + LARGE_INTEGER DelayInterval; + LONGLONG llDelay = delayInMillis * 10000LL; + DelayInterval.QuadPart = -llDelay; + + if (!API::IsAvailable(API_IDENTIFIER::API_NtDelayExecution)) + return TRUE; // TODO: make this a warning (NtDelayExecution should always exist) + + auto NtDelayExecution = static_cast(API::GetAPI(API_IDENTIFIER::API_NtDelayExecution)); + NtDelayExecution(FALSE, &DelayInterval); + + return FALSE; +} + +BOOL bProcessed = FALSE; + +VOID CALLBACK TimerProc(HWND hwnd, UINT message, UINT_PTR iTimerID, DWORD dwTime) +{ + // Malicious code is place here .... + bProcessed = TRUE; +} + + +BOOL timing_SetTimer(UINT delayInMillis) +{ + MSG Msg; + UINT_PTR iTimerID; + + // Set our timer without window handle + iTimerID = SetTimer(NULL, 0, delayInMillis, TimerProc); + + if (iTimerID == NULL) + return TRUE; + + // Because we are running in a console app, we should get the messages from + // the queue and check if msg is WM_TIMER + while (GetMessage(&Msg, NULL, 0, 0) & !bProcessed) + { + TranslateMessage(&Msg); + DispatchMessage(&Msg); + } + + // Kill the timer + KillTimer(NULL, iTimerID); + + return FALSE; +} + + +VOID CALLBACK TimerFunction(UINT uTimerID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2) +{ + bProcessed = TRUE; +} + +BOOL timing_timeSetEvent(UINT delayInMillis) +{ + // Some vars + UINT uResolution; + TIMECAPS tc; + MMRESULT idEvent; + + // We can obtain this minimum value by calling + timeGetDevCaps(&tc, sizeof(TIMECAPS)); + uResolution = min(max(tc.wPeriodMin, 0), tc.wPeriodMax); + + // Create the timer + idEvent = timeSetEvent( + delayInMillis, + uResolution, + TimerFunction, + 0, + TIME_ONESHOT); + + if (idEvent == NULL) + return TRUE; + + while (!bProcessed){ + // wait until uor function finish + } + + // destroy the timer + timeKillEvent(idEvent); + + // reset the timer + timeEndPeriod(uResolution); + + return FALSE; +} + + +BOOL timing_WaitForSingleObject(UINT delayInMillis) +{ + HANDLE hEvent; + + // Create a nonsignaled event + hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + if (hEvent == NULL) + { + print_last_error(_T("CreateEvent")); + return TRUE; + } + + // Wait until timeout + DWORD x = WaitForSingleObject(hEvent, delayInMillis); + + // Malicious code goes here + + return FALSE; +} + +BOOL timing_WaitForMultipleObjects(UINT delayInMillis) { + HANDLE hThread; + HANDLE ghEvents[2]; + DWORD i, dwEvent, dwThreadID; + + // Create two event objects + + for (i = 0; i < 2; i++) + { + ghEvents[i] = CreateEvent( + NULL, // default security attributes + FALSE, // auto-reset event object + FALSE, // initial state is nonsignaled + NULL); // unnamed object + + if (ghEvents[i] == NULL) + { + print_last_error(_T("CreateEvent")); + return TRUE; + } + } + + dwEvent = WaitForMultipleObjects( + 2, // number of objects in array + ghEvents, // array of objects + FALSE, // wait for any object + delayInMillis); // delay in milliseconds + + return FALSE; +} + +BOOL timing_sleep_loop (UINT delayInMillis) +{ + /* + This trick is about performing a low number of seconds to sleep but in a loop, + the reason behind that sandboxes tries to avoid patching such sleeps because it + could lead to race conditions and also because it is just negliable. However, + when you do it in a loop, you can make it efficiant to cuz the sandboxe to reach + its timeout. + */ + + int delayInMillis_divided = delayInMillis / 1000; + + /* Example: we want to sleep 300 seeconds, then we can sleep + 0.3s for 1000 times which is like: 300 seconds = 5 minues */ + for (int i = 0; i < 1000; i++) { + Sleep(delayInMillis_divided); + } + + // Malicious code goes here + + return FALSE; +} + + +/* +RDSTC is a famous x86 instruction to count the number of cycle since reset. +This can be used to detect the VM. Thanks to Forcepoint for blog article. +*/ + +#define LODWORD(_qw) ((DWORD)(_qw)) +BOOL rdtsc_diff_locky() +{ + ULONGLONG tsc1; + ULONGLONG tsc2; + ULONGLONG tsc3; + DWORD i = 0; + + // Try this 10 times in case of small fluctuations + for (i = 0; i < 10; i++) + { + tsc1 = __rdtsc(); + + // Waste some cycles - should be faster than CloseHandle on bare metal + GetProcessHeap(); + + tsc2 = __rdtsc(); + + // Waste some cycles - slightly longer than GetProcessHeap() on bare metal + CloseHandle(0); + + tsc3 = __rdtsc(); + + // Did it take at least 10 times more CPU cycles to perform CloseHandle than it took to perform GetProcessHeap()? + if ((LODWORD(tsc3) - LODWORD(tsc2)) / (LODWORD(tsc2) - LODWORD(tsc1)) >= 10) + return FALSE; + } + + // We consistently saw a small ratio of difference between GetProcessHeap and CloseHandle execution times + // so we're probably in a VM! + return TRUE; +} + + +/* +CPUID is an instruction which cauz a VM Exit to the VMM, +this little overhead can show the presence of a hypervisor +*/ + +BOOL rdtsc_diff_vmexit() +{ + ULONGLONG tsc1 = 0; + ULONGLONG tsc2 = 0; + ULONGLONG avg = 0; + INT cpuInfo[4] = {}; + + // Try this 10 times in case of small fluctuations + for (INT i = 0; i < 10; i++) + { + tsc1 = __rdtsc(); + __cpuid(cpuInfo, 0); + tsc2 = __rdtsc(); + + // Get the delta of the two RDTSC + avg += (tsc2 - tsc1); + } + + // We repeated the process 10 times so we make sure our check is as much reliable as we can + avg = avg / 10; + return (avg < 1000 && avg > 0) ? FALSE : TRUE; +} + + +/* +Another timinig attack using the API IcmpSendEcho which takes a TimeOut +in milliseconds as a parameter, to wait for IPv4 ICMP packets replies. +First time observed: http://blog.talosintelligence.com/2017/09/avast-distributes-malware.html +*/ +BOOL timing_IcmpSendEcho(UINT delayInMillis) +{ + + HANDLE hIcmpFile; + unsigned long DestinationAddress = INADDR_NONE; + char SendData[32] = "Data Buffer"; + LPVOID ReplyBuffer = NULL; + DWORD ReplySize = 0; + const char ipaddr[] = "224.0.0.0"; + + hIcmpFile = IcmpCreateFile(); + if (hIcmpFile == INVALID_HANDLE_VALUE) { + printf("\tUnable to open handle.\n"); + printf("IcmpCreatefile returned error: %u\n", GetLastError()); + return TRUE; + } + + // + // Size of ICMP_ECHO_REPLY + size of send data + 8 extra bytes for ICMP error message + // + ReplySize = sizeof(ICMP_ECHO_REPLY) + sizeof(SendData) + 8; + ReplyBuffer = (VOID*)malloc(ReplySize); + if (ReplyBuffer == NULL) { + IcmpCloseHandle(hIcmpFile); + printf("\tUnable to allocate memory\n"); + return TRUE; + } + + IcmpSendEcho(hIcmpFile, DestinationAddress, SendData, sizeof(SendData), NULL, ReplyBuffer, ReplySize, delayInMillis); + IcmpCloseHandle(hIcmpFile); + free(ReplyBuffer); + + return FALSE; +} + +/* +Timing attack using waitable timers. Test fails if any of the calls return an error state. +*/ +BOOL timing_CreateWaitableTimer(UINT delayInMillis) +{ + HANDLE hTimer; + LARGE_INTEGER dueTime; + + BOOL bResult = FALSE; + + dueTime.QuadPart = delayInMillis * -10000LL; + + hTimer = CreateWaitableTimer(NULL, TRUE, NULL); + + if (hTimer == NULL) + { + return TRUE; + } + + if (SetWaitableTimer(hTimer, &dueTime, 0, NULL, NULL, FALSE) == FALSE) + { + bResult = TRUE; + } + else { + if (WaitForSingleObject(hTimer, INFINITE) != WAIT_OBJECT_0) + { + bResult = TRUE; + } + } + + CancelWaitableTimer(hTimer); + CloseHandle(hTimer); + return bResult; +} + +HANDLE g_hEventCTQT = NULL; + +/* +Timing attack using CreateTimerQueueTimer. Test fails if any of the calls return an error state. +*/ +BOOL timing_CreateTimerQueueTimer(UINT delayInMillis) +{ + HANDLE hTimerQueue; + HANDLE hTimerQueueTimer = NULL; + BOOL bResult = FALSE; + + g_hEventCTQT = CreateEvent(NULL, FALSE, FALSE, NULL); + if (g_hEventCTQT == NULL) + return FALSE; + + hTimerQueue = CreateTimerQueue(); + if (hTimerQueue == NULL) + { + return TRUE; + } + + if (CreateTimerQueueTimer( + &hTimerQueueTimer, + hTimerQueue, + &CallbackCTQT, + reinterpret_cast(0xDEADBEEFULL), + delayInMillis, + 0, + WT_EXECUTEDEFAULT) == FALSE) + { + bResult = TRUE; + } + else { + + // idea here is to wait only 10x the expected delay time + // if the wait expires before the timer comes back, we fail the test + if (WaitForSingleObject(g_hEventCTQT, delayInMillis * 10) != WAIT_OBJECT_0) + { + bResult = FALSE; + } + + } + + // Delete all timers in the timer queue. + DeleteTimerQueueEx(hTimerQueue, NULL); + + CloseHandle(g_hEventCTQT); + + return bResult; +} + +VOID CALLBACK CallbackCTQT(PVOID lParam, BOOLEAN TimerOrWaitFired) +{ + if (TimerOrWaitFired == TRUE && lParam == reinterpret_cast(0xDEADBEEFULL)) + { + SetEvent(g_hEventCTQT); + } +} diff --git a/byp/sbexecution/TimingAttacks/timing.h b/byp/sbexecution/TimingAttacks/timing.h new file mode 100644 index 00000000..4523d211 --- /dev/null +++ b/byp/sbexecution/TimingAttacks/timing.h @@ -0,0 +1,14 @@ +#pragma once + +BOOL timing_SetTimer(UINT delayInMillis); +BOOL timing_NtDelayexecution(UINT delayInMillis); +BOOL timing_timeSetEvent(UINT delayInMillis); +BOOL timing_WaitForSingleObject(UINT delayInMillis); +BOOL timing_WaitForMultipleObjects(UINT delayInMillis); +BOOL timing_sleep_loop(UINT delayInMillis); +BOOL rdtsc_diff_locky(); +BOOL rdtsc_diff_vmexit(); +BOOL timing_IcmpSendEcho(UINT delayInMillis); +BOOL timing_CreateWaitableTimer(UINT delayInMillis); +BOOL timing_CreateTimerQueueTimer(UINT delayInMillis); +VOID CALLBACK CallbackCTQT(PVOID lParam, BOOLEAN TimerOrWaitFired); diff --git a/byp/sbexecution/blackmarlinexec.cpp b/byp/sbexecution/blackmarlinexec.cpp new file mode 100644 index 00000000..126f1428 --- /dev/null +++ b/byp/sbexecution/blackmarlinexec.cpp @@ -0,0 +1,377 @@ +// al-khaser.cpp : This file contains the 'main' function. Program execution begins and ends there. +// + +#include "pch.h" + + +BOOL ENABLE_TLS_CHECKS = FALSE; +BOOL ENABLE_DEBUG_CHECKS = FALSE; +BOOL ENABLE_INJECTION_CHECKS = FALSE; +BOOL ENABLE_GEN_SANDBOX_CHECKS = FALSE; +BOOL ENABLE_VBOX_CHECKS = FALSE; +BOOL ENABLE_VMWARE_CHECKS = FALSE; +BOOL ENABLE_VPC_CHECKS = FALSE; +BOOL ENABLE_QEMU_CHECKS = FALSE; +BOOL ENABLE_KVM_CHECKS = FALSE; +BOOL ENABLE_XEN_CHECKS = FALSE; +BOOL ENABLE_WINE_CHECKS = FALSE; +BOOL ENABLE_PARALLELS_CHECKS = FALSE; +BOOL ENABLE_HYPERV_CHECKS = FALSE; +BOOL ENABLE_CODE_INJECTIONS = FALSE; +BOOL ENABLE_TIMING_ATTACKS = FALSE; +BOOL ENABLE_DUMPING_CHECK = FALSE; +BOOL ENABLE_ANALYSIS_TOOLS_CHECK = FALSE; +BOOL ENABLE_ANTI_DISASSM_CHECKS = FALSE; + + +void EnableDefaultChecks() { + ENABLE_TLS_CHECKS = TRUE; + ENABLE_DEBUG_CHECKS = TRUE; + ENABLE_INJECTION_CHECKS = TRUE; + ENABLE_GEN_SANDBOX_CHECKS = TRUE; + ENABLE_VBOX_CHECKS = TRUE; + ENABLE_VMWARE_CHECKS = TRUE; + ENABLE_VPC_CHECKS = TRUE; + ENABLE_QEMU_CHECKS = TRUE; + ENABLE_KVM_CHECKS = TRUE; + ENABLE_XEN_CHECKS = TRUE; + ENABLE_WINE_CHECKS = TRUE; + ENABLE_PARALLELS_CHECKS = TRUE; + ENABLE_HYPERV_CHECKS = TRUE; + ENABLE_TIMING_ATTACKS = TRUE; + ENABLE_DUMPING_CHECK = TRUE; + ENABLE_ANALYSIS_TOOLS_CHECK = TRUE; + ENABLE_ANTI_DISASSM_CHECKS = TRUE; +} + + +void EnableChecks(std::string checkType) { + if (checkType == "TLS") ENABLE_TLS_CHECKS = TRUE; + else if (checkType == "DEBUG") ENABLE_DEBUG_CHECKS = TRUE; + else if (checkType == "INJECTION") ENABLE_INJECTION_CHECKS = TRUE; + else if (checkType == "GEN_SANDBOX") ENABLE_GEN_SANDBOX_CHECKS = TRUE; + else if (checkType == "VBOX") ENABLE_VBOX_CHECKS = TRUE; + else if (checkType == "VMWARE") ENABLE_VMWARE_CHECKS = TRUE; + else if (checkType == "VPC") ENABLE_VPC_CHECKS = TRUE; + else if (checkType == "QEMU") ENABLE_QEMU_CHECKS = TRUE; + else if (checkType == "KVM") ENABLE_KVM_CHECKS = TRUE; + else if (checkType == "XEN") ENABLE_XEN_CHECKS = TRUE; + else if (checkType == "WINE") ENABLE_WINE_CHECKS = TRUE; + else if (checkType == "PARALLELS") ENABLE_PARALLELS_CHECKS = TRUE; + else if (checkType == "HYPERV") ENABLE_HYPERV_CHECKS = TRUE; + else if (checkType == "CODE_INJECTIONS") ENABLE_CODE_INJECTIONS = TRUE; + else if (checkType == "TIMING_ATTACKS") ENABLE_TIMING_ATTACKS = TRUE; + else if (checkType == "DUMPING_CHECK") ENABLE_DUMPING_CHECK = TRUE; + else if (checkType == "ANALYSIS_TOOLS") ENABLE_ANALYSIS_TOOLS_CHECK = TRUE; + else if (checkType == "ANTI_DISASSM") ENABLE_ANTI_DISASSM_CHECKS = TRUE; +} + + +int main(int argc, char* argv[]) +{ + /* enable functions */ + if (argc > 1) { + for (int i = 1; i < argc; i += 2) { + if (strcmp(argv[i], "--check") == 0 && (i + 1 < argc)) { + EnableChecks(argv[i + 1]); + } + } + } + else { + EnableDefaultChecks(); + } + + /* Resize the console window for better visibility */ + resize_console_window(); + + /* Display general informations */ + _tprintf(_T("[al-khaser version 0.82]")); + + print_category(TEXT("Initialisation")); + API::Init(); + print_os(); + API::PrintAvailabilityReport(); + + /* Are we running under WoW64 */ + if (IsWoW64()) + _tprintf(_T("Process is running under WOW64\n\n")); + + if (ENABLE_DEBUG_CHECKS) PageExceptionInitialEnum(); + + /* 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 ")); + } + + /* 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 ")); + } + + 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 ")); + } + + /* Generic sandbox detection */ + if (ENABLE_GEN_SANDBOX_CHECKS) { + print_category(TEXT("Generic Sandboxe/VM Detection")); + loaded_dlls(); + known_file_names(); + known_usernames(); + known_hostnames(); + other_known_sandbox_environment_checks(); + 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(&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 ")); + } + + /* 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 ")); + 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) ")); + vbox_devices(); + exec_check(&vbox_window_class, TEXT("Checking VBoxTrayToolWndClass / VBoxTrayToolWnd ")); + exec_check(&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 ")); + } + + /* VMWare Detection */ + if (ENABLE_VMWARE_CHECKS) { + print_category(TEXT("VMWare Detection")); + vmware_reg_key_value(); + vmware_reg_keys(); + vmware_files(); + vmware_mac(); + exec_check(&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 ")); + } + + /* Virtual PC Detection */ + if (ENABLE_VPC_CHECKS) { + print_category(TEXT("Virtual PC Detection")); + virtual_pc_process(); + virtual_pc_reg_keys(); + } + + /* QEMU Detection */ + if (ENABLE_QEMU_CHECKS) { + print_category(TEXT("QEMU Detection")); + qemu_reg_key_value(); + qemu_processes(); + qemu_dir(); + exec_check(&qemu_firmware_SMBIOS, TEXT("Checking SMBIOS firmware ")); + exec_check(&qemu_firmware_ACPI, TEXT("Checking ACPI tables ")); + + } + + /* Xen Detection */ + if (ENABLE_XEN_CHECKS) { + print_category(TEXT("Xen Detection")); + xen_process(); + exec_check(&xen_check_mac, TEXT("Checking Mac Address start with 08:16:3E ")); + } + + /* KVM Detection */ + if (ENABLE_KVM_CHECKS) { + print_category(TEXT("Xen Detection")); + kvm_files(); + kvm_reg_keys(); + exec_check(&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 ")); + wine_reg_keys(); + } + + /* Paralles Detection */ + if (ENABLE_PARALLELS_CHECKS) { + print_category(TEXT("Paralles Detection")); + parallels_process(); + exec_check(¶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 ")); + } + + /* Code injections techniques */ + if (ENABLE_CODE_INJECTIONS) { + CreateRemoteThread_Injection(); + SetWindowsHooksEx_Injection(); + NtCreateThreadEx_Injection(); + RtlCreateUserThread_Injection(); + QueueUserAPC_Injection(); + GetSetThreadContext_Injection(); + } + + /* 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); + + 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) ")); + } + + /* Malware analysis tools */ + if (ENABLE_ANALYSIS_TOOLS_CHECK) { + print_category(TEXT("Analysis-tools")); + analysis_tools_process(); + } + + /* Anti disassembler tricks */ + if (ENABLE_ANTI_DISASSM_CHECKS) { + _tprintf(_T("Begin AntiDisassmConstantCondition\n")); + AntiDisassmConstantCondition(); + _tprintf(_T("Begin AntiDisassmAsmJmpSameTarget\n")); + AntiDisassmAsmJmpSameTarget(); + _tprintf(_T("Begin AntiDisassmImpossibleDiasassm\n")); + AntiDisassmImpossibleDiasassm(); + _tprintf(_T("Begin AntiDisassmFunctionPointer\n")); + AntiDisassmFunctionPointer(); + _tprintf(_T("Begin AntiDisassmReturnPointerAbuse\n")); + AntiDisassmReturnPointerAbuse(); +#ifndef _WIN64 + _tprintf(_T("Begin AntiDisassmSEHMisuse\n")); + AntiDisassmSEHMisuse(); +#endif + } + + /* Anti Dumping */ + if (ENABLE_DUMPING_CHECK) { + print_category(TEXT("Anti Dumping")); + ErasePEHeaderFromMemory(); + SizeOfImage(); + } + + _tprintf(_T("\n\nAnalysis done, I hope you didn't get red flags :)")); + + getchar(); + return 0; +} + diff --git a/byp/sbexecution/blackmarlinexec.filters b/byp/sbexecution/blackmarlinexec.filters new file mode 100644 index 00000000..21721590 --- /dev/null +++ b/byp/sbexecution/blackmarlinexec.filters @@ -0,0 +1,509 @@ + + + + + {18e12ba4-7f6b-434f-8271-d5bbb46fa4c9} + + + {bf1fe4e8-39e0-495b-9f5b-b5c5da2a2d08} + + + {f97845a6-27f4-4e98-874d-63f896f1006b} + + + {666c0b5a-f811-4eb2-b4c9-a2e91c1ea6a0} + + + {33fc6fa5-2c5b-43c3-ba25-d67335382f71} + + + {41e90f25-fc84-4cdd-ace6-cca5db49fbb4} + + + {c260c597-7ad7-4fc7-b84d-fa69d45c4b99} + + + {5d11ce3d-06d9-4e4c-b7f1-aef4153ac76b} + + + {bc3f3752-625a-4170-bfae-873fc9a063ef} + + + {0abe0968-9567-474e-8ee3-02ce966590e2} + + + {7c1ba53c-7a4c-43a5-9c70-55888d8554b9} + + + {d8bae499-5da2-4540-b525-4de33b7b7719} + + + {807d0507-ce74-4b62-ab79-8fbd34904fe7} + + + {cf06cc61-c616-45d1-ae2f-7577948bc3e0} + + + {f9672dc2-2eb4-4fdb-87ea-763a7a86872e} + + + {1bbf6302-26d8-43f4-a4d3-befc9b58d300} + + + {21cdc14d-e1ad-40cd-aa30-6e2635ef68cc} + + + {a1ad376c-c1f2-45b7-9ae6-e9829edad1e2} + + + {7ac2da9c-be04-4cfd-8687-20a6ac63a45a} + + + {6e37020f-ba4e-4b6f-82ed-0e4f5e5ec872} + + + {bcf9eab0-7525-4627-843b-878d0ae1732f} + + + {3c7ae943-1975-45bf-a23c-2bdfc5e58f93} + + + {fcfb2a05-4437-4cb4-a3e3-6467c256b185} + + + {c5411e59-e406-4610-87a8-321a00883ffe} + + + + + + AntiDebug\Header + + + AntiDebug\Header + + + AntiDebug\Header + + + AntiDebug\Header + + + AntiDebug\Header + + + AntiDebug\Header + + + AntiDebug\Header + + + AntiDebug\Header + + + AntiDebug\Header + + + AntiDebug\Header + + + AntiDebug\Header + + + AntiDebug\Header + + + AntiDebug\Header + + + AntiDebug\Header + + + AntiDebug\Header + + + AntiDebug\Header + + + AntiDebug\Header + + + AntiDebug\Header + + + AntiDebug\Header + + + AntiDebug\Header + + + AntiDebug\Header + + + AntiDebug\Header + + + AntiDebug\Header + + + AntiDebug\Header + + + AntiDebug\Header + + + AntiDebug\Header + + + AntiDebug\Header + + + AntiDebug\Header + + + AntiDebug\Header + + + Shared\Header + + + Shared\Header + + + Shared\Header + + + Shared\Header + + + Shared\Header + + + Shared\Header + + + Shared\Header + + + Shared\Header + + + AntiDebug\Header + + + Shared\Header + + + CodeInjection\Header + + + CodeInjection\Header + + + CodeInjection\Header + + + CodeInjection\Header + + + CodeInjection\Header + + + CodeInjection\Header + + + CodeInjection\Header + + + AntiAnalysis\Header + + + AntiAnalysis\Header + + + AntiDump\Header + + + AntiDump\Header + + + AntiDump\Header + + + AntiVM\Header + + + AntiVM\Header + + + AntiVM\Header + + + AntiVM\Header + + + AntiVM\Header + + + AntiVM\Header + + + AntiVM\Header + + + AntiVM\Header + + + AntiVM\Header + + + AntiVM\Header + + + TimingAttacks\Header + + + TimingAttacks\Header + + + AntiDebug\Header + + + AntiDebug\Header + + + AntiDebug\Header + + + AntiDisassm\Header + + + AntiDisassm\Header + + + AntiDebug\Header + + + AntiDebug\Header + + + AntiVM\Header + + + AntiVM\Header + + + + + + + + AntiDebug\Source + + + AntiDebug\Source + + + AntiDebug\Source + + + AntiDebug\Source + + + AntiDebug\Source + + + AntiDebug\Source + + + AntiDebug\Source + + + AntiDebug\Source + + + AntiDebug\Source + + + AntiDebug\Source + + + AntiDebug\Source + + + AntiDebug\Source + + + AntiDebug\Source + + + AntiDebug\Source + + + AntiDebug\Source + + + AntiDebug\Source + + + AntiDebug\Source + + + AntiDebug\Source + + + AntiDebug\Source + + + AntiDebug\Source + + + AntiDebug\Source + + + AntiDebug\Source + + + AntiDebug\Source + + + AntiDebug\Source + + + AntiDebug\Source + + + AntiDebug\Source + + + AntiDebug\Source + + + AntiDebug\Source + + + AntiDebug\Source + + + AntiDebug\Source + + + Shared\Source + + + Shared\Source + + + Shared\Source + + + Shared\Source + + + Shared\Source + + + CodeInjection\Source + + + CodeInjection\Source + + + CodeInjection\Source + + + CodeInjection\Source + + + CodeInjection\Source + + + CodeInjection\Source + + + AntiAnalysis\Source + + + AntiDump\Source + + + AntiDump\Source + + + AntiVM\Source + + + AntiVM\Source + + + AntiVM\Source + + + AntiVM\Source + + + AntiVM\Source + + + AntiVM\Source + + + AntiVM\Source + + + AntiVM\Source + + + AntiVM\Source + + + TimingAttacks\Source + + + AntiDebug\Source + + + AntiDebug\Source + + + AntiDebug\Source + + + AntiDisassm\Source + + + AntiDebug\Source + + + AntiDebug\Source + + + AntiVM\Source + + + AntiVM\Source + + + + + + AntiDebug\Source + + + AntiDebug\Source + + + + + + AntiDisassm\Source + + + AntiDisassm\Source + + + + + + + \ No newline at end of file diff --git a/byp/sbexecution/blackmarlinexec.vcxproj b/byp/sbexecution/blackmarlinexec.vcxproj new file mode 100644 index 00000000..46187bd5 --- /dev/null +++ b/byp/sbexecution/blackmarlinexec.vcxproj @@ -0,0 +1,351 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {77AEFBC3-0ECE-46AD-A113-966AAAA838E1} + Win32Proj + alkhaser + 10.0 + + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + false + + + + Use + Level3 + Disabled + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + pch.h + + + Console + true + false + + + + + + + + + Use + Level3 + Disabled + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + pch.h + + + Console + true + + + + + + + + + Use + Level3 + MaxSpeed + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + pch.h + + + Console + true + true + true + false + + + copy $(OutDir)$(AssemblyName).exe $(SolutionDir)$(AssemblyName)_$(PlatformTarget).exe + + + + + Use + Level3 + MaxSpeed + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + pch.h + + + Console + true + true + true + + + copy $(OutDir)$(AssemblyName).exe $(SolutionDir)$(AssemblyName)_$(Platform).exe + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Create + Create + Create + Create + + + + + + + + + + + Document + true + true + + + Document + true + true + true + + + true + true + + + true + true + true + + + + + + + + + + + + + + \ No newline at end of file diff --git a/byp/sbexecution/packages.config b/byp/sbexecution/packages.config new file mode 100644 index 00000000..2bf64c32 --- /dev/null +++ b/byp/sbexecution/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/byp/sbexecution/pch.cpp b/byp/sbexecution/pch.cpp new file mode 100644 index 00000000..3a3d12b5 --- /dev/null +++ b/byp/sbexecution/pch.cpp @@ -0,0 +1,5 @@ +// pch.cpp: source file corresponding to pre-compiled header; necessary for compilation to succeed + +#include "pch.h" + +// In general, ignore this file, but keep it around if you are using pre-compiled headers. diff --git a/byp/sbexecution/pch.h b/byp/sbexecution/pch.h new file mode 100644 index 00000000..f546cf31 --- /dev/null +++ b/byp/sbexecution/pch.h @@ -0,0 +1,142 @@ +// Tips for Getting Started: +// 1. Use the Solution Explorer window to add/manage files +// 2. Use the Team Explorer window to connect to source control +// 3. Use the Output window to see build output and other messages +// 4. Use the Error List window to view errors +// 5. Go to Project > Add New Item to create new code files, or Project > Add Existing Item to add existing code files to the project +// 6. In the future, to open this project again, go to File > Open > Project and select the .sln file + +#ifndef PCH_H +#define PCH_H + +// add headers that you want to pre-compile here + + + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // Device guids +#include // IOCTL +#include // cpuid() +#include // 64-bit wchar atoi +#include // check_power_modes() +#include +#include +#include +#include // SLIsGenuineLocal + +#pragma comment(lib, "wbemuuid.lib") +#pragma comment(lib, "Shlwapi.lib") +#pragma comment(lib, "Mpr.lib") +#pragma comment(lib, "Iphlpapi.lib") +#pragma comment(lib, "Shlwapi.lib") +#pragma comment(lib, "Psapi.lib") +#pragma comment(lib, "wbemuuid.lib") +#pragma comment(lib, "Winmm.lib") +#pragma comment(lib, "setupapi.lib") +#pragma comment(lib, "powrprof.lib") +#pragma comment(lib, "Slwga.lib") + +#include "Shared/Common.h" +#include "Shared/VersionHelpers.h" +#include "Shared/log.h" +#include "Shared/Utils.h" +#include "Shared/WinStructs.h" +#include "Shared/ApiTypeDefs.h" +#include "Shared/APIs.h" +#include "Shared/winapifamily.h" + +/* AntiDebugs headers */ +#include "AntiDebug/CheckRemoteDebuggerPresent.h" +#include "AntiDebug/IsDebuggerPresent.h" +#include "AntiDebug/BeingDebugged.h" +#include "AntiDebug/ProcessHeap_Flags.h" +#include "AntiDebug/ProcessHeap_ForceFlags.h" +#include "AntiDebug/NtGlobalFlag.h" +#include "AntiDebug/NtQueryInformationProcess_ProcessDebugPort.h" +#include "AntiDebug/NtQueryInformationProcess_ProcessDebugFlags.h" +#include "AntiDebug/NtQueryInformationProcess_ProcessDebugObject.h" +#include "AntiDebug/NtSetInformationThread_ThreadHideFromDebugger.h" +#include "AntiDebug/CloseHandle_InvalidHandle.h" +#include "AntiDebug/NtSystemDebugControl.h" +#include "AntiDebug/UnhandledExceptionFilter_Handler.h" +#include "AntiDebug/OutputDebugStringAPI.h" +#include "AntiDebug/HardwareBreakpoints.h" +#include "AntiDebug/SoftwareBreakpoints.h" +#include "AntiDebug/Interrupt_0x2d.h" +#include "AntiDebug/Interrupt_3.h" +#include "AntiDebug/TrapFlag.h" +#include "AntiDebug/MemoryBreakpoints_PageGuard.h" +#include "AntiDebug/ParentProcess.h" +#include "AntiDebug/SeDebugPrivilege.h" +#include "AntiDebug/NtQueryObject_ObjectInformation.h" +#include "AntiDebug/NtYieldExecution.h" +#include "AntiDebug/SetHandleInformation_API.h" +#include "AntiDebug/TLS_callbacks.h" +#include "AntiDebug/NtQuerySystemInformation_SystemKernelDebuggerInformation.h" +#include "AntiDebug/SharedUserData_KernelDebugger.h" +#include "AntiDebug/ProcessJob.h" +#include "AntiDebug/WriteWatch.h" +#include "AntiDebug/PageExceptionBreakpointCheck.h" +#include "AntiDebug/ModuleBoundsHookCheck.h" +#include "AntiDebug/ScanForModules.h" +#include "AntiDebug/WUDF_IsDebuggerPresent.h" +#include "AntiDebug/LowFragmentationHeap.h" + + +/* Anti dumping headers */ +#include "AntiDump/ErasePEHeaderFromMemory.h" +#include "AntiDump/SizeOfImage.h" + +/* Anti VM headers */ +#include "AntiVM/VirtualBox.h" +#include "AntiVM/VMware.h" +#include "AntiVM/Wine.h" +#include "AntiVM/Generic.h" +#include "AntiVM/VirtualPC.h" +#include "AntiVM/QEMU.h" +#include "AntiVM/Xen.h" +#include "AntiVM/KVM.h" +#include "AntiVM/Parallels.h" +#include "AntiVM/Services.h" +#include "AntiVM/HyperV.h" + +/* Code Injections Headers */ +#include "CodeInjection/CreateRemoteThread.h" +#include "CodeInjection/SetWindowsHooksEx.h" +#include "CodeInjection/NtCreateThreadEx.h" +#include "CodeInjection/RtlCreateUserThread.h" +#include "CodeInjection/QueueUserAPC.h" +#include "CodeInjection/GetSetThreadContext.h" + +/* Delay Execution */ +#include "TimingAttacks/timing.h" + +/* Anti-Analysis */ +#include "AntiAnalysis/process.h" + +/* Anti-Disassembly */ +#include "AntiDisassm/AntiDisassm.h" + + +#endif //PCH_H diff --git a/byp/tools/ATAIdentifyDump/ATAIdentifyDump.cpp b/byp/tools/ATAIdentifyDump/ATAIdentifyDump.cpp new file mode 100644 index 00000000..82bfcbcb --- /dev/null +++ b/byp/tools/ATAIdentifyDump/ATAIdentifyDump.cpp @@ -0,0 +1,442 @@ +#include "pch.h" + +int main() +{ + printf("Dumping data for all disks.\n"); + printf("\n"); + for (int driveNumber = 0; driveNumber < 16; driveNumber++) + { + char deviceNameBuffer[64] = { 0 }; + sprintf_s(deviceNameBuffer, "\\\\.\\PhysicalDrive%d", driveNumber); + + HANDLE diskHandle = CreateFileA( + deviceNameBuffer, + GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + 0, + OPEN_EXISTING, + 0, + 0 + ); + + if (diskHandle == INVALID_HANDLE_VALUE) + { + printf("====================\n"); + printf("ERROR: Failed to open handle to %s. Last error: %d\n", deviceNameBuffer, GetLastError()); + printf("====================\n"); + continue; + } + + const unsigned int IdentifyBufferSize = 512; + const BYTE IdentifyCommandID = 0xEC; + unsigned char Buffer[IdentifyBufferSize + sizeof(ATA_PASS_THROUGH_EX)] = { 0 }; + ATA_PASS_THROUGH_EX & pte = *reinterpret_cast(Buffer); + pte.Length = sizeof(pte); + pte.TimeOutValue = 10; + pte.DataTransferLength = 512; + pte.DataBufferOffset = sizeof(ATA_PASS_THROUGH_EX); + + IDEREGS* regs = (IDEREGS*)pte.CurrentTaskFile; + regs->bCommandReg = IdentifyCommandID; + regs->bSectorCountReg = 1; + + pte.AtaFlags = ATA_FLAGS_DATA_IN | ATA_FLAGS_DRDY_REQUIRED; + + DWORD br = 0; + BOOL ioctlSuccess = DeviceIoControl( + diskHandle, + IOCTL_ATA_PASS_THROUGH, + &pte, + sizeof(Buffer), + &pte, + sizeof(Buffer), + &br, + 0 + ); + + if (!ioctlSuccess) + { + printf("====================\n"); + printf("ATA pass through IOCTL failed for drive %s. Last error: %d\n", deviceNameBuffer, GetLastError()); + printf("====================\n"); + CloseHandle(diskHandle); + continue; + } + + IDENTIFY_DEVICE_DATA *idd = reinterpret_cast(Buffer + sizeof(ATA_PASS_THROUGH_EX)); + + printf("\n"); + printf("====================\n"); + printf("BEGIN IDENTIFY_DEVICE_DATA for %s\n", deviceNameBuffer); + printf("====================\n"); + printf("GeneralConfiguration.Reserved1 = %hu\n", idd->GeneralConfiguration.Reserved1); + printf("GeneralConfiguration.Retired3 = %hu\n", idd->GeneralConfiguration.Retired3); + printf("GeneralConfiguration.ResponseIncomplete = %hu\n", idd->GeneralConfiguration.ResponseIncomplete); + printf("GeneralConfiguration.Retired2 = %hu\n", idd->GeneralConfiguration.Retired2); + printf("GeneralConfiguration.FixedDevice = %hu\n", idd->GeneralConfiguration.FixedDevice); + printf("GeneralConfiguration.RemovableMedia = %hu\n", idd->GeneralConfiguration.RemovableMedia); + printf("GeneralConfiguration.Retired1 = %hu\n", idd->GeneralConfiguration.Retired1); + printf("GeneralConfiguration.DeviceType = %hu\n", idd->GeneralConfiguration.DeviceType); + printf("NumCylinders = %hu\n", idd->NumCylinders); + printf("ReservedWord2 = %hu\n", idd->ReservedWord2); + printf("NumHeads = %hu\n", idd->NumHeads); + printf("Retired1[0] = %hu\n", idd->Retired1[0]); + printf("Retired1[1] = %hu\n", idd->Retired1[1]); + printf("NumSectorsPerTrack = %hu\n", idd->NumSectorsPerTrack); + printf("VendorUnique1[0] = %hu\n", idd->VendorUnique1[0]); + printf("VendorUnique1[1] = %hu\n", idd->VendorUnique1[1]); + printf("VendorUnique1[2] = %hu\n", idd->VendorUnique1[2]); + printf("SerialNumber = \"%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\"\n", idd->SerialNumber[1], idd->SerialNumber[0], idd->SerialNumber[3], idd->SerialNumber[2], idd->SerialNumber[5], idd->SerialNumber[4], idd->SerialNumber[7], idd->SerialNumber[6], idd->SerialNumber[9], idd->SerialNumber[8], idd->SerialNumber[11], idd->SerialNumber[10], idd->SerialNumber[13], idd->SerialNumber[12], idd->SerialNumber[15], idd->SerialNumber[14], idd->SerialNumber[17], idd->SerialNumber[16], idd->SerialNumber[19], idd->SerialNumber[18]); + printf("Retired2[0] = %hu\n", idd->Retired2[0]); + printf("Retired2[1] = %hu\n", idd->Retired2[1]); + printf("Obsolete1 = %hu\n", idd->Obsolete1); + printf("FirmwareRevision = \"%c%c%c%c%c%c%c%c\"\n", idd->FirmwareRevision[1], idd->FirmwareRevision[0], idd->FirmwareRevision[3], idd->FirmwareRevision[2], idd->FirmwareRevision[5], idd->FirmwareRevision[4], idd->FirmwareRevision[7], idd->FirmwareRevision[6]); + printf("ModelNumber = \"%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\"\n", idd->ModelNumber[1], idd->ModelNumber[0], idd->ModelNumber[3], idd->ModelNumber[2], idd->ModelNumber[5], idd->ModelNumber[4], idd->ModelNumber[7], idd->ModelNumber[6], idd->ModelNumber[9], idd->ModelNumber[8], idd->ModelNumber[11], idd->ModelNumber[10], idd->ModelNumber[13], idd->ModelNumber[12], idd->ModelNumber[15], idd->ModelNumber[14], idd->ModelNumber[17], idd->ModelNumber[16], idd->ModelNumber[19], idd->ModelNumber[18], idd->ModelNumber[21], idd->ModelNumber[20], idd->ModelNumber[23], idd->ModelNumber[22], idd->ModelNumber[25], idd->ModelNumber[24], idd->ModelNumber[27], idd->ModelNumber[26], idd->ModelNumber[29], idd->ModelNumber[28], idd->ModelNumber[31], idd->ModelNumber[30], idd->ModelNumber[33], idd->ModelNumber[32], idd->ModelNumber[35], idd->ModelNumber[34], idd->ModelNumber[37], idd->ModelNumber[36], idd->ModelNumber[39], idd->ModelNumber[38]); + printf("MaximumBlockTransfer = %d\n", idd->MaximumBlockTransfer); + printf("VendorUnique2 = %d\n", idd->VendorUnique2); + printf("ReservedWord48 = %hu\n", idd->ReservedWord48); + printf("Capabilities.ReservedByte49 = %d\n", idd->Capabilities.ReservedByte49); + printf("Capabilities.DmaSupported = %d\n", idd->Capabilities.DmaSupported); + printf("Capabilities.LbaSupported = %d\n", idd->Capabilities.LbaSupported); + printf("Capabilities.IordyDisable = %d\n", idd->Capabilities.IordyDisable); + printf("Capabilities.IordySupported = %d\n", idd->Capabilities.IordySupported); + printf("Capabilities.Reserved1 = %d\n", idd->Capabilities.Reserved1); + printf("Capabilities.StandybyTimerSupport = %d\n", idd->Capabilities.StandybyTimerSupport); + printf("Capabilities.Reserved2 = %d\n", idd->Capabilities.Reserved2); + printf("Capabilities.ReservedWord50 = %hu\n", idd->Capabilities.ReservedWord50); + printf("ObsoleteWords51[0] = %hu\n", idd->ObsoleteWords51[0]); + printf("ObsoleteWords51[1] = %hu\n", idd->ObsoleteWords51[1]); + printf("TranslationFieldsValid = %hu\n", idd->TranslationFieldsValid); + printf("Reserved3 = %hu\n", idd->Reserved3); + printf("NumberOfCurrentCylinders = %hu\n", idd->NumberOfCurrentCylinders); + printf("NumberOfCurrentHeads = %hu\n", idd->NumberOfCurrentHeads); + printf("CurrentSectorsPerTrack = %hu\n", idd->CurrentSectorsPerTrack); + printf("CurrentSectorCapacity = %lu\n", idd->CurrentSectorCapacity); + printf("CurrentMultiSectorSetting = %d\n", idd->CurrentMultiSectorSetting); + printf("MultiSectorSettingValid = %d\n", idd->MultiSectorSettingValid); + printf("ReservedByte59 = %d\n", idd->ReservedByte59); + printf("UserAddressableSectors = %lu\n", idd->UserAddressableSectors); + printf("ObsoleteWord62 = %hu\n", idd->ObsoleteWord62); + printf("MultiWordDMASupport = %hu\n", idd->MultiWordDMASupport); + printf("MultiWordDMAActive = %hu\n", idd->MultiWordDMAActive); + printf("AdvancedPIOModes = %hu\n", idd->AdvancedPIOModes); + printf("ReservedByte64 = %hu\n", idd->ReservedByte64); + printf("MinimumMWXferCycleTime = %hu\n", idd->MinimumMWXferCycleTime); + printf("RecommendedMWXferCycleTime = %hu\n", idd->RecommendedMWXferCycleTime); + printf("MinimumPIOCycleTime = %hu\n", idd->MinimumPIOCycleTime); + printf("MinimumPIOCycleTimeIORDY = %hu\n", idd->MinimumPIOCycleTimeIORDY); + printf("ReservedWords69[0] = %hu\n", idd->ReservedWords69[0]); + printf("ReservedWords69[1] = %hu\n", idd->ReservedWords69[1]); + printf("ReservedWords69[2] = %hu\n", idd->ReservedWords69[2]); + printf("ReservedWords69[3] = %hu\n", idd->ReservedWords69[3]); + printf("ReservedWords69[4] = %hu\n", idd->ReservedWords69[4]); + printf("ReservedWords69[5] = %hu\n", idd->ReservedWords69[5]); + printf("QueueDepth = %hu\n", idd->QueueDepth); + printf("ReservedWord75 = %hu\n", idd->ReservedWord75); + printf("ReservedWords76[0] = %hu\n", idd->ReservedWords76[0]); + printf("ReservedWords76[1] = %hu\n", idd->ReservedWords76[1]); + printf("ReservedWords76[2] = %hu\n", idd->ReservedWords76[2]); + printf("ReservedWords76[3] = %hu\n", idd->ReservedWords76[3]); + printf("MajorRevision = %hu\n", idd->MajorRevision); + printf("MinorRevision = %hu\n", idd->MinorRevision); + printf("CommandSetSupport.SmartCommands = %hu\n", idd->CommandSetSupport.SmartCommands); + printf("CommandSetSupport.SecurityMode = %hu\n", idd->CommandSetSupport.SecurityMode); + printf("CommandSetSupport.RemovableMediaFeature = %hu\n", idd->CommandSetSupport.RemovableMediaFeature); + printf("CommandSetSupport.PowerManagement = %hu\n", idd->CommandSetSupport.PowerManagement); + printf("CommandSetSupport.Reserved1 = %hu\n", idd->CommandSetSupport.Reserved1); + printf("CommandSetSupport.WriteCache = %hu\n", idd->CommandSetSupport.WriteCache); + printf("CommandSetSupport.LookAhead = %hu\n", idd->CommandSetSupport.LookAhead); + printf("CommandSetSupport.ReleaseInterrupt = %hu\n", idd->CommandSetSupport.ReleaseInterrupt); + printf("CommandSetSupport.ServiceInterrupt = %hu\n", idd->CommandSetSupport.ServiceInterrupt); + printf("CommandSetSupport.DeviceReset = %hu\n", idd->CommandSetSupport.DeviceReset); + printf("CommandSetSupport.HostProtectedArea = %hu\n", idd->CommandSetSupport.HostProtectedArea); + printf("CommandSetSupport.Obsolete1 = %hu\n", idd->CommandSetSupport.Obsolete1); + printf("CommandSetSupport.WriteBuffer = %hu\n", idd->CommandSetSupport.WriteBuffer); + printf("CommandSetSupport.ReadBuffer = %hu\n", idd->CommandSetSupport.ReadBuffer); + printf("CommandSetSupport.Nop = %hu\n", idd->CommandSetSupport.Nop); + printf("CommandSetSupport.Obsolete2 = %hu\n", idd->CommandSetSupport.Obsolete2); + printf("CommandSetSupport.DownloadMicrocode = %hu\n", idd->CommandSetSupport.DownloadMicrocode); + printf("CommandSetSupport.DmaQueued = %hu\n", idd->CommandSetSupport.DmaQueued); + printf("CommandSetSupport.Cfa = %hu\n", idd->CommandSetSupport.Cfa); + printf("CommandSetSupport.AdvancedPm = %hu\n", idd->CommandSetSupport.AdvancedPm); + printf("CommandSetSupport.Msn = %hu\n", idd->CommandSetSupport.Msn); + printf("CommandSetSupport.PowerUpInStandby = %hu\n", idd->CommandSetSupport.PowerUpInStandby); + printf("CommandSetSupport.ManualPowerUp = %hu\n", idd->CommandSetSupport.ManualPowerUp); + printf("CommandSetSupport.Reserved2 = %hu\n", idd->CommandSetSupport.Reserved2); + printf("CommandSetSupport.SetMax = %hu\n", idd->CommandSetSupport.SetMax); + printf("CommandSetSupport.Acoustics = %hu\n", idd->CommandSetSupport.Acoustics); + printf("CommandSetSupport.BigLba = %hu\n", idd->CommandSetSupport.BigLba); + printf("CommandSetSupport.DeviceConfigOverlay = %hu\n", idd->CommandSetSupport.DeviceConfigOverlay); + printf("CommandSetSupport.FlushCache = %hu\n", idd->CommandSetSupport.FlushCache); + printf("CommandSetSupport.FlushCacheExt = %hu\n", idd->CommandSetSupport.FlushCacheExt); + printf("CommandSetSupport.Resrved3 = %hu\n", idd->CommandSetSupport.Resrved3); + printf("CommandSetSupport.SmartErrorLog = %hu\n", idd->CommandSetSupport.SmartErrorLog); + printf("CommandSetSupport.SmartSelfTest = %hu\n", idd->CommandSetSupport.SmartSelfTest); + printf("CommandSetSupport.MediaSerialNumber = %hu\n", idd->CommandSetSupport.MediaSerialNumber); + printf("CommandSetSupport.MediaCardPassThrough = %hu\n", idd->CommandSetSupport.MediaCardPassThrough); + printf("CommandSetSupport.StreamingFeature = %hu\n", idd->CommandSetSupport.StreamingFeature); + printf("CommandSetSupport.GpLogging = %hu\n", idd->CommandSetSupport.GpLogging); + printf("CommandSetSupport.WriteFua = %hu\n", idd->CommandSetSupport.WriteFua); + printf("CommandSetSupport.WriteQueuedFua = %hu\n", idd->CommandSetSupport.WriteQueuedFua); + printf("CommandSetSupport.WWN64Bit = %hu\n", idd->CommandSetSupport.WWN64Bit); + printf("CommandSetSupport.URGReadStream = %hu\n", idd->CommandSetSupport.URGReadStream); + printf("CommandSetSupport.URGWriteStream = %hu\n", idd->CommandSetSupport.URGWriteStream); + printf("CommandSetSupport.ReservedForTechReport = %hu\n", idd->CommandSetSupport.ReservedForTechReport); + printf("CommandSetSupport.IdleWithUnloadFeature = %hu\n", idd->CommandSetSupport.IdleWithUnloadFeature); + printf("CommandSetSupport.Reserved4 = %hu\n", idd->CommandSetSupport.Reserved4); + printf("CommandSetActive.SmartCommands = %hu\n", idd->CommandSetActive.SmartCommands); + printf("CommandSetActive.SecurityMode = %hu\n", idd->CommandSetActive.SecurityMode); + printf("CommandSetActive.RemovableMediaFeature = %hu\n", idd->CommandSetActive.RemovableMediaFeature); + printf("CommandSetActive.PowerManagement = %hu\n", idd->CommandSetActive.PowerManagement); + printf("CommandSetActive.Reserved1 = %hu\n", idd->CommandSetActive.Reserved1); + printf("CommandSetActive.WriteCache = %hu\n", idd->CommandSetActive.WriteCache); + printf("CommandSetActive.LookAhead = %hu\n", idd->CommandSetActive.LookAhead); + printf("CommandSetActive.ReleaseInterrupt = %hu\n", idd->CommandSetActive.ReleaseInterrupt); + printf("CommandSetActive.ServiceInterrupt = %hu\n", idd->CommandSetActive.ServiceInterrupt); + printf("CommandSetActive.DeviceReset = %hu\n", idd->CommandSetActive.DeviceReset); + printf("CommandSetActive.HostProtectedArea = %hu\n", idd->CommandSetActive.HostProtectedArea); + printf("CommandSetActive.Obsolete1 = %hu\n", idd->CommandSetActive.Obsolete1); + printf("CommandSetActive.WriteBuffer = %hu\n", idd->CommandSetActive.WriteBuffer); + printf("CommandSetActive.ReadBuffer = %hu\n", idd->CommandSetActive.ReadBuffer); + printf("CommandSetActive.Nop = %hu\n", idd->CommandSetActive.Nop); + printf("CommandSetActive.Obsolete2 = %hu\n", idd->CommandSetActive.Obsolete2); + printf("CommandSetActive.DownloadMicrocode = %hu\n", idd->CommandSetActive.DownloadMicrocode); + printf("CommandSetActive.DmaQueued = %hu\n", idd->CommandSetActive.DmaQueued); + printf("CommandSetActive.Cfa = %hu\n", idd->CommandSetActive.Cfa); + printf("CommandSetActive.AdvancedPm = %hu\n", idd->CommandSetActive.AdvancedPm); + printf("CommandSetActive.Msn = %hu\n", idd->CommandSetActive.Msn); + printf("CommandSetActive.PowerUpInStandby = %hu\n", idd->CommandSetActive.PowerUpInStandby); + printf("CommandSetActive.ManualPowerUp = %hu\n", idd->CommandSetActive.ManualPowerUp); + printf("CommandSetActive.Reserved2 = %hu\n", idd->CommandSetActive.Reserved2); + printf("CommandSetActive.SetMax = %hu\n", idd->CommandSetActive.SetMax); + printf("CommandSetActive.Acoustics = %hu\n", idd->CommandSetActive.Acoustics); + printf("CommandSetActive.BigLba = %hu\n", idd->CommandSetActive.BigLba); + printf("CommandSetActive.DeviceConfigOverlay = %hu\n", idd->CommandSetActive.DeviceConfigOverlay); + printf("CommandSetActive.FlushCache = %hu\n", idd->CommandSetActive.FlushCache); + printf("CommandSetActive.FlushCacheExt = %hu\n", idd->CommandSetActive.FlushCacheExt); + printf("CommandSetActive.Resrved3 = %hu\n", idd->CommandSetActive.Resrved3); + printf("CommandSetActive.SmartErrorLog = %hu\n", idd->CommandSetActive.SmartErrorLog); + printf("CommandSetActive.SmartSelfTest = %hu\n", idd->CommandSetActive.SmartSelfTest); + printf("CommandSetActive.MediaSerialNumber = %hu\n", idd->CommandSetActive.MediaSerialNumber); + printf("CommandSetActive.MediaCardPassThrough = %hu\n", idd->CommandSetActive.MediaCardPassThrough); + printf("CommandSetActive.StreamingFeature = %hu\n", idd->CommandSetActive.StreamingFeature); + printf("CommandSetActive.GpLogging = %hu\n", idd->CommandSetActive.GpLogging); + printf("CommandSetActive.WriteFua = %hu\n", idd->CommandSetActive.WriteFua); + printf("CommandSetActive.WriteQueuedFua = %hu\n", idd->CommandSetActive.WriteQueuedFua); + printf("CommandSetActive.WWN64Bit = %hu\n", idd->CommandSetActive.WWN64Bit); + printf("CommandSetActive.URGReadStream = %hu\n", idd->CommandSetActive.URGReadStream); + printf("CommandSetActive.URGWriteStream = %hu\n", idd->CommandSetActive.URGWriteStream); + printf("CommandSetActive.ReservedForTechReport = %hu\n", idd->CommandSetActive.ReservedForTechReport); + printf("CommandSetActive.IdleWithUnloadFeature = %hu\n", idd->CommandSetActive.IdleWithUnloadFeature); + printf("CommandSetActive.Reserved4 = %hu\n", idd->CommandSetActive.Reserved4); + printf("UltraDMASupport = %hu\n", idd->UltraDMASupport); + printf("UltraDMAActive = %hu\n", idd->UltraDMAActive); + printf("ReservedWord89[0] = %hu\n", idd->ReservedWord89[0]); + printf("ReservedWord89[1] = %hu\n", idd->ReservedWord89[1]); + printf("ReservedWord89[2] = %hu\n", idd->ReservedWord89[2]); + printf("ReservedWord89[3] = %hu\n", idd->ReservedWord89[3]); + printf("HardwareResetResult = %hu\n", idd->HardwareResetResult); + printf("CurrentAcousticValue = %hu\n", idd->CurrentAcousticValue); + printf("RecommendedAcousticValue = %hu\n", idd->RecommendedAcousticValue); + printf("ReservedWord95[0] = %hu\n", idd->ReservedWord95[0]); + printf("ReservedWord95[1] = %hu\n", idd->ReservedWord95[1]); + printf("ReservedWord95[2] = %hu\n", idd->ReservedWord95[2]); + printf("ReservedWord95[3] = %hu\n", idd->ReservedWord95[3]); + printf("ReservedWord95[4] = %hu\n", idd->ReservedWord95[4]); + printf("Max48BitLBA[0] = %lu\n", idd->Max48BitLBA[0]); + printf("Max48BitLBA[1] = %lu\n", idd->Max48BitLBA[1]); + printf("StreamingTransferTime = %hu\n", idd->StreamingTransferTime); + printf("ReservedWord105 = %hu\n", idd->ReservedWord105); + printf("PhysicalLogicalSectorSize.LogicalSectorsPerPhysicalSector = %hu\n", idd->PhysicalLogicalSectorSize.LogicalSectorsPerPhysicalSector); + printf("PhysicalLogicalSectorSize.Reserved0 = %hu\n", idd->PhysicalLogicalSectorSize.Reserved0); + printf("PhysicalLogicalSectorSize.LogicalSectorLongerThan256Words = %hu\n", idd->PhysicalLogicalSectorSize.LogicalSectorLongerThan256Words); + printf("PhysicalLogicalSectorSize.MultipleLogicalSectorsPerPhysicalSector = %hu\n", idd->PhysicalLogicalSectorSize.MultipleLogicalSectorsPerPhysicalSector); + printf("PhysicalLogicalSectorSize.Reserved1 = %hu\n", idd->PhysicalLogicalSectorSize.Reserved1); + printf("InterSeekDelay = %hu\n", idd->InterSeekDelay); + printf("WorldWideName[0] = %hu\n", idd->WorldWideName[0]); + printf("WorldWideName[1] = %hu\n", idd->WorldWideName[1]); + printf("WorldWideName[2] = %hu\n", idd->WorldWideName[2]); + printf("WorldWideName[3] = %hu\n", idd->WorldWideName[3]); + printf("ReservedForWorldWideName128[0] = %hu\n", idd->ReservedForWorldWideName128[0]); + printf("ReservedForWorldWideName128[1] = %hu\n", idd->ReservedForWorldWideName128[1]); + printf("ReservedForWorldWideName128[2] = %hu\n", idd->ReservedForWorldWideName128[2]); + printf("ReservedForWorldWideName128[3] = %hu\n", idd->ReservedForWorldWideName128[3]); + printf("ReservedForTlcTechnicalReport = %hu\n", idd->ReservedForTlcTechnicalReport); + printf("WordsPerLogicalSector[0] = %hu\n", idd->WordsPerLogicalSector[0]); + printf("WordsPerLogicalSector[1] = %hu\n", idd->WordsPerLogicalSector[1]); + printf("CommandSetSupportExt.ReservedForDrqTechnicalReport = %hu\n", idd->CommandSetSupportExt.ReservedForDrqTechnicalReport); + printf("CommandSetSupportExt.WriteReadVerifySupported = %hu\n", idd->CommandSetSupportExt.WriteReadVerifySupported); + printf("CommandSetSupportExt.Reserved01 = %hu\n", idd->CommandSetSupportExt.Reserved01); + printf("CommandSetSupportExt.Reserved1 = %hu\n", idd->CommandSetSupportExt.Reserved1); + printf("CommandSetActiveExt.ReservedForDrqTechnicalReport = %hu\n", idd->CommandSetActiveExt.ReservedForDrqTechnicalReport); + printf("CommandSetActiveExt.WriteReadVerifyEnabled = %hu\n", idd->CommandSetActiveExt.WriteReadVerifyEnabled); + printf("CommandSetActiveExt.Reserved01 = %hu\n", idd->CommandSetActiveExt.Reserved01); + printf("CommandSetActiveExt.Reserved1 = %hu\n", idd->CommandSetActiveExt.Reserved1); + printf("ReservedForExpandedSupportandActive[0] = %hu\n", idd->ReservedForExpandedSupportandActive[0]); + printf("ReservedForExpandedSupportandActive[1] = %hu\n", idd->ReservedForExpandedSupportandActive[1]); + printf("ReservedForExpandedSupportandActive[2] = %hu\n", idd->ReservedForExpandedSupportandActive[2]); + printf("ReservedForExpandedSupportandActive[3] = %hu\n", idd->ReservedForExpandedSupportandActive[3]); + printf("ReservedForExpandedSupportandActive[4] = %hu\n", idd->ReservedForExpandedSupportandActive[4]); + printf("ReservedForExpandedSupportandActive[5] = %hu\n", idd->ReservedForExpandedSupportandActive[5]); + printf("MsnSupport = %hu\n", idd->MsnSupport); + printf("ReservedWord1274 = %hu\n", idd->ReservedWord1274); + printf("SecurityStatus.SecuritySupported = %hu\n", idd->SecurityStatus.SecuritySupported); + printf("SecurityStatus.SecurityEnabled = %hu\n", idd->SecurityStatus.SecurityEnabled); + printf("SecurityStatus.SecurityLocked = %hu\n", idd->SecurityStatus.SecurityLocked); + printf("SecurityStatus.SecurityFrozen = %hu\n", idd->SecurityStatus.SecurityFrozen); + printf("SecurityStatus.SecurityCountExpired = %hu\n", idd->SecurityStatus.SecurityCountExpired); + printf("SecurityStatus.EnhancedSecurityEraseSupported = %hu\n", idd->SecurityStatus.EnhancedSecurityEraseSupported); + printf("SecurityStatus.Reserved0 = %hu\n", idd->SecurityStatus.Reserved0); + printf("SecurityStatus.SecurityLevel = %hu\n", idd->SecurityStatus.SecurityLevel); + printf("SecurityStatus.Reserved1 = %hu\n", idd->SecurityStatus.Reserved1); + printf("ReservedWord129[0] = %hu\n", idd->ReservedWord129[0]); + printf("ReservedWord129[1] = %hu\n", idd->ReservedWord129[1]); + printf("ReservedWord129[2] = %hu\n", idd->ReservedWord129[2]); + printf("ReservedWord129[3] = %hu\n", idd->ReservedWord129[3]); + printf("ReservedWord129[4] = %hu\n", idd->ReservedWord129[4]); + printf("ReservedWord129[5] = %hu\n", idd->ReservedWord129[5]); + printf("ReservedWord129[6] = %hu\n", idd->ReservedWord129[6]); + printf("ReservedWord129[7] = %hu\n", idd->ReservedWord129[7]); + printf("ReservedWord129[8] = %hu\n", idd->ReservedWord129[8]); + printf("ReservedWord129[9] = %hu\n", idd->ReservedWord129[9]); + printf("ReservedWord129[10] = %hu\n", idd->ReservedWord129[10]); + printf("ReservedWord129[11] = %hu\n", idd->ReservedWord129[11]); + printf("ReservedWord129[12] = %hu\n", idd->ReservedWord129[12]); + printf("ReservedWord129[13] = %hu\n", idd->ReservedWord129[13]); + printf("ReservedWord129[14] = %hu\n", idd->ReservedWord129[14]); + printf("ReservedWord129[15] = %hu\n", idd->ReservedWord129[15]); + printf("ReservedWord129[16] = %hu\n", idd->ReservedWord129[16]); + printf("ReservedWord129[17] = %hu\n", idd->ReservedWord129[17]); + printf("ReservedWord129[18] = %hu\n", idd->ReservedWord129[18]); + printf("ReservedWord129[19] = %hu\n", idd->ReservedWord129[19]); + printf("ReservedWord129[20] = %hu\n", idd->ReservedWord129[20]); + printf("ReservedWord129[21] = %hu\n", idd->ReservedWord129[21]); + printf("ReservedWord129[22] = %hu\n", idd->ReservedWord129[22]); + printf("ReservedWord129[23] = %hu\n", idd->ReservedWord129[23]); + printf("ReservedWord129[24] = %hu\n", idd->ReservedWord129[24]); + printf("ReservedWord129[25] = %hu\n", idd->ReservedWord129[25]); + printf("ReservedWord129[26] = %hu\n", idd->ReservedWord129[26]); + printf("ReservedWord129[27] = %hu\n", idd->ReservedWord129[27]); + printf("ReservedWord129[28] = %hu\n", idd->ReservedWord129[28]); + printf("ReservedWord129[29] = %hu\n", idd->ReservedWord129[29]); + printf("ReservedWord129[30] = %hu\n", idd->ReservedWord129[30]); + printf("CfaPowerModel.MaximumCurrentInMA2 = %hu\n", idd->CfaPowerModel.MaximumCurrentInMA2); + printf("CfaPowerModel.CfaPowerMode1Disabled = %hu\n", idd->CfaPowerModel.CfaPowerMode1Disabled); + printf("CfaPowerModel.CfaPowerMode1Required = %hu\n", idd->CfaPowerModel.CfaPowerMode1Required); + printf("CfaPowerModel.Reserved0 = %hu\n", idd->CfaPowerModel.Reserved0); + printf("CfaPowerModel.Word160Supported = %hu\n", idd->CfaPowerModel.Word160Supported); + printf("ReservedForCfaWord161[0] = %hu\n", idd->ReservedForCfaWord161[0]); + printf("ReservedForCfaWord161[1] = %hu\n", idd->ReservedForCfaWord161[1]); + printf("ReservedForCfaWord161[2] = %hu\n", idd->ReservedForCfaWord161[2]); + printf("ReservedForCfaWord161[3] = %hu\n", idd->ReservedForCfaWord161[3]); + printf("ReservedForCfaWord161[4] = %hu\n", idd->ReservedForCfaWord161[4]); + printf("ReservedForCfaWord161[5] = %hu\n", idd->ReservedForCfaWord161[5]); + printf("ReservedForCfaWord161[6] = %hu\n", idd->ReservedForCfaWord161[6]); + printf("ReservedForCfaWord161[7] = %hu\n", idd->ReservedForCfaWord161[7]); + printf("DataSetManagementFeature.SupportsTrim = %hu\n", idd->DataSetManagementFeature.SupportsTrim); + printf("DataSetManagementFeature.Reserved0 = %hu\n", idd->DataSetManagementFeature.Reserved0); + printf("ReservedForCfaWord170[0] = %hu\n", idd->ReservedForCfaWord170[0]); + printf("ReservedForCfaWord170[1] = %hu\n", idd->ReservedForCfaWord170[1]); + printf("ReservedForCfaWord170[2] = %hu\n", idd->ReservedForCfaWord170[2]); + printf("ReservedForCfaWord170[3] = %hu\n", idd->ReservedForCfaWord170[3]); + printf("ReservedForCfaWord170[4] = %hu\n", idd->ReservedForCfaWord170[4]); + printf("ReservedForCfaWord170[5] = %hu\n", idd->ReservedForCfaWord170[5]); + printf("CurrentMediaSerialNumber[0] = %hu\n", idd->CurrentMediaSerialNumber[0]); + printf("CurrentMediaSerialNumber[1] = %hu\n", idd->CurrentMediaSerialNumber[1]); + printf("CurrentMediaSerialNumber[2] = %hu\n", idd->CurrentMediaSerialNumber[2]); + printf("CurrentMediaSerialNumber[3] = %hu\n", idd->CurrentMediaSerialNumber[3]); + printf("CurrentMediaSerialNumber[4] = %hu\n", idd->CurrentMediaSerialNumber[4]); + printf("CurrentMediaSerialNumber[5] = %hu\n", idd->CurrentMediaSerialNumber[5]); + printf("CurrentMediaSerialNumber[6] = %hu\n", idd->CurrentMediaSerialNumber[6]); + printf("CurrentMediaSerialNumber[7] = %hu\n", idd->CurrentMediaSerialNumber[7]); + printf("CurrentMediaSerialNumber[8] = %hu\n", idd->CurrentMediaSerialNumber[8]); + printf("CurrentMediaSerialNumber[9] = %hu\n", idd->CurrentMediaSerialNumber[9]); + printf("CurrentMediaSerialNumber[10] = %hu\n", idd->CurrentMediaSerialNumber[10]); + printf("CurrentMediaSerialNumber[11] = %hu\n", idd->CurrentMediaSerialNumber[11]); + printf("CurrentMediaSerialNumber[12] = %hu\n", idd->CurrentMediaSerialNumber[12]); + printf("CurrentMediaSerialNumber[13] = %hu\n", idd->CurrentMediaSerialNumber[13]); + printf("CurrentMediaSerialNumber[14] = %hu\n", idd->CurrentMediaSerialNumber[14]); + printf("CurrentMediaSerialNumber[15] = %hu\n", idd->CurrentMediaSerialNumber[15]); + printf("CurrentMediaSerialNumber[16] = %hu\n", idd->CurrentMediaSerialNumber[16]); + printf("CurrentMediaSerialNumber[17] = %hu\n", idd->CurrentMediaSerialNumber[17]); + printf("CurrentMediaSerialNumber[18] = %hu\n", idd->CurrentMediaSerialNumber[18]); + printf("CurrentMediaSerialNumber[19] = %hu\n", idd->CurrentMediaSerialNumber[19]); + printf("CurrentMediaSerialNumber[20] = %hu\n", idd->CurrentMediaSerialNumber[20]); + printf("CurrentMediaSerialNumber[21] = %hu\n", idd->CurrentMediaSerialNumber[21]); + printf("CurrentMediaSerialNumber[22] = %hu\n", idd->CurrentMediaSerialNumber[22]); + printf("CurrentMediaSerialNumber[23] = %hu\n", idd->CurrentMediaSerialNumber[23]); + printf("CurrentMediaSerialNumber[24] = %hu\n", idd->CurrentMediaSerialNumber[24]); + printf("CurrentMediaSerialNumber[25] = %hu\n", idd->CurrentMediaSerialNumber[25]); + printf("CurrentMediaSerialNumber[26] = %hu\n", idd->CurrentMediaSerialNumber[26]); + printf("CurrentMediaSerialNumber[27] = %hu\n", idd->CurrentMediaSerialNumber[27]); + printf("CurrentMediaSerialNumber[28] = %hu\n", idd->CurrentMediaSerialNumber[28]); + printf("CurrentMediaSerialNumber[29] = %hu\n", idd->CurrentMediaSerialNumber[29]); + printf("ReservedWord206 = %hu\n", idd->ReservedWord206); + printf("ReservedWord207[0] = %hu\n", idd->ReservedWord207[0]); + printf("ReservedWord207[1] = %hu\n", idd->ReservedWord207[1]); + printf("BlockAlignment.AlignmentOfLogicalWithinPhysical = %hu\n", idd->BlockAlignment.AlignmentOfLogicalWithinPhysical); + printf("BlockAlignment.Word209Supported = %hu\n", idd->BlockAlignment.Word209Supported); + printf("BlockAlignment.Reserved0 = %hu\n", idd->BlockAlignment.Reserved0); + printf("WriteReadVerifySectorCountMode3Only[0] = %hu\n", idd->WriteReadVerifySectorCountMode3Only[0]); + printf("WriteReadVerifySectorCountMode3Only[1] = %hu\n", idd->WriteReadVerifySectorCountMode3Only[1]); + printf("WriteReadVerifySectorCountMode2Only[0] = %hu\n", idd->WriteReadVerifySectorCountMode2Only[0]); + printf("WriteReadVerifySectorCountMode2Only[1] = %hu\n", idd->WriteReadVerifySectorCountMode2Only[1]); + printf("NVCacheCapabilities.NVCachePowerModeEnabled = %hu\n", idd->NVCacheCapabilities.NVCachePowerModeEnabled); + printf("NVCacheCapabilities.Reserved0 = %hu\n", idd->NVCacheCapabilities.Reserved0); + printf("NVCacheCapabilities.NVCacheFeatureSetEnabled = %hu\n", idd->NVCacheCapabilities.NVCacheFeatureSetEnabled); + printf("NVCacheCapabilities.Reserved1 = %hu\n", idd->NVCacheCapabilities.Reserved1); + printf("NVCacheCapabilities.NVCachePowerModeVersion = %hu\n", idd->NVCacheCapabilities.NVCachePowerModeVersion); + printf("NVCacheCapabilities.NVCacheFeatureSetVersion = %hu\n", idd->NVCacheCapabilities.NVCacheFeatureSetVersion); + printf("NVCacheSizeLSW = %hu\n", idd->NVCacheSizeLSW); + printf("NVCacheSizeMSW = %hu\n", idd->NVCacheSizeMSW); + printf("NominalMediaRotationRate = %hu\n", idd->NominalMediaRotationRate); + printf("ReservedWord218 = %hu\n", idd->ReservedWord218); + printf("NVCacheOptions.NVCacheEstimatedTimeToSpinUpInSeconds = %d\n", idd->NVCacheOptions.NVCacheEstimatedTimeToSpinUpInSeconds); + printf("NVCacheOptions.Reserved = %d\n", idd->NVCacheOptions.Reserved); + printf("ReservedWord220[0] = %hu\n", idd->ReservedWord220[0]); + printf("ReservedWord220[1] = %hu\n", idd->ReservedWord220[1]); + printf("ReservedWord220[2] = %hu\n", idd->ReservedWord220[2]); + printf("ReservedWord220[3] = %hu\n", idd->ReservedWord220[3]); + printf("ReservedWord220[4] = %hu\n", idd->ReservedWord220[4]); + printf("ReservedWord220[5] = %hu\n", idd->ReservedWord220[5]); + printf("ReservedWord220[6] = %hu\n", idd->ReservedWord220[6]); + printf("ReservedWord220[7] = %hu\n", idd->ReservedWord220[7]); + printf("ReservedWord220[8] = %hu\n", idd->ReservedWord220[8]); + printf("ReservedWord220[9] = %hu\n", idd->ReservedWord220[9]); + printf("ReservedWord220[10] = %hu\n", idd->ReservedWord220[10]); + printf("ReservedWord220[11] = %hu\n", idd->ReservedWord220[11]); + printf("ReservedWord220[12] = %hu\n", idd->ReservedWord220[12]); + printf("ReservedWord220[13] = %hu\n", idd->ReservedWord220[13]); + printf("ReservedWord220[14] = %hu\n", idd->ReservedWord220[14]); + printf("ReservedWord220[15] = %hu\n", idd->ReservedWord220[15]); + printf("ReservedWord220[16] = %hu\n", idd->ReservedWord220[16]); + printf("ReservedWord220[17] = %hu\n", idd->ReservedWord220[17]); + printf("ReservedWord220[18] = %hu\n", idd->ReservedWord220[18]); + printf("ReservedWord220[19] = %hu\n", idd->ReservedWord220[19]); + printf("ReservedWord220[20] = %hu\n", idd->ReservedWord220[20]); + printf("ReservedWord220[21] = %hu\n", idd->ReservedWord220[21]); + printf("ReservedWord220[22] = %hu\n", idd->ReservedWord220[22]); + printf("ReservedWord220[23] = %hu\n", idd->ReservedWord220[23]); + printf("ReservedWord220[24] = %hu\n", idd->ReservedWord220[24]); + printf("ReservedWord220[25] = %hu\n", idd->ReservedWord220[25]); + printf("ReservedWord220[26] = %hu\n", idd->ReservedWord220[26]); + printf("ReservedWord220[27] = %hu\n", idd->ReservedWord220[27]); + printf("ReservedWord220[28] = %hu\n", idd->ReservedWord220[28]); + printf("ReservedWord220[29] = %hu\n", idd->ReservedWord220[29]); + printf("ReservedWord220[30] = %hu\n", idd->ReservedWord220[30]); + printf("ReservedWord220[31] = %hu\n", idd->ReservedWord220[31]); + printf("ReservedWord220[32] = %hu\n", idd->ReservedWord220[32]); + printf("ReservedWord220[33] = %hu\n", idd->ReservedWord220[33]); + printf("ReservedWord220[34] = %hu\n", idd->ReservedWord220[34]); + printf("Signature = %hu\n", idd->Signature); + printf("CheckSum = %hu\n", idd->CheckSum); + printf("====================\n"); + printf("END IDENTIFY_DEVICE_DATA for %s\n", deviceNameBuffer); + printf("====================\n"); + printf("\n"); + + CloseHandle(diskHandle); + } + + return 0; +} diff --git a/byp/tools/ATAIdentifyDump/ATAIdentifyDump.vcxproj b/byp/tools/ATAIdentifyDump/ATAIdentifyDump.vcxproj new file mode 100644 index 00000000..7dc33408 --- /dev/null +++ b/byp/tools/ATAIdentifyDump/ATAIdentifyDump.vcxproj @@ -0,0 +1,169 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {245D8670-A888-4ECC-9B51-80584E55B701} + Win32Proj + ATAIdentifyDump + 10.0 + + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + false + + + + Use + Level3 + Disabled + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + pch.h + + + Console + true + + + + + Use + Level3 + Disabled + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + pch.h + + + Console + true + + + + + Use + Level3 + MaxSpeed + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + pch.h + + + Console + true + true + true + + + + + Use + Level3 + MaxSpeed + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + pch.h + + + Console + true + true + true + + + + + + + + + + Create + Create + Create + Create + + + + + + \ No newline at end of file diff --git a/byp/tools/ATAIdentifyDump/ATAIdentifyDump.vcxproj.filters b/byp/tools/ATAIdentifyDump/ATAIdentifyDump.vcxproj.filters new file mode 100644 index 00000000..6bd69bf5 --- /dev/null +++ b/byp/tools/ATAIdentifyDump/ATAIdentifyDump.vcxproj.filters @@ -0,0 +1,33 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/byp/tools/ATAIdentifyDump/IdentifyDeviceData.h b/byp/tools/ATAIdentifyDump/IdentifyDeviceData.h new file mode 100644 index 00000000..22970c2f --- /dev/null +++ b/byp/tools/ATAIdentifyDump/IdentifyDeviceData.h @@ -0,0 +1,250 @@ +#pragma once + +typedef struct _IDENTIFY_DEVICE_DATA { + struct { + USHORT Reserved1 : 1; + USHORT Retired3 : 1; + USHORT ResponseIncomplete : 1; + USHORT Retired2 : 3; + USHORT FixedDevice : 1; + USHORT RemovableMedia : 1; + USHORT Retired1 : 7; + USHORT DeviceType : 1; + } GeneralConfiguration; + USHORT NumCylinders; + USHORT ReservedWord2; + USHORT NumHeads; + USHORT Retired1[2]; + USHORT NumSectorsPerTrack; + USHORT VendorUnique1[3]; + UCHAR SerialNumber[20]; + USHORT Retired2[2]; + USHORT Obsolete1; + UCHAR FirmwareRevision[8]; + UCHAR ModelNumber[40]; + UCHAR MaximumBlockTransfer; + UCHAR VendorUnique2; + USHORT ReservedWord48; + struct { + UCHAR ReservedByte49; + UCHAR DmaSupported : 1; + UCHAR LbaSupported : 1; + UCHAR IordyDisable : 1; + UCHAR IordySupported : 1; + UCHAR Reserved1 : 1; + UCHAR StandybyTimerSupport : 1; + UCHAR Reserved2 : 2; + USHORT ReservedWord50; + } Capabilities; + USHORT ObsoleteWords51[2]; + USHORT TranslationFieldsValid : 3; + USHORT Reserved3 : 13; + USHORT NumberOfCurrentCylinders; + USHORT NumberOfCurrentHeads; + USHORT CurrentSectorsPerTrack; + ULONG CurrentSectorCapacity; + UCHAR CurrentMultiSectorSetting; + UCHAR MultiSectorSettingValid : 1; + UCHAR ReservedByte59 : 7; + ULONG UserAddressableSectors; + USHORT ObsoleteWord62; + USHORT MultiWordDMASupport : 8; + USHORT MultiWordDMAActive : 8; + USHORT AdvancedPIOModes : 8; + USHORT ReservedByte64 : 8; + USHORT MinimumMWXferCycleTime; + USHORT RecommendedMWXferCycleTime; + USHORT MinimumPIOCycleTime; + USHORT MinimumPIOCycleTimeIORDY; + USHORT ReservedWords69[6]; + USHORT QueueDepth : 5; + USHORT ReservedWord75 : 11; + USHORT ReservedWords76[4]; + USHORT MajorRevision; + USHORT MinorRevision; + struct { + USHORT SmartCommands : 1; + USHORT SecurityMode : 1; + USHORT RemovableMediaFeature : 1; + USHORT PowerManagement : 1; + USHORT Reserved1 : 1; + USHORT WriteCache : 1; + USHORT LookAhead : 1; + USHORT ReleaseInterrupt : 1; + USHORT ServiceInterrupt : 1; + USHORT DeviceReset : 1; + USHORT HostProtectedArea : 1; + USHORT Obsolete1 : 1; + USHORT WriteBuffer : 1; + USHORT ReadBuffer : 1; + USHORT Nop : 1; + USHORT Obsolete2 : 1; + USHORT DownloadMicrocode : 1; + USHORT DmaQueued : 1; + USHORT Cfa : 1; + USHORT AdvancedPm : 1; + USHORT Msn : 1; + USHORT PowerUpInStandby : 1; + USHORT ManualPowerUp : 1; + USHORT Reserved2 : 1; + USHORT SetMax : 1; + USHORT Acoustics : 1; + USHORT BigLba : 1; + USHORT DeviceConfigOverlay : 1; + USHORT FlushCache : 1; + USHORT FlushCacheExt : 1; + USHORT Resrved3 : 2; + USHORT SmartErrorLog : 1; + USHORT SmartSelfTest : 1; + USHORT MediaSerialNumber : 1; + USHORT MediaCardPassThrough : 1; + USHORT StreamingFeature : 1; + USHORT GpLogging : 1; + USHORT WriteFua : 1; + USHORT WriteQueuedFua : 1; + USHORT WWN64Bit : 1; + USHORT URGReadStream : 1; + USHORT URGWriteStream : 1; + USHORT ReservedForTechReport : 2; + USHORT IdleWithUnloadFeature : 1; + USHORT Reserved4 : 2; + } CommandSetSupport; + struct { + USHORT SmartCommands : 1; + USHORT SecurityMode : 1; + USHORT RemovableMediaFeature : 1; + USHORT PowerManagement : 1; + USHORT Reserved1 : 1; + USHORT WriteCache : 1; + USHORT LookAhead : 1; + USHORT ReleaseInterrupt : 1; + USHORT ServiceInterrupt : 1; + USHORT DeviceReset : 1; + USHORT HostProtectedArea : 1; + USHORT Obsolete1 : 1; + USHORT WriteBuffer : 1; + USHORT ReadBuffer : 1; + USHORT Nop : 1; + USHORT Obsolete2 : 1; + USHORT DownloadMicrocode : 1; + USHORT DmaQueued : 1; + USHORT Cfa : 1; + USHORT AdvancedPm : 1; + USHORT Msn : 1; + USHORT PowerUpInStandby : 1; + USHORT ManualPowerUp : 1; + USHORT Reserved2 : 1; + USHORT SetMax : 1; + USHORT Acoustics : 1; + USHORT BigLba : 1; + USHORT DeviceConfigOverlay : 1; + USHORT FlushCache : 1; + USHORT FlushCacheExt : 1; + USHORT Resrved3 : 2; + USHORT SmartErrorLog : 1; + USHORT SmartSelfTest : 1; + USHORT MediaSerialNumber : 1; + USHORT MediaCardPassThrough : 1; + USHORT StreamingFeature : 1; + USHORT GpLogging : 1; + USHORT WriteFua : 1; + USHORT WriteQueuedFua : 1; + USHORT WWN64Bit : 1; + USHORT URGReadStream : 1; + USHORT URGWriteStream : 1; + USHORT ReservedForTechReport : 2; + USHORT IdleWithUnloadFeature : 1; + USHORT Reserved4 : 2; + } CommandSetActive; + USHORT UltraDMASupport : 8; + USHORT UltraDMAActive : 8; + USHORT ReservedWord89[4]; + USHORT HardwareResetResult; + USHORT CurrentAcousticValue : 8; + USHORT RecommendedAcousticValue : 8; + USHORT ReservedWord95[5]; + ULONG Max48BitLBA[2]; + USHORT StreamingTransferTime; + USHORT ReservedWord105; + struct { + USHORT LogicalSectorsPerPhysicalSector : 4; + USHORT Reserved0 : 8; + USHORT LogicalSectorLongerThan256Words : 1; + USHORT MultipleLogicalSectorsPerPhysicalSector : 1; + USHORT Reserved1 : 2; + } PhysicalLogicalSectorSize; + USHORT InterSeekDelay; + USHORT WorldWideName[4]; + USHORT ReservedForWorldWideName128[4]; + USHORT ReservedForTlcTechnicalReport; + USHORT WordsPerLogicalSector[2]; + struct { + USHORT ReservedForDrqTechnicalReport : 1; + USHORT WriteReadVerifySupported : 1; + USHORT Reserved01 : 11; + USHORT Reserved1 : 2; + } CommandSetSupportExt; + struct { + USHORT ReservedForDrqTechnicalReport : 1; + USHORT WriteReadVerifyEnabled : 1; + USHORT Reserved01 : 11; + USHORT Reserved1 : 2; + } CommandSetActiveExt; + USHORT ReservedForExpandedSupportandActive[6]; + USHORT MsnSupport : 2; + USHORT ReservedWord1274 : 14; + struct { + USHORT SecuritySupported : 1; + USHORT SecurityEnabled : 1; + USHORT SecurityLocked : 1; + USHORT SecurityFrozen : 1; + USHORT SecurityCountExpired : 1; + USHORT EnhancedSecurityEraseSupported : 1; + USHORT Reserved0 : 2; + USHORT SecurityLevel : 1; + USHORT Reserved1 : 7; + } SecurityStatus; + USHORT ReservedWord129[31]; + struct { + USHORT MaximumCurrentInMA2 : 12; + USHORT CfaPowerMode1Disabled : 1; + USHORT CfaPowerMode1Required : 1; + USHORT Reserved0 : 1; + USHORT Word160Supported : 1; + } CfaPowerModel; + USHORT ReservedForCfaWord161[8]; + struct { + USHORT SupportsTrim : 1; + USHORT Reserved0 : 15; + } DataSetManagementFeature; + USHORT ReservedForCfaWord170[6]; + USHORT CurrentMediaSerialNumber[30]; + USHORT ReservedWord206; + USHORT ReservedWord207[2]; + struct { + USHORT AlignmentOfLogicalWithinPhysical : 14; + USHORT Word209Supported : 1; + USHORT Reserved0 : 1; + } BlockAlignment; + USHORT WriteReadVerifySectorCountMode3Only[2]; + USHORT WriteReadVerifySectorCountMode2Only[2]; + struct { + USHORT NVCachePowerModeEnabled : 1; + USHORT Reserved0 : 3; + USHORT NVCacheFeatureSetEnabled : 1; + USHORT Reserved1 : 3; + USHORT NVCachePowerModeVersion : 4; + USHORT NVCacheFeatureSetVersion : 4; + } NVCacheCapabilities; + USHORT NVCacheSizeLSW; + USHORT NVCacheSizeMSW; + USHORT NominalMediaRotationRate; + USHORT ReservedWord218; + struct { + UCHAR NVCacheEstimatedTimeToSpinUpInSeconds; + UCHAR Reserved; + } NVCacheOptions; + USHORT ReservedWord220[35]; + USHORT Signature : 8; + USHORT CheckSum : 8; +} IDENTIFY_DEVICE_DATA, *PIDENTIFY_DEVICE_DATA; \ No newline at end of file diff --git a/byp/tools/ATAIdentifyDump/pch.cpp b/byp/tools/ATAIdentifyDump/pch.cpp new file mode 100644 index 00000000..1d9f38c5 --- /dev/null +++ b/byp/tools/ATAIdentifyDump/pch.cpp @@ -0,0 +1 @@ +#include "pch.h" diff --git a/byp/tools/ATAIdentifyDump/pch.h b/byp/tools/ATAIdentifyDump/pch.h new file mode 100644 index 00000000..d7aee1f5 --- /dev/null +++ b/byp/tools/ATAIdentifyDump/pch.h @@ -0,0 +1,9 @@ +#ifndef PCH_H +#define PCH_H + +#include +#include +#include +#include "IdentifyDeviceData.h" + +#endif // PCH_H \ No newline at end of file diff --git a/byp/tools/StructDumpCodegen/struct_dump_codegen.linq b/byp/tools/StructDumpCodegen/struct_dump_codegen.linq new file mode 100644 index 00000000..bc566835 --- /dev/null +++ b/byp/tools/StructDumpCodegen/struct_dump_codegen.linq @@ -0,0 +1,213 @@ + + <RuntimeDirectory>\System.Drawing.dll + <RuntimeDirectory>\System.IO.dll + <RuntimeDirectory>\System.Net.dll + <RuntimeDirectory>\System.Numerics.dll + <RuntimeDirectory>\System.Numerics.Vectors.dll + <RuntimeDirectory>\System.Security.dll + System.Collections + System.Collections.Concurrent + System.Collections.Generic + System.Collections.Specialized + System.Drawing + System.Drawing.Imaging + System.IO + System.IO.MemoryMappedFiles + System.IO.Pipes + System.IO.Ports + System.Net + System.Net.Sockets + System.Numerics + System.Runtime.InteropServices + System.Runtime.InteropServices + System.Runtime.Serialization + System.Runtime.Serialization.Formatters.Binary + System.Security + System.Security.AccessControl + System.Security.Cryptography + System.Security.Principal + System.Text + System.Threading + System.Threading.Tasks + + +/* +Script to turn a struct definition into C++ code that prints out its contents. So far it supports USHORT, ULONG, and UCHAR. + +This was written specifically for IDENTIFY_DEVICE_DATA in order to speed up writing ATAIdentifyDump. + +This can probably be used for similar structs too, so it might be useful elsewhere. +*/ + +const string SourceFile = @"C:\Users\Graham\Source\Repos\al-khaser\Tools\ATAIdentifyDump\IdentifyDeviceData.h"; +const string StructVar = "idd"; +const bool SwapStringEndian = true; // for IDENTIFY_DEVICE_DATA + +void Main() +{ + + string[] lines = File.ReadAllLines(SourceFile); + + bool foundStart = false; + bool inStruct = false; + var structLines = new List(); + + var output = new StringBuilder(); + + foreach (string rawLine in lines) + { + var line = rawLine.Trim().TrimEnd(';'); + if (!foundStart) + { + if (line.StartsWith("typedef struct")) + { + foundStart = true; + } + continue; + } + + if (line.StartsWith("struct {")) + { + if (inStruct) + { + throw new InvalidDataException(); + } + + // we're starting a nested structure + inStruct = true; + structLines.Clear(); + continue; + } + + if (line.StartsWith("}")) + { + if (!inStruct) + { + Console.WriteLine("// end"); + break; + } + + // we're ending a nested structure + var structNameMatch = Regex.Match(line, "^}\\s+([a-zA-Z0-9]+)$"); + if (!structNameMatch.Success) + { + throw new InvalidDataException(); + } + + string structName = structNameMatch.Groups[1].Value; + + inStruct = false; + foreach (string structLine in structLines) + { + ProcessLine(StructVar, structLine, structName); + } + continue; + } + + if (inStruct) + { + structLines.Add(line); + continue; + } + + ProcessLine(StructVar, line); + } +} + +void ProcessLine(string structvar, string line, string structname = null) +{ + string[] parts = line.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); + + string fieldType = null; + string fieldName = null; + int arraySize = 0; + + if (parts.Length == 2) + { + fieldType = parts[0]; + if (parts[1].Contains("[")) + { + var arrayMatch = Regex.Match(parts[1], "^([a-zA-Z0-9]+)\\[(\\d+)\\]$"); + if (!arrayMatch.Success) + { + throw new InvalidDataException(); + } + fieldName = arrayMatch.Groups[1].Value; + arraySize = int.Parse(arrayMatch.Groups[2].Value); + } + else + { + fieldName = parts[1]; + } + } + else + { + if (!parts.Contains(":")) + { + throw new InvalidDataException(); + } + + fieldType = parts[0]; + fieldName = parts[1]; + } + + if (structname != null) + { + structname += "."; + } + + if (fieldType == "USHORT") + { + if (arraySize == 0) + { + Console.WriteLine($"printf(\"{structname ?? ""}{fieldName} = %hu\\r\\n\", {structvar}->{structname ?? ""}{fieldName});"); + } + else + { + for (int i = 0; i < arraySize; i++) + { + Console.WriteLine($"printf(\"{structname ?? ""}{fieldName}[{i}] = %hu\\r\\n\", {structvar}->{structname ?? ""}{fieldName}[{i}]);"); + } + } + } + else if (fieldType == "ULONG") + { + if (arraySize == 0) + { + Console.WriteLine($"printf(\"{structname ?? ""}{fieldName} = %lu\\r\\n\", {structvar}->{structname ?? ""}{fieldName});"); + } + else + { + for (int i = 0; i < arraySize; i++) + { + Console.WriteLine($"printf(\"{structname ?? ""}{fieldName}[{i}] = %lu\\r\\n\", {structvar}->{structname ?? ""}{fieldName}[{i}]);"); + } + } + } + else if (fieldType == "UCHAR") + { + if (arraySize == 0) + { + Console.WriteLine($"printf(\"{structname ?? ""}{fieldName} = %d\\r\\n\", {structvar}->{structname ?? ""}{fieldName});"); + } + else + { + string format = string.Concat(Enumerable.Repeat("%c", arraySize)); + Console.Write($"printf(\"{structname ?? ""}{fieldName} = \\\"{format}\\\"\\r\\n\""); + for (int i = 0; i < arraySize; i++) + { + int ni = i; + if (SwapStringEndian) + { + ni = (i - (i % 2)) + (1 - (i % 2)); + } + Console.Write($", {structvar}->{structname ?? ""}{fieldName}[{ni}]"); + } + Console.WriteLine(");"); + } + } + else + { + throw new InvalidDataException(); + } +} \ No newline at end of file